diff --git a/.gitignore b/.gitignore index 2b6cabec..ab2b03cf 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,6 @@ *~ -/build +/lede /output /site -/openwrt +/tmp /packages -/modules.local diff --git a/Makefile b/Makefile index 98faefbc..74a4cd9a 100644 --- a/Makefile +++ b/Makefile @@ -4,503 +4,148 @@ LC_ALL:=C LANG:=C export LC_ALL LANG -export SHELL:=/usr/bin/env bash -GLUONPATH ?= $(PATH) -export GLUONPATH := $(GLUONPATH) +GLUON_SITEDIR ?= $(CURDIR)/site +GLUON_TMPDIR ?= $(CURDIR)/tmp -empty:= -space:= $(empty) $(empty) +GLUON_OUTPUTDIR ?= $(CURDIR)/output +GLUON_IMAGEDIR ?= $(GLUON_OUTPUTDIR)/images +GLUON_MODULEDIR ?= $(GLUON_OUTPUTDIR)/modules -GLUONMAKE_EARLY = PATH=$(GLUONPATH) $(SUBMAKE) -C $(GLUON_ORIGOPENWRTDIR) -f $(GLUONDIR)/Makefile GLUON_TOOLS=0 QUILT= -GLUONMAKE = PATH=$(GLUONPATH) $(SUBMAKE) -C $(GLUON_OPENWRTDIR) -f $(GLUONDIR)/Makefile +export GLUON_TMPDIR GLUON_IMAGEDIR GLUON_MODULEDIR -ifneq ($(OPENWRT_BUILD),1) -GLUONDIR:=${CURDIR} +GLUON_VERSION := $(shell git describe --always --dirty=+ 2>/dev/null || echo unknown) +GLUON_SITE_VERSION := $(shell ( cd $(GLUON_SITEDIR) && git --git-dir=.git describe --always --dirty=+ ) 2>/dev/null || echo unknown) -include $(GLUONDIR)/include/gluon.mk -TOPDIR:=$(GLUON_ORIGOPENWRTDIR) -export TOPDIR +$(GLUON_SITEDIR)/site.mk: + $(error No site configuration was found. Please check out a site configuration to $(GLUON_SITEDIR)) + +-include $(GLUON_SITEDIR)/site.mk + +ifeq ($(GLUON_RELEASE),) +$(error GLUON_RELEASE not set. GLUON_RELEASE can be set in site.mk or on the command line.) +endif + +GLUON_LANGS ?= en + +export GLUON_RELEASE GLUON_ATH10K_MESH GLUON_REGION update: FORCE - $(GLUONDIR)/scripts/update.sh - $(GLUONDIR)/scripts/patch.sh + @scripts/update.sh + @scripts/patch.sh + @scripts/feeds.sh update-patches: FORCE - $(GLUONDIR)/scripts/update.sh - $(GLUONDIR)/scripts/update-patches.sh - $(GLUONDIR)/scripts/patch.sh + @scripts/update.sh + @scripts/update-patches.sh + @scripts/patch.sh --include $(TOPDIR)/include/host.mk - -_SINGLE=export MAKEFLAGS=$(space); - -override OPENWRT_BUILD=1 -override GLUON_TOOLS=1 -GREP_OPTIONS= -export OPENWRT_BUILD GLUON_TOOLS GREP_OPTIONS - --include $(TOPDIR)/include/debug.mk --include $(TOPDIR)/include/depends.mk -include $(GLUONDIR)/include/toplevel.mk +update-feeds: FORCE + @scripts/feeds.sh -include $(GLUONDIR)/targets/targets.mk +GLUON_TARGETS := + +define GluonTarget +gluon_target := $(1)$$(if $(2),-$(2)) +GLUON_TARGETS += $$(gluon_target) +GLUON_TARGET_$$(gluon_target)_BOARD := $(1) +GLUON_TARGET_$$(gluon_target)_SUBTARGET := $(if $(3),$(3),$(2)) +endef + +include targets/targets.mk -CheckTarget := [ -n '$(GLUON_TARGET)' -a -n '$(GLUON_TARGET_$(GLUON_TARGET)_BOARD)' ] \ - || (echo -e 'Please set GLUON_TARGET to a valid target. Gluon supports the following targets:$(subst $(space),\n * ,$(GLUON_TARGETS))'; false) +LEDEMAKE = $(MAKE) -C lede + +BOARD := $(GLUON_TARGET_$(GLUON_TARGET)_BOARD) +SUBTARGET := $(GLUON_TARGET_$(GLUON_TARGET)_SUBTARGET) +LEDE_TARGET := $(BOARD)$(if $(SUBTARGET),-$(SUBTARGET)) + +export LEDE_TARGET -CheckExternal := test -d $(GLUON_ORIGOPENWRTDIR) || (echo 'You don'"'"'t seem to have obtained the external repositories needed by Gluon; please call `make update` first!'; false) +CheckTarget := [ -n '$(GLUON_TARGET)' -a -n '$(LEDE_TARGET)' ] \ + || (echo 'Please set GLUON_TARGET to a valid target. Gluon supports the following targets:'; $(foreach target,$(GLUON_TARGETS),echo ' * $(target)';) false) + +CheckExternal := test -d lede || (echo 'You don'"'"'t seem to have obtained the external repositories needed by Gluon; please call `make update` first!'; false) -create-key: FORCE - @$(CheckExternal) - +@$(GLUONMAKE_EARLY) create-key +GLUON_DEFAULT_PACKAGES := -odhcpd -ppp -ppp-mod-pppoe -uboot-envtools -wpad-mini gluon-core ip6tables hostapd-mini + +GLUON_PACKAGES := +define merge_packages + $(foreach pkg,$(1), + GLUON_PACKAGES := $$(strip $$(filter-out -$$(patsubst -%,%,$(pkg)) $$(patsubst -%,%,$(pkg)),$$(GLUON_PACKAGES)) $(pkg)) + ) +endef +$(eval $(call merge_packages,$(GLUON_DEFAULT_PACKAGES) $(GLUON_SITE_PACKAGES))) + +GLUON_PACKAGES_YES := $(filter-out -%,$(GLUON_PACKAGES)) +GLUON_PACKAGES_NO := $(patsubst -%,%,$(filter -%,$(GLUON_PACKAGES))) + prepare-target: FORCE @$(CheckExternal) @$(CheckTarget) - +@$(GLUONMAKE_EARLY) prepare-target + @( \ + echo 'CONFIG_TARGET_$(BOARD)=y' \ + $(if $(SUBTARGET),&& echo 'CONFIG_TARGET_$(BOARD)_$(SUBTARGET)=y') \ + $(foreach pkg,$(GLUON_PACKAGES_NO),&& echo '# CONFIG_PACKAGE_$(pkg) is not set') \ + && scripts/target_config.sh generic \ + && scripts/target_config.sh '$(GLUON_TARGET)' \ + $(foreach pkg,$(GLUON_PACKAGES_YES),&& echo 'CONFIG_PACKAGE_$(pkg)=y') \ + $(foreach lang,$(GLUON_LANGS),&& echo 'CONFIG_LUCI_LANG_$(lang)=y') \ + && echo 'CONFIG_GLUON_VERSION="$(GLUON_VERSION)"' \ + && echo 'CONFIG_GLUON_SITE_VERSION="$(GLUON_SITE_VERSION)"' \ + && echo 'CONFIG_GLUON_RELEASE="$(GLUON_RELEASE)"' \ + && echo 'CONFIG_GLUON_SITEDIR="$(GLUON_SITEDIR)"' \ + && echo 'CONFIG_GLUON_BRANCH="$(GLUON_BRANCH)"' \ + ) > lede/.config + +@$(LEDEMAKE) defconfig + + # FIXME: check config + # FIXME: opkg config all: prepare-target - +@$(GLUONMAKE) build-key - +@$(GLUONMAKE) prepare - +@$(GLUONMAKE) images - +@$(GLUONMAKE) modules - -prepare: prepare-target - +@$(GLUONMAKE) build-key - +@$(GLUONMAKE) $@ - -clean download images modules: FORCE - @$(CheckExternal) - @$(CheckTarget) - +@$(GLUONMAKE_EARLY) maybe-prepare-target - +@$(GLUONMAKE) build-key - +@$(GLUONMAKE) $@ - -toolchain/% package/% target/% image/%: FORCE - @$(CheckExternal) - @$(CheckTarget) - +@$(GLUONMAKE_EARLY) maybe-prepare-target - +@$(GLUONMAKE) build-key - +@$(GLUONMAKE) $@ - -manifest: FORCE - @[ -n '$(GLUON_BRANCH)' ] || (echo 'Please set GLUON_BRANCH to create a manifest.'; false) - @echo '$(GLUON_PRIORITY)' | grep -qE '^([0-9]*\.)?[0-9]+$$' || (echo 'Please specify a numeric value for GLUON_PRIORITY to create a manifest.'; false) - @$(CheckExternal) - - ( \ - echo 'BRANCH=$(GLUON_BRANCH)' && \ - echo 'DATE=$(shell $(GLUON_ORIGOPENWRTDIR)/staging_dir/host/bin/lua $(GLUONDIR)/scripts/rfc3339date.lua)' && \ - echo 'PRIORITY=$(GLUON_PRIORITY)' && \ - echo \ - ) > $(GLUON_BUILDDIR)/$(GLUON_BRANCH).manifest.tmp - - +($(foreach GLUON_TARGET,$(GLUON_TARGETS), \ - ( [ ! -e $(BOARD_BUILDDIR)/prepared ] || ( $(GLUONMAKE) manifest GLUON_TARGET='$(GLUON_TARGET)' V=s$(OPENWRT_VERBOSE) ) ) && \ - ) :) - - mkdir -p $(GLUON_IMAGEDIR)/sysupgrade - mv $(GLUON_BUILDDIR)/$(GLUON_BRANCH).manifest.tmp $(GLUON_IMAGEDIR)/sysupgrade/$(GLUON_BRANCH).manifest - -dirclean : FORCE - for dir in build_dir dl staging_dir tmp; do \ - rm -rf $(GLUON_ORIGOPENWRTDIR)/$$dir; \ - done - rm -rf $(GLUON_BUILDDIR) $(GLUON_OUTPUTDIR) - -else - -TOPDIR=${CURDIR} -export TOPDIR - -include rules.mk - -include $(GLUONDIR)/include/gluon.mk - -include $(INCLUDE_DIR)/host.mk -include $(INCLUDE_DIR)/depends.mk -include $(INCLUDE_DIR)/subdir.mk - -include package/Makefile -include tools/Makefile -include toolchain/Makefile -include target/Makefile - - -PROFILES := -PROFILE_PACKAGES := - -define Profile - $(eval $(call Profile/Default)) - $(eval $(call Profile/$(1))) -endef - -define GluonProfile -PROFILES += $(1) -PROFILE_PACKAGES += $(filter-out -%,$(2) $(GLUON_$(1)_SITE_PACKAGES)) -GLUON_$(1)_PROFILE := $(if $(3),$(3),$(1)) -GLUON_$(1)_DEFAULT_PACKAGES := $(2) -GLUON_$(1)_FACTORY_SUFFIX := -squashfs-factory -GLUON_$(1)_SYSUPGRADE_SUFFIX := -squashfs-sysupgrade -GLUON_$(1)_FACTORY_EXT := .bin -GLUON_$(1)_SYSUPGRADE_EXT := .bin -GLUON_$(1)_FACTORY_EXTRA := -GLUON_$(1)_SYSUPGRADE_EXTRA := -GLUON_$(1)_MODELS := -endef - -define GluonProfileFactorySuffix -GLUON_$(1)_FACTORY_SUFFIX := $(2) -GLUON_$(1)_FACTORY_EXT := $(3) -GLUON_$(1)_FACTORY_EXTRA := $(4) -endef - -define GluonProfileSysupgradeSuffix -GLUON_$(1)_SYSUPGRADE_SUFFIX := $(2) -GLUON_$(1)_SYSUPGRADE_EXT := $(3) -GLUON_$(1)_SYSUPGRADE_EXTRA := $(4) -endef - -define GluonModel -GLUON_$(1)_MODELS += $(3) -GLUON_$(1)_MODEL_$(3) := $(2) -GLUON_$(1)_MODEL_$(3)_ALIASES := -endef - -define GluonModelAlias -GLUON_$(1)_MODEL_$(2)_ALIASES += $(3) -endef - - -export SHA512SUM := $(GLUONDIR)/scripts/sha512sum.sh - - -prereq: FORCE - +$(NO_TRACE_MAKE) prereq - -prepare-tmpinfo: FORCE - @+$(MAKE) -r -s staging_dir/host/.prereq-build OPENWRT_BUILD= QUIET=0 - mkdir -p tmp/info - $(_SINGLE)$(NO_TRACE_MAKE) -j1 -r -s -f include/scan.mk SCAN_TARGET="packageinfo" SCAN_DIR="package" SCAN_NAME="package" SCAN_DEPS="$(TOPDIR)/include/package*.mk $(TOPDIR)/overlay/*/*.mk" SCAN_EXTRA="" - $(_SINGLE)$(NO_TRACE_MAKE) -j1 -r -s -f include/scan.mk SCAN_TARGET="targetinfo" SCAN_DIR="target/linux" SCAN_NAME="target" SCAN_DEPS="profiles/*.mk $(TOPDIR)/include/kernel*.mk $(TOPDIR)/include/target.mk" SCAN_DEPTH=2 SCAN_EXTRA="" SCAN_MAKEOPTS="TARGET_BUILD=1" - for type in package target; do \ - f=tmp/.$${type}info; t=tmp/.config-$${type}.in; \ - [ "$$t" -nt "$$f" ] || ./scripts/metadata.pl $${type}_config "$$f" > "$$t" || { rm -f "$$t"; echo "Failed to build $$t"; false; break; }; \ - done - [ tmp/.config-feeds.in -nt tmp/.packagefeeds ] || ./scripts/feeds feed_config > tmp/.config-feeds.in - ./scripts/metadata.pl package_mk tmp/.packageinfo > tmp/.packagedeps || { rm -f tmp/.packagedeps; false; } - ./scripts/metadata.pl package_feeds tmp/.packageinfo > tmp/.packagefeeds || { rm -f tmp/.packagefeeds; false; } - touch $(TOPDIR)/tmp/.build - -feeds: FORCE - rm -rf $(TOPDIR)/package/feeds - mkdir $(TOPDIR)/package/feeds - [ ! -f $(GLUON_SITEDIR)/modules ] || . $(GLUON_SITEDIR)/modules && for feed in $$GLUON_SITE_FEEDS; do ln -s ../../../packages/$$feed $(TOPDIR)/package/feeds/$$feed; done - ln -s ../../../package $(TOPDIR)/package/feeds/gluon - . $(GLUONDIR)/modules && for feed in $$GLUON_FEEDS; do ln -s ../../../packages/$$feed $(TOPDIR)/package/feeds/module_$$feed; done - +$(GLUONMAKE_EARLY) prepare-tmpinfo - -gluon-tools: FORCE - +$(GLUONMAKE_EARLY) tools/patch/install - +$(GLUONMAKE_EARLY) tools/sed/install - +$(GLUONMAKE_EARLY) tools/cmake/install - +$(GLUONMAKE_EARLY) package/lua/host/install package/usign/host/install - - - -early_prepared_stamp := $(GLUON_BUILDDIR)/prepared_$(shell \ - ( \ - $(SHA512SUM) $(GLUONDIR)/modules; \ - [ ! -r $(GLUON_SITEDIR)/modules ] || $(SHA512SUM) $(GLUON_SITEDIR)/modules \ - ) | $(SHA512SUM) ) - -prepare-early: FORCE - for dir in build_dir dl staging_dir; do \ - mkdir -p $(GLUON_ORIGOPENWRTDIR)/$$dir; \ - done - - +$(GLUONMAKE_EARLY) feeds - +$(GLUONMAKE_EARLY) gluon-tools - - mkdir -p $$(dirname $(early_prepared_stamp)) - touch $(early_prepared_stamp) - -$(early_prepared_stamp): - rm -f $(GLUON_BUILDDIR)/prepared_* - +$(GLUONMAKE_EARLY) prepare-early - -$(GLUON_OPKG_KEY): $(early_prepared_stamp) FORCE - [ -s $(GLUON_OPKG_KEY) -a -s $(GLUON_OPKG_KEY).pub ] || \ - ( mkdir -p $$(dirname $(GLUON_OPKG_KEY)) && $(STAGING_DIR_HOST)/bin/usign -G -s $(GLUON_OPKG_KEY) -p $(GLUON_OPKG_KEY).pub -c "Gluon opkg key" ) - -$(GLUON_OPKG_KEY).pub: $(GLUON_OPKG_KEY) - -create-key: $(GLUON_OPKG_KEY).pub - -include $(GLUONDIR)/targets/targets.mk - -ifneq ($(GLUON_TARGET),) - -include $(GLUONDIR)/targets/$(GLUON_TARGET)/profiles.mk - -BOARD := $(GLUON_TARGET_$(GLUON_TARGET)_BOARD) -override SUBTARGET := $(GLUON_TARGET_$(GLUON_TARGET)_SUBTARGET) - -target_prepared_stamp := $(BOARD_BUILDDIR)/target-prepared -gluon_prepared_stamp := $(BOARD_BUILDDIR)/prepared - -PREPARED_RELEASE = $$(cat $(gluon_prepared_stamp)) -IMAGE_PREFIX = gluon-$(GLUON_SITE_CODE)-$(PREPARED_RELEASE) -MODULE_PREFIX = gluon-$(GLUON_SITE_CODE)-$(PREPARED_RELEASE) - - -include $(INCLUDE_DIR)/target.mk - -build-key: FORCE - rm -f $(BUILD_KEY) $(BUILD_KEY).pub - cp $(GLUON_OPKG_KEY) $(BUILD_KEY) - cp $(GLUON_OPKG_KEY).pub $(BUILD_KEY).pub - -config: FORCE - +$(NO_TRACE_MAKE) scripts/config/conf OPENWRT_BUILD= QUIET=0 - +$(GLUONMAKE) prepare-tmpinfo - ( \ - cat $(GLUONDIR)/include/config; \ - echo 'CONFIG_TARGET_$(GLUON_TARGET_$(GLUON_TARGET)_BOARD)=y'; \ - $(if $(GLUON_TARGET_$(GLUON_TARGET)_SUBTARGET), \ - echo 'CONFIG_TARGET_$(GLUON_TARGET_$(GLUON_TARGET)_BOARD)_$(GLUON_TARGET_$(GLUON_TARGET)_SUBTARGET)=y'; \ - ) \ - cat $(GLUONDIR)/targets/$(GLUON_TARGET)/config 2>/dev/null; \ - echo 'CONFIG_BUILD_SUFFIX="gluon-$(GLUON_TARGET)"'; \ - echo '$(patsubst %,CONFIG_PACKAGE_%=m,$(sort $(filter-out -%,$(GLUON_DEFAULT_PACKAGES) $(GLUON_SITE_PACKAGES) $(PROFILE_PACKAGES))))' \ - | sed -e 's/ /\n/g'; \ - echo '$(patsubst %,CONFIG_LUCI_LANG_%=y,$(GLUON_LANGS))' \ - | sed -e 's/ /\n/g'; \ - ) > $(BOARD_BUILDDIR)/config.tmp - scripts/config/conf --defconfig=$(BOARD_BUILDDIR)/config.tmp Config.in - +$(SUBMAKE) tools/install - -prepare-target: $(GLUON_OPKG_KEY).pub - rm $(GLUON_OPENWRTDIR)/tmp || true - mkdir -p $(GLUON_OPENWRTDIR)/tmp - - for link in build_dir config Config.in dl include Makefile package rules.mk scripts staging_dir target toolchain tools; do \ - ln -sf $(GLUON_ORIGOPENWRTDIR)/$$link $(GLUON_OPENWRTDIR); \ - done - - +$(GLUONMAKE) config - touch $(target_prepared_stamp) - -$(target_prepared_stamp): - +$(GLUONMAKE_EARLY) prepare-target - -maybe-prepare-target: $(target_prepared_stamp) - +$(GLUONMAKE_EARLY) $(GLUON_OPKG_KEY).pub - -$(BUILD_DIR)/.prepared: Makefile - @mkdir -p $$(dirname $@) - @touch $@ - -$(toolchain/stamp-install): $(tools/stamp-install) -$(package/stamp-compile): $(package/stamp-cleanup) - - -clean: FORCE - +$(SUBMAKE) clean - rm -f $(gluon_prepared_stamp) - - -download: FORCE - +$(SUBMAKE) tools/download - +$(SUBMAKE) toolchain/download - +$(SUBMAKE) package/download - +$(SUBMAKE) target/download - -toolchain: $(toolchain/stamp-install) $(tools/stamp-install) - -include $(INCLUDE_DIR)/kernel.mk - -kernel: FORCE - +$(NO_TRACE_MAKE) -C $(TOPDIR)/target/linux/$(BOARD) $(LINUX_DIR)/.image TARGET_BUILD=1 - +$(NO_TRACE_MAKE) -C $(TOPDIR)/target/linux/$(BOARD) $(LINUX_DIR)/.modules TARGET_BUILD=1 - -packages: $(package/stamp-compile) - $(_SINGLE)$(SUBMAKE) -r package/index - -prepare-image: FORCE - rm -rf $(BOARD_KDIR) - mkdir -p $(BOARD_KDIR) - -cp $(KERNEL_BUILD_DIR)/* $(BOARD_KDIR)/ - +$(SUBMAKE) -C $(TOPDIR)/target/linux/$(BOARD)/image image_prepare KDIR="$(BOARD_KDIR)" - -prepare: FORCE - @$(STAGING_DIR_HOST)/bin/lua $(GLUONDIR)/scripts/site_config.lua \ - || (echo 'Your site configuration did not pass validation.'; false) - - mkdir -p $(GLUON_IMAGEDIR) $(BOARD_BUILDDIR) - echo 'src packages file:../openwrt/bin/$(BOARD)/packages' > $(BOARD_BUILDDIR)/opkg.conf - - +$(GLUONMAKE) toolchain - +$(GLUONMAKE) kernel - +$(GLUONMAKE) packages - +$(GLUONMAKE) prepare-image - - echo "$(GLUON_RELEASE)" > $(gluon_prepared_stamp) - -$(gluon_prepared_stamp): - +$(GLUONMAKE) prepare - -modules: FORCE $(gluon_prepared_stamp) - -rm -f $(GLUON_MODULEDIR)/*/$(BOARD)/$(if $(SUBTARGET),$(SUBTARGET),generic)/* - -rmdir -p $(GLUON_MODULEDIR)/*/$(BOARD)/$(if $(SUBTARGET),$(SUBTARGET),generic) - mkdir -p $(GLUON_MODULEDIR)/$(MODULE_PREFIX)/$(BOARD)/$(if $(SUBTARGET),$(SUBTARGET),generic) - cp $(PACKAGE_DIR)/kmod-*.ipk $(GLUON_MODULEDIR)/$(MODULE_PREFIX)/$(BOARD)/$(if $(SUBTARGET),$(SUBTARGET),generic) - - $(_SINGLE)$(SUBMAKE) -r package/index PACKAGE_DIR=$(GLUON_MODULEDIR)/$(MODULE_PREFIX)/$(BOARD)/$(if $(SUBTARGET),$(SUBTARGET),generic) - - -include $(INCLUDE_DIR)/package-ipkg.mk - -# override variables from rules.mk -PACKAGE_DIR = $(GLUON_OPENWRTDIR)/bin/$(BOARD)/packages - -PROFILE_BUILDDIR = $(BOARD_BUILDDIR)/profiles/$(PROFILE) -PROFILE_KDIR = $(PROFILE_BUILDDIR)/kernel -BIN_DIR = $(PROFILE_BUILDDIR)/images - -TARGET_DIR = $(PROFILE_BUILDDIR)/root - -OPKG:= \ - TMPDIR="$(TMP_DIR)" \ - IPKG_INSTROOT="$(TARGET_DIR)" \ - IPKG_CONF_DIR="$(TMP_DIR)" \ - IPKG_OFFLINE_ROOT="$(TARGET_DIR)" \ - $(STAGING_DIR_HOST)/bin/opkg \ - -f $(BOARD_BUILDDIR)/opkg.conf \ - --cache $(TMP_DIR)/dl \ - --offline-root $(TARGET_DIR) \ - --force-postinstall \ - --add-dest root:/ \ - --add-arch all:100 \ - --add-arch $(ARCH_PACKAGES):200 - -EnableInitscript = ! grep -q '\#!/bin/sh /etc/rc.common' $(1) || bash ./etc/rc.common $(1) enable - - -enable_initscripts: FORCE - cd $(TARGET_DIR) && ( export IPKG_INSTROOT=$(TARGET_DIR); \ - $(foreach script,$(wildcard $(TARGET_DIR)/etc/init.d/*), \ - $(call EnableInitscript,$(script)); \ - ) : \ - ) - - -# Generate package list -$(eval $(call merge-lists,INSTALL_PACKAGES,DEFAULT_PACKAGES GLUON_DEFAULT_PACKAGES GLUON_SITE_PACKAGES GLUON_$(PROFILE)_DEFAULT_PACKAGES GLUON_$(PROFILE)_SITE_PACKAGES)) - -package_install: FORCE - $(OPKG) update - $(OPKG) install $(PACKAGE_DIR)/base-files_*.ipk $(PACKAGE_DIR)/libc_*.ipk - $(OPKG) install $(PACKAGE_DIR)/kernel_*.ipk - - $(OPKG) install $(INSTALL_PACKAGES) - +$(GLUONMAKE) enable_initscripts - - rm -f $(TARGET_DIR)/usr/lib/opkg/lists/* $(TARGET_DIR)/tmp/opkg.lock - rm -f $(TARGET_DIR)/usr/lib/opkg/info/*.postinst* - -# Remove opkg database when opkg is not intalled - if [ ! -x $(TARGET_DIR)/bin/opkg ]; then rm -rf $(TARGET_DIR)/usr/lib/opkg; fi - - -include $(INCLUDE_DIR)/version.mk - -opkg_config: FORCE - for d in base packages luci routing telephony management; do \ - echo "src/gz %n_$$d %U/$$d"; \ - done > $(TARGET_DIR)/etc/opkg/distfeeds.conf - $(VERSION_SED) $(TARGET_DIR)/etc/opkg/distfeeds.conf - - -image: FORCE - rm -rf $(TARGET_DIR) $(BIN_DIR) $(PROFILE_KDIR) - mkdir -p $(TARGET_DIR) $(BIN_DIR) $(TARGET_DIR)/tmp $(GLUON_IMAGEDIR)/factory $(GLUON_IMAGEDIR)/sysupgrade - cp -r $(BOARD_KDIR) $(PROFILE_KDIR) - - +$(GLUONMAKE) package_install - +$(GLUONMAKE) opkg_config - - $(call Image/mkfs/prepare) - $(_SINGLE)$(NO_TRACE_MAKE) -C $(TOPDIR)/target/linux/$(BOARD)/image install TARGET_BUILD=1 IMG_PREFIX=gluon \ - PROFILE="$(GLUON_$(PROFILE)_PROFILE)" KDIR="$(PROFILE_KDIR)" TARGET_DIR="$(TARGET_DIR)" BIN_DIR="$(BIN_DIR)" TMP_DIR="$(TMP_DIR)" - - $(foreach model,$(GLUON_$(PROFILE)_MODELS), \ - $(if $(GLUON_$(PROFILE)_SYSUPGRADE_EXT), \ - rm -f $(GLUON_IMAGEDIR)/sysupgrade/gluon-*-$(model)-sysupgrade$(GLUON_$(PROFILE)_SYSUPGRADE_EXT) && \ - cp $(BIN_DIR)/gluon-$(GLUON_$(PROFILE)_MODEL_$(model))$(GLUON_$(PROFILE)_SYSUPGRADE_SUFFIX)$(GLUON_$(PROFILE)_SYSUPGRADE_EXT) $(GLUON_IMAGEDIR)/sysupgrade/$(IMAGE_PREFIX)-$(model)-sysupgrade$(GLUON_$(PROFILE)_SYSUPGRADE_EXT) && \ - ) \ - $(if $(GLUON_$(PROFILE)_FACTORY_EXT), \ - rm -f $(GLUON_IMAGEDIR)/factory/gluon-*-$(model)$(GLUON_$(PROFILE)_FACTORY_EXT) && \ - cp $(BIN_DIR)/gluon-$(GLUON_$(PROFILE)_MODEL_$(model))$(GLUON_$(PROFILE)_FACTORY_SUFFIX)$(GLUON_$(PROFILE)_FACTORY_EXT) $(GLUON_IMAGEDIR)/factory/$(IMAGE_PREFIX)-$(model)$(GLUON_$(PROFILE)_FACTORY_EXT) && \ - ) \ - \ - $(if $(GLUON_$(PROFILE)_SYSUPGRADE_EXTRA), \ - rm -f $(GLUON_IMAGEDIR)/sysupgrade/gluon-*-$(model)-sysupgrade$(GLUON_$(PROFILE)_SYSUPGRADE_EXTRA) && \ - cp $(BIN_DIR)/gluon$(GLUON_$(PROFILE)_SYSUPGRADE_EXTRA) $(GLUON_IMAGEDIR)/sysupgrade/$(IMAGE_PREFIX)-$(model)-sysupgrade$(GLUON_$(PROFILE)_SYSUPGRADE_EXTRA) && \ - ) \ - $(if $(GLUON_$(PROFILE)_FACTORY_EXTRA), \ - rm -f $(GLUON_IMAGEDIR)/factory/gluon-*-$(model)$(GLUON_$(PROFILE)_FACTORY_EXTRA) && \ - cp $(BIN_DIR)/gluon$(GLUON_$(PROFILE)_FACTORY_EXTRA) $(GLUON_IMAGEDIR)/factory/$(IMAGE_PREFIX)-$(model)$(GLUON_$(PROFILE)_FACTORY_EXTRA) && \ - ) \ - \ - $(foreach alias,$(GLUON_$(PROFILE)_MODEL_$(model)_ALIASES), \ - $(if $(GLUON_$(PROFILE)_SYSUPGRADE_EXT), \ - rm -f $(GLUON_IMAGEDIR)/sysupgrade/gluon-*-$(alias)-sysupgrade$(GLUON_$(PROFILE)_SYSUPGRADE_EXT) && \ - ln -s $(IMAGE_PREFIX)-$(model)-sysupgrade$(GLUON_$(PROFILE)_SYSUPGRADE_EXT) $(GLUON_IMAGEDIR)/sysupgrade/$(IMAGE_PREFIX)-$(alias)-sysupgrade$(GLUON_$(PROFILE)_SYSUPGRADE_EXT) && \ - ) \ - $(if $(GLUON_$(PROFILE)_FACTORY_EXT), \ - rm -f $(GLUON_IMAGEDIR)/factory/gluon-*-$(alias)$(GLUON_$(PROFILE)_FACTORY_EXT) && \ - ln -s $(IMAGE_PREFIX)-$(model)$(GLUON_$(PROFILE)_FACTORY_EXT) $(GLUON_IMAGEDIR)/factory/$(IMAGE_PREFIX)-$(alias)$(GLUON_$(PROFILE)_FACTORY_EXT) && \ - ) \ - ) \ - ) : - - -image/%: $(gluon_prepared_stamp) - +$(GLUONMAKE) image PROFILE="$(patsubst image/%,%,$@)" V=s$(OPENWRT_VERBOSE) - -call_image/%: FORCE - +$(GLUONMAKE) $(patsubst call_image/%,image/%,$@) - -images: $(patsubst %,call_image/%,$(PROFILES)) ; - -manifest: FORCE - ( \ - cd $(GLUON_IMAGEDIR)/sysupgrade; \ - $(foreach profile,$(PROFILES), \ - $(if $(GLUON_$(profile)_SYSUPGRADE_EXT), \ - $(foreach model,$(GLUON_$(profile)_MODELS), \ - file="$(IMAGE_PREFIX)-$(model)-sysupgrade$(GLUON_$(profile)_SYSUPGRADE_EXT)"; \ - [ -e "$$file" ] && echo '$(model)' "$(PREPARED_RELEASE)" "$$($(SHA512SUM) "$$file")" "$$file"; \ - \ - $(foreach alias,$(GLUON_$(profile)_MODEL_$(model)_ALIASES), \ - file="$(IMAGE_PREFIX)-$(alias)-sysupgrade$(GLUON_$(profile)_SYSUPGRADE_EXT)"; \ - [ -e "$$file" ] && echo '$(alias)' "$(PREPARED_RELEASE)" "$$($(SHA512SUM) "$$file")" "$$file"; \ - ) \ - ) \ - ) \ - ) : \ - ) >> $(GLUON_BUILDDIR)/$(GLUON_BRANCH).manifest.tmp - -.PHONY: all create-key prepare images modules clean gluon-tools manifest - -endif -endif + +@$(LEDEMAKE) tools/install + +@$(LEDEMAKE) package/lua/host/install + # FIXME: early site check + + +@$(LEDEMAKE) + @scripts/copy_output.sh '$(GLUON_TARGET)' + +clean download: prepare-target + +@$(LEDEMAKE) $@ + +dirclean: FORCE + +@$(LEDEMAKE) defconfig + +@$(LEDEMAKE) dirclean + rm -rf $(GLUON_TMPDIR) $(GLUON_OUTPUTDIR) + +#manifest: FORCE +# @[ -n '$(GLUON_BRANCH)' ] || (echo 'Please set GLUON_BRANCH to create a manifest.'; false) +# @echo '$(GLUON_PRIORITY)' | grep -qE '^([0-9]*\.)?[0-9]+$$' || (echo 'Please specify a numeric value for GLUON_PRIORITY to create a manifest.'; false) +# @$(CheckExternal) +# +# ( \ +# echo 'BRANCH=$(GLUON_BRANCH)' && \ +# echo 'DATE=$(shell $(GLUON_ORIGOPENWRTDIR)/staging_dir/host/bin/lua scripts/rfc3339date.lua)' && \ +# echo 'PRIORITY=$(GLUON_PRIORITY)' && \ +# echo \ +# ) > $(GLUON_BUILDDIR)/$(GLUON_BRANCH).manifest.tmp +# +# +($(foreach GLUON_TARGET,$(GLUON_TARGETS), \ +# ( [ ! -e $(BOARD_BUILDDIR)/prepared ] || ( $(GLUONMAKE) manifest GLUON_TARGET='$(GLUON_TARGET)' V=s$(OPENWRT_VERBOSE) ) ) && \ +# ) :) +# +# mkdir -p $(GLUON_IMAGEDIR)/sysupgrade +# mv $(GLUON_BUILDDIR)/$(GLUON_BRANCH).manifest.tmp $(GLUON_IMAGEDIR)/sysupgrade/$(GLUON_BRANCH).manifest + +FORCE: ; + +.PHONY: FORCE +.NOTPARALLEL: diff --git a/include/config b/include/config deleted file mode 100644 index 12f8a7d4..00000000 --- a/include/config +++ /dev/null @@ -1,22 +0,0 @@ -CONFIG_IMAGEOPT=y -# CONFIG_PER_FEED_REPO is not set -# CONFIG_TARGET_ROOTFS_INITRAMFS is not set -CONFIG_DEVEL=y -CONFIG_ALL_KMODS=y - -CONFIG_BUSYBOX_CUSTOM=y -CONFIG_BUSYBOX_CONFIG_SHA512SUM=y -# CONFIG_BUSYBOX_CONFIG_FEATURE_PREFER_IPV4_ADDRESS is not set -CONFIG_BUSYBOX_CONFIG_IP=y -CONFIG_BUSYBOX_CONFIG_FEATURE_IP_ADDRESS=y -CONFIG_BUSYBOX_CONFIG_FEATURE_IP_LINK=y -CONFIG_BUSYBOX_CONFIG_FEATURE_IP_ROUTE=y -CONFIG_BUSYBOX_CONFIG_FEATURE_IP_TUNNEL=y -CONFIG_BUSYBOX_CONFIG_FEATURE_IP_RULE=y -CONFIG_BUSYBOX_CONFIG_FEATURE_IP_SHORT_FORMS=y -CONFIG_BUSYBOX_CONFIG_FEATURE_WGET_TIMEOUT=y - -CONFIG_ATH_USER_REGD=y -CONFIG_PACKAGE_ATH_DEBUG=y - -CONFIG_LUCI_SRCDIET=y diff --git a/include/gluon.mk b/include/gluon.mk deleted file mode 100644 index 29ecf3ed..00000000 --- a/include/gluon.mk +++ /dev/null @@ -1,85 +0,0 @@ -ifneq ($(__gluon_inc),1) -__gluon_inc=1 - -GLUON_SITEDIR ?= $(GLUONDIR)/site -GLUON_BUILDDIR ?= $(GLUONDIR)/build - -GLUON_ORIGOPENWRTDIR := $(GLUONDIR)/openwrt -GLUON_SITE_CONFIG := $(GLUON_SITEDIR)/site.conf - -GLUON_OUTPUTDIR ?= $(GLUONDIR)/output -GLUON_IMAGEDIR ?= $(GLUON_OUTPUTDIR)/images -GLUON_MODULEDIR ?= $(GLUON_OUTPUTDIR)/modules - -GLUON_OPKG_KEY ?= $(GLUON_BUILDDIR)/gluon-opkg-key - -export GLUONDIR GLUON_SITEDIR GLUON_BUILDDIR GLUON_SITE_CONFIG GLUON_OUTPUTDIR GLUON_IMAGEDIR GLUON_MODULEDIR - - -BOARD_BUILDDIR = $(GLUON_BUILDDIR)/$(GLUON_TARGET) -BOARD_KDIR = $(BOARD_BUILDDIR)/kernel - -export BOARD_BUILDDIR - - -LINUX_RELEASE := 2 -export LINUX_RELEASE - - -GLUON_OPENWRTDIR = $(BOARD_BUILDDIR)/openwrt - - -$(GLUON_SITEDIR)/site.mk: - $(error There was no site configuration found. Please check out a site configuration to $(GLUON_SITEDIR)) - --include $(GLUON_SITEDIR)/site.mk - - -GLUON_VERSION := $(shell cd $(GLUONDIR) && git describe --always --dirty=+ 2>/dev/null || echo unknown) -export GLUON_VERSION - -GLUON_SITE_VERSION := $(shell cd $(GLUON_SITEDIR) && git --git-dir=.git describe --always --dirty=+ 2>/dev/null || echo unknown) -export GLUON_SITE_VERSION - -GLUON_LANGS ?= en -export GLUON_LANGS - - -ifeq ($(OPENWRT_BUILD),1) -ifeq ($(GLUON_TOOLS),1) - -GLUON_OPENWRT_FEEDS := base packages luci routing telephony management -export GLUON_OPENWRT_FEEDS - -GLUON_SITE_CODE := $(shell $(GLUONDIR)/scripts/site.sh site_code) -export GLUON_SITE_CODE - -ifeq ($(GLUON_RELEASE),) -$(error GLUON_RELEASE not set. GLUON_RELEASE can be set in site.mk or on the command line.) -endif -export GLUON_RELEASE - -endif -endif - - -define merge-lists -$(1) := -$(foreach var,$(2),$(1) := $$(filter-out -% $$(patsubst -%,%,$$(filter -%,$$($(var)))),$$($(1)) $$($(var))) -) -endef - -GLUON_TARGETS := - -define GluonTarget -gluon_target := $(1)$$(if $(2),-$(2)) -GLUON_TARGETS += $$(gluon_target) -GLUON_TARGET_$$(gluon_target)_BOARD := $(1) -GLUON_TARGET_$$(gluon_target)_SUBTARGET := $(2) -endef - -GLUON_DEFAULT_PACKAGES := gluon-core firewall ip6tables -uboot-envtools -wpad-mini hostapd-mini - -override DEFAULT_PACKAGES.router := - -endif #__gluon_inc diff --git a/include/toplevel.mk b/include/toplevel.mk deleted file mode 100644 index 087a7a19..00000000 --- a/include/toplevel.mk +++ /dev/null @@ -1,62 +0,0 @@ -# Makefile for OpenWrt -# -# Copyright (C) 2007-2012 OpenWrt.org -# Copyright (C) 2013-2014 Project Gluon -# -# This is free software, licensed under the GNU General Public License v2. -# See /LICENSE for more information. -# - -RELEASE:=Chaos Calmer -PREP_MK= OPENWRT_BUILD= QUIET=0 - -export IS_TTY=$(shell tty -s && echo 1 || echo 0) - -include $(GLUONDIR)/include/verbose.mk - -REVISION:=$(shell [ -d $(TOPDIR) ] && cd $(TOPDIR) && ./scripts/getver.sh 2>/dev/null) - -HOSTCC ?= gcc -OPENWRTVERSION:=$(RELEASE)$(if $(REVISION), ($(REVISION))) -export RELEASE -export REVISION -export OPENWRTVERSION -export IS_TTY=$(shell tty -s && echo 1 || echo 0) -export LD_LIBRARY_PATH:=$(subst ::,:,$(if $(LD_LIBRARY_PATH),$(LD_LIBRARY_PATH):)$(STAGING_DIR_HOST)/lib) -export DYLD_LIBRARY_PATH:=$(subst ::,:,$(if $(DYLD_LIBRARY_PATH),$(DYLD_LIBRARY_PATH):)$(STAGING_DIR_HOST)/lib) -export GIT_CONFIG_PARAMETERS='core.autocrlf=false' -export MAKE_JOBSERVER=$(filter --jobserver%,$(MAKEFLAGS)) - -# prevent perforce from messing with the patch utility -unexport P4PORT P4USER P4CONFIG P4CLIENT - -# prevent user defaults for quilt from interfering -unexport QUILT_PATCHES QUILT_PATCH_OPTS - -unexport C_INCLUDE_PATH CROSS_COMPILE ARCH - -# prevent distro default LPATH from interfering -unexport LPATH - -# make sure that a predefined CFLAGS variable does not disturb packages -export CFLAGS= - -ifneq ($(shell $(HOSTCC) 2>&1 | grep clang),) - export HOSTCC_REAL?=$(HOSTCC) - export HOSTCC_WRAPPER:=$(TOPDIR)/scripts/clang-gcc-wrapper -else - export HOSTCC_WRAPPER:=$(HOSTCC) -endif - -SCAN_COOKIE?=$(shell echo $$$$) -export SCAN_COOKIE - -SUBMAKE:=umask 022; $(SUBMAKE) - -ULIMIT_FIX=_limit=`ulimit -n`; [ "$$_limit" = "unlimited" -o "$$_limit" -ge 1024 ] || ulimit -n 1024; - -FORCE: ; - -.PHONY: FORCE -.NOTPARALLEL: - diff --git a/include/verbose.mk b/include/verbose.mk deleted file mode 100644 index d34f55fc..00000000 --- a/include/verbose.mk +++ /dev/null @@ -1,67 +0,0 @@ -# -# Copyright (C) 2006 OpenWrt.org -# -# This is free software, licensed under the GNU General Public License v2. -# See /LICENSE for more information. -# - -ifndef OPENWRT_VERBOSE - OPENWRT_VERBOSE:= -endif -ifeq ("$(origin V)", "command line") - OPENWRT_VERBOSE:=$(V) -endif - -ifeq ($(OPENWRT_VERBOSE),1) - OPENWRT_VERBOSE:=w -endif -ifeq ($(OPENWRT_VERBOSE),99) - OPENWRT_VERBOSE:=s -endif - -ifeq ($(NO_TRACE_MAKE),) -NO_TRACE_MAKE := $(MAKE) V=s$(OPENWRT_VERBOSE) -export NO_TRACE_MAKE -endif - -ifeq ($(IS_TTY),1) - ifneq ($(strip $(NO_COLOR)),1) - _Y:=\\033[33m - _R:=\\033[31m - _N:=\\033[m - endif -endif - -ifeq ($(findstring s,$(OPENWRT_VERBOSE)),) - define MESSAGE - printf "$(_Y)%s$(_N)\n" "$(1)" >&8 - endef - - define ERROR_MESSAGE - printf "$(_R)%s$(_N)\n" "$(1)" >&8 - endef - - ifeq ($(QUIET),1) - ifneq ($(CURDIR),$(TOPDIR)) - _DIR:=$(patsubst $(TOPDIR)/%,%,${CURDIR}) - else - _DIR:= - endif - _NULL:=$(if $(MAKECMDGOALS),$(shell \ - $(call MESSAGE, make[$(MAKELEVEL)]$(if $(_DIR), -C $(_DIR)) $(MAKECMDGOALS)); \ - )) - SUBMAKE=$(MAKE) - else - SILENT:=>/dev/null $(if $(findstring w,$(OPENWRT_VERBOSE)),,2>&1) - export QUIET:=1 - SUBMAKE=cmd() { $(SILENT) $(MAKE) -s $$* < /dev/null || { echo "make $$*: build failed. Please re-run make with V=s to see what's going on"; false; } } 8>&1 9>&2; cmd - endif - - .SILENT: $(MAKECMDGOALS) -else - SUBMAKE=$(MAKE) -w - define MESSAGE - printf "%s\n" "$(1)" - endef - ERROR_MESSAGE=$(MESSAGE) -endif diff --git a/modules b/modules index 0a9a16de..ece15fe0 100644 --- a/modules +++ b/modules @@ -1,12 +1,10 @@ GLUON_FEEDS='openwrt gluon routing luci' -OPENWRT_REPO=git://github.com/openwrt/openwrt.git -OPENWRT_COMMIT=0f757bd2606971252f901ef3faf4dbd0086315f7 -OPENWRT_BRANCH=chaos_calmer +LEDE_REPO=git://git.lede-project.org/source.git +LEDE_COMMIT=7c47f43fe650309e6a2383c99273dc1bde367bc1 PACKAGES_OPENWRT_REPO=git://github.com/openwrt/packages.git -PACKAGES_OPENWRT_COMMIT=73776792f7d58e982be9e5819450d4875b273159 -PACKAGES_OPENWRT_BRANCH=for-15.05 +PACKAGES_OPENWRT_COMMIT=18ce1a8f18a7c5ab2b654b8d30d85a381d36abcb PACKAGES_GLUON_REPO=git://github.com/freifunk-gluon/packages.git PACKAGES_GLUON_COMMIT=5280cd19070ccccc36a39dc48c7f51fe76bc4268 @@ -15,5 +13,4 @@ PACKAGES_ROUTING_REPO=git://github.com/openwrt-routing/packages.git PACKAGES_ROUTING_COMMIT=899235a4a6370e86ad3674c38c3f95d23c8f3dc8 PACKAGES_LUCI_REPO=git://github.com/openwrt/luci.git -PACKAGES_LUCI_COMMIT=70a4d43cc895b7d728b4fc201f2b6fd9f4b8aaec -PACKAGES_LUCI_BRANCH=for-15.05 +PACKAGES_LUCI_COMMIT=e65f6512e7d6978eab01e4ee473dafa88320e9f8 diff --git a/package/gluon-autoupdater/Makefile b/package/gluon-autoupdater/Makefile index 41cdf796..6e133c81 100644 --- a/package/gluon-autoupdater/Makefile +++ b/package/gluon-autoupdater/Makefile @@ -2,11 +2,13 @@ include $(TOPDIR)/rules.mk PKG_NAME:=gluon-autoupdater PKG_VERSION:=4 -PKG_RELEASE:=$(GLUON_BRANCH) PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME) + +PKG_CONFIG_DEPENDS := CONFIG_GLUON_BRANCH PKG_BUILD_DEPENDS := respondd + include ../gluon.mk @@ -17,6 +19,13 @@ define Package/gluon-autoupdater TITLE:=Automatically update firmware endef +define Package/gluon-autoupdater/config +config GLUON_BRANCH + string "Gluon autoupdater branch" + depends on PACKAGE_gluon-autoupdater + default "" +endef + define Build/Prepare mkdir -p $(PKG_BUILD_DIR) $(CP) ./src/* $(PKG_BUILD_DIR)/ @@ -34,10 +43,10 @@ define Package/gluon-autoupdater/install $(INSTALL_DIR) $(1)/lib/gluon/respondd $(CP) $(PKG_BUILD_DIR)/respondd.so $(1)/lib/gluon/respondd/autoupdater.so - if [ '$(GLUON_BRANCH)' ]; then \ - $(INSTALL_DIR) $(1)/lib/gluon/autoupdater; \ - echo '$(GLUON_BRANCH)' > $(1)/lib/gluon/autoupdater/default_branch; \ - fi +ifneq ($(CONFIG_GLUON_BRANCH),"") + $(INSTALL_DIR) $(1)/lib/gluon/autoupdater + echo '$(call qstrip,$(CONFIG_GLUON_BRANCH))' > $(1)/lib/gluon/autoupdater/default_branch +endif endef define Package/gluon-autoupdater/postinst diff --git a/package/gluon-core/Makefile b/package/gluon-core/Makefile index 3e0ae059..5f326f42 100644 --- a/package/gluon-core/Makefile +++ b/package/gluon-core/Makefile @@ -2,7 +2,8 @@ include $(TOPDIR)/rules.mk PKG_NAME:=gluon-core PKG_VERSION:=3 -PKG_RELEASE:=$(GLUON_VERSION) + +PKG_CONFIG_DEPENDS := CONFIG_GLUON_VERSION PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME) @@ -20,8 +21,16 @@ define Package/gluon-core/description Gluon community wifi mesh firmware framework: core endef -define Build/Prepare - mkdir -p $(PKG_BUILD_DIR) +define Package/gluon-core/config +config GLUON_VERSION + string "Gluon version number" + depends on PACKAGE_gluon-core + default "" + +config GLUON_SITE_VERSION + string "Gluon site version number" + depends on PACKAGE_gluon-core + default "" endef define Build/Configure @@ -34,11 +43,10 @@ endef define Package/gluon-core/install $(CP) ./files/* $(1)/ $(CP) $(PKG_BUILD_DIR)/luadest/* $(1)/ - $(SED) 's/__GLUON_OPENWRT_FEEDS__/{$(GLUON_OPENWRT_FEEDS:%="%",)}/' $(1)/lib/gluon/upgrade/500-opkg $(INSTALL_DIR) $(1)/lib/gluon - echo "$(GLUON_VERSION)" > $(1)/lib/gluon/gluon-version - echo "$(GLUON_SITE_VERSION)" > $(1)/lib/gluon/site-version + echo '$(call qstrip,$(CONFIG_GLUON_VERSION))' > $(1)/lib/gluon/gluon-version + echo '$(call qstrip,$(CONFIG_GLUON_SITE_VERSION))' > $(1)/lib/gluon/site-version endef define Package/gluon-core/postinst diff --git a/package/gluon-core/luasrc/lib/gluon/upgrade/500-opkg b/package/gluon-core/luasrc/lib/gluon/upgrade/500-opkg index 4380050c..858ca005 100755 --- a/package/gluon-core/luasrc/lib/gluon/upgrade/500-opkg +++ b/package/gluon-core/luasrc/lib/gluon/upgrade/500-opkg @@ -24,10 +24,9 @@ end if site.opkg then if site.opkg.openwrt then - local url = replace_patterns(site.opkg.openwrt) local f = io.open('/etc/opkg/distfeeds.conf', 'w') - for _, v in ipairs(__GLUON_OPENWRT_FEEDS__) do + for _, v in ipairs("base", "packages", "luci", "routing", "telephony", "management") do f:write(replace_patterns(string.format('src/gz %%n_%s %s/%s\n', v, site.opkg.openwrt, v))) end diff --git a/package/gluon-setup-mode/files/lib/gluon/setup-mode/rc.d/K50dropbear b/package/gluon-setup-mode/files/lib/gluon/setup-mode/rc.d/K50dropbear deleted file mode 120000 index 066549b3..00000000 --- a/package/gluon-setup-mode/files/lib/gluon/setup-mode/rc.d/K50dropbear +++ /dev/null @@ -1 +0,0 @@ -/etc/init.d/dropbear \ No newline at end of file diff --git a/package/gluon-setup-mode/files/lib/gluon/setup-mode/rc.d/S13haveged b/package/gluon-setup-mode/files/lib/gluon/setup-mode/rc.d/S13haveged index b4af677a..27b1a595 100755 --- a/package/gluon-setup-mode/files/lib/gluon/setup-mode/rc.d/S13haveged +++ b/package/gluon-setup-mode/files/lib/gluon/setup-mode/rc.d/S13haveged @@ -1,5 +1,5 @@ #!/bin/sh /etc/rc.common -if /etc/init.d/haveged enabled; then +if [ -x /etc/init.d/haveged ] && /etc/init.d/haveged enabled; then . /etc/init.d/haveged fi diff --git a/package/gluon-setup-mode/files/lib/gluon/setup-mode/rc.d/S50dropbear b/package/gluon-setup-mode/files/lib/gluon/setup-mode/rc.d/S50dropbear deleted file mode 120000 index 066549b3..00000000 --- a/package/gluon-setup-mode/files/lib/gluon/setup-mode/rc.d/S50dropbear +++ /dev/null @@ -1 +0,0 @@ -/etc/init.d/dropbear \ No newline at end of file diff --git a/package/gluon-setup-mode/files/lib/gluon/setup-mode/rc.d/S50dropbear b/package/gluon-setup-mode/files/lib/gluon/setup-mode/rc.d/S50dropbear new file mode 100755 index 00000000..590aede3 --- /dev/null +++ b/package/gluon-setup-mode/files/lib/gluon/setup-mode/rc.d/S50dropbear @@ -0,0 +1,21 @@ +#!/bin/sh /etc/rc.common + +USE_PROCD=1 +PROG=/usr/sbin/dropbear +NAME=dropbear + +start_service() { + [ -x /etc/init.d/dropbear ] || return 0 + + . /etc/init.d/dropbear + + [ -s /etc/dropbear/dropbear_rsa_host_key ] || keygen + + . /lib/functions.sh + . /lib/functions/network.sh + + procd_open_instance + procd_set_param command "$PROG" -F -f + procd_set_param respawn + procd_close_instance +} diff --git a/package/gluon-setup-mode/files/lib/gluon/setup-mode/rc.d/S50telnet b/package/gluon-setup-mode/files/lib/gluon/setup-mode/rc.d/S50telnet deleted file mode 100755 index b524b2ce..00000000 --- a/package/gluon-setup-mode/files/lib/gluon/setup-mode/rc.d/S50telnet +++ /dev/null @@ -1,12 +0,0 @@ -#!/bin/sh /etc/rc.common - -START=50 - -USE_PROCD=1 -PROG=/usr/sbin/telnetd - -start_service() { - procd_open_instance - procd_set_param command "$PROG" -F -l /lib/gluon/setup-mode/ash-login - procd_close_instance -} diff --git a/package/gluon-site/Makefile b/package/gluon-site/Makefile index b7138e3c..426a52d5 100644 --- a/package/gluon-site/Makefile +++ b/package/gluon-site/Makefile @@ -1,9 +1,11 @@ include $(TOPDIR)/rules.mk PKG_NAME:=gluon-site -PKG_VERSION:=$(if $(GLUON_SITE_CODE),$(GLUON_SITE_CODE),1) -PKG_RELEASE:=$(GLUON_RELEASE) +PKG_VERSION:=1 +GLUON_SITEDIR = '$(call qstrip,$(CONFIG_GLUON_SITEDIR))' + +PKG_CONFIG_DEPENDS := CONFIG_GLUON_RELEASE CONFIG_GLUON_SITEDIR PKG_FILE_DEPENDS := $(GLUON_SITEDIR)/site.conf $(GLUON_SITEDIR)/i18n/ PKG_BUILD_DEPENDS := luci-base/host lua-cjson/host @@ -20,6 +22,18 @@ define Package/gluon-site TITLE:=Site-specific files of Gluon endef +define Package/gluon-site/config +config GLUON_RELEASE + string "Gluon release number" + depends on PACKAGE_gluon-site + default "" + +config GLUON_SITEDIR + string "Gluon site configuration directory" + depends on PACKAGE_gluon-site + default "" +endef + define Build/Prepare mkdir -p $(PKG_BUILD_DIR) endef @@ -28,14 +42,14 @@ define Build/Configure endef define Build/Compile - lua -e 'print(require("cjson").encode(assert(dofile("../../scripts/site_config.lua"))))' > $(PKG_BUILD_DIR)/site.json + lua -e 'arg = {$(CONFIG_GLUON_SITEDIR)}; print(require("cjson").encode(assert(dofile("../../scripts/site_config.lua"))))' > $(PKG_BUILD_DIR)/site.json $(call GluonBuildI18N,gluon-site,$(GLUON_SITEDIR)/i18n) endef define Package/gluon-site/install $(INSTALL_DIR) $(1)/lib/gluon $(INSTALL_DATA) $(PKG_BUILD_DIR)/site.json $(1)/lib/gluon/ - echo "$(GLUON_RELEASE)" > $(1)/lib/gluon/release + echo '$(call qstrip,$(CONFIG_GLUON_RELEASE))' > $(1)/lib/gluon/release $(call GluonInstallI18N,gluon-site,$(1)) endef diff --git a/package/gluon.mk b/package/gluon.mk index 9d35ad3c..f51cfce8 100644 --- a/package/gluon.mk +++ b/package/gluon.mk @@ -5,13 +5,13 @@ include $(INCLUDE_DIR)/package.mk # Annoyingly, make's shell function replaces all newlines with spaces, so we have to do some escaping work. Yuck. define GluonCheckSite -[ -z "$$GLUONDIR" ] || sed -e 's/-@/\n/g' -e 's/+@/@/g' <<'END__GLUON__CHECK__SITE' | "$$GLUONDIR"/scripts/check_site.sh +[ -z "$$TOPDIR" ] || sed -e 's/-@/\n/g' -e 's/+@/@/g' <<'END__GLUON__CHECK__SITE' | "$$TOPDIR"/../scripts/check_site.sh $(shell cat $(1) | sed -ne '1h; 1!H; $$ {g; s/@/+@/g; s/\n/-@/g; p}') END__GLUON__CHECK__SITE endef # Languages supported by LuCi -GLUON_SUPPORTED_LANGS := ca zh_cn en fr de el he hu it ja ms no pl pt_br pt ro ru es sv uk vi +GLUON_SUPPORTED_LANGS := ca cs de el en es fr he hu it ja ms no pl pt-br pt ro ru sk sv tr uk vi zh-cn zh-tw GLUON_I18N_PACKAGES := $(foreach lang,$(GLUON_SUPPORTED_LANGS),+LUCI_LANG_$(lang):luci-i18n-base-$(lang)) GLUON_I18N_CONFIG := $(foreach lang,$(GLUON_SUPPORTED_LANGS),CONFIG_LUCI_LANG_$(lang)) @@ -41,11 +41,9 @@ define GluonSrcDiet rm -rf $(2) $(CP) $(1) $(2) $(FIND) $(2) -type f | while read src; do \ - if $(STAGING_DIR_HOST)/bin/lua $(STAGING_DIR_HOST)/bin/LuaSrcDiet \ - --noopt-binequiv -o "$$$$src.o" "$$$$src"; \ - then \ - chmod $$$$(stat -c%a "$$$$src") "$$$$src.o"; \ - mv "$$$$src.o" "$$$$src"; \ - fi; \ + if LuaSrcDiet --noopt-binequiv -o "$$$$src.o" "$$$$src"; then \ + chmod $$$$(stat -c%a "$$$$src") "$$$$src.o"; \ + mv "$$$$src.o" "$$$$src"; \ + fi; \ done endef diff --git a/patches/openwrt/0002-procd-add-support-for-alternative-rc.d-directories.patch b/patches/lede/0001-procd-add-support-for-alternative-rc.d-directories.patch similarity index 100% rename from patches/openwrt/0002-procd-add-support-for-alternative-rc.d-directories.patch rename to patches/lede/0001-procd-add-support-for-alternative-rc.d-directories.patch diff --git a/patches/openwrt/0003-odhcp6c-always-accept-RDNSS-independent-of-the-default-router-lifetime.patch b/patches/lede/0002-odhcp6c-always-accept-RDNSS-independently-of-the-default-router-lifetime.patch similarity index 71% rename from patches/openwrt/0003-odhcp6c-always-accept-RDNSS-independent-of-the-default-router-lifetime.patch rename to patches/lede/0002-odhcp6c-always-accept-RDNSS-independently-of-the-default-router-lifetime.patch index 82de5300..2adf6c62 100644 --- a/patches/openwrt/0003-odhcp6c-always-accept-RDNSS-independent-of-the-default-router-lifetime.patch +++ b/patches/lede/0002-odhcp6c-always-accept-RDNSS-independently-of-the-default-router-lifetime.patch @@ -1,16 +1,16 @@ From: Matthias Schiffer Date: Thu, 13 Nov 2014 01:17:24 +0100 -Subject: odhcp6c: always accept RDNSS, independent of the default router lifetime +Subject: odhcp6c: always accept RDNSS, independently of the default router lifetime diff --git a/package/network/ipv6/odhcp6c/patches/001-always_accept_rdnss.patch b/package/network/ipv6/odhcp6c/patches/001-always_accept_rdnss.patch new file mode 100644 -index 0000000..cb694ca +index 0000000..b9a9a83 --- /dev/null +++ b/package/network/ipv6/odhcp6c/patches/001-always_accept_rdnss.patch -@@ -0,0 +1,21 @@ +@@ -0,0 +1,22 @@ +--- a/src/ra.c ++++ b/src/ra.c -+@@ -438,18 +438,6 @@ bool ra_process(void) ++@@ -442,19 +442,6 @@ bool ra_process(void) + } + } + } @@ -20,8 +20,9 @@ index 0000000..cb694ca +- size_t ra_dns_len; +- uint8_t *start = odhcp6c_get_state(states[i], &ra_dns_len); +- for (struct odhcp6c_entry *c = (struct odhcp6c_entry*)start; -+- (uint8_t*)c < &start[ra_dns_len] && &c->auxtarget[c->auxlen] <= &start[ra_dns_len]; -+- c = (struct odhcp6c_entry*)(&c->auxtarget[c->auxlen])) ++- (uint8_t*)c < &start[ra_dns_len] && ++- (uint8_t*)odhcp6c_next_entry(c) <= &start[ra_dns_len]; ++- c = odhcp6c_next_entry(c)) +- if (IN6_ARE_ADDR_EQUAL(&c->router, &from.sin6_addr) && +- c->valid > router_valid) +- c->valid = router_valid; diff --git a/patches/openwrt/0005-base-files-disable-reset-button-handling.patch b/patches/lede/0003-base-files-disable-reset-button-handling.patch similarity index 50% rename from patches/openwrt/0005-base-files-disable-reset-button-handling.patch rename to patches/lede/0003-base-files-disable-reset-button-handling.patch index a889df96..4bc53510 100644 --- a/patches/openwrt/0005-base-files-disable-reset-button-handling.patch +++ b/patches/lede/0003-base-files-disable-reset-button-handling.patch @@ -6,27 +6,38 @@ This conflicts with our reset button usage. diff --git a/package/base-files/files/etc/rc.button/reset b/package/base-files/files/etc/rc.button/reset deleted file mode 100755 -index 3e24146..0000000 +index 4265767..0000000 --- a/package/base-files/files/etc/rc.button/reset +++ /dev/null -@@ -1,20 +0,0 @@ +@@ -1,31 +0,0 @@ -#!/bin/sh - --[ "${ACTION}" = "released" ] || exit 0 -- -. /lib/functions.sh - --logger "$BUTTON pressed for $SEEN seconds" +-OVERLAY="$( grep ' /overlay ' /proc/mounts )" - --if [ "$SEEN" -lt 1 ] --then -- echo "REBOOT" > /dev/console -- sync -- reboot --elif [ "$SEEN" -gt 5 ] --then -- echo "FACTORY RESET" > /dev/console -- jffs2reset -y && reboot & --fi +-case "$ACTION" in +-pressed) +- [ -z "$OVERLAY" ] && return 0 +- +- return 5 +-;; +-timeout) +- . /etc/diag.sh +- set_state failsafe +-;; +-released) +- if [ "$SEEN" -lt 1 ] +- then +- echo "REBOOT" > /dev/console +- sync +- reboot +- elif [ "$SEEN" -gt 5 -a -n "$OVERLAY" ] +- then +- echo "FACTORY RESET" > /dev/console +- jffs2reset -y && reboot & +- fi +-;; +-esac - -return 0 diff --git a/patches/openwrt/0009-hostapd-prevent-channel-switch-for-5GHz.patch b/patches/lede/0004-hostapd-prevent-channel-switch-for-5GHz.patch similarity index 100% rename from patches/openwrt/0009-hostapd-prevent-channel-switch-for-5GHz.patch rename to patches/lede/0004-hostapd-prevent-channel-switch-for-5GHz.patch diff --git a/patches/openwrt/0042-libjson-c-Add-support-for-custom-format-strings-for-doubles.patch b/patches/lede/0005-libjson-c-Add-support-for-custom-format-strings-for-doubles.patch similarity index 100% rename from patches/openwrt/0042-libjson-c-Add-support-for-custom-format-strings-for-doubles.patch rename to patches/lede/0005-libjson-c-Add-support-for-custom-format-strings-for-doubles.patch diff --git a/patches/lede/0006-dropbear-add-a-failsafe-mode-that-will-always-allow-password-less-root-login.patch b/patches/lede/0006-dropbear-add-a-failsafe-mode-that-will-always-allow-password-less-root-login.patch new file mode 100644 index 00000000..b145157a --- /dev/null +++ b/patches/lede/0006-dropbear-add-a-failsafe-mode-that-will-always-allow-password-less-root-login.patch @@ -0,0 +1,69 @@ +From: Matthias Schiffer +Date: Tue, 27 Sep 2016 03:55:55 +0200 +Subject: dropbear: add a failsafe mode that will always allow password-less root login + +Signed-off-by: Matthias Schiffer + +diff --git a/package/network/services/dropbear/patches/700-failsafe-mode.patch b/package/network/services/dropbear/patches/700-failsafe-mode.patch +new file mode 100644 +index 0000000..c6e4542 +--- /dev/null ++++ b/package/network/services/dropbear/patches/700-failsafe-mode.patch +@@ -0,0 +1,57 @@ ++--- a/runopts.h +++++ b/runopts.h ++@@ -97,6 +97,8 @@ typedef struct svr_runopts { ++ int norootpass; ++ int allowblankpass; ++ +++ int failsafe_mode; +++ ++ #ifdef ENABLE_SVR_REMOTETCPFWD ++ int noremotetcp; ++ #endif ++--- a/svr-auth.c +++++ b/svr-auth.c ++@@ -149,10 +149,11 @@ void recv_msg_userauth_request() { ++ AUTH_METHOD_NONE_LEN) == 0) { ++ TRACE(("recv_msg_userauth_request: 'none' request")) ++ if (valid_user ++- && (svr_opts.allowblankpass || !strcmp(ses.authstate.pw_name, "root")) ++- && !svr_opts.noauthpass ++- && !(svr_opts.norootpass && ses.authstate.pw_uid == 0) ++- && ses.authstate.pw_passwd[0] == '\0') +++ && ((svr_opts.failsafe_mode && !strcmp(ses.authstate.pw_name, "root")) +++ || ((svr_opts.allowblankpass || !strcmp(ses.authstate.pw_name, "root")) +++ && !svr_opts.noauthpass +++ && !(svr_opts.norootpass && ses.authstate.pw_uid == 0) +++ && ses.authstate.pw_passwd[0] == '\0'))) ++ { ++ dropbear_log(LOG_NOTICE, ++ "Auth succeeded with blank password for '%s' from %s", ++--- a/svr-runopts.c +++++ b/svr-runopts.c ++@@ -72,6 +72,7 @@ static void printhelp(const char * progn ++ "-s Disable password logins\n" ++ "-g Disable password logins for root\n" ++ "-B Allow blank password logins\n" +++ "-f Failsafe mode: always allow password-less root login\n" ++ #endif ++ #ifdef ENABLE_SVR_LOCALTCPFWD ++ "-j Disable local port forwarding\n" ++@@ -130,6 +131,7 @@ void svr_getopts(int argc, char ** argv) ++ svr_opts.noauthpass = 0; ++ svr_opts.norootpass = 0; ++ svr_opts.allowblankpass = 0; +++ svr_opts.failsafe_mode = 0; ++ svr_opts.inetdmode = 0; ++ svr_opts.portcount = 0; ++ svr_opts.hostkey = NULL; ++@@ -244,6 +246,9 @@ void svr_getopts(int argc, char ** argv) ++ case 'B': ++ svr_opts.allowblankpass = 1; ++ break; +++ case 'f': +++ svr_opts.failsafe_mode = 1; +++ break; ++ #endif ++ case 'h': ++ printhelp(argv[0]); diff --git a/patches/openwrt/0001-tools-Makefile-fix-host-tools-build-dependencies.patch b/patches/openwrt/0001-tools-Makefile-fix-host-tools-build-dependencies.patch deleted file mode 100644 index 0db0eda7..00000000 --- a/patches/openwrt/0001-tools-Makefile-fix-host-tools-build-dependencies.patch +++ /dev/null @@ -1,36 +0,0 @@ -From: Matthias Schiffer -Date: Sat, 26 Jul 2014 06:10:23 +0200 -Subject: tools/Makefile: fix host tools build dependencies - -diff --git a/tools/Makefile b/tools/Makefile -index d2fe2ff..c6cded8 100644 ---- a/tools/Makefile -+++ b/tools/Makefile -@@ -95,10 +95,16 @@ define PrepareStaging - endef - - # preparatory work -+ifneq ($(ARCH),) -+staging_prepared = $(STAGING_DIR)/.prepared -+ - $(STAGING_DIR)/.prepared: $(TMP_DIR)/.build - $(call PrepareStaging,$(STAGING_DIR)) - mkdir -p $(BUILD_DIR)/stamp - touch $@ -+else -+staging_prepared := -+endif - - $(STAGING_DIR_HOST)/.prepared: $(TMP_DIR)/.build - $(call PrepareStaging,$(STAGING_DIR_HOST)) -@@ -110,8 +116,8 @@ $(STAGING_DIR_HOST)/.prepared: $(TMP_DIR)/.build - - endif - --$(curdir)//prepare = $(STAGING_DIR)/.prepared $(STAGING_DIR_HOST)/.prepared --$(curdir)//compile = $(STAGING_DIR)/.prepared $(STAGING_DIR_HOST)/.prepared -+$(curdir)//prepare = $(staging_prepared) $(STAGING_DIR_HOST)/.prepared -+$(curdir)//compile = $(staging_prepared) $(STAGING_DIR_HOST)/.prepared - - # prerequisites for the individual targets - $(curdir)/ := .config prereq diff --git a/patches/openwrt/0004-busybox-enable-telnet-only-when-root-password-is-really-empty-not-when-it-is-locked.patch b/patches/openwrt/0004-busybox-enable-telnet-only-when-root-password-is-really-empty-not-when-it-is-locked.patch deleted file mode 100644 index 772ade62..00000000 --- a/patches/openwrt/0004-busybox-enable-telnet-only-when-root-password-is-really-empty-not-when-it-is-locked.patch +++ /dev/null @@ -1,26 +0,0 @@ -From: Matthias Schiffer -Date: Fri, 5 Dec 2014 18:57:16 +0100 -Subject: busybox: enable telnet only when root password is really empty, not when it is locked - -diff --git a/package/utils/busybox/files/telnet b/package/utils/busybox/files/telnet -index a1d1cdf..f95be90 100755 ---- a/package/utils/busybox/files/telnet -+++ b/package/utils/busybox/files/telnet -@@ -11,7 +11,7 @@ has_root_pwd() { - pwd="${pwd#*root:}" - pwd="${pwd%%:*}" - -- test -n "${pwd#[\!x]}" -+ test -n "${pwd}" - } - - get_root_home() { -@@ -28,7 +28,7 @@ has_ssh_pubkey() { - - start_service() { - if ( ! has_ssh_pubkey && \ -- ! has_root_pwd /etc/passwd && ! has_root_pwd /etc/shadow ) || \ -+ ( ! has_root_pwd /etc/passwd || ! has_root_pwd /etc/shadow ) ) || \ - ( ! /etc/init.d/dropbear enabled 2> /dev/null && ! /etc/init.d/sshd enabled 2> /dev/null ); - then - procd_open_instance diff --git a/patches/openwrt/0006-ar71xx-define-wmac-reset-function-for-QCA955x.patch b/patches/openwrt/0006-ar71xx-define-wmac-reset-function-for-QCA955x.patch deleted file mode 100644 index 81d95a9a..00000000 --- a/patches/openwrt/0006-ar71xx-define-wmac-reset-function-for-QCA955x.patch +++ /dev/null @@ -1,85 +0,0 @@ -From: Matthias Schiffer -Date: Tue, 19 Jul 2016 17:48:53 +0200 -Subject: ar71xx: define wmac reset function for QCA955x - -Signed-off-by: Felix Fietkau - -Backport of LEDE a176168a85477caa44eef7e979567d1d52868fde - -diff --git a/target/linux/ar71xx/patches-3.18/640-MIPS-ath79-add-QCA955x-wmac-reset.patch b/target/linux/ar71xx/patches-3.18/640-MIPS-ath79-add-QCA955x-wmac-reset.patch -new file mode 100644 -index 0000000..4ac5acd ---- /dev/null -+++ b/target/linux/ar71xx/patches-3.18/640-MIPS-ath79-add-QCA955x-wmac-reset.patch -@@ -0,0 +1,71 @@ -+--- a/arch/mips/ath79/common.h -++++ b/arch/mips/ath79/common.h -+@@ -19,6 +19,8 @@ -+ #define ATH79_MEM_SIZE_MIN (2 * 1024 * 1024) -+ #define ATH79_MEM_SIZE_MAX (128 * 1024 * 1024) -+ -++extern void __iomem *ath79_ddr_base; -++ -+ void ath79_clocks_init(void); -+ unsigned long ath79_get_sys_clk_rate(const char *id); -+ -+--- a/arch/mips/ath79/dev-wmac.c -++++ b/arch/mips/ath79/dev-wmac.c -+@@ -149,6 +149,27 @@ static void ar934x_wmac_setup(void) -+ ath79_wmac_data.is_clk_25mhz = true; -+ } -+ -++static int ar955x_wmac_reset(void) -++{ -++ int i; -++ -++ /* Try to wait for WMAC DDR activity to stop */ -++ for (i = 0; i < 10; i++) { -++ if (!(__raw_readl(ath79_ddr_base + QCA955X_DDR_CTL_CONFIG) & -++ QCA955X_DDR_CTL_CONFIG_ACT_WMAC)) -++ break; -++ -++ udelay(10); -++ } -++ -++ ath79_device_reset_set(QCA955X_RESET_RTC); -++ udelay(10); -++ ath79_device_reset_clear(QCA955X_RESET_RTC); -++ udelay(10); -++ -++ return 0; -++} -++ -+ static void qca955x_wmac_setup(void) -+ { -+ u32 t; -+@@ -165,6 +186,8 @@ static void qca955x_wmac_setup(void) -+ ath79_wmac_data.is_clk_25mhz = false; -+ else -+ ath79_wmac_data.is_clk_25mhz = true; -++ -++ ath79_wmac_data.external_reset = ar955x_wmac_reset; -+ } -+ -+ static bool __init -+--- a/arch/mips/include/asm/mach-ath79/ar71xx_regs.h -++++ b/arch/mips/include/asm/mach-ath79/ar71xx_regs.h -+@@ -32,7 +32,7 @@ -+ #define AR71XX_SPI_SIZE 0x01000000 -+ -+ #define AR71XX_DDR_CTRL_BASE (AR71XX_APB_BASE + 0x00000000) -+-#define AR71XX_DDR_CTRL_SIZE 0x100 -++#define AR71XX_DDR_CTRL_SIZE 0x200 -+ #define AR71XX_UART_BASE (AR71XX_APB_BASE + 0x00020000) -+ #define AR71XX_UART_SIZE 0x100 -+ #define AR71XX_USB_CTRL_BASE (AR71XX_APB_BASE + 0x00030000) -+@@ -173,6 +173,9 @@ -+ #define AR934X_DDR_REG_FLUSH_PCIE 0xa8 -+ #define AR934X_DDR_REG_FLUSH_WMAC 0xac -+ -++#define QCA955X_DDR_CTL_CONFIG 0x108 -++#define QCA955X_DDR_CTL_CONFIG_ACT_WMAC BIT(23) -++ -+ /* -+ * PLL block -+ */ diff --git a/patches/openwrt/0007-mac80211-hostapd-iw-.-update.patch b/patches/openwrt/0007-mac80211-hostapd-iw-.-update.patch deleted file mode 100644 index 59103f84..00000000 --- a/patches/openwrt/0007-mac80211-hostapd-iw-.-update.patch +++ /dev/null @@ -1,25894 +0,0 @@ -From: Matthias Schiffer -Date: Tue, 11 Oct 2016 02:53:43 +0200 -Subject: mac80211, hostapd, iw, ...: update - -The following package is updated to -LEDE 6c2651566cce8f5b3a3d3b976439dee2bac5e07e: - -* mac80211 - -The following packages are updated to -LEDE 42f559ed70897a7b74dd3e6293b42e6d2e511eaa: - -* acx-mac80211 -* ath10k-firmware -* hostapd -* iw -* linux-firmware -* mt76 - -diff --git a/package/firmware/ath10k-firmware/Makefile b/package/firmware/ath10k-firmware/Makefile -index b03d644..624da6a 100644 ---- a/package/firmware/ath10k-firmware/Makefile -+++ b/package/firmware/ath10k-firmware/Makefile -@@ -8,7 +8,7 @@ - include $(TOPDIR)/rules.mk - - PKG_NAME:=ath10k-firmware --PKG_SOURCE_VERSION:=77f72b5f7dd940386d9e619a17904987759b7186 -+PKG_SOURCE_VERSION:=b00eb8d30fbebb6a5047ccacefa8c37e072fca9c - PKG_VERSION:=2014-11-13-$(PKG_SOURCE_VERSION) - PKG_RELEASE:=1 - -@@ -17,7 +17,7 @@ PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz - PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION) - PKG_SOURCE_URL:=https://github.com/kvalo/ath10k-firmware.git - --PKG_MAINTAINER:=Felix Fietkau -+PKG_MAINTAINER:=Felix Fietkau - - include $(INCLUDE_DIR)/package.mk - -@@ -28,14 +28,48 @@ define Package/ath10k-firmware-default - CATEGORY:=Kernel modules - SUBMENU:=$(WMENU) - URL:=$(PKG_SOURCE_URL) -+ DEPENDS:= - endef - -+define Package/ath10k-firmware-qca9887 -+$(Package/ath10k-firmware-default) -+ TITLE:=ath10k firmware for QCA9887 devices -+endef -+ -+QCA9887_REV:=3cce88e245f2d685e49411c4f80998f94baf67b8 -+QCA9887_FIRMWARE_FILE:=firmware-5.bin_10.2.4-1.0-00013 -+QCA9887_FIRMWARE_FILE_MD5:=bd9cdcbf49561c7176432a81c29e7e87 -+QCA9887_FIRMWARE_FILE_DL:=$(QCA9887_FIRMWARE_FILE).$(QCA9887_FIRMWARE_FILE_MD5) -+QCA9887_BOARD_FILE:=board.bin -+QCA9887_BOARD_FILE_MD5:=ebf3af10160c45373f19e0b8226b02ae -+QCA9887_BOARD_FILE_DL:=$(QCA9887_BOARD_FILE).$(QCA9887_BOARD_FILE_MD5) -+ -+define Download/ath10k-qca9887-firmware -+ URL:=https://github.com/kvalo/ath10k-firmware/raw/$(QCA9887_REV)/QCA9887/hw1.0/ -+ URL_FILE:=$(QCA9887_FIRMWARE_FILE) -+ FILE:=$(QCA9887_FIRMWARE_FILE_DL) -+ MD5SUM:=$(QCA9887_FIRMWARE_FILE_MD5) -+endef -+$(eval $(call Download,ath10k-qca9887-firmware)) -+ -+define Download/ath10k-qca9887-board -+ URL:=https://github.com/kvalo/ath10k-firmware/raw/$(QCA9887_REV)/QCA9887/hw1.0/ -+ URL_FILE:=$(QCA9887_BOARD_FILE) -+ FILE:=$(QCA9887_BOARD_FILE_DL) -+ MD5SUM:=$(QCA9887_BOARD_FILE_MD5) -+endef -+$(eval $(call Download,ath10k-qca9887-board)) -+ - define Package/ath10k-firmware-qca988x - $(Package/ath10k-firmware-default) -+ DEFAULT:=PACKAGE_kmod-ath10k - TITLE:=ath10k firmware for QCA988x devices - endef - - QCA988X_FIRMWARE_FILE:=firmware-5.bin_10.2.4.97-1 -+QCA988X_FIRMWARE_FILE_CT:=firmware-2-ct-full-community-16.1.bin-lede -+QCA99X0_FIRMWARE_FILE_CT:=firmware-5-ct-full-community-7.bin-lede.004 -+QCA9984_FIRMWARE_FILE_CT:=firmware-5-ct-full-community-7.bin-lede.004 - - define Download/ath10k-firmware-qca988x - URL:=https://www.codeaurora.org/cgit/quic/qsdk/oss/firmware/ath10k-firmware/plain/10.2.4/ -@@ -44,11 +78,83 @@ define Download/ath10k-firmware-qca988x - endef - $(eval $(call Download,ath10k-firmware-qca988x)) - -+define Download/ath10k-firmware-qca988x-ct -+ URL:=https://www.candelatech.com/downloads/ -+ FILE:=$(QCA988X_FIRMWARE_FILE_CT) -+ MD5SUM:=d7e081e9782936ed544b78994c9133fb -+endef -+$(eval $(call Download,ath10k-firmware-qca988x-ct)) -+ -+define Download/ath10k-firmware-qca99x0-ct -+ URL:=https://www.candelatech.com/downloads/ath10k-10-4/ -+ FILE:=$(QCA99X0_FIRMWARE_FILE_CT) -+ MD5SUM:=809bb9bf8a18ea218a8e1b9ffc0f8447 -+endef -+$(eval $(call Download,ath10k-firmware-qca99x0-ct)) -+ -+define Download/ath10k-firmware-qca9984-ct -+ URL:=https://www.candelatech.com/downloads/ath10k-9984-10-4/ -+ FILE:=$(QCA9984_FIRMWARE_FILE_CT) -+ MD5SUM:=924eb8ea30de11299b13e207469a3350 -+endef -+$(eval $(call Download,ath10k-firmware-qca9984-ct)) -+ - define Package/ath10k-firmware-qca99x0 - $(Package/ath10k-firmware-default) - TITLE:=ath10k firmware for QCA99x0 devices - endef - -+define Package/ath10k-firmware-qca988x-ct -+$(Package/ath10k-firmware-default) -+ TITLE:=ath10k CT 10.1 firmware for QCA988x devices -+endef -+ -+define Package/ath10k-firmware-qca988x-ct/description -+Alternative ath10k firmware for QCA988X from Candela Technologies. -+Enables IBSS and other features. See: -+http://www.candelatech.com/ath10k-10.1.php -+This firmware will NOT be used unless the standard ath10k-firmware-qca988x -+is un-selected since the driver will try to load firmware-5.bin before -+firmware-2.bin -+endef -+ -+define Package/ath10k-firmware-qca99x0-ct/description -+Alternative ath10k firmware for QCA99x0 from Candela Technologies. -+Enables IBSS and other features. See: -+http://www.candelatech.com/ath10k-10.4.php -+This firmware conflicts with the standard 99x0 firmware, so select only -+one. -+endef -+ -+define Package/ath10k-firmware-qca9984-ct/description -+Alternative ath10k firmware for QCA9984 from Candela Technologies. -+Enables IBSS and other features. See: -+http://www.candelatech.com/ath10k-10.4-9984.php -+This firmware conflicts with the standard 9984 firmware, so select only -+one. -+endef -+ -+define Package/ath10k-firmware-qca99x0/description -+Standard ath10k firmware for QCA99x0 from QCA -+This firmware conflicts with the CT 99x0 firmware, so select only -+one. -+endef -+ -+define Package/ath10k-firmware-qca99x0-ct -+$(Package/ath10k-firmware-default) -+ TITLE:=ath10k CT 10.4.3 firmware for QCA99x0 devices -+endef -+ -+define Package/ath10k-firmware-qca9984-ct -+$(Package/ath10k-firmware-default) -+ TITLE:=ath10k CT 10.4.3 firmware for QCA9984 devices -+endef -+ -+define Package/ath10k-firmware-qca9984 -+$(Package/ath10k-firmware-default) -+ TITLE:=ath10k firmware for QCA9984 devices -+endef -+ - define Package/ath10k-firmware-qca6174 - $(Package/ath10k-firmware-default) - TITLE:=ath10k firmware for QCA6174 devices -@@ -58,8 +164,8 @@ QCA99X0_BOARD_REV:=ddcec9efd245da9365c474f513a855a55f3ac7fe - QCA99X0_BOARD_FILE:=board-2.bin.$(QCA99X0_BOARD_REV) - - define Download/qca99x0-board -- URL:=https://www.codeaurora.org/cgit/quic/qsdk/oss/firmware/ath10k-firmware/plain/ath10k/QCA99X0/hw2.0 -- URL_FILE:=board-2.bin?id=ddcec9efd245da9365c474f513a855a55f3ac7fe -+ URL:=https://source.codeaurora.org/quic/qsdk/oss/firmware/ath10k-firmware/plain/ath10k/QCA99X0/hw2.0 -+ URL_FILE:=board-2.bin?id=$(QCA99X0_BOARD_REV) - FILE:=$(QCA99X0_BOARD_FILE) - MD5SUM:=a2b3c653c2363a5641200051d6333d0a - endef -@@ -69,6 +175,16 @@ define Build/Compile - - endef - -+define Package/ath10k-firmware-qca9887/install -+ $(INSTALL_DIR) $(1)/lib/firmware/ath10k/QCA9887/hw1.0 -+ $(INSTALL_DATA) \ -+ $(DL_DIR)/$(QCA9887_FIRMWARE_FILE_DL) \ -+ $(1)/lib/firmware/ath10k/QCA9887/hw1.0/firmware-5.bin -+ $(INSTALL_DATA) \ -+ $(DL_DIR)/$(QCA9887_BOARD_FILE_DL) \ -+ $(1)/lib/firmware/ath10k/QCA9887/hw1.0/board.bin -+endef -+ - define Package/ath10k-firmware-qca988x/install - $(INSTALL_DIR) $(1)/lib/firmware/ath10k/QCA988X/hw2.0 - $(INSTALL_DATA) \ -@@ -79,6 +195,16 @@ define Package/ath10k-firmware-qca988x/install - $(1)/lib/firmware/ath10k/QCA988X/hw2.0/firmware-5.bin - endef - -+define Package/ath10k-firmware-qca988x-ct/install -+ $(INSTALL_DIR) $(1)/lib/firmware/ath10k/QCA988X/hw2.0 -+ $(INSTALL_DATA) \ -+ $(PKG_BUILD_DIR)/QCA988X/board.bin \ -+ $(1)/lib/firmware/ath10k/QCA988X/hw2.0/ -+ $(INSTALL_DATA) \ -+ $(DL_DIR)/$(QCA988X_FIRMWARE_FILE_CT) \ -+ $(1)/lib/firmware/ath10k/QCA988X/hw2.0/firmware-2.bin -+endef -+ - define Package/ath10k-firmware-qca6174/install - $(INSTALL_DIR) $(1)/lib/firmware/ath10k - $(CP) $(PKG_BUILD_DIR)/QCA6174 $(1)/lib/firmware/ath10k/ -@@ -97,6 +223,51 @@ define Package/ath10k-firmware-qca99x0/install - $(1)/lib/firmware/ath10k/QCA99X0/hw2.0/firmware-5.bin - endef - -+define Package/ath10k-firmware-qca99x0-ct/install -+ $(INSTALL_DIR) $(1)/lib/firmware/ath10k/QCA99X0/hw2.0 -+ $(INSTALL_DATA) \ -+ $(DL_DIR)/$(QCA99X0_BOARD_FILE) \ -+ $(1)/lib/firmware/ath10k/QCA99X0/hw2.0/board-2.bin -+ $(INSTALL_DATA) \ -+ $(PKG_BUILD_DIR)/QCA99X0/hw2.0/boardData_AR900B_CUS239_5G_v2_001.bin \ -+ $(1)/lib/firmware/ath10k/QCA99X0/hw2.0/board.bin -+ $(INSTALL_DATA) \ -+ $(DL_DIR)/$(QCA99X0_FIRMWARE_FILE_CT) \ -+ $(1)/lib/firmware/ath10k/QCA99X0/hw2.0/firmware-5.bin -+endef -+ -+define Package/ath10k-firmware-qca9984/install -+ $(INSTALL_DIR) $(1)/lib/firmware/ath10k/QCA9984/hw1.0 -+ ln -s \ -+ ../../cal-pci-0000:01:00.0.bin \ -+ $(1)/lib/firmware/ath10k/QCA9984/hw1.0/board.bin -+ $(INSTALL_DATA) \ -+ $(PKG_BUILD_DIR)/QCA9984/hw1.0/board-2.bin \ -+ $(1)/lib/firmware/ath10k/QCA9984/hw1.0/board-2.bin -+ $(INSTALL_DATA) \ -+ $(PKG_BUILD_DIR)/QCA9984/hw1.0/firmware-5.bin_10.4-3.2-00072 \ -+ $(1)/lib/firmware/ath10k/QCA9984/hw1.0/firmware-5.bin -+endef -+ -+define Package/ath10k-firmware-qca9984-ct/install -+ $(INSTALL_DIR) $(1)/lib/firmware/ath10k/QCA9984/hw1.0 -+ ln -s \ -+ ../../cal-pci-0000:01:00.0.bin \ -+ $(1)/lib/firmware/ath10k/QCA9984/hw1.0/board.bin -+ $(INSTALL_DATA) \ -+ $(PKG_BUILD_DIR)/QCA9984/hw1.0/board-2.bin \ -+ $(1)/lib/firmware/ath10k/QCA9984/hw1.0/board-2.bin -+ $(INSTALL_DATA) \ -+ $(DL_DIR)/$(QCA9984_FIRMWARE_FILE_CT) \ -+ $(1)/lib/firmware/ath10k/QCA9984/hw1.0/firmware-5.bin -+endef -+ -+$(eval $(call BuildPackage,ath10k-firmware-qca9887)) - $(eval $(call BuildPackage,ath10k-firmware-qca988x)) - $(eval $(call BuildPackage,ath10k-firmware-qca99x0)) - $(eval $(call BuildPackage,ath10k-firmware-qca6174)) -+$(eval $(call BuildPackage,ath10k-firmware-qca9984)) -+ -+$(eval $(call BuildPackage,ath10k-firmware-qca988x-ct)) -+$(eval $(call BuildPackage,ath10k-firmware-qca99x0-ct)) -+$(eval $(call BuildPackage,ath10k-firmware-qca9984-ct)) -diff --git a/package/firmware/linux-firmware/Makefile b/package/firmware/linux-firmware/Makefile -index 2fcd93b..ae5894c 100644 ---- a/package/firmware/linux-firmware/Makefile -+++ b/package/firmware/linux-firmware/Makefile -@@ -17,9 +17,9 @@ PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz - PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_SOURCE_VERSION) - PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_SOURCE_SUBDIR) - PKG_SOURCE_URL:=git://git.kernel.org/pub/scm/linux/kernel/git/firmware/linux-firmware.git --PKG_MIRROR_MD5SUM:=ca4d289ad9380471cae376fc7dd3660a -+PKG_MIRROR_MD5SUM:=8d44332359de89b1936b4ff608a72614 - --PKG_MAINTAINER:=Felix Fietkau -+PKG_MAINTAINER:=Felix Fietkau - - SCAN_DEPS = *.mk - -diff --git a/package/firmware/linux-firmware/realtek.mk b/package/firmware/linux-firmware/realtek.mk -index 0f8b1ce..4229ca0 100644 ---- a/package/firmware/linux-firmware/realtek.mk -+++ b/package/firmware/linux-firmware/realtek.mk -@@ -43,8 +43,15 @@ endef - $(eval $(call BuildPackage,rtl8192de-firmware)) - - Package/rtl8192se-firmware = $(call Package/firmware-default,RealTek RTL8192SE firmware) --define KernelPackage/rtl8192se/install -+define Package/rtl8192se-firmware/install - $(INSTALL_DIR) $(1)/lib/firmware/rtlwifi - $(INSTALL_DATA) $(PKG_BUILD_DIR)/rtlwifi/rtl8192sefw.bin $(1)/lib/firmware/rtlwifi - endef - $(eval $(call BuildPackage,rtl8192se-firmware)) -+ -+Package/rtl8192su-firmware = $(call Package/firmware-default,RealTek RTL8192SU firmware) -+define Package/rtl8192su-firmware/install -+ $(INSTALL_DIR) $(1)/lib/firmware/rtlwifi -+ $(INSTALL_DATA) $(PKG_BUILD_DIR)/rtlwifi/rtl8712u.bin $(1)/lib/firmware/rtlwifi -+endef -+$(eval $(call BuildPackage,rtl8192su-firmware)) -diff --git a/package/kernel/acx-mac80211/Makefile b/package/kernel/acx-mac80211/Makefile -index 1820e7a..8fce374 100644 ---- a/package/kernel/acx-mac80211/Makefile -+++ b/package/kernel/acx-mac80211/Makefile -@@ -9,12 +9,12 @@ include $(TOPDIR)/rules.mk - include $(INCLUDE_DIR)/kernel.mk - - PKG_NAME:=acx-mac80211 --PKG_REV:=v20130127 --PKG_VERSION:=20130909 -+PKG_REV:=b6fc31491020cb01d2cd1acc170cfa03ced7e726 -+PKG_VERSION:=20140216 - PKG_RELEASE:=1 - - PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2 --PKG_SOURCE_URL:=git://acx100.git.sourceforge.net/gitroot/acx100/acx-mac80211 -+PKG_SOURCE_URL:=http://git.code.sf.net/p/acx100/acx-mac80211 - PKG_SOURCE_PROTO:=git - PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION) - PKG_SOURCE_VERSION:=$(PKG_REV) -@@ -190,7 +190,7 @@ define Build/Compile - CROSS_COMPILE="$(TARGET_CROSS)" \ - SUBDIRS="$(PKG_BUILD_DIR)" \ - $(PKG_EXTRA_KCONFIG) \ -- EXTRA_CFLAGS="$(PKG_EXTRA_CFLAGS) -DCONFIG_ACX_MAC80211_VERSION=\"KERNEL_VERSION(3,14,0)\"" \ -+ EXTRA_CFLAGS="$(PKG_EXTRA_CFLAGS) -DCONFIG_ACX_MAC80211_VERSION=\"KERNEL_VERSION(4,2,0)\"" \ - LINUXINCLUDE="-I$(STAGING_DIR)/usr/include/mac80211-backport/uapi -I$(STAGING_DIR)/usr/include/mac80211-backport \ - -I$(STAGING_DIR)/usr/include/mac80211/uapi -I$(STAGING_DIR)/usr/include/mac80211 \ - -I$(LINUX_DIR)/include -I$(LINUX_DIR)/include/$(LINUX_UAPI_DIR) \ -diff --git a/package/kernel/acx-mac80211/patches/001-pci-mem-Fix-3.8-build.patch b/package/kernel/acx-mac80211/patches/001-pci-mem-Fix-3.8-build.patch -deleted file mode 100644 -index fa4a6be..0000000 ---- a/package/kernel/acx-mac80211/patches/001-pci-mem-Fix-3.8-build.patch -+++ /dev/null -@@ -1,129 +0,0 @@ --From 8a0f5890019bf43f4bc95ef0754b062ddfcfa9cd Mon Sep 17 00:00:00 2001 --From: Oliver Winker --Date: Sun, 10 Mar 2013 21:04:23 +0100 --Subject: [PATCH 1/3] pci, mem: Fix 3.8 build -- --__devexit and __devinit not used anymore in 3.8 -- --Signed-off-by: Reinhard Karcher --Signed-off-by: Oliver Winker ----- -- mem.c | 13 ++++++++++++- -- pci.c | 26 +++++++++++++++++++++++++- -- 2 files changed, 37 insertions(+), 2 deletions(-) -- ----- a/mem.c --+++ b/mem.c --@@ -2216,7 +2216,11 @@ int acx100mem_ioctl_set_phy_amp_bias(str -- * ================================================== -- */ -- --+#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 8, 0) -- static int __devinit acxmem_probe(struct platform_device *pdev) --+#else --+static int acxmem_probe(struct platform_device *pdev) --+#endif -- { -- acx_device_t *adev = NULL; -- const char *chip_name; --@@ -2392,7 +2396,11 @@ static int __devinit acxmem_probe(struct -- * pdev - ptr to PCI device structure containing info about pci -- * configuration -- */ --+#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 8, 0) -- static int __devexit acxmem_remove(struct platform_device *pdev) --+#else --+static int acxmem_remove(struct platform_device *pdev) --+#endif -- { -- struct ieee80211_hw *hw = (struct ieee80211_hw *) -- platform_get_drvdata(pdev); --@@ -2594,8 +2602,11 @@ static struct platform_driver acxmem_dri -- .name = "acx-mem", -- }, -- .probe = acxmem_probe, --+#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 8, 0) -- .remove = __devexit_p(acxmem_remove), --- --+#else --+ .remove = acxmem_remove, --+#endif -- #ifdef CONFIG_PM -- .suspend = acxmem_e_suspend, -- .resume = acxmem_e_resume ----- a/pci.c --+++ b/pci.c --@@ -1039,7 +1039,11 @@ int acx100pci_ioctl_set_phy_amp_bias(str -- * id - ptr to the device id entry that matched this device -- */ -- #ifdef CONFIG_PCI --+#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 8, 0) -- static int __devinit acxpci_probe(struct pci_dev *pdev, --+#else --+static int acxpci_probe(struct pci_dev *pdev, --+#endif -- const struct pci_device_id *id) -- { -- unsigned long mem_region1 = 0; --@@ -1292,7 +1296,11 @@ static int __devinit acxpci_probe(struct -- * -- * pdev - ptr to PCI device structure containing info about pci configuration -- */ --+#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 8, 0) -- static void __devexit acxpci_remove(struct pci_dev *pdev) --+#else --+static void acxpci_remove(struct pci_dev *pdev) --+#endif -- { -- struct ieee80211_hw *hw -- = (struct ieee80211_hw *) pci_get_drvdata(pdev); --@@ -1505,7 +1513,11 @@ static struct pci_driver acxpci_driver = -- .name = "acx_pci", -- .id_table = acxpci_id_tbl, -- .probe = acxpci_probe, --+#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 8, 0) -- .remove = __devexit_p(acxpci_remove), --+#else --+ .remove = acxpci_remove, --+#endif -- #ifdef CONFIG_PM -- .suspend = acxpci_e_suspend, -- .resume = acxpci_e_resume --@@ -1603,8 +1615,12 @@ static struct vlynq_device_id acx_vlynq_ -- }; -- -- --+#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 8, 0) -- static __devinit int vlynq_probe(struct vlynq_device *vdev, --- struct vlynq_device_id *id) --+#else --+static int vlynq_probe(struct vlynq_device *vdev, --+#endif --+ struct vlynq_device_id *id) -- { -- int result = -EIO, i; -- u32 addr; --@@ -1785,7 +1801,11 @@ static __devinit int vlynq_probe(struct -- return result; -- } -- --+#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 8, 0) -- static __devexit void vlynq_remove(struct vlynq_device *vdev) --+#else --+static void vlynq_remove(struct vlynq_device *vdev) --+#endif -- { -- struct ieee80211_hw *hw = vlynq_get_drvdata(vdev); -- acx_device_t *adev = hw2adev(hw); --@@ -1851,7 +1871,11 @@ static struct vlynq_driver acxvlynq_driv -- .name = "acx_vlynq", -- .id_table = acx_vlynq_id, -- .probe = vlynq_probe, --+#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 8, 0) -- .remove = __devexit_p(vlynq_remove), --+#else --+ .remove = vlynq_remove, --+#endif -- }; -- #endif /* CONFIG_VLYNQ */ -- -diff --git a/package/kernel/acx-mac80211/patches/003-Fix-3.10-build.patch b/package/kernel/acx-mac80211/patches/003-Fix-3.10-build.patch -deleted file mode 100644 -index c737844..0000000 ---- a/package/kernel/acx-mac80211/patches/003-Fix-3.10-build.patch -+++ /dev/null -@@ -1,31 +0,0 @@ --From 1daf4bfdb072b08f3b4e412bbfa9645f88dc0a01 Mon Sep 17 00:00:00 2001 --From: Oliver Winker --Date: Tue, 3 Sep 2013 20:36:36 +0200 --Subject: [PATCH 3/3] Fix 3.10 build -- --Signed-off-by: Reinhard Karcher --Signed-off-by: Oliver Winker ----- -- main.c | 7 +++++++ -- 1 file changed, 7 insertions(+) -- ----- a/main.c --+++ b/main.c --@@ -682,10 +682,17 @@ int acx_op_config(struct ieee80211_hw *h -- -- if (changed & IEEE80211_CONF_CHANGE_CHANNEL) { -- logf1(L_DEBUG, "IEEE80211_CONF_CHANGE_CHANNEL," --+#if CONFIG_ACX_MAC80211_VERSION >= KERNEL_VERSION(3, 10, 0) --+ "channel->hw_value=%i\n", conf->chandef.chan->hw_value); --+ --+ acx_set_channel(adev, conf->chandef.chan->hw_value, --+ conf->chandef.chan->center_freq); --+#else -- "channel->hw_value=%i\n", conf->channel->hw_value); -- -- acx_set_channel(adev, conf->channel->hw_value, -- conf->channel->center_freq); --+#endif -- -- changed_not_done &= ~IEEE80211_CONF_CHANGE_CHANNEL; -- } -diff --git a/package/kernel/acx-mac80211/patches/004-Fix-3.14-build.patch b/package/kernel/acx-mac80211/patches/004-Fix-3.14-build.patch -deleted file mode 100644 -index 847b573..0000000 ---- a/package/kernel/acx-mac80211/patches/004-Fix-3.14-build.patch -+++ /dev/null -@@ -1,22 +0,0 @@ --From d17fcac710e629463591f6bd09d76b66ec591583 Mon Sep 17 00:00:00 2001 --From: Hauke Mehrtens --Date: Wed, 5 Feb 2014 20:57:07 +0100 --Subject: [PATCH] Fix 3.14 build -- --Signed-off-by: Hauke Mehrtens ----- -- main.c | 2 ++ -- 1 file changed, 2 insertions(+) -- ----- a/main.c --+++ b/main.c --@@ -500,7 +500,9 @@ int acx_init_ieee80211(acx_device_t *ade -- hw->flags &= ~IEEE80211_HW_RX_INCLUDES_FCS; -- hw->queues = 1; -- hw->wiphy->max_scan_ssids = 1; --+#if CONFIG_ACX_MAC80211_VERSION < KERNEL_VERSION(3, 14, 0) -- hw->channel_change_time = 10000; --+#endif -- -- /* OW TODO Check if RTS/CTS threshold can be included here */ -- -diff --git a/package/kernel/acx-mac80211/patches/300-api_sync.patch b/package/kernel/acx-mac80211/patches/300-api_sync.patch -new file mode 100644 -index 0000000..94d6135 ---- /dev/null -+++ b/package/kernel/acx-mac80211/patches/300-api_sync.patch -@@ -0,0 +1,83 @@ -+--- a/main.c -++++ b/main.c -+@@ -497,7 +497,7 @@ int acx_free_mechanics(acx_device_t *ade -+ -+ int acx_init_ieee80211(acx_device_t *adev, struct ieee80211_hw *hw) -+ { -+- hw->flags &= ~IEEE80211_HW_RX_INCLUDES_FCS; -++ __clear_bit(IEEE80211_HW_RX_INCLUDES_FCS, hw->flags); -+ hw->queues = 1; -+ hw->wiphy->max_scan_ssids = 1; -+ -+@@ -525,14 +525,14 @@ int acx_init_ieee80211(acx_device_t *ade -+ /* We base signal quality on winlevel approach of previous driver -+ * TODO OW 20100615 This should into a common init code -+ */ -+- hw->flags |= IEEE80211_HW_SIGNAL_UNSPEC; -++ __set_bit(IEEE80211_HW_SIGNAL_UNSPEC, hw->flags); -+ hw->max_signal = 100; -+ -+ if (IS_ACX100(adev)) { -+- adev->hw->wiphy->bands[IEEE80211_BAND_2GHZ] = -++ adev->hw->wiphy->bands[NL80211_BAND_2GHZ] = -+ &acx100_band_2GHz; -+ } else if (IS_ACX111(adev)) -+- adev->hw->wiphy->bands[IEEE80211_BAND_2GHZ] = -++ adev->hw->wiphy->bands[NL80211_BAND_2GHZ] = -+ &acx111_band_2GHz; -+ else { -+ log(L_ANY, "Error: Unknown device"); -+@@ -945,8 +945,8 @@ void acx_op_configure_filter(struct ieee -+ changed_flags, *total_flags); -+ -+ /* OWI TODO: Set also FIF_PROBE_REQ ? */ -+- *total_flags &= (FIF_PROMISC_IN_BSS | FIF_ALLMULTI | FIF_FCSFAIL -+- | FIF_CONTROL | FIF_OTHER_BSS); -++ *total_flags &= (FIF_ALLMULTI | FIF_FCSFAIL | FIF_CONTROL -++ | FIF_OTHER_BSS); -+ -+ logf1(L_DEBUG, "2: *total_flags=0x%08x\n", *total_flags); -+ -+@@ -1045,9 +1045,10 @@ void acx_op_tx(struct ieee80211_hw *hw, -+ } -+ -+ int acx_op_hw_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif, -+- struct cfg80211_scan_request *req) -++ struct ieee80211_scan_request *hw_req) -+ { -+ acx_device_t *adev = hw2adev(hw); -++ struct cfg80211_scan_request *req = &hw_req->req; -+ struct sk_buff *skb; -+ size_t ssid_len = 0; -+ u8 *ssid = NULL; -+@@ -1082,7 +1083,7 @@ int acx_op_hw_scan(struct ieee80211_hw * -+ goto out; -+ } -+ #else -+- skb = ieee80211_probereq_get(adev->hw, adev->vif, ssid, ssid_len, -++ skb = ieee80211_probereq_get(adev->hw, vif->addr, ssid, ssid_len, -+ req->ie_len); -+ if (!skb) { -+ ret = -ENOMEM; -+--- a/main.h -++++ b/main.h -+@@ -62,7 +62,7 @@ void acx_op_tx(struct ieee80211_hw *hw, -+ #endif -+ -+ int acx_op_hw_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif, -+- struct cfg80211_scan_request *req); -++ struct ieee80211_scan_request *req); -+ -+ int acx_recover_hw(acx_device_t *adev); -+ -+--- a/cardsetting.c -++++ b/cardsetting.c -+@@ -159,7 +159,7 @@ int acx_set_channel(acx_device_t *adev, -+ int res = 0; -+ -+ adev->rx_status.freq = freq; -+- adev->rx_status.band = IEEE80211_BAND_2GHZ; -++ adev->rx_status.band = NL80211_BAND_2GHZ; -+ -+ adev->channel = channel; -+ -diff --git a/package/kernel/ath10k-ct/Makefile b/package/kernel/ath10k-ct/Makefile -new file mode 100644 -index 0000000..bbff8d8 ---- /dev/null -+++ b/package/kernel/ath10k-ct/Makefile -@@ -0,0 +1,80 @@ -+include $(TOPDIR)/rules.mk -+ -+PKG_NAME:=ath10k-ct -+PKG_VERSION:=2016-08-24 -+PKG_RELEASE=1 -+ -+PKG_LICENSE:=GPLv2 -+PKG_LICENSE_FILES:= -+ -+PKG_SOURCE_URL:=https://github.com/greearb/ath10k-ct.git -+PKG_SOURCE_PROTO:=git -+PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION) -+PKG_SOURCE_VERSION:=cd725d5465e1d4476a504794c541afeeba84b479 -+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)-$(PKG_SOURCE_VERSION).tar.xz -+ -+PKG_MAINTAINER:=Ben Greear -+PKG_BUILD_PARALLEL:=1 -+ -+STAMP_CONFIGURED_DEPENDS := $(STAGING_DIR)/usr/include/mac80211-backport/backport/autoconf.h -+ -+include $(INCLUDE_DIR)/kernel.mk -+include $(INCLUDE_DIR)/package.mk -+ -+define KernelPackage/ath10k-ct -+ SUBMENU:=Wireless Drivers -+ TITLE:=ath10k-ct driver optimized for CT ath10k firmware -+ DEPENDS:=+kmod-mac80211 +kmod-ath +@DRIVER_11N_SUPPORT @PCI_SUPPORT +@KERNEL_RELAY -+ FILES:=\ -+ $(PKG_BUILD_DIR)/ath10k/ath10k_pci.ko \ -+ $(PKG_BUILD_DIR)/ath10k/ath10k_core.ko -+ AUTOLOAD:=$(call AutoLoad,50,mac80211 ath ath10k_core ath10k_pci) -+endef -+ -+NOSTDINC_FLAGS = \ -+ -I$(PKG_BUILD_DIR) \ -+ -I$(STAGING_DIR)/usr/include/mac80211-backport/uapi \ -+ -I$(STAGING_DIR)/usr/include/mac80211-backport \ -+ -I$(STAGING_DIR)/usr/include/mac80211/uapi \ -+ -I$(STAGING_DIR)/usr/include/mac80211 \ -+ -include backport/autoconf.h \ -+ -include backport/backport.h -+ -+ifdef CONFIG_PACKAGE_MAC80211_MESH -+ NOSTDINC_FLAGS += -DCONFIG_MAC80211_MESH -+endif -+ -+CT_MAKEDEFS += CONFIG_ATH10K=m CONFIG_ATH10K_PCI=m -+# No AHB support enabled yet. Could conditionally enable it later. -+#CT_MAKEDEFS += CONFIG_ATH10K_AHB=y -+#NOSTDINC_FLAGS += -DCONFIG_ATH10K_AHB -+NOSTDINC_FLAGS += -DSTANDALONE_CT -+ -+ifdef CONFIG_PACKAGE_MAC80211_DEBUGFS -+ CT_MAKEDEFS += CONFIG_ATH10K_DEBUGFS=y CONFIG_MAC80211_DEBUGFS=y -+ NOSTDINC_FLAGS += -DCONFIG_MAC80211_DEBUGFS -+ NOSTDINC_FLAGS += -DCONFIG_ATH10K_DEBUGFS -+endif -+ -+ifdef CONFIG_PACKAGE_ATH_DEBUG -+ NOSTDINC_FLAGS += -DCONFIG_ATH10K_DEBUG -+endif -+ -+define Build/Configure -+ cp $(STAGING_DIR)/usr/include/mac80211/ath/*.h $(PKG_BUILD_DIR) -+endef -+ -+ifneq ($(findstring c,$(OPENWRT_VERBOSE)),) -+ CT_MAKEDEFS += V=1 -+endif -+ -+define Build/Compile -+ +$(MAKE) $(CT_MAKEDEFS) $(PKG_JOBS) -C "$(LINUX_DIR)" \ -+ ARCH="$(LINUX_KARCH)" \ -+ CROSS_COMPILE="$(TARGET_CROSS)" \ -+ SUBDIRS="$(PKG_BUILD_DIR)/ath10k" \ -+ NOSTDINC_FLAGS="$(NOSTDINC_FLAGS)" \ -+ modules -+endef -+ -+$(eval $(call KernelPackage,ath10k-ct)) -diff --git a/package/kernel/mac80211/Makefile b/package/kernel/mac80211/Makefile -index 30da1cf..f2839cd 100644 ---- a/package/kernel/mac80211/Makefile -+++ b/package/kernel/mac80211/Makefile -@@ -10,20 +10,21 @@ include $(INCLUDE_DIR)/kernel.mk - - PKG_NAME:=mac80211 - --PKG_VERSION:=2016-01-10 -+PKG_VERSION:=2016-06-20 - PKG_RELEASE:=1 - PKG_SOURCE_URL:=http://mirror2.openwrt.org/sources - PKG_BACKPORT_VERSION:= --PKG_MD5SUM:=be5fae2e8d6f7490f9b073374fb895ba -+PKG_MD5SUM:=29c79bdc3928ef5113b17042ebda9237 - - PKG_SOURCE:=compat-wireless-$(PKG_VERSION)$(PKG_BACKPORT_VERSION).tar.bz2 - PKG_BUILD_DIR:=$(KERNEL_BUILD_DIR)/compat-wireless-$(PKG_VERSION) - PKG_BUILD_PARALLEL:=1 - --PKG_MAINTAINER:=Felix Fietkau -+PKG_MAINTAINER:=Felix Fietkau - - PKG_DRIVERS = \ - adm8211 \ -+ airo \ - ath ath5k ath9k ath9k-common ath9k-htc ath10k \ - b43 b43legacy \ - carl9170 \ -@@ -52,6 +53,7 @@ PKG_CONFIG_DEPENDS:= \ - $(patsubst %,CONFIG_PACKAGE_kmod-%,$(PKG_DRIVERS)) \ - CONFIG_PACKAGE_MAC80211_DEBUGFS \ - CONFIG_PACKAGE_MAC80211_MESH \ -+ CONFIG_PACKAGE_MAC80211_TRACING \ - CONFIG_PACKAGE_ATH_DEBUG \ - CONFIG_PACKAGE_ATH_DFS \ - CONFIG_PACKAGE_B43_DEBUG \ -@@ -63,7 +65,12 @@ PKG_CONFIG_DEPENDS:= \ - CONFIG_PACKAGE_B43_BUSES_BCMA_AND_SSB \ - CONFIG_PACKAGE_B43_BUSES_BCMA \ - CONFIG_PACKAGE_B43_BUSES_SSB \ -+ CONFIG_PACKAGE_BRCM80211_DEBUG \ -+ CONFIG_PACKAGE_IWLWIFI_DEBUG \ -+ CONFIG_PACKAGE_IWLWIFI_DEBUGFS \ - CONFIG_PACKAGE_RTLWIFI_DEBUG \ -+ CONFIG_ATH9K_SUPPORT_PCOEM \ -+ CONFIG_ATH9K_TX99 \ - CONFIG_ATH_USER_REGD \ - - include $(INCLUDE_DIR)/package.mk -@@ -73,7 +80,7 @@ WMENU:=Wireless Drivers - define KernelPackage/mac80211/Default - SUBMENU:=$(WMENU) - URL:=https://wireless.wiki.kernel.org/ -- MAINTAINER:=Felix Fietkau -+ MAINTAINER:=Felix Fietkau - endef - - define KernelPackage/cfg80211 -@@ -92,7 +99,7 @@ endef - define KernelPackage/mac80211 - $(call KernelPackage/mac80211/Default) - TITLE:=Linux 802.11 Wireless Networking Stack -- DEPENDS+= +kmod-cfg80211 +hostapd-common +kmod-crypto-core +kmod-crypto-arc4 -+ DEPENDS+= +kmod-cfg80211 +hostapd-common - KCONFIG:=\ - CONFIG_AVERAGE=y - FILES:= $(PKG_BUILD_DIR)/net/mac80211/mac80211.ko -@@ -138,10 +145,23 @@ define KernelPackage/adm8211 - AUTOLOAD:=$(call AutoProbe,adm8211) - endef - -+define KernelPackage/airo -+ $(call KernelPackage/mac80211/Default) -+ TITLE:=Cisco Aironet driver -+ DEPENDS+=@PCI_SUPPORT +@DRIVER_WEXT_SUPPORT +kmod-cfg80211 @TARGET_x86 -+ FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/cisco/airo.ko -+ AUTOLOAD:=$(call AutoProbe,airo) -+endef -+ -+define KernelPackage/airo/description -+ Kernel support for Cisco Aironet cards -+endef -+ - define KernelPackage/ath/config - if PACKAGE_kmod-ath - config ATH_USER_REGD - bool "Force Atheros drivers to respect the user's regdomain settings" -+ default y - help - Atheros' idea of regulatory handling is that the EEPROM of the card defines - the regulatory limits and the user is only allowed to restrict the settings -@@ -199,6 +219,7 @@ define KernelPackage/ath9k-common - $(call KernelPackage/mac80211/Default) - TITLE:=Atheros 802.11n wireless devices (common code for ath9k and ath9k_htc) - URL:=https://wireless.wiki.kernel.org/en/users/drivers/ath9k -+ HIDDEN:=1 - DEPENDS+= @PCI_SUPPORT||USB_SUPPORT||TARGET_ar71xx +kmod-ath +@DRIVER_11N_SUPPORT +@DRIVER_11W_SUPPORT +@KERNEL_RELAY - FILES:= \ - $(PKG_BUILD_DIR)/drivers/net/wireless/ath/ath9k/ath9k_common.ko \ -@@ -226,6 +247,10 @@ define KernelPackage/ath9k/config - bool "Support chips used in PC OEM cards" - depends on PACKAGE_kmod-ath9k - -+ config ATH9K_TX99 -+ bool "Enable TX99 support" -+ depends on PACKAGE_kmod-ath9k -+ - endef - - define KernelPackage/ath9k-htc -@@ -247,7 +272,7 @@ define KernelPackage/ath10k - $(call KernelPackage/mac80211/Default) - TITLE:=Atheros 802.11ac wireless cards support - URL:=https://wireless.wiki.kernel.org/en/users/Drivers/ath10k -- DEPENDS+= @PCI_SUPPORT +kmod-ath +@DRIVER_11N_SUPPORT +@DRIVER_11W_SUPPORT +@KERNEL_RELAY +ath10k-firmware-qca988x -+ DEPENDS+= @PCI_SUPPORT +kmod-ath +@DRIVER_11N_SUPPORT +@DRIVER_11W_SUPPORT +@KERNEL_RELAY - FILES:= \ - $(PKG_BUILD_DIR)/drivers/net/wireless/ath/ath10k/ath10k_core.ko \ - $(PKG_BUILD_DIR)/drivers/net/wireless/ath/ath10k/ath10k_pci.ko -@@ -673,6 +698,7 @@ define KernelPackage/brcmfmac/config - - config BRCMFMAC_SDIO - bool "Enable SDIO bus interface support" -+ default y if TARGET_brcm2708 - default n - help - Enable support for cards attached to an SDIO bus. -@@ -761,7 +787,7 @@ endef - - define KernelPackage/iwlwifi - $(call KernelPackage/mac80211/Default) -- DEPENDS:= +kmod-mac80211 @PCI_SUPPORT +@DRIVER_11N_SUPPORT +iwlwifi-firmware -+ DEPENDS:= +kmod-mac80211 @PCI_SUPPORT +@DRIVER_11N_SUPPORT +iwlwifi-firmware @!LINUX_3_18 - TITLE:=Intel AGN Wireless support - FILES:= \ - $(PKG_BUILD_DIR)/drivers/net/wireless/intel/iwlwifi/iwlwifi.ko \ -@@ -870,7 +896,7 @@ endef - define KernelPackage/lib80211 - $(call KernelPackage/mac80211/Default) - TITLE:=802.11 Networking stack -- DEPENDS:=+kmod-cfg80211 -+ DEPENDS:=+kmod-cfg80211 +kmod-crypto-hash - FILES:= \ - $(PKG_BUILD_DIR)/net/wireless/lib80211.ko \ - $(PKG_BUILD_DIR)/net/wireless/lib80211_crypt_wep.ko \ -@@ -897,7 +923,7 @@ endef - define KernelPackage/libipw - $(call KernelPackage/mac80211/Default) - TITLE:=libipw for ipw2100 and ipw2200 -- DEPENDS:=@PCI_SUPPORT +kmod-crypto-michael-mic +kmod-crypto-core +kmod-crypto-arc4 +kmod-lib80211 +kmod-cfg80211 +@DRIVER_WEXT_SUPPORT @!BIG_ENDIAN -+ DEPENDS:=@PCI_SUPPORT +kmod-crypto-michael-mic +kmod-lib80211 +kmod-cfg80211 +@DRIVER_WEXT_SUPPORT @!BIG_ENDIAN - FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/intel/ipw2x00/libipw.ko - AUTOLOAD:=$(call AutoProbe,libipw) - endef -@@ -978,7 +1004,7 @@ endef - define KernelPackage/libertas-spi - $(call KernelPackage/mac80211/Default) - SUBMENU:=Wireless Drivers -- DEPENDS+= +kmod-cfg80211 +kmod-lib80211 +@DRIVER_WEXT_SUPPORT +libertas-spi-firmware -+ DEPENDS+= +kmod-cfg80211 +kmod-lib80211 +@DRIVER_WEXT_SUPPORT @!TARGET_uml +libertas-spi-firmware - KCONFIG := \ - CONFIG_SPI=y \ - CONFIG_SPI_MASTER=y -@@ -1036,33 +1062,6 @@ define KernelPackage/mwifiex-pcie/description - Kernel modules for Marvell 802.11n/802.11ac PCIe Wireless cards - endef - -- --# Prism54 drivers --P54PCIFW:=2.13.12.0.arm --P54USBFW:=2.13.24.0.lm87.arm --P54SPIFW:=2.13.0.0.a.13.14.arm -- --define Download/p54usb -- FILE:=$(P54USBFW) -- URL:=http://daemonizer.de/prism54/prism54-fw/fw-usb -- MD5SUM:=8e8ab005a4f8f0123bcdc51bc25b47f6 --endef --$(eval $(call Download,p54usb)) -- --define Download/p54pci -- FILE:=$(P54PCIFW) -- URL:=http://daemonizer.de/prism54/prism54-fw/fw-softmac -- MD5SUM:=ff7536af2092b1c4b21315bd103ef4c4 --endef --$(eval $(call Download,p54pci)) -- --define Download/p54spi -- FILE:=$(P54SPIFW) -- URL:=http://daemonizer.de/prism54/prism54-fw/stlc4560 -- MD5SUM:=42661f8ecbadd88012807493f596081d --endef --$(eval $(call Download,p54spi)) -- - define KernelPackage/p54/Default - $(call KernelPackage/mac80211/Default) - TITLE:=Prism54 Drivers -@@ -1082,7 +1081,7 @@ endef - define KernelPackage/p54-pci - $(call KernelPackage/p54/Default) - TITLE+= (PCI) -- DEPENDS+= @PCI_SUPPORT +kmod-p54-common -+ DEPENDS+= @PCI_SUPPORT +kmod-p54-common +p54-pci-firmware - FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/intersil/p54/p54pci.ko - AUTOLOAD:=$(call AutoProbe,p54pci) - endef -@@ -1090,7 +1089,7 @@ endef - define KernelPackage/p54-usb - $(call KernelPackage/p54/Default) - TITLE+= (USB) -- DEPENDS+= @USB_SUPPORT +kmod-usb-core +kmod-p54-common -+ DEPENDS+= @USB_SUPPORT +kmod-usb-core +kmod-p54-common +p54-usb-firmware - FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/intersil/p54/p54usb.ko - AUTOLOAD:=$(call AutoProbe,p54usb) - endef -@@ -1098,7 +1097,7 @@ endef - define KernelPackage/p54-spi - $(call KernelPackage/p54/Default) - TITLE+= (SPI) -- DEPENDS+= @TARGET_omap24xx +kmod-p54-common -+ 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 -@@ -1453,6 +1452,7 @@ config-y:= \ - WLAN_VENDOR_ATH \ - WLAN_VENDOR_ATMEL \ - WLAN_VENDOR_BROADCOM \ -+ WLAN_VENDOR_CISCO \ - WLAN_VENDOR_INTEL \ - WLAN_VENDOR_INTERSIL \ - WLAN_VENDOR_MARVELL \ -@@ -1491,6 +1491,8 @@ endif - - config-$(call config_package,lib80211) += LIB80211 LIB80211_CRYPT_WEP LIB80211_CRYPT_CCMP LIB80211_CRYPT_TKIP - -+config-$(call config_package,airo) += AIRO -+ - config-$(call config_package,ath) += ATH_CARDS ATH_COMMON - config-$(CONFIG_PACKAGE_ATH_DEBUG) += ATH_DEBUG ATH10K_DEBUG - config-$(CONFIG_PACKAGE_ATH_DFS) += ATH9K_DFS_CERTIFIED ATH10K_DFS_CERTIFIED -@@ -1501,6 +1503,7 @@ config-$(CONFIG_TARGET_ar71xx) += ATH9K_AHB - config-$(CONFIG_PCI) += ATH9K_PCI - config-$(CONFIG_ATH_USER_REGD) += ATH_USER_REGD - config-$(CONFIG_ATH9K_SUPPORT_PCOEM) += ATH9K_PCOEM -+config-$(CONFIG_ATH9K_TX99) += ATH9K_TX99 - - config-$(call config_package,ath9k-htc) += ATH9K_HTC - config-$(call config_package,ath10k) += ATH10K ATH10K_PCI -@@ -1742,21 +1745,6 @@ define KernelPackage/ipw2200/install - $(INSTALL_DATA) $(PKG_BUILD_DIR)/$(IPW2200_NAME)-$(IPW2200_VERSION)/ipw2200*.fw $(1)/lib/firmware - endef - --define KernelPackage/p54-pci/install -- $(INSTALL_DIR) $(1)/lib/firmware -- $(INSTALL_DATA) $(DL_DIR)/$(P54PCIFW) $(1)/lib/firmware/isl3886pci --endef -- --define KernelPackage/p54-usb/install -- $(INSTALL_DIR) $(1)/lib/firmware -- $(INSTALL_DATA) $(DL_DIR)/$(P54USBFW) $(1)/lib/firmware/isl3887usb --endef -- --define KernelPackage/p54-spi/install -- $(INSTALL_DIR) $(1)/lib/firmware -- $(INSTALL_DATA) $(DL_DIR)/$(P54SPIFW) $(1)/lib/firmware/3826.arm --endef -- - define KernelPackage/zd1211rw/install - $(INSTALL_DIR) $(1)/lib/firmware/zd1211 - $(INSTALL_DATA) $(PKG_BUILD_DIR)/$(ZD1211FW_NAME)/zd1211* $(1)/lib/firmware/zd1211 -@@ -1764,6 +1752,7 @@ endef - - - $(eval $(call KernelPackage,adm8211)) -+$(eval $(call KernelPackage,airo)) - $(eval $(call KernelPackage,ath)) - $(eval $(call KernelPackage,ath10k)) - $(eval $(call KernelPackage,ath5k)) -diff --git a/package/kernel/mac80211/files/lib/netifd/wireless/mac80211.sh b/package/kernel/mac80211/files/lib/netifd/wireless/mac80211.sh -index fb2f928..e3d612e 100644 ---- a/package/kernel/mac80211/files/lib/netifd/wireless/mac80211.sh -+++ b/package/kernel/mac80211/files/lib/netifd/wireless/mac80211.sh -@@ -23,6 +23,7 @@ drv_mac80211_init_device_config() { - config_add_int rxantenna txantenna antenna_gain txpower distance - config_add_boolean noscan ht_coex - config_add_array ht_capab -+ config_add_array channels - config_add_boolean \ - rxldpc \ - short_gi_80 \ -@@ -89,6 +90,7 @@ mac80211_hostapd_setup_base() { - json_select config - - [ "$auto_channel" -gt 0 ] && channel=acs_survey -+ [ "$auto_channel" -gt 0 ] && json_get_values channel_list channels - - json_get_vars noscan ht_coex - json_get_values ht_capab_list ht_capab -@@ -218,7 +220,6 @@ mac80211_hostapd_setup_base() { - vht_max_a_mpdu_len_exp:7 \ - vht_max_mpdu:11454 \ - rx_stbc:4 \ -- tx_stbc:4 \ - vht_link_adapt:3 \ - vht160:2 - -@@ -230,13 +231,13 @@ mac80211_hostapd_setup_base() { - - cap_rx_stbc=$((($vht_cap >> 8) & 7)) - [ "$rx_stbc" -lt "$cap_rx_stbc" ] && cap_rx_stbc="$rx_stbc" -- ht_cap_mask="$(( ($vht_cap & ~(0x700)) | ($cap_rx_stbc << 8) ))" -+ vht_cap="$(( ($vht_cap & ~(0x700)) | ($cap_rx_stbc << 8) ))" - - mac80211_add_capabilities vht_capab $vht_cap \ - RXLDPC:0x10::$rxldpc \ - SHORT-GI-80:0x20::$short_gi_80 \ - SHORT-GI-160:0x40::$short_gi_160 \ -- TX-STBC-2BY1:0x80::$tx_stbc \ -+ TX-STBC-2BY1:0x80::$tx_stbc_2by1 \ - SU-BEAMFORMER:0x800::$su_beamformer \ - SU-BEAMFORMEE:0x1000::$su_beamformee \ - MU-BEAMFORMER:0x80000::$mu_beamformer \ -@@ -245,10 +246,10 @@ mac80211_hostapd_setup_base() { - HTC-VHT:0x400000::$htc_vht \ - RX-ANTENNA-PATTERN:0x10000000::$rx_antenna_pattern \ - TX-ANTENNA-PATTERN:0x20000000::$tx_antenna_pattern \ -- RX-STBC1:0x700:0x100:1 \ -- RX-STBC12:0x700:0x200:1 \ -- RX-STBC123:0x700:0x300:1 \ -- RX-STBC1234:0x700:0x400:1 \ -+ RX-STBC-1:0x700:0x100:1 \ -+ RX-STBC-12:0x700:0x200:1 \ -+ RX-STBC-123:0x700:0x300:1 \ -+ RX-STBC-1234:0x700:0x400:1 \ - - # supported Channel widths - vht160_hw=0 -@@ -301,6 +302,7 @@ mac80211_hostapd_setup_base() { - hostapd_prepare_device_config "$hostapd_conf_file" nl80211 - cat >> "$hostapd_conf_file" </dev/null); do -+ case "$(readlink -f /sys/class/ieee80211/$phy/device)" in -+ *$path) return 0;; -+ esac - done - } - [ -n "$macaddr" ] && { -@@ -481,7 +482,7 @@ mac80211_prepare_vif() { - # All interfaces must have unique mac addresses - # which can either be explicitly set in the device - # section, or automatically generated -- ifconfig "$ifname" hw ether "$macaddr" -+ ip link set dev "$ifname" address "$macaddr" - fi - - json_select .. -@@ -496,7 +497,7 @@ mac80211_setup_supplicant() { - mac80211_setup_adhoc_htmode() { - case "$htmode" in - VHT20|HT20) ibss_htmode=HT20;; -- HT40*|VHT40|VHT80|VHT160) -+ HT40*|VHT40|VHT160) - case "$hwmode" in - a) - case "$(( ($channel / 4) % 2 ))" in -@@ -520,6 +521,9 @@ mac80211_setup_adhoc_htmode() { - esac - [ "$auto_channel" -gt 0 ] && ibss_htmode="HT40+" - ;; -+ VHT80) -+ ibss_htmode="80MHZ" -+ ;; - NONE|NOHT) - ibss_htmode="NOHT" - ;; -@@ -580,7 +584,7 @@ mac80211_setup_vif() { - json_get_vars mode - json_get_var vif_txpower txpower - -- ifconfig "$ifname" up || { -+ ip link set dev "$ifname" up || { - wireless_setup_vif_failed IFUP_ERROR - json_select .. - return -@@ -643,7 +647,7 @@ mac80211_interface_cleanup() { - local phy="$1" - - for wdev in $(list_phy_interfaces "$phy"); do -- ifconfig "$wdev" down 2>/dev/null -+ ip link set dev "$wdev" down 2>/dev/null - iw dev "$wdev" del - done - } -diff --git a/package/kernel/mac80211/files/lib/wifi/mac80211.sh b/package/kernel/mac80211/files/lib/wifi/mac80211.sh -index ea229d6..06f3b8b 100644 ---- a/package/kernel/mac80211/files/lib/wifi/mac80211.sh -+++ b/package/kernel/mac80211/files/lib/wifi/mac80211.sh -@@ -9,11 +9,10 @@ lookup_phy() { - local devpath - config_get devpath "$device" path - [ -n "$devpath" ] && { -- for _phy in /sys/devices/$devpath/ieee80211/phy*; do -- [ -e "$_phy" ] && { -- phy="${_phy##*/}" -- return -- } -+ for phy in $(ls /sys/class/ieee80211 2>/dev/null); do -+ case "$(readlink -f /sys/class/ieee80211/$phy/device)" in -+ *$devpath) return;; -+ esac - done - } - -@@ -102,6 +101,9 @@ detect_mac80211() { - fi - if [ -n "$path" ]; then - path="${path##/sys/devices/}" -+ case "$path" in -+ platform*/pci*) path="${path##platform/}";; -+ esac - dev_id=" option path '$path'" - else - dev_id=" option macaddr $(cat /sys/class/ieee80211/${dev}/macaddress)" -diff --git a/package/kernel/mac80211/patches/004-backports-add-skb_free_frag.patch b/package/kernel/mac80211/patches/004-backports-add-skb_free_frag.patch -deleted file mode 100644 -index 9adfd8f..0000000 ---- a/package/kernel/mac80211/patches/004-backports-add-skb_free_frag.patch -+++ /dev/null -@@ -1,21 +0,0 @@ --From: Felix Fietkau --Date: Thu, 28 Jan 2016 15:16:35 +0100 --Subject: [PATCH] backports: add skb_free_frag() -- --Signed-off-by: Felix Fietkau ----- -- ----- a/backport-include/linux/skbuff.h --+++ b/backport-include/linux/skbuff.h --@@ -300,4 +300,11 @@ int skb_ensure_writable(struct sk_buff * -- -- #endif /* LINUX_VERSION_CODE < KERNEL_VERSION(3,19,0) */ -- --+#if LINUX_VERSION_CODE < KERNEL_VERSION(4,2,0) --+static inline void skb_free_frag(void *data) --+{ --+ put_page(virt_to_head_page(data)); --+} --+#endif --+ -- #endif /* __BACKPORT_SKBUFF_H */ -diff --git a/package/kernel/mac80211/patches/004-fix_duplicate_skcipher_backport.patch b/package/kernel/mac80211/patches/004-fix_duplicate_skcipher_backport.patch -new file mode 100644 -index 0000000..38b3179 ---- /dev/null -+++ b/package/kernel/mac80211/patches/004-fix_duplicate_skcipher_backport.patch -@@ -0,0 +1,11 @@ -+--- a/compat/Makefile -++++ b/compat/Makefile -+@@ -35,8 +35,6 @@ compat-$(CPTCFG_KERNEL_4_6) += backport- -+ -+ compat-$(CPTCFG_BPAUTO_BUILD_CRYPTO_CCM) += crypto-ccm.o -+ compat-$(CPTCFG_BPAUTO_CRYPTO_SKCIPHER) += crypto-skcipher.o -+-skcipher-objs += crypto-skcipher.o -+-obj-$(CPTCFG_BPAUTO_CRYPTO_SKCIPHER) += skcipher.o -+ compat-$(CPTCFG_BPAUTO_BUILD_WANT_DEV_COREDUMP) += drivers-base-devcoredump.o -+ compat-$(CPTCFG_BPAUTO_RHASHTABLE) += lib-rhashtable.o -+ cordic-objs += lib-cordic.o -diff --git a/package/kernel/mac80211/patches/005-backport_skb_get_hash_perturb.patch b/package/kernel/mac80211/patches/005-backport_skb_get_hash_perturb.patch -new file mode 100644 -index 0000000..29bccc1 ---- /dev/null -+++ b/package/kernel/mac80211/patches/005-backport_skb_get_hash_perturb.patch -@@ -0,0 +1,22 @@ -+--- a/backport-include/linux/skbuff.h -++++ b/backport-include/linux/skbuff.h -+@@ -305,6 +305,19 @@ static inline void skb_free_frag(void *d -+ { -+ put_page(virt_to_head_page(data)); -+ } -++ -++#include -++#include -++ -++static inline u32 skb_get_hash_perturb(struct sk_buff *skb, u32 key) -++{ -++ struct flow_keys keys; -++ -++ skb_flow_dissect(skb, &keys); -++ return jhash_3words((__force u32)keys.dst, -++ (__force u32)keys.src ^ keys.ip_proto, -++ (__force u32)keys.ports, key); -++} -+ #endif -+ -+ #endif /* __BACKPORT_SKBUFF_H */ -diff --git a/package/kernel/mac80211/patches/005-backports-add-napi_alloc_frag.patch b/package/kernel/mac80211/patches/005-backports-add-napi_alloc_frag.patch -deleted file mode 100644 -index 9b672a8..0000000 ---- a/package/kernel/mac80211/patches/005-backports-add-napi_alloc_frag.patch -+++ /dev/null -@@ -1,20 +0,0 @@ --From: Felix Fietkau --Date: Thu, 28 Jan 2016 15:19:22 +0100 --Subject: [PATCH] backports: add napi_alloc_frag -- --Signed-off-by: Felix Fietkau ----- -- ----- a/backport-include/linux/netdevice.h --+++ b/backport-include/linux/netdevice.h --@@ -232,6 +232,10 @@ static inline void backport_unregister_n -- #define unregister_netdevice_many LINUX_BACKPORT(unregister_netdevice_many) -- #endif -- --+#if LINUX_VERSION_CODE < KERNEL_VERSION(3,19,0) --+#define napi_alloc_frag netdev_alloc_frag --+#endif --+ -- /* -- * Complicated way of saying: We only backport netdev_rss_key stuff on kernels -- * that either already have net_get_random_once() (>= 3.13) or where we've been -diff --git a/package/kernel/mac80211/patches/060-no_local_ssb_bcma.patch b/package/kernel/mac80211/patches/060-no_local_ssb_bcma.patch -index fd1e1cf..8be5fa1 100644 ---- a/package/kernel/mac80211/patches/060-no_local_ssb_bcma.patch -+++ b/package/kernel/mac80211/patches/060-no_local_ssb_bcma.patch -@@ -1,6 +1,6 @@ - --- a/.local-symbols - +++ b/.local-symbols --@@ -476,44 +476,6 @@ USB_IPHETH= -+@@ -481,45 +481,6 @@ USB_IPHETH= - USB_SIERRA_NET= - USB_VL600= - USB_NET_CH9200= -@@ -37,6 +37,7 @@ - -BCMA_DRIVER_PCI= - -BCMA_DRIVER_PCI_HOSTMODE= - -BCMA_DRIVER_MIPS= -+-BCMA_PFLASH= - -BCMA_SFLASH= - -BCMA_NFLASH= - -BCMA_DRIVER_GMAC_CMN= -@@ -56,7 +57,7 @@ - return (bus->chipco.dev ? bus->chipco.dev : bus->pcicore.dev); - #else - return bus->chipco.dev; --@@ -4903,7 +4903,7 @@ static int b43_wireless_core_init(struct -+@@ -4883,7 +4883,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. */ -diff --git a/package/kernel/mac80211/patches/080-disable_clk_backport.patch b/package/kernel/mac80211/patches/080-disable_clk_backport.patch -deleted file mode 100644 -index 3765591..0000000 ---- a/package/kernel/mac80211/patches/080-disable_clk_backport.patch -+++ /dev/null -@@ -1,20 +0,0 @@ ----- a/compat/compat-3.6.c --+++ b/compat/compat-3.6.c --@@ -147,17 +147,3 @@ int sg_alloc_table_from_pages(struct sg_ -- return 0; -- } -- EXPORT_SYMBOL_GPL(sg_alloc_table_from_pages); --- ---/* whoopsie ! */ ---#ifndef CONFIG_COMMON_CLK ---int clk_enable(struct clk *clk) ---{ --- return 0; ---} ---EXPORT_SYMBOL_GPL(clk_enable); --- ---void clk_disable(struct clk *clk) ---{ ---} ---EXPORT_SYMBOL_GPL(clk_disable); ---#endif -diff --git a/package/kernel/mac80211/patches/100-remove-cryptoapi-dependencies.patch b/package/kernel/mac80211/patches/100-remove-cryptoapi-dependencies.patch -index 02f46c7..fbe22e5 100644 ---- a/package/kernel/mac80211/patches/100-remove-cryptoapi-dependencies.patch -+++ b/package/kernel/mac80211/patches/100-remove-cryptoapi-dependencies.patch -@@ -309,7 +309,7 @@ - #endif /* AES_GMAC_H */ - --- a/net/mac80211/key.h - +++ b/net/mac80211/key.h --@@ -84,7 +84,7 @@ struct ieee80211_key { -+@@ -88,7 +88,7 @@ struct ieee80211_key { - * Management frames. - */ - u8 rx_pn[IEEE80211_NUM_TIDS + 1][IEEE80211_CCMP_PN_LEN]; -@@ -320,7 +320,7 @@ - struct { - --- a/net/mac80211/wpa.c - +++ b/net/mac80211/wpa.c --@@ -307,7 +307,8 @@ ieee80211_crypto_tkip_decrypt(struct iee -+@@ -304,7 +304,8 @@ ieee80211_crypto_tkip_decrypt(struct iee - } - - -@@ -330,7 +330,7 @@ - { - __le16 mask_fc; - int a4_included, mgmt; --@@ -337,14 +338,8 @@ static void ccmp_special_blocks(struct s -+@@ -334,14 +335,8 @@ static void ccmp_special_blocks(struct s - else - qos_tid = 0; - -@@ -347,7 +347,7 @@ - - /* Nonce: Nonce Flags | A2 | PN - * Nonce Flags: Priority (b0..b3) | Management (b4) | Reserved (b5..b7) --@@ -352,6 +347,8 @@ static void ccmp_special_blocks(struct s -+@@ -349,6 +344,8 @@ static void ccmp_special_blocks(struct s - b_0[1] = qos_tid | (mgmt << 4); - memcpy(&b_0[2], hdr->addr2, ETH_ALEN); - memcpy(&b_0[8], pn, IEEE80211_CCMP_PN_LEN); -@@ -356,7 +356,7 @@ - - /* AAD (extra authenticate-only data) / masked 802.11 header - * FC | A1 | A2 | A3 | SC | [A4] | [QC] */ --@@ -463,7 +460,7 @@ static int ccmp_encrypt_skb(struct ieee8 -+@@ -460,7 +457,7 @@ static int ccmp_encrypt_skb(struct ieee8 - return 0; - - pos += IEEE80211_CCMP_HDR_LEN; -@@ -365,7 +365,7 @@ - ieee80211_aes_ccm_encrypt(key->u.ccmp.tfm, b_0, aad, pos, len, - skb_put(skb, mic_len), mic_len); - --@@ -534,7 +531,7 @@ ieee80211_crypto_ccmp_decrypt(struct iee -+@@ -537,7 +534,7 @@ ieee80211_crypto_ccmp_decrypt(struct iee - u8 aad[2 * AES_BLOCK_SIZE]; - u8 b_0[AES_BLOCK_SIZE]; - /* hardware didn't decrypt/verify MIC */ -diff --git a/package/kernel/mac80211/patches/110-mac80211_keep_keys_on_stop_ap.patch b/package/kernel/mac80211/patches/110-mac80211_keep_keys_on_stop_ap.patch -index d1d9fbd..3ca166f 100644 ---- a/package/kernel/mac80211/patches/110-mac80211_keep_keys_on_stop_ap.patch -+++ b/package/kernel/mac80211/patches/110-mac80211_keep_keys_on_stop_ap.patch -@@ -2,7 +2,7 @@ Used for AP+STA support in OpenWrt - preserve AP mode keys across STA reconnects - - --- a/net/mac80211/cfg.c - +++ b/net/mac80211/cfg.c --@@ -846,7 +846,6 @@ static int ieee80211_stop_ap(struct wiph -+@@ -850,7 +850,6 @@ static int ieee80211_stop_ap(struct wiph - sdata->u.ap.driver_smps_mode = IEEE80211_SMPS_OFF; - - __sta_info_flush(sdata, true); -diff --git a/package/kernel/mac80211/patches/150-disable_addr_notifier.patch b/package/kernel/mac80211/patches/150-disable_addr_notifier.patch -index 2855a88..16fab84 100644 ---- a/package/kernel/mac80211/patches/150-disable_addr_notifier.patch -+++ b/package/kernel/mac80211/patches/150-disable_addr_notifier.patch -@@ -18,9 +18,9 @@ - static int ieee80211_ifa6_changed(struct notifier_block *nb, - unsigned long data, void *arg) - { --@@ -1087,14 +1087,14 @@ int ieee80211_register_hw(struct ieee802 -- -- rtnl_unlock(); -+@@ -1090,14 +1090,14 @@ int ieee80211_register_hw(struct ieee802 -+ if (result) -+ goto fail_flows; - - -#ifdef CONFIG_INET - +#ifdef __disabled__CONFIG_INET -@@ -35,7 +35,7 @@ - local->ifa6_notifier.notifier_call = ieee80211_ifa6_changed; - result = register_inet6addr_notifier(&local->ifa6_notifier); - if (result) --@@ -1103,13 +1103,13 @@ int ieee80211_register_hw(struct ieee802 -+@@ -1106,13 +1106,13 @@ int ieee80211_register_hw(struct ieee802 - - return 0; - -@@ -51,8 +51,8 @@ - +#if defined(__disabled__CONFIG_INET) || defined(__disabled__CONFIG_IPV6) - fail_ifa: - #endif -- rtnl_lock(); --@@ -1137,10 +1137,10 @@ void ieee80211_unregister_hw(struct ieee -+ ieee80211_txq_teardown_flows(local); -+@@ -1142,10 +1142,10 @@ void ieee80211_unregister_hw(struct ieee - tasklet_kill(&local->tx_pending_tasklet); - tasklet_kill(&local->tasklet); - -diff --git a/package/kernel/mac80211/patches/210-ap_scan.patch b/package/kernel/mac80211/patches/210-ap_scan.patch -index a99cbd2..29f05c4 100644 ---- a/package/kernel/mac80211/patches/210-ap_scan.patch -+++ b/package/kernel/mac80211/patches/210-ap_scan.patch -@@ -1,6 +1,6 @@ - --- a/net/mac80211/cfg.c - +++ b/net/mac80211/cfg.c --@@ -1999,7 +1999,7 @@ static int ieee80211_scan(struct wiphy * -+@@ -2008,7 +2008,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/220-fq_disable_hack.patch b/package/kernel/mac80211/patches/220-fq_disable_hack.patch -new file mode 100644 -index 0000000..7f420be ---- /dev/null -+++ b/package/kernel/mac80211/patches/220-fq_disable_hack.patch -@@ -0,0 +1,15 @@ -+mac80211 fq has been found to cause a regression in multi-stream TCP -+performance. Disable it until the cause has been found and fixed -+ -+--- a/include/net/fq_impl.h -++++ b/include/net/fq_impl.h -+@@ -104,6 +104,9 @@ static struct fq_flow *fq_flow_classify( -+ -+ lockdep_assert_held(&fq->lock); -+ -++ /* HACK: disable fq for now until TCP issues are fixed */ -++ return get_default_func(fq, tin, 0, skb); -++ -+ hash = skb_get_hash_perturb(skb, fq->perturbation); -+ idx = reciprocal_scale(hash, fq->flows_cnt); -+ flow = &fq->flows[idx]; -diff --git a/package/kernel/mac80211/patches/300-ath9k-force-rx_clear-when-disabling-rx.patch b/package/kernel/mac80211/patches/300-ath9k-force-rx_clear-when-disabling-rx.patch -index bddb15a..098bda7 100644 ---- a/package/kernel/mac80211/patches/300-ath9k-force-rx_clear-when-disabling-rx.patch -+++ b/package/kernel/mac80211/patches/300-ath9k-force-rx_clear-when-disabling-rx.patch -@@ -3,15 +3,16 @@ Date: Sun, 7 Jun 2015 13:53:35 +0200 - Subject: [PATCH] ath9k: force rx_clear when disabling rx - - This makes stopping Rx more reliable and should reduce the frequency of --Rx related DMA stop warnings -+Rx related DMA stop warnings. Don't use rx_clear in TX99 mode. - - Cc: stable@vger.kernel.org --Signed-off-by: Felix Fietkau -+Signed-off-by: Felix Fietkau -+Signed-off-by: Helmut Schaa - --- - - --- a/drivers/net/wireless/ath/ath9k/mac.c - +++ b/drivers/net/wireless/ath/ath9k/mac.c --@@ -677,13 +677,15 @@ void ath9k_hw_startpcureceive(struct ath -+@@ -677,13 +677,18 @@ void ath9k_hw_startpcureceive(struct ath - - ath9k_ani_reset(ah, is_scanning); - -@@ -24,8 +25,11 @@ Signed-off-by: Felix Fietkau - void ath9k_hw_abortpcurecv(struct ath_hw *ah) - { - - REG_SET_BIT(ah, AR_DIAG_SW, AR_DIAG_RX_ABORT | AR_DIAG_RX_DIS); --+ REG_SET_BIT(ah, AR_DIAG_SW, --+ AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT | AR_DIAG_FORCE_RX_CLEAR); -++ u32 reg = AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT; -++ -++ if (!config_enabled(CPTCFG_ATH9K_TX99)) -++ reg |= AR_DIAG_FORCE_RX_CLEAR; -++ REG_SET_BIT(ah, AR_DIAG_SW, reg); - - ath9k_hw_disable_mib_counters(ah); - } -diff --git a/package/kernel/mac80211/patches/302-Revert-ath9k-interpret-requested-txpower-in-EIRP-dom.patch b/package/kernel/mac80211/patches/302-Revert-ath9k-interpret-requested-txpower-in-EIRP-dom.patch -new file mode 100644 -index 0000000..7caa9be ---- /dev/null -+++ b/package/kernel/mac80211/patches/302-Revert-ath9k-interpret-requested-txpower-in-EIRP-dom.patch -@@ -0,0 +1,37 @@ -+From: Felix Fietkau -+Date: Sat, 14 May 2016 14:51:02 +0200 -+Subject: [PATCH] Revert "ath9k: interpret requested txpower in EIRP -+ domain" -+ -+This reverts commit 71f5137bf010c6faffab50c0ec15374c59c4a411. -+--- -+ -+--- a/drivers/net/wireless/ath/ath9k/hw.c -++++ b/drivers/net/wireless/ath/ath9k/hw.c -+@@ -2914,7 +2914,8 @@ void ath9k_hw_apply_txpower(struct ath_h -+ { -+ struct ath_regulatory *reg = ath9k_hw_regulatory(ah); -+ struct ieee80211_channel *channel; -+- int chan_pwr, new_pwr; -++ int chan_pwr, new_pwr, max_gain; -++ int ant_gain, ant_reduction = 0; -+ -+ if (!chan) -+ return; -+@@ -2922,10 +2923,15 @@ void ath9k_hw_apply_txpower(struct ath_h -+ channel = chan->chan; -+ chan_pwr = min_t(int, channel->max_power * 2, MAX_RATE_POWER); -+ new_pwr = min_t(int, chan_pwr, reg->power_limit); -++ max_gain = chan_pwr - new_pwr + channel->max_antenna_gain * 2; -++ -++ ant_gain = get_antenna_gain(ah, chan); -++ if (ant_gain > max_gain) -++ ant_reduction = ant_gain - max_gain; -+ -+ ah->eep_ops->set_txpower(ah, chan, -+ ath9k_regd_get_ctl(reg, chan), -+- get_antenna_gain(ah, chan), new_pwr, test); -++ ant_reduction, new_pwr, test); -+ } -+ -+ void ath9k_hw_set_txpowerlimit(struct ath_hw *ah, u32 limit, bool test) -diff --git a/package/kernel/mac80211/patches/302-ath9k_hw-add-low-power-tx-gain-table-for-AR953x.patch b/package/kernel/mac80211/patches/302-ath9k_hw-add-low-power-tx-gain-table-for-AR953x.patch -deleted file mode 100644 -index 22b987a..0000000 ---- a/package/kernel/mac80211/patches/302-ath9k_hw-add-low-power-tx-gain-table-for-AR953x.patch -+++ /dev/null -@@ -1,95 +0,0 @@ --From: Felix Fietkau --Date: Thu, 14 Jan 2016 03:14:03 +0100 --Subject: [PATCH] ath9k_hw: add low power tx gain table for AR953x -- --Used in some newer TP-Link AR9533 devices. -- --Signed-off-by: Felix Fietkau ----- -- ----- a/drivers/net/wireless/ath/ath9k/ar9003_hw.c --+++ b/drivers/net/wireless/ath/ath9k/ar9003_hw.c --@@ -698,6 +698,9 @@ static void ar9003_tx_gain_table_mode2(s -- else if (AR_SREV_9340(ah)) -- INIT_INI_ARRAY(&ah->iniModesTxGain, -- ar9340Modes_low_ob_db_tx_gain_table_1p0); --+ else if (AR_SREV_9531_11(ah)) --+ INIT_INI_ARRAY(&ah->iniModesTxGain, --+ qca953x_1p1_modes_no_xpa_low_power_tx_gain_table); -- else if (AR_SREV_9485_11_OR_LATER(ah)) -- INIT_INI_ARRAY(&ah->iniModesTxGain, -- ar9485Modes_low_ob_db_tx_gain_1_1); ----- a/drivers/net/wireless/ath/ath9k/ar953x_initvals.h --+++ b/drivers/net/wireless/ath/ath9k/ar953x_initvals.h --@@ -757,6 +757,71 @@ static const u32 qca953x_1p1_modes_xpa_t -- {0x00016448, 0x6c927a70}, -- }; -- --+static const u32 qca953x_1p1_modes_no_xpa_low_power_tx_gain_table[][2] = { --+ /* Addr allmodes */ --+ {0x0000a2dc, 0xfff55592}, --+ {0x0000a2e0, 0xfff99924}, --+ {0x0000a2e4, 0xfffe1e00}, --+ {0x0000a2e8, 0xffffe000}, --+ {0x0000a410, 0x000050d6}, --+ {0x0000a500, 0x00000069}, --+ {0x0000a504, 0x0400006b}, --+ {0x0000a508, 0x0800006d}, --+ {0x0000a50c, 0x0c000269}, --+ {0x0000a510, 0x1000026b}, --+ {0x0000a514, 0x1400026d}, --+ {0x0000a518, 0x18000669}, --+ {0x0000a51c, 0x1c00066b}, --+ {0x0000a520, 0x1d000a68}, --+ {0x0000a524, 0x21000a6a}, --+ {0x0000a528, 0x25000a6c}, --+ {0x0000a52c, 0x29000a6e}, --+ {0x0000a530, 0x2d0012a9}, --+ {0x0000a534, 0x310012ab}, --+ {0x0000a538, 0x350012ad}, --+ {0x0000a53c, 0x39001b0a}, --+ {0x0000a540, 0x3d001b0c}, --+ {0x0000a544, 0x41001b0e}, --+ {0x0000a548, 0x43001bae}, --+ {0x0000a54c, 0x45001914}, --+ {0x0000a550, 0x47001916}, --+ {0x0000a554, 0x49001b96}, --+ {0x0000a558, 0x49001b96}, --+ {0x0000a55c, 0x49001b96}, --+ {0x0000a560, 0x49001b96}, --+ {0x0000a564, 0x49001b96}, --+ {0x0000a568, 0x49001b96}, --+ {0x0000a56c, 0x49001b96}, --+ {0x0000a570, 0x49001b96}, --+ {0x0000a574, 0x49001b96}, --+ {0x0000a578, 0x49001b96}, --+ {0x0000a57c, 0x49001b96}, --+ {0x0000a600, 0x00000000}, --+ {0x0000a604, 0x00000000}, --+ {0x0000a608, 0x00000000}, --+ {0x0000a60c, 0x00000000}, --+ {0x0000a610, 0x00000000}, --+ {0x0000a614, 0x00000000}, --+ {0x0000a618, 0x00804201}, --+ {0x0000a61c, 0x01408201}, --+ {0x0000a620, 0x01408502}, --+ {0x0000a624, 0x01408502}, --+ {0x0000a628, 0x01408502}, --+ {0x0000a62c, 0x01408502}, --+ {0x0000a630, 0x01408502}, --+ {0x0000a634, 0x01408502}, --+ {0x0000a638, 0x01408502}, --+ {0x0000a63c, 0x01408502}, --+ {0x0000b2dc, 0xfff55592}, --+ {0x0000b2e0, 0xfff99924}, --+ {0x0000b2e4, 0xfffe1e00}, --+ {0x0000b2e8, 0xffffe000}, --+ {0x00016044, 0x044922db}, --+ {0x00016048, 0x6c927a70}, --+ {0x00016444, 0x044922db}, --+ {0x00016448, 0x6c927a70}, --+}; --+ -- static const u32 qca953x_2p0_baseband_core[][2] = { -- /* Addr allmodes */ -- {0x00009800, 0xafe68e30}, -diff --git a/package/kernel/mac80211/patches/303-ath10k-Ensure-txrx-compl-task-is-stopped-when-cleani.patch b/package/kernel/mac80211/patches/303-ath10k-Ensure-txrx-compl-task-is-stopped-when-cleani.patch -new file mode 100644 -index 0000000..73accd8 ---- /dev/null -+++ b/package/kernel/mac80211/patches/303-ath10k-Ensure-txrx-compl-task-is-stopped-when-cleani.patch -@@ -0,0 +1,21 @@ -+From: Ben Greear -+Date: Fri, 1 Apr 2016 14:12:08 -0700 -+Subject: [PATCH] ath10k: Ensure txrx-compl-task is stopped when cleaning -+ htt-tx. -+ -+Otherwise, the txrx-compl-task may access some bad memory? -+ -+Signed-off-by: Ben Greear -+--- -+ -+--- a/drivers/net/wireless/ath/ath10k/htt_tx.c -++++ b/drivers/net/wireless/ath/ath10k/htt_tx.c -+@@ -388,6 +388,8 @@ void ath10k_htt_tx_free(struct ath10k_ht -+ { -+ int size; -+ -++ tasklet_kill(&htt->txrx_compl_task); -++ -+ idr_for_each(&htt->pending_tx, ath10k_htt_tx_clean_up_pending, htt->ar); -+ idr_destroy(&htt->pending_tx); -+ -diff --git a/package/kernel/mac80211/patches/303-rt2x00-fix-monitor-mode-regression.patch b/package/kernel/mac80211/patches/303-rt2x00-fix-monitor-mode-regression.patch -deleted file mode 100644 -index 7bb7435..0000000 ---- a/package/kernel/mac80211/patches/303-rt2x00-fix-monitor-mode-regression.patch -+++ /dev/null -@@ -1,156 +0,0 @@ --From: Eli Cooper --Date: Thu, 14 Jan 2016 00:07:12 +0800 --Subject: [PATCH] rt2x00: fix monitor mode regression -- --Since commit df1404650ccbfeb76a84f301f22316be0d00a864 monitor mode for rt2x00 --has been made effectively useless because the hardware filter is configured to --drop packets whose intended recipient is not the device, regardless of the --presence of monitor mode interfaces. -- --This patch fixes this regression by adding explicit monitor mode support, and --configuring the hardware filter accordingly. -- --Signed-off-by: Eli Cooper ----- -- ----- a/drivers/net/wireless/ralink/rt2x00/rt2400pci.c --+++ b/drivers/net/wireless/ralink/rt2x00/rt2400pci.c --@@ -273,8 +273,10 @@ static void rt2400pci_config_filter(stru -- !(filter_flags & FIF_PLCPFAIL)); -- rt2x00_set_field32(®, RXCSR0_DROP_CONTROL, -- !(filter_flags & FIF_CONTROL)); --- rt2x00_set_field32(®, RXCSR0_DROP_NOT_TO_ME, 1); --+ rt2x00_set_field32(®, RXCSR0_DROP_NOT_TO_ME, --+ !rt2x00dev->is_monitoring); -- rt2x00_set_field32(®, RXCSR0_DROP_TODS, --+ !rt2x00dev->is_monitoring && -- !rt2x00dev->intf_ap_count); -- rt2x00_set_field32(®, RXCSR0_DROP_VERSION_ERROR, 1); -- rt2x00mmio_register_write(rt2x00dev, RXCSR0, reg); ----- a/drivers/net/wireless/ralink/rt2x00/rt2500pci.c --+++ b/drivers/net/wireless/ralink/rt2x00/rt2500pci.c --@@ -274,8 +274,10 @@ static void rt2500pci_config_filter(stru -- !(filter_flags & FIF_PLCPFAIL)); -- rt2x00_set_field32(®, RXCSR0_DROP_CONTROL, -- !(filter_flags & FIF_CONTROL)); --- rt2x00_set_field32(®, RXCSR0_DROP_NOT_TO_ME, 1); --+ rt2x00_set_field32(®, RXCSR0_DROP_NOT_TO_ME, --+ !rt2x00dev->is_monitoring); -- rt2x00_set_field32(®, RXCSR0_DROP_TODS, --+ !rt2x00dev->is_monitoring && -- !rt2x00dev->intf_ap_count); -- rt2x00_set_field32(®, RXCSR0_DROP_VERSION_ERROR, 1); -- rt2x00_set_field32(®, RXCSR0_DROP_MCAST, ----- a/drivers/net/wireless/ralink/rt2x00/rt2500usb.c --+++ b/drivers/net/wireless/ralink/rt2x00/rt2500usb.c --@@ -437,8 +437,10 @@ static void rt2500usb_config_filter(stru -- !(filter_flags & FIF_PLCPFAIL)); -- rt2x00_set_field16(®, TXRX_CSR2_DROP_CONTROL, -- !(filter_flags & FIF_CONTROL)); --- rt2x00_set_field16(®, TXRX_CSR2_DROP_NOT_TO_ME, 1); --+ rt2x00_set_field16(®, TXRX_CSR2_DROP_NOT_TO_ME, --+ !rt2x00dev->is_monitoring); -- rt2x00_set_field16(®, TXRX_CSR2_DROP_TODS, --+ !rt2x00dev->is_monitoring && -- !rt2x00dev->intf_ap_count); -- rt2x00_set_field16(®, TXRX_CSR2_DROP_VERSION_ERROR, 1); -- rt2x00_set_field16(®, TXRX_CSR2_DROP_MULTICAST, ----- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c --+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c --@@ -1490,7 +1490,8 @@ void rt2800_config_filter(struct rt2x00_ -- !(filter_flags & FIF_FCSFAIL)); -- rt2x00_set_field32(®, RX_FILTER_CFG_DROP_PHY_ERROR, -- !(filter_flags & FIF_PLCPFAIL)); --- rt2x00_set_field32(®, RX_FILTER_CFG_DROP_NOT_TO_ME, 1); --+ rt2x00_set_field32(®, RX_FILTER_CFG_DROP_NOT_TO_ME, --+ !rt2x00dev->is_monitoring); -- rt2x00_set_field32(®, RX_FILTER_CFG_DROP_NOT_MY_BSSD, 0); -- rt2x00_set_field32(®, RX_FILTER_CFG_DROP_VER_ERROR, 1); -- rt2x00_set_field32(®, RX_FILTER_CFG_DROP_MULTICAST, ----- a/drivers/net/wireless/ralink/rt2x00/rt2x00.h --+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00.h --@@ -844,11 +844,13 @@ struct rt2x00_dev { -- * - Open sta interface count. -- * - Association count. -- * - Beaconing enabled count. --+ * - Whether the device is monitoring. -- */ -- unsigned int intf_ap_count; -- unsigned int intf_sta_count; -- unsigned int intf_associated; -- unsigned int intf_beaconing; --+ bool is_monitoring; -- -- /* -- * Interface combinations ----- a/drivers/net/wireless/ralink/rt2x00/rt2x00config.c --+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00config.c --@@ -244,6 +244,16 @@ void rt2x00lib_config(struct rt2x00_dev -- (ieee80211_flags & IEEE80211_CONF_CHANGE_PS)) -- cancel_delayed_work_sync(&rt2x00dev->autowakeup_work); -- --+ if (ieee80211_flags & IEEE80211_CONF_CHANGE_MONITOR) { --+ if (conf->flags & IEEE80211_CONF_MONITOR) { --+ rt2x00_dbg(rt2x00dev, "Monitor mode is enabled\n"); --+ rt2x00dev->is_monitoring = true; --+ } else { --+ rt2x00_dbg(rt2x00dev, "Monitor mode is disabled\n"); --+ rt2x00dev->is_monitoring = false; --+ } --+ } --+ -- /* -- * Start configuration. -- */ ----- a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c --+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c --@@ -1204,6 +1204,7 @@ int rt2x00lib_start(struct rt2x00_dev *r -- rt2x00dev->intf_ap_count = 0; -- rt2x00dev->intf_sta_count = 0; -- rt2x00dev->intf_associated = 0; --+ rt2x00dev->is_monitoring = false; -- -- /* Enable the radio */ -- retval = rt2x00lib_enable_radio(rt2x00dev); ----- a/drivers/net/wireless/ralink/rt2x00/rt2x00mac.c --+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00mac.c --@@ -385,11 +385,6 @@ void rt2x00mac_configure_filter(struct i -- *total_flags |= FIF_PSPOLL; -- } -- --- /* --- * Check if there is any work left for us. --- */ --- if (rt2x00dev->packet_filter == *total_flags) --- return; -- rt2x00dev->packet_filter = *total_flags; -- -- rt2x00dev->ops->lib->config_filter(rt2x00dev, *total_flags); ----- a/drivers/net/wireless/ralink/rt2x00/rt61pci.c --+++ b/drivers/net/wireless/ralink/rt2x00/rt61pci.c --@@ -530,8 +530,10 @@ static void rt61pci_config_filter(struct -- !(filter_flags & FIF_PLCPFAIL)); -- rt2x00_set_field32(®, TXRX_CSR0_DROP_CONTROL, -- !(filter_flags & (FIF_CONTROL | FIF_PSPOLL))); --- rt2x00_set_field32(®, TXRX_CSR0_DROP_NOT_TO_ME, 1); --+ rt2x00_set_field32(®, TXRX_CSR0_DROP_NOT_TO_ME, --+ !rt2x00dev->is_monitoring); -- rt2x00_set_field32(®, TXRX_CSR0_DROP_TO_DS, --+ !rt2x00dev->is_monitoring && -- !rt2x00dev->intf_ap_count); -- rt2x00_set_field32(®, TXRX_CSR0_DROP_VERSION_ERROR, 1); -- rt2x00_set_field32(®, TXRX_CSR0_DROP_MULTICAST, ----- a/drivers/net/wireless/ralink/rt2x00/rt73usb.c --+++ b/drivers/net/wireless/ralink/rt2x00/rt73usb.c --@@ -480,8 +480,10 @@ static void rt73usb_config_filter(struct -- !(filter_flags & FIF_PLCPFAIL)); -- rt2x00_set_field32(®, TXRX_CSR0_DROP_CONTROL, -- !(filter_flags & (FIF_CONTROL | FIF_PSPOLL))); --- rt2x00_set_field32(®, TXRX_CSR0_DROP_NOT_TO_ME, 1); --+ rt2x00_set_field32(®, TXRX_CSR0_DROP_NOT_TO_ME, --+ !rt2x00dev->is_monitoring); -- rt2x00_set_field32(®, TXRX_CSR0_DROP_TO_DS, --+ !rt2x00dev->is_monitoring && -- !rt2x00dev->intf_ap_count); -- rt2x00_set_field32(®, TXRX_CSR0_DROP_VERSION_ERROR, 1); -- rt2x00_set_field32(®, TXRX_CSR0_DROP_MULTICAST, -diff --git a/package/kernel/mac80211/patches/304-ath10k-Ensure-peer_map-references-are-cleaned-up.patch b/package/kernel/mac80211/patches/304-ath10k-Ensure-peer_map-references-are-cleaned-up.patch -new file mode 100644 -index 0000000..7dec1fb ---- /dev/null -+++ b/package/kernel/mac80211/patches/304-ath10k-Ensure-peer_map-references-are-cleaned-up.patch -@@ -0,0 +1,60 @@ -+From: Ben Greear -+Date: Fri, 1 Apr 2016 14:12:09 -0700 -+Subject: [PATCH] ath10k: Ensure peer_map references are cleaned up. -+ -+While debugging OS crashes due to firmware crashes, I enabled -+kasan, and it noticed that peer objects were being used-after-freed. -+ -+Looks like there are two places we could be leaving stale references -+in the peer-map, so clean that up. -+ -+Signed-off-by: Ben Greear -+--- -+ -+--- a/drivers/net/wireless/ath/ath10k/mac.c -++++ b/drivers/net/wireless/ath/ath10k/mac.c -+@@ -802,6 +802,7 @@ static void ath10k_peer_cleanup(struct a -+ { -+ struct ath10k_peer *peer, *tmp; -+ int peer_id; -++ int i; -+ -+ lockdep_assert_held(&ar->conf_mutex); -+ -+@@ -818,6 +819,17 @@ static void ath10k_peer_cleanup(struct a -+ ar->peer_map[peer_id] = NULL; -+ } -+ -++ /* Double check that peer is properly un-referenced from -++ * the peer_map -++ */ -++ for (i = 0; i < ARRAY_SIZE(ar->peer_map); i++) { -++ if (ar->peer_map[i] == peer) { -++ ath10k_warn(ar, "removing stale peer_map entry for %pM (ptr %p idx %d)\n", -++ peer->addr, peer, i); -++ ar->peer_map[i] = NULL; -++ } -++ } -++ -+ list_del(&peer->list); -+ kfree(peer); -+ ar->num_peers--; -+@@ -828,6 +840,7 @@ static void ath10k_peer_cleanup(struct a -+ static void ath10k_peer_cleanup_all(struct ath10k *ar) -+ { -+ struct ath10k_peer *peer, *tmp; -++ int i; -+ -+ lockdep_assert_held(&ar->conf_mutex); -+ -+@@ -836,6 +849,10 @@ static void ath10k_peer_cleanup_all(stru -+ list_del(&peer->list); -+ kfree(peer); -+ } -++ -++ for (i = 0; i < ARRAY_SIZE(ar->peer_map); i++) -++ ar->peer_map[i] = NULL; -++ -+ spin_unlock_bh(&ar->data_lock); -+ -+ ar->num_peers = 0; -diff --git a/package/kernel/mac80211/patches/304-ath9k-avoid-ANI-restart-if-no-trigger.patch b/package/kernel/mac80211/patches/304-ath9k-avoid-ANI-restart-if-no-trigger.patch -deleted file mode 100644 -index 049059a..0000000 ---- a/package/kernel/mac80211/patches/304-ath9k-avoid-ANI-restart-if-no-trigger.patch -+++ /dev/null -@@ -1,32 +0,0 @@ --From: Miaoqing Pan --Date: Fri, 15 Jan 2016 18:17:17 +0800 --Subject: [PATCH] ath9k: avoid ANI restart if no trigger -- --Fixes commit 54da20d83f0e ("ath9k_hw: improve ANI processing and rx desensitizing parameters") -- --Call ath9k_ani_restart() only when the phy error rate reach the --ANI immunity threshold. Sync the logic with internal code base. -- --Signed-off-by: Miaoqing Pan ----- -- ----- a/drivers/net/wireless/ath/ath9k/ani.c --+++ b/drivers/net/wireless/ath/ath9k/ani.c --@@ -444,14 +444,16 @@ void ath9k_hw_ani_monitor(struct ath_hw -- ofdmPhyErrRate < ah->config.ofdm_trig_low) { -- ath9k_hw_ani_lower_immunity(ah); -- aniState->ofdmsTurn = !aniState->ofdmsTurn; --+ ath9k_ani_restart(ah); -- } else if (ofdmPhyErrRate > ah->config.ofdm_trig_high) { -- ath9k_hw_ani_ofdm_err_trigger(ah); -- aniState->ofdmsTurn = false; --+ ath9k_ani_restart(ah); -- } else if (cckPhyErrRate > ah->config.cck_trig_high) { -- ath9k_hw_ani_cck_err_trigger(ah); -- aniState->ofdmsTurn = true; --+ ath9k_ani_restart(ah); -- } --- ath9k_ani_restart(ah); -- } -- } -- EXPORT_SYMBOL(ath9k_hw_ani_monitor); -diff --git a/package/kernel/mac80211/patches/305-ath10k-Clean-up-peer-when-sta-goes-away.patch b/package/kernel/mac80211/patches/305-ath10k-Clean-up-peer-when-sta-goes-away.patch -new file mode 100644 -index 0000000..7248a8c ---- /dev/null -+++ b/package/kernel/mac80211/patches/305-ath10k-Clean-up-peer-when-sta-goes-away.patch -@@ -0,0 +1,32 @@ -+From: Ben Greear -+Date: Fri, 1 Apr 2016 14:12:11 -0700 -+Subject: [PATCH] ath10k: Clean up peer when sta goes away. -+ -+If WMI and/or firmware has issues removing the peer object, -+then we still need to clean up the peer object in the driver. -+ -+Signed-off-by: Ben Greear -+--- -+ -+--- a/drivers/net/wireless/ath/ath10k/mac.c -++++ b/drivers/net/wireless/ath/ath10k/mac.c -+@@ -5992,9 +5992,17 @@ static int ath10k_sta_state(struct ieee8 -+ continue; -+ -+ if (peer->sta == sta) { -+- ath10k_warn(ar, "found sta peer %pM entry on vdev %i after it was supposedly removed\n", -+- sta->addr, arvif->vdev_id); -++ ath10k_warn(ar, "found sta peer %pM (ptr %p id %d) entry on vdev %i after it was supposedly removed\n", -++ sta->addr, peer, i, arvif->vdev_id); -+ peer->sta = NULL; -++ -++ /* Clean up the peer object as well since we -++ * must have failed to do this above. -++ */ -++ list_del(&peer->list); -++ ar->peer_map[i] = NULL; -++ kfree(peer); -++ ar->num_peers--; -+ } -+ } -+ spin_unlock_bh(&ar->data_lock); -diff --git a/package/kernel/mac80211/patches/305-ath9k-clean-up-ANI-per-channel-pointer-checking.patch b/package/kernel/mac80211/patches/305-ath9k-clean-up-ANI-per-channel-pointer-checking.patch -deleted file mode 100644 -index a1ac67c..0000000 ---- a/package/kernel/mac80211/patches/305-ath9k-clean-up-ANI-per-channel-pointer-checking.patch -+++ /dev/null -@@ -1,91 +0,0 @@ --From: Miaoqing Pan --Date: Fri, 15 Jan 2016 18:17:18 +0800 --Subject: [PATCH] ath9k: clean up ANI per-channel pointer checking -- --commit c24bd3620c50 ("ath9k: Do not maintain ANI state per-channel") --removed per-channel handling, the code to check 'curchan' also --should be removed as never used. -- --Signed-off-by: Miaoqing Pan ----- -- ----- a/drivers/net/wireless/ath/ath9k/ani.c --+++ b/drivers/net/wireless/ath/ath9k/ani.c --@@ -126,12 +126,8 @@ static void ath9k_hw_update_mibstats(str -- -- static void ath9k_ani_restart(struct ath_hw *ah) -- { --- struct ar5416AniState *aniState; --- --- if (!ah->curchan) --- return; --+ struct ar5416AniState *aniState = &ah->ani; -- --- aniState = &ah->ani; -- aniState->listenTime = 0; -- -- ENABLE_REGWRITE_BUFFER(ah); --@@ -221,12 +217,7 @@ static void ath9k_hw_set_ofdm_nil(struct -- -- static void ath9k_hw_ani_ofdm_err_trigger(struct ath_hw *ah) -- { --- struct ar5416AniState *aniState; --- --- if (!ah->curchan) --- return; --- --- aniState = &ah->ani; --+ struct ar5416AniState *aniState = &ah->ani; -- -- if (aniState->ofdmNoiseImmunityLevel < ATH9K_ANI_OFDM_MAX_LEVEL) -- ath9k_hw_set_ofdm_nil(ah, aniState->ofdmNoiseImmunityLevel + 1, false); --@@ -281,12 +272,7 @@ static void ath9k_hw_set_cck_nil(struct -- -- static void ath9k_hw_ani_cck_err_trigger(struct ath_hw *ah) -- { --- struct ar5416AniState *aniState; --- --- if (!ah->curchan) --- return; --- --- aniState = &ah->ani; --+ struct ar5416AniState *aniState = &ah->ani; -- -- if (aniState->cckNoiseImmunityLevel < ATH9K_ANI_CCK_MAX_LEVEL) -- ath9k_hw_set_cck_nil(ah, aniState->cckNoiseImmunityLevel + 1, --@@ -299,9 +285,7 @@ static void ath9k_hw_ani_cck_err_trigger -- */ -- static void ath9k_hw_ani_lower_immunity(struct ath_hw *ah) -- { --- struct ar5416AniState *aniState; --- --- aniState = &ah->ani; --+ struct ar5416AniState *aniState = &ah->ani; -- -- /* lower OFDM noise immunity */ -- if (aniState->ofdmNoiseImmunityLevel > 0 && --@@ -329,7 +313,7 @@ void ath9k_ani_reset(struct ath_hw *ah, -- struct ath_common *common = ath9k_hw_common(ah); -- int ofdm_nil, cck_nil; -- --- if (!ah->curchan) --+ if (!chan) -- return; -- -- BUG_ON(aniState == NULL); --@@ -416,14 +400,10 @@ static bool ath9k_hw_ani_read_counters(s -- -- void ath9k_hw_ani_monitor(struct ath_hw *ah, struct ath9k_channel *chan) -- { --- struct ar5416AniState *aniState; --+ struct ar5416AniState *aniState = &ah->ani; -- struct ath_common *common = ath9k_hw_common(ah); -- u32 ofdmPhyErrRate, cckPhyErrRate; -- --- if (!ah->curchan) --- return; --- --- aniState = &ah->ani; -- if (!ath9k_hw_ani_read_counters(ah)) -- return; -- -diff --git a/package/kernel/mac80211/patches/306-ath9k-do-not-reset-while-BB-panic-0x4000409-on-ar956.patch b/package/kernel/mac80211/patches/306-ath9k-do-not-reset-while-BB-panic-0x4000409-on-ar956.patch -deleted file mode 100644 -index cf8194a..0000000 ---- a/package/kernel/mac80211/patches/306-ath9k-do-not-reset-while-BB-panic-0x4000409-on-ar956.patch -+++ /dev/null -@@ -1,31 +0,0 @@ --From: Miaoqing Pan --Date: Fri, 15 Jan 2016 18:17:19 +0800 --Subject: [PATCH] ath9k: do not reset while BB panic(0x4000409) on ar9561 -- --BB panic(0x4000409) observed while AP enabling/disabling --bursting. -- --Signed-off-by: Miaoqing Pan ----- -- ----- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c --+++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c --@@ -2071,7 +2071,8 @@ void ar9003_hw_attach_phy_ops(struct ath -- * to be disabled. -- * -- * 0x04000409: Packet stuck on receive. --- * Full chip reset is required for all chips except AR9340. --+ * Full chip reset is required for all chips except --+ * AR9340, AR9531 and AR9561. -- */ -- -- /* --@@ -2100,7 +2101,7 @@ bool ar9003_hw_bb_watchdog_check(struct -- case 0x04000b09: -- return true; -- case 0x04000409: --- if (AR_SREV_9340(ah) || AR_SREV_9531(ah)) --+ if (AR_SREV_9340(ah) || AR_SREV_9531(ah) || AR_SREV_9561(ah)) -- return false; -- else -- return true; -diff --git a/package/kernel/mac80211/patches/306-mac80211-add-hdrlen-to-ieee80211_tx_data.patch b/package/kernel/mac80211/patches/306-mac80211-add-hdrlen-to-ieee80211_tx_data.patch -new file mode 100644 -index 0000000..4a8f143 ---- /dev/null -+++ b/package/kernel/mac80211/patches/306-mac80211-add-hdrlen-to-ieee80211_tx_data.patch -@@ -0,0 +1,203 @@ -+From: Janusz Dziedzic -+Date: Fri, 19 Feb 2016 11:01:49 +0100 -+Subject: [PATCH] mac80211: add hdrlen to ieee80211_tx_data -+ -+Add hdrlen to ieee80211_tx_data and use this -+when wep/ccmd/tkip. This is preparation for -+aligned4 code. -+ -+Signed-off-by: Janusz Dziedzic -+--- -+ -+--- a/net/mac80211/ieee80211_i.h -++++ b/net/mac80211/ieee80211_i.h -+@@ -173,6 +173,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 -+@@ -922,7 +922,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 */ -+@@ -943,8 +943,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; -+@@ -1176,6 +1174,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; -+--- a/net/mac80211/util.c -++++ b/net/mac80211/util.c -+@@ -1226,6 +1226,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 */ -+@@ -1250,8 +1251,10 @@ void ieee80211_send_auth(struct ieee8021 -+ memcpy(skb_put(skb, extra_len), 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; -+ -+@@ -306,13 +306,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 -+@@ -43,7 +43,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; -+ -+@@ -186,7 +186,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; -+@@ -201,7 +200,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) -+@@ -418,7 +417,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) -+@@ -651,7 +650,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) -+@@ -791,7 +790,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; -+@@ -807,8 +805,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/307-ath9k-fix-inconsistent-use-of-tab-and-space-in-inden.patch b/package/kernel/mac80211/patches/307-ath9k-fix-inconsistent-use-of-tab-and-space-in-inden.patch -deleted file mode 100644 -index 80b781c..0000000 ---- a/package/kernel/mac80211/patches/307-ath9k-fix-inconsistent-use-of-tab-and-space-in-inden.patch -+++ /dev/null -@@ -1,27 +0,0 @@ --From: Miaoqing Pan --Date: Fri, 15 Jan 2016 18:17:20 +0800 --Subject: [PATCH] ath9k: fix inconsistent use of tab and space in -- indentation -- --Minor changes for indenting. -- --Signed-off-by: Miaoqing Pan ----- -- ----- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c --+++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c --@@ -5485,11 +5485,11 @@ unsigned int ar9003_get_paprd_scale_fact -- AR9300_PAPRD_SCALE_1); -- else { -- if (chan->channel >= 5700) --- return MS(le32_to_cpu(eep->modalHeader5G.papdRateMaskHt20), --- AR9300_PAPRD_SCALE_1); --+ return MS(le32_to_cpu(eep->modalHeader5G.papdRateMaskHt20), --+ AR9300_PAPRD_SCALE_1); -- else if (chan->channel >= 5400) -- return MS(le32_to_cpu(eep->modalHeader5G.papdRateMaskHt40), --- AR9300_PAPRD_SCALE_2); --+ AR9300_PAPRD_SCALE_2); -- else -- return MS(le32_to_cpu(eep->modalHeader5G.papdRateMaskHt40), -- AR9300_PAPRD_SCALE_1); -diff --git a/package/kernel/mac80211/patches/307-mac80211-add-NEED_ALIGNED4_SKBS-hw-flag.patch b/package/kernel/mac80211/patches/307-mac80211-add-NEED_ALIGNED4_SKBS-hw-flag.patch -new file mode 100644 -index 0000000..eeb881e ---- /dev/null -+++ b/package/kernel/mac80211/patches/307-mac80211-add-NEED_ALIGNED4_SKBS-hw-flag.patch -@@ -0,0 +1,235 @@ -+From: Janusz Dziedzic -+Date: Fri, 19 Feb 2016 11:01:50 +0100 -+Subject: [PATCH] mac80211: add NEED_ALIGNED4_SKBS hw flag -+ -+HW/driver should set NEED_ALIGNED4_SKBS flag in case -+require aligned skbs to four-byte boundaries. -+This affect only TX direction. -+ -+Padding is added after ieee80211_hdr, before IV/LLC. -+ -+Before we have to do memmove(hdrlen) twice in the -+dirver. Once before we pass this to HW and next -+in tx completion (to be sure monitor will report -+this tx frame correctly). -+ -+With this patch we can skip this memmove() and save CPU. -+ -+Currently this was tested with ath9k, both hw/sw crypt for -+wep/tkip/ccmp. -+ -+Signed-off-by: Janusz Dziedzic -+--- -+ -+--- a/include/net/mac80211.h -++++ b/include/net/mac80211.h -+@@ -2014,6 +2014,9 @@ struct ieee80211_txq { -+ * @IEEE80211_HW_TX_FRAG_LIST: Hardware (or driver) supports sending frag_list -+ * skbs, needed for zero-copy software A-MSDU. -+ * -++ * @IEEE80211_HW_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 { -+@@ -2054,6 +2057,7 @@ enum ieee80211_hw_flags { -+ IEEE80211_HW_USES_RSS, -+ IEEE80211_HW_TX_AMSDU, -+ IEEE80211_HW_TX_FRAG_LIST, -++ IEEE80211_HW_NEEDS_ALIGNED4_SKBS, -+ -+ /* keep last, obviously */ -+ NUM_IEEE80211_HW_FLAGS -+--- a/net/mac80211/debugfs.c -++++ b/net/mac80211/debugfs.c -+@@ -302,6 +302,7 @@ static const char *hw_flag_names[] = { -+ FLAG(USES_RSS), -+ FLAG(TX_AMSDU), -+ FLAG(TX_FRAG_LIST), -++ FLAG(NEEDS_ALIGNED4_SKBS), -+ #undef FLAG -+ }; -+ -+--- a/net/mac80211/ieee80211_i.h -++++ b/net/mac80211/ieee80211_i.h -+@@ -1497,6 +1497,29 @@ ieee80211_have_rx_timestamp(struct ieee8 -+ return false; -+ } -+ -++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, NEEDS_ALIGNED4_SKBS)) -++ return hdrlen & 2; -++ return 0; -++} -++ -++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; -++} -++ -+ u64 ieee80211_calculate_rx_timestamp(struct ieee80211_local *local, -+ struct ieee80211_rx_status *status, -+ unsigned int mpdu_len, -+--- a/net/mac80211/sta_info.h -++++ b/net/mac80211/sta_info.h -+@@ -279,7 +279,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 -+@@ -683,9 +683,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, 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 -+@@ -1173,8 +1173,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)) -+@@ -2108,7 +2107,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; -+@@ -2334,7 +2333,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; -+@@ -2554,6 +2553,9 @@ static struct sk_buff *ieee80211_build_h -+ hdrlen += 2; -+ } -+ -++ /* Check aligned4 skb required */ -++ padsize = ieee80211_hdr_padsize(&sdata->local->hw, hdrlen); -++ -+ /* -+ * Drop unicast frames to unauthorised stations unless they are -+ * EAPOL frames from the local station. -+@@ -2640,6 +2642,7 @@ static struct sk_buff *ieee80211_build_h -+ h_pos -= skip_header_bytes; -+ -+ 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 -+@@ -2678,6 +2681,9 @@ static struct sk_buff *ieee80211_build_h -+ } -+ #endif -+ -++ if (padsize) -++ memset(skb_push(skb, padsize), 0, padsize); -++ -+ if (ieee80211_is_data_qos(fc)) { -+ __le16 *qos_control; -+ -+@@ -2691,8 +2697,8 @@ static struct sk_buff *ieee80211_build_h -+ } else -+ memcpy(skb_push(skb, hdrlen), &hdr, hdrlen); -+ -+- nh_pos += hdrlen; -+- h_pos += hdrlen; -++ nh_pos += hdrlen + padsize; -++ h_pos += hdrlen + padsize; -+ -+ /* Update skb pointers to various headers since this modified frame -+ * is going to go through Linux networking code that may potentially -+@@ -2861,6 +2867,9 @@ void ieee80211_check_fast_xmit(struct st -+ fc |= cpu_to_le16(IEEE80211_STYPE_QOS_DATA); -+ } -+ -++ /* Check aligned4 skb required */ -++ 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, -+--- a/net/mac80211/util.c -++++ b/net/mac80211/util.c -+@@ -1224,6 +1224,7 @@ void ieee80211_send_auth(struct ieee8021 -+ u32 tx_flags) -+ { -+ struct ieee80211_local *local = sdata->local; -++ struct ieee80211_hw *hw = &local->hw; -+ struct sk_buff *skb; -+ struct ieee80211_mgmt *mgmt; -+ unsigned int hdrlen; -+@@ -1251,7 +1252,7 @@ void ieee80211_send_auth(struct ieee8021 -+ memcpy(skb_put(skb, extra_len), extra, extra_len); -+ -+ if (auth_alg == WLAN_AUTH_SHARED_KEY && transaction == 3) { -+- hdrlen = ieee80211_hdrlen(mgmt->frame_control); -++ hdrlen = ieee80211_padded_hdrlen(hw, mgmt->frame_control); -+ mgmt->frame_control |= cpu_to_le16(IEEE80211_FCTL_PROTECTED); -+ err = ieee80211_wep_encrypt(local, skb, hdrlen, key, -+ key_len, key_idx); -diff --git a/package/kernel/mac80211/patches/308-ath10k-Fix-sending-NULL-Qos-NULL-data-frames-for-QCA.patch b/package/kernel/mac80211/patches/308-ath10k-Fix-sending-NULL-Qos-NULL-data-frames-for-QCA.patch -new file mode 100644 -index 0000000..8590aad ---- /dev/null -+++ b/package/kernel/mac80211/patches/308-ath10k-Fix-sending-NULL-Qos-NULL-data-frames-for-QCA.patch -@@ -0,0 +1,72 @@ -+From: Mohammed Shafi Shajakhan -+Date: Thu, 23 Jun 2016 22:10:01 +0530 -+Subject: [PATCH] ath10k: Fix sending NULL/ Qos NULL data frames for -+ QCA99X0 and later -+ -+For chipsets like QCA99X0, IPQ4019 and later we are not getting proper -+NULL func status (always acked/successs !!) when hostapd does a -+PROBE_CLIENT via nullfunc frames when the station is powered off -+abruptly (inactive timer probes client via null func after the inactive -+time reaches beyond the threshold). Fix this by disabling the workaround -+(getting the ACK status of NULL func frames by sending via HTT mgmt-tx -+ path) introduced by the change ("ath10k: fix beacon loss handling ") -+for QCA99X0 and later chipsets. The normal tx path provides the proper -+ACK status for NULL data frames. As of now disable this workaround for -+chipsets QCA99X0 and later, once the 10.1 firmware is obselete we can -+completely get rid of this workaround for all the chipsets -+ -+Signed-off-by: Tamizh chelvam -+Signed-off-by: Mohammed Shafi Shajakhan -+--- -+ -+--- a/drivers/net/wireless/ath/ath10k/core.c -++++ b/drivers/net/wireless/ath/ath10k/core.c -+@@ -181,6 +181,7 @@ static const struct ath10k_hw_params ath -+ .board = QCA99X0_HW_2_0_BOARD_DATA_FILE, -+ .board_size = QCA99X0_BOARD_DATA_SZ, -+ .board_ext_size = QCA99X0_BOARD_EXT_DATA_SZ, -++ .disable_null_func_workaround = true, -+ }, -+ }, -+ { -+@@ -204,6 +205,7 @@ static const struct ath10k_hw_params ath -+ .board = QCA9984_HW_1_0_BOARD_DATA_FILE, -+ .board_size = QCA99X0_BOARD_DATA_SZ, -+ .board_ext_size = QCA99X0_BOARD_EXT_DATA_SZ, -++ .disable_null_func_workaround = true, -+ }, -+ }, -+ { -+@@ -262,6 +264,7 @@ static const struct ath10k_hw_params ath -+ .board = QCA4019_HW_1_0_BOARD_DATA_FILE, -+ .board_size = QCA4019_BOARD_DATA_SZ, -+ .board_ext_size = QCA4019_BOARD_EXT_DATA_SZ, -++ .disable_null_func_workaround = true, -+ }, -+ }, -+ }; -+--- a/drivers/net/wireless/ath/ath10k/core.h -++++ b/drivers/net/wireless/ath/ath10k/core.h -+@@ -750,6 +750,12 @@ struct ath10k { -+ const char *board; -+ size_t board_size; -+ size_t board_ext_size; -++ /* Workaround of sending NULL data frames via -++ * HTT mgmt TX and getting the proper ACK status does -++ * not works for chipsets QCA99X0 and later, while -++ * Tx data path reports the ACK status properly. -++ */ -++ bool disable_null_func_workaround; -+ } fw; -+ } hw_params; -+ -+--- a/drivers/net/wireless/ath/ath10k/mac.c -++++ b/drivers/net/wireless/ath/ath10k/mac.c -+@@ -3253,6 +3253,7 @@ ath10k_mac_tx_h_get_txmode(struct ath10k -+ * mode though because AP don't sleep. -+ */ -+ if (ar->htt.target_version_major < 3 && -++ !ar->hw_params.fw.disable_null_func_workaround && -+ (ieee80211_is_nullfunc(fc) || ieee80211_is_qos_nullfunc(fc)) && -+ !test_bit(ATH10K_FW_FEATURE_HAS_WMI_MGMT_TX, -+ ar->running_fw->fw_file.fw_features)) -diff --git a/package/kernel/mac80211/patches/308-ath9k-fix-data-bus-error-on-ar9300-and-ar9580.patch b/package/kernel/mac80211/patches/308-ath9k-fix-data-bus-error-on-ar9300-and-ar9580.patch -deleted file mode 100644 -index d408866..0000000 ---- a/package/kernel/mac80211/patches/308-ath9k-fix-data-bus-error-on-ar9300-and-ar9580.patch -+++ /dev/null -@@ -1,65 +0,0 @@ --From: Miaoqing Pan --Date: Fri, 15 Jan 2016 18:17:21 +0800 --Subject: [PATCH] ath9k: fix data bus error on ar9300 and ar9580 -- --One crash issue be found on ar9300: RTC_RC reg read leads crash, leading --the data bus error, due to RTC_RC reg write not happen properly. -- --Warm Reset trigger in continuous beacon stuck for one of the customer for --other chip, noticed the MAC was stuck in RTC reset. After analysis noticed --DMA did not complete when RTC was put in reset. -- --So, before resetting the MAC need to make sure there are no pending DMA --transactions because this reset does not reset all parts of the chip. -- --The 12th and 11th bit of MAC _DMA_CFG register used to do that. -- 12 cfg_halt_ack 0x0 -- 0 DMA has not yet halted -- 1 DMA has halted -- 11 cfg_halt_req 0x0 -- 0 DMA logic operates normally -- 1 Request DMA logic to stop so software can reset the MAC -- --The Bit [12] of this register indicates when the halt has taken effect or --not. the DMA halt IS NOT recoverable; once software sets bit [11] to --request a DMA halt, software must wait for bit [12] to be set and reset --the MAC. -- --So, the same thing we implemented for ar9580 chip. -- --Signed-off-by: Miaoqing Pan ----- -- ----- a/drivers/net/wireless/ath/ath9k/hw.c --+++ b/drivers/net/wireless/ath/ath9k/hw.c --@@ -1368,6 +1368,16 @@ static bool ath9k_hw_set_reset(struct at -- if (ath9k_hw_mci_is_enabled(ah)) -- ar9003_mci_check_gpm_offset(ah); -- --+ /* DMA HALT added to resolve ar9300 and ar9580 bus error during --+ * RTC_RC reg read --+ */ --+ if (AR_SREV_9300(ah) || AR_SREV_9580(ah)) { --+ REG_SET_BIT(ah, AR_CFG, AR_CFG_HALT_REQ); --+ ath9k_hw_wait(ah, AR_CFG, AR_CFG_HALT_ACK, AR_CFG_HALT_ACK, --+ 20 * AH_WAIT_TIMEOUT); --+ REG_CLR_BIT(ah, AR_CFG, AR_CFG_HALT_REQ); --+ } --+ -- REG_WRITE(ah, AR_RTC_RC, rst_flags); -- -- REGWRITE_BUFFER_FLUSH(ah); ----- a/drivers/net/wireless/ath/ath9k/reg.h --+++ b/drivers/net/wireless/ath/ath9k/reg.h --@@ -34,8 +34,10 @@ -- #define AR_CFG_SWRG 0x00000010 -- #define AR_CFG_AP_ADHOC_INDICATION 0x00000020 -- #define AR_CFG_PHOK 0x00000100 ---#define AR_CFG_CLK_GATE_DIS 0x00000400 -- #define AR_CFG_EEBS 0x00000200 --+#define AR_CFG_CLK_GATE_DIS 0x00000400 --+#define AR_CFG_HALT_REQ 0x00000800 --+#define AR_CFG_HALT_ACK 0x00001000 -- #define AR_CFG_PCI_MASTER_REQ_Q_THRESH 0x00060000 -- #define AR_CFG_PCI_MASTER_REQ_Q_THRESH_S 17 -- -diff --git a/package/kernel/mac80211/patches/309-01-brcmfmac-add-missing-include.patch b/package/kernel/mac80211/patches/309-01-brcmfmac-add-missing-include.patch -deleted file mode 100644 -index d9511c8..0000000 ---- a/package/kernel/mac80211/patches/309-01-brcmfmac-add-missing-include.patch -+++ /dev/null -@@ -1,19 +0,0 @@ --From: Felix Fietkau --Date: Fri, 15 Jan 2016 15:59:45 +0100 --Subject: [PATCH] brcmfmac: add missing include -- --linux/module.h is required for defining module parameters -- --Signed-off-by: Felix Fietkau ----- -- ----- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c --+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c --@@ -17,6 +17,7 @@ -- #include -- #include -- #include --+#include -- #include -- #include -- #include "core.h" -diff --git a/package/kernel/mac80211/patches/309-02-brcmfmac-fix-sdio-sg-table-alloc-crash.patch b/package/kernel/mac80211/patches/309-02-brcmfmac-fix-sdio-sg-table-alloc-crash.patch -deleted file mode 100644 -index 711e019..0000000 ---- a/package/kernel/mac80211/patches/309-02-brcmfmac-fix-sdio-sg-table-alloc-crash.patch -+++ /dev/null -@@ -1,118 +0,0 @@ --From: Hante Meuleman --Date: Tue, 19 Jan 2016 12:39:24 +0100 --Subject: [PATCH] brcmfmac: fix sdio sg table alloc crash -- --With commit 7d34b0560567 ("brcmfmac: Move all module parameters to --one place") a bug was introduced causing a null pointer exception. --This patch fixes the bug by initializing the sg table till after --the settings have been initialized. -- --Fixes: 7d34b0560567 ("brcmfmac: Move all module parameters to one place") --Reported-by: Marc Zyngier --Tested-by: Marc Zyngier --Reviewed-by: Arend Van Spriel --Reviewed-by: Franky (Zhenhui) Lin --Reviewed-by: Pieter-Paul Giesberts --Signed-off-by: Hante Meuleman --Signed-off-by: Arend van Spriel --Signed-off-by: Kalle Valo ----- -- ----- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c --+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c --@@ -879,11 +879,24 @@ int brcmf_sdiod_abort(struct brcmf_sdio_ -- return 0; -- } -- ---static void brcmf_sdiod_sgtable_alloc(struct brcmf_sdio_dev *sdiodev) --+void brcmf_sdiod_sgtable_alloc(struct brcmf_sdio_dev *sdiodev) -- { --+ struct sdio_func *func; --+ struct mmc_host *host; --+ uint max_blocks; -- uint nents; -- int err; -- --+ func = sdiodev->func[2]; --+ host = func->card->host; --+ sdiodev->sg_support = host->max_segs > 1; --+ max_blocks = min_t(uint, host->max_blk_count, 511u); --+ sdiodev->max_request_size = min_t(uint, host->max_req_size, --+ max_blocks * func->cur_blksize); --+ sdiodev->max_segment_count = min_t(uint, host->max_segs, --+ SG_MAX_SINGLE_ALLOC); --+ sdiodev->max_segment_size = host->max_seg_size; --+ -- if (!sdiodev->sg_support) -- return; -- --@@ -1021,9 +1034,6 @@ static void brcmf_sdiod_host_fixup(struc -- -- static int brcmf_sdiod_probe(struct brcmf_sdio_dev *sdiodev) -- { --- struct sdio_func *func; --- struct mmc_host *host; --- uint max_blocks; -- int ret = 0; -- -- sdiodev->num_funcs = 2; --@@ -1054,26 +1064,6 @@ static int brcmf_sdiod_probe(struct brcm -- goto out; -- } -- --- /* --- * determine host related variables after brcmf_sdiod_probe() --- * as func->cur_blksize is properly set and F2 init has been --- * completed successfully. --- */ --- func = sdiodev->func[2]; --- host = func->card->host; --- sdiodev->sg_support = host->max_segs > 1; --- max_blocks = min_t(uint, host->max_blk_count, 511u); --- sdiodev->max_request_size = min_t(uint, host->max_req_size, --- max_blocks * func->cur_blksize); --- sdiodev->max_segment_count = min_t(uint, host->max_segs, --- SG_MAX_SINGLE_ALLOC); --- sdiodev->max_segment_size = host->max_seg_size; --- --- /* allocate scatter-gather table. sg support --- * will be disabled upon allocation failure. --- */ --- brcmf_sdiod_sgtable_alloc(sdiodev); --- -- ret = brcmf_sdiod_freezer_attach(sdiodev); -- if (ret) -- goto out; --@@ -1084,7 +1074,7 @@ static int brcmf_sdiod_probe(struct brcm -- ret = -ENODEV; -- goto out; -- } --- brcmf_sdiod_host_fixup(host); --+ brcmf_sdiod_host_fixup(sdiodev->func[2]->card->host); -- out: -- if (ret) -- brcmf_sdiod_remove(sdiodev); ----- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c --+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c --@@ -4114,6 +4114,11 @@ struct brcmf_sdio *brcmf_sdio_probe(stru -- goto fail; -- } -- --+ /* allocate scatter-gather table. sg support --+ * will be disabled upon allocation failure. --+ */ --+ brcmf_sdiod_sgtable_alloc(bus->sdiodev); --+ -- /* Query the F2 block size, set roundup accordingly */ -- bus->blocksize = bus->sdiodev->func[2]->cur_blksize; -- bus->roundup = min(max_roundup, bus->blocksize); ----- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h --+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h --@@ -342,6 +342,7 @@ int brcmf_sdiod_ramrw(struct brcmf_sdio_ -- -- /* Issue an abort to the specified function */ -- int brcmf_sdiod_abort(struct brcmf_sdio_dev *sdiodev, uint fn); --+void brcmf_sdiod_sgtable_alloc(struct brcmf_sdio_dev *sdiodev); -- void brcmf_sdiod_change_state(struct brcmf_sdio_dev *sdiodev, -- enum brcmf_sdiod_state state); -- #ifdef CONFIG_PM_SLEEP -diff --git a/package/kernel/mac80211/patches/309-cfg80211-fix-proto-in-ieee80211_data_to_8023-for-fra.patch b/package/kernel/mac80211/patches/309-cfg80211-fix-proto-in-ieee80211_data_to_8023-for-fra.patch -new file mode 100644 -index 0000000..41c27ca ---- /dev/null -+++ b/package/kernel/mac80211/patches/309-cfg80211-fix-proto-in-ieee80211_data_to_8023-for-fra.patch -@@ -0,0 +1,37 @@ -+From: Felix Fietkau -+Date: Wed, 29 Jun 2016 10:02:32 +0200 -+Subject: [PATCH] cfg80211: fix proto in ieee80211_data_to_8023 for frames -+ without LLC header -+ -+The PDU length of incoming LLC frames is set to the total skb payload size -+in __ieee80211_data_to_8023() of net/wireless/util.c which incorrectly -+includes the length of the IEEE 802.11 header. -+ -+The resulting LLC frame header has a too large PDU length, causing the -+llc_fixup_skb() function of net/llc/llc_input.c to reject the incoming -+skb, effectively breaking STP. -+ -+Solve the problem by properly substracting the IEEE 802.11 frame header size -+from the PDU length, allowing the LLC processor to pick up the incoming -+control messages. -+ -+Special thanks to Gerry Rozema for tracking down the regression and proposing -+a suitable patch. -+ -+Fixes: 2d1c304cb2d5 ("cfg80211: add function for 802.3 conversion with separate output buffer") -+Cc: stable@vger.kernel.org -+Reported-by: Gerry Rozema -+Signed-off-by: Felix Fietkau -+--- -+ -+--- a/net/wireless/util.c -++++ b/net/wireless/util.c -+@@ -509,7 +509,7 @@ static int __ieee80211_data_to_8023(stru -+ * replace EtherType */ -+ hdrlen += ETH_ALEN + 2; -+ else -+- tmp.h_proto = htons(skb->len); -++ tmp.h_proto = htons(skb->len - hdrlen); -+ -+ pskb_pull(skb, hdrlen); -+ -diff --git a/package/kernel/mac80211/patches/310-ath9k_hw-ignore-eeprom-magic-mismatch-on-flash-based.patch b/package/kernel/mac80211/patches/310-ath9k_hw-ignore-eeprom-magic-mismatch-on-flash-based.patch -deleted file mode 100644 -index 287d6e1..0000000 ---- a/package/kernel/mac80211/patches/310-ath9k_hw-ignore-eeprom-magic-mismatch-on-flash-based.patch -+++ /dev/null -@@ -1,38 +0,0 @@ --From: Felix Fietkau --Date: Thu, 21 Jan 2016 16:28:44 +0100 --Subject: [PATCH] ath9k_hw: ignore eeprom magic mismatch on flash based devices -- --Many AR913x based devices (maybe others too) do not have a valid EEPROM --magic in their calibration data partition. -- --Fixes: 6fa658fd5ab2 ("ath9k: Simplify and fix eeprom endianness swapping") --Signed-off-by: Felix Fietkau ----- -- ----- a/drivers/net/wireless/ath/ath9k/eeprom.c --+++ b/drivers/net/wireless/ath/ath9k/eeprom.c --@@ -150,18 +150,18 @@ int ath9k_hw_nvram_swap_data(struct ath_ -- return -EIO; -- } -- --- if (magic == AR5416_EEPROM_MAGIC) { --- *swap_needed = false; --- } else if (swab16(magic) == AR5416_EEPROM_MAGIC) { --+ *swap_needed = false; --+ if (swab16(magic) == AR5416_EEPROM_MAGIC) { -- if (ah->ah_flags & AH_NO_EEP_SWAP) { -- ath_info(common, -- "Ignoring endianness difference in EEPROM magic bytes.\n"); --- --- *swap_needed = false; -- } else { -- *swap_needed = true; -- } --- } else { --+ } else if (magic != AR5416_EEPROM_MAGIC) { --+ if (ath9k_hw_use_flash(ah)) --+ return 0; --+ -- ath_err(common, -- "Invalid EEPROM Magic (0x%04x).\n", magic); -- return -EINVAL; -diff --git a/package/kernel/mac80211/patches/310-mac80211-minstrel-Enable-STBC-and-LDPC-for-VHT-Rates.patch b/package/kernel/mac80211/patches/310-mac80211-minstrel-Enable-STBC-and-LDPC-for-VHT-Rates.patch -new file mode 100644 -index 0000000..25929c9 ---- /dev/null -+++ b/package/kernel/mac80211/patches/310-mac80211-minstrel-Enable-STBC-and-LDPC-for-VHT-Rates.patch -@@ -0,0 +1,81 @@ -+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 -+@@ -1550,6 +1550,7 @@ struct ieee80211_vht_operation { -+ #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 -+@@ -1166,13 +1166,14 @@ 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; -+ int use_vht; -+ int n_supported = 0; -+ 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) -+@@ -1210,16 +1211,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; -+@@ -1232,10 +1241,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/311-ath10k-disable-wake_tx_queue-for-older-devices.patch b/package/kernel/mac80211/patches/311-ath10k-disable-wake_tx_queue-for-older-devices.patch -new file mode 100644 -index 0000000..4cf26a6 ---- /dev/null -+++ b/package/kernel/mac80211/patches/311-ath10k-disable-wake_tx_queue-for-older-devices.patch -@@ -0,0 +1,73 @@ -+From: Michal Kazior -+Date: Tue, 17 May 2016 14:47:01 +0200 -+Subject: [PATCH] ath10k: disable wake_tx_queue for older devices -+ -+Some setups suffer performance regressions with -+current wake_tx_queue implementation. -+ -+Signed-off-by: Michal Kazior -+--- -+ -+--- a/drivers/net/wireless/ath/ath10k/core.h -++++ b/drivers/net/wireless/ath/ath10k/core.h -+@@ -667,6 +667,7 @@ struct ath10k_fw_components { -+ struct ath10k { -+ struct ath_common ath_common; -+ struct ieee80211_hw *hw; -++ struct ieee80211_ops *ops; -+ struct device *dev; -+ u8 mac_addr[ETH_ALEN]; -+ -+--- a/drivers/net/wireless/ath/ath10k/mac.c -++++ b/drivers/net/wireless/ath/ath10k/mac.c -+@@ -7497,21 +7497,32 @@ static const struct ieee80211_channel at -+ struct ath10k *ath10k_mac_create(size_t priv_size) -+ { -+ struct ieee80211_hw *hw; -++ struct ieee80211_ops *ops; -+ struct ath10k *ar; -+ -+- hw = ieee80211_alloc_hw(sizeof(struct ath10k) + priv_size, &ath10k_ops); -+- if (!hw) -++ ops = kmemdup(&ath10k_ops, sizeof(ath10k_ops), GFP_KERNEL); -++ if (!ops) -++ return NULL; -++ -++ hw = ieee80211_alloc_hw(sizeof(struct ath10k) + priv_size, ops); -++ if (!hw) { -++ kfree(ops); -+ return NULL; -++ } -+ -+ ar = hw->priv; -+ ar->hw = hw; -++ ar->ops = ops; -+ -+ return ar; -+ } -+ -+ void ath10k_mac_destroy(struct ath10k *ar) -+ { -++ struct ieee80211_ops *ops = ar->ops; -++ -+ ieee80211_free_hw(ar->hw); -++ kfree(ops); -+ } -+ -+ static const struct ieee80211_iface_limit ath10k_if_limits[] = { -+@@ -7945,6 +7956,15 @@ int ath10k_mac_register(struct ath10k *a -+ ath10k_warn(ar, "failed to initialise DFS pattern detector\n"); -+ } -+ -++ /* Current wake_tx_queue implementation imposes a significant -++ * performance penalty in some setups. The tx scheduling code needs -++ * more work anyway so disable the wake_tx_queue unless firmware -++ * supports the pull-push mechanism. -++ */ -++ if (!test_bit(ATH10K_FW_FEATURE_PEER_FLOW_CONTROL, -++ ar->running_fw->fw_file.fw_features)) -++ ar->ops->wake_tx_queue = NULL; -++ -+ ret = ath_regd_init(&ar->ath_common.regulatory, ar->hw->wiphy, -+ ath10k_reg_notifier); -+ if (ret) { -diff --git a/package/kernel/mac80211/patches/311-ath9k-do-not-limit-the-number-of-DFS-interfaces-to-1.patch b/package/kernel/mac80211/patches/311-ath9k-do-not-limit-the-number-of-DFS-interfaces-to-1.patch -deleted file mode 100644 -index 070efa9..0000000 ---- a/package/kernel/mac80211/patches/311-ath9k-do-not-limit-the-number-of-DFS-interfaces-to-1.patch -+++ /dev/null -@@ -1,55 +0,0 @@ --From: Felix Fietkau --Date: Fri, 22 Jan 2016 01:05:56 +0100 --Subject: [PATCH] ath9k: do not limit the number of DFS interfaces to 1 -- --Signed-off-by: Felix Fietkau ----- -- ----- a/drivers/net/wireless/ath/ath9k/init.c --+++ b/drivers/net/wireless/ath/ath9k/init.c --@@ -751,14 +751,6 @@ static const struct ieee80211_iface_comb -- -- #endif /* CPTCFG_ATH9K_CHANNEL_CONTEXT */ -- ---static const struct ieee80211_iface_limit if_dfs_limits[] = { --- { .max = 1, .types = BIT(NL80211_IFTYPE_AP) | ---#ifdef CPTCFG_MAC80211_MESH --- BIT(NL80211_IFTYPE_MESH_POINT) | ---#endif --- BIT(NL80211_IFTYPE_ADHOC) }, ---}; --- -- static const struct ieee80211_iface_combination if_comb[] = { -- { -- .limits = if_limits, --@@ -766,6 +758,11 @@ static const struct ieee80211_iface_comb -- .max_interfaces = 2048, -- .num_different_channels = 1, -- .beacon_int_infra_match = true, --+#ifdef CPTCFG_ATH9K_DFS_CERTIFIED --+ .radar_detect_widths = BIT(NL80211_CHAN_WIDTH_20_NOHT) | --+ BIT(NL80211_CHAN_WIDTH_20) | --+ BIT(NL80211_CHAN_WIDTH_40), --+#endif -- }, -- { -- .limits = wds_limits, --@@ -774,18 +771,6 @@ static const struct ieee80211_iface_comb -- .num_different_channels = 1, -- .beacon_int_infra_match = true, -- }, ---#ifdef CPTCFG_ATH9K_DFS_CERTIFIED --- { --- .limits = if_dfs_limits, --- .n_limits = ARRAY_SIZE(if_dfs_limits), --- .max_interfaces = 1, --- .num_different_channels = 1, --- .beacon_int_infra_match = true, --- .radar_detect_widths = BIT(NL80211_CHAN_WIDTH_20_NOHT) | --- BIT(NL80211_CHAN_WIDTH_20) | --- BIT(NL80211_CHAN_WIDTH_40), --- } ---#endif -- }; -- -- #ifdef CPTCFG_ATH9K_CHANNEL_CONTEXT -diff --git a/package/kernel/mac80211/patches/312-ath9k-Correct-TSF-adjustment-to-align-the-beacon-tim.patch b/package/kernel/mac80211/patches/312-ath9k-Correct-TSF-adjustment-to-align-the-beacon-tim.patch -new file mode 100644 -index 0000000..df43105 ---- /dev/null -+++ b/package/kernel/mac80211/patches/312-ath9k-Correct-TSF-adjustment-to-align-the-beacon-tim.patch -@@ -0,0 +1,45 @@ -+From: Benjamin Berg -+Date: Mon, 4 Jul 2016 14:37:20 +0200 -+Subject: [PATCH] ath9k: Correct TSF adjustment to align the beacon time -+ correctly -+ -+Beacons were not send out at (timestamp % beacon_time == 0) for interfaces -+other than the primary one. To send out beacons with the correct timestamp -+according to 10.1.3.2 of the 802.11 standard the tsf_adjustment has to be -+set to the negative time difference instead of positive. This way the -+later beacons get corrected to have a lower (and similar) timestamp with -+regard to the beacon from slot 0. -+ -+I am not aware about any issues that have been caused by this. -+ -+Signed-off-by: Benjamin Berg -+--- -+ -+--- a/drivers/net/wireless/ath/ath9k/beacon.c -++++ b/drivers/net/wireless/ath/ath9k/beacon.c -+@@ -279,17 +279,21 @@ static void ath9k_set_tsfadjust(struct a -+ struct ath_common *common = ath9k_hw_common(sc->sc_ah); -+ struct ath_vif *avp = (void *)vif->drv_priv; -+ struct ath_beacon_config *cur_conf = &avp->chanctx->beacon; -+- u32 tsfadjust; -++ s64 tsfadjust; -+ -+ if (avp->av_bslot == 0) -+ return; -+ -++ /* tsf_adjust is added to the TSF value. We send out the beacon late, -++ * so need to adjust the TSF starting point to be later in time (i.e. -++ * the theoretical first beacon has a TSF of 0 after correction). -++ */ -+ tsfadjust = cur_conf->beacon_interval * avp->av_bslot; -+- tsfadjust = TU_TO_USEC(tsfadjust) / ATH_BCBUF; -++ tsfadjust = -TU_TO_USEC(tsfadjust) / ATH_BCBUF; -+ avp->tsf_adjust = cpu_to_le64(tsfadjust); -+ -+- ath_dbg(common, CONFIG, "tsfadjust is: %llu for bslot: %d\n", -+- (unsigned long long)tsfadjust, avp->av_bslot); -++ ath_dbg(common, CONFIG, "tsfadjust is: %lld for bslot: %d\n", -++ (signed long long)tsfadjust, avp->av_bslot); -+ } -+ -+ bool ath9k_csa_is_finished(struct ath_softc *sc, struct ieee80211_vif *vif) -diff --git a/package/kernel/mac80211/patches/312-mac80211-fix-txq-queue-related-crashes.patch b/package/kernel/mac80211/patches/312-mac80211-fix-txq-queue-related-crashes.patch -deleted file mode 100644 -index 61cafc7..0000000 ---- a/package/kernel/mac80211/patches/312-mac80211-fix-txq-queue-related-crashes.patch -+++ /dev/null -@@ -1,27 +0,0 @@ --From: Michal Kazior --Date: Thu, 21 Jan 2016 14:23:07 +0100 --Subject: [PATCH] mac80211: fix txq queue related crashes -- --The driver can access the queue simultanously --while mac80211 tears down the interface. Without --spinlock protection this could lead to corrupting --sk_buff_head and subsequently to an invalid --pointer dereference. -- --Fixes: ba8c3d6f16a1 ("mac80211: add an intermediate software queue implementation") --Signed-off-by: Michal Kazior ----- -- ----- a/net/mac80211/iface.c --+++ b/net/mac80211/iface.c --@@ -977,7 +977,10 @@ static void ieee80211_do_stop(struct iee -- if (sdata->vif.txq) { -- struct txq_info *txqi = to_txq_info(sdata->vif.txq); -- --+ spin_lock_bh(&txqi->queue.lock); -- ieee80211_purge_tx_queue(&local->hw, &txqi->queue); --+ spin_unlock_bh(&txqi->queue.lock); --+ -- atomic_set(&sdata->txqs_len[txqi->txq.ac], 0); -- } -- -diff --git a/package/kernel/mac80211/patches/313-ath9k-Handle-channel-context-in-get_-set_-reset_tsf.patch b/package/kernel/mac80211/patches/313-ath9k-Handle-channel-context-in-get_-set_-reset_tsf.patch -new file mode 100644 -index 0000000..ef0afbe ---- /dev/null -+++ b/package/kernel/mac80211/patches/313-ath9k-Handle-channel-context-in-get_-set_-reset_tsf.patch -@@ -0,0 +1,70 @@ -+From: Benjamin Berg -+Date: Mon, 4 Jul 2016 14:37:21 +0200 -+Subject: [PATCH] ath9k: Handle channel context in get_/set_/reset_tsf -+ -+The ath9k TSF handling routines need to be aware of the channel context that -+is being modified. With this change the TSF related values that are stored -+in each channel context will be correctly tracked and the harware will only -+be updated if the modified context is currently the active one. -+ -+Without this change the TSF modifications done using these routines would -+for example be lost during a hardware reset as done by ath_complete_reset. -+ -+Signed-off-by: Benjamin Berg -+--- -+ -+--- a/drivers/net/wireless/ath/ath9k/main.c -++++ b/drivers/net/wireless/ath/ath9k/main.c -+@@ -1823,11 +1823,18 @@ static void ath9k_bss_info_changed(struc -+ static u64 ath9k_get_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif) -+ { -+ struct ath_softc *sc = hw->priv; -++ struct ath_vif *avp = (void *)vif->drv_priv; -+ u64 tsf; -+ -+ mutex_lock(&sc->mutex); -+ ath9k_ps_wakeup(sc); -+- tsf = ath9k_hw_gettsf64(sc->sc_ah); -++ /* Get current TSF either from HW or kernel time. */ -++ if (sc->cur_chan == avp->chanctx) { -++ tsf = ath9k_hw_gettsf64(sc->sc_ah); -++ } else { -++ tsf = sc->cur_chan->tsf_val + -++ ath9k_hw_get_tsf_offset(&sc->cur_chan->tsf_ts, NULL); -++ } -+ ath9k_ps_restore(sc); -+ mutex_unlock(&sc->mutex); -+ -+@@ -1839,10 +1846,14 @@ static void ath9k_set_tsf(struct ieee802 -+ u64 tsf) -+ { -+ struct ath_softc *sc = hw->priv; -++ struct ath_vif *avp = (void *)vif->drv_priv; -+ -+ mutex_lock(&sc->mutex); -+ ath9k_ps_wakeup(sc); -+- ath9k_hw_settsf64(sc->sc_ah, tsf); -++ getrawmonotonic(&avp->chanctx->tsf_ts); -++ if (sc->cur_chan == avp->chanctx) -++ ath9k_hw_settsf64(sc->sc_ah, tsf); -++ avp->chanctx->tsf_val = tsf; -+ ath9k_ps_restore(sc); -+ mutex_unlock(&sc->mutex); -+ } -+@@ -1850,11 +1861,15 @@ static void ath9k_set_tsf(struct ieee802 -+ static void ath9k_reset_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif) -+ { -+ struct ath_softc *sc = hw->priv; -++ struct ath_vif *avp = (void *)vif->drv_priv; -+ -+ mutex_lock(&sc->mutex); -+ -+ ath9k_ps_wakeup(sc); -+- ath9k_hw_reset_tsf(sc->sc_ah); -++ getrawmonotonic(&avp->chanctx->tsf_ts); -++ if (sc->cur_chan == avp->chanctx) -++ ath9k_hw_reset_tsf(sc->sc_ah); -++ avp->chanctx->tsf_val = 0; -+ ath9k_ps_restore(sc); -+ -+ mutex_unlock(&sc->mutex); -diff --git a/package/kernel/mac80211/patches/313-mac80211-fix-unnecessary-frame-drops-in-mesh-fwding.patch b/package/kernel/mac80211/patches/313-mac80211-fix-unnecessary-frame-drops-in-mesh-fwding.patch -deleted file mode 100644 -index 844d43b..0000000 ---- a/package/kernel/mac80211/patches/313-mac80211-fix-unnecessary-frame-drops-in-mesh-fwding.patch -+++ /dev/null -@@ -1,57 +0,0 @@ --From: Michal Kazior --Date: Mon, 25 Jan 2016 14:43:24 +0100 --Subject: [PATCH] mac80211: fix unnecessary frame drops in mesh fwding -- --The ieee80211_queue_stopped() expects hw queue --number but it was given raw WMM AC number instead. -- --This could cause frame drops and problems with --traffic in some cases - most notably if driver --doesn't map AC numbers to queue numbers 1:1 and --uses ieee80211_stop_queues() and --ieee80211_wake_queue() only without ever calling --ieee80211_wake_queues(). -- --On ath10k it was possible to hit this problem in --the following case: -- -- 1. wlan0 uses queue 0 -- (ath10k maps queues per vif) -- 2. offchannel uses queue 15 -- 3. queues 1-14 are unused -- 4. ieee80211_stop_queues() -- 5. ieee80211_wake_queue(q=0) -- 6. ieee80211_wake_queue(q=15) -- (other queues are not woken up because both -- driver and mac80211 know other queues are -- unused) -- 7. ieee80211_rx_h_mesh_fwding() -- 8. ieee80211_select_queue_80211() returns 2 -- 9. ieee80211_queue_stopped(q=2) returns true -- 10. frame is dropped (oops!) -- --Fixes: d3c1597b8d1b ("mac80211: fix forwarded mesh frame queue mapping") --Signed-off-by: Michal Kazior ----- -- ----- a/net/mac80211/rx.c --+++ b/net/mac80211/rx.c --@@ -2235,7 +2235,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 q, hdrlen; --+ u16 ac, q, hdrlen; -- -- hdr = (struct ieee80211_hdr *) skb->data; -- hdrlen = ieee80211_hdrlen(hdr->frame_control); --@@ -2304,7 +2304,8 @@ ieee80211_rx_h_mesh_fwding(struct ieee80 -- ether_addr_equal(sdata->vif.addr, hdr->addr3)) -- return RX_CONTINUE; -- --- q = ieee80211_select_queue_80211(sdata, skb, hdr); --+ ac = ieee80211_select_queue_80211(sdata, skb, hdr); --+ q = sdata->vif.hw_queue[ac]; -- if (ieee80211_queue_stopped(&local->hw, q)) { -- IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, dropped_frames_congestion); -- return RX_DROP_MONITOR; -diff --git a/package/kernel/mac80211/patches/314-ath9k-Use-tsf-offset-helper-in-ath9k_hw_reset.patch b/package/kernel/mac80211/patches/314-ath9k-Use-tsf-offset-helper-in-ath9k_hw_reset.patch -new file mode 100644 -index 0000000..e725a8b ---- /dev/null -+++ b/package/kernel/mac80211/patches/314-ath9k-Use-tsf-offset-helper-in-ath9k_hw_reset.patch -@@ -0,0 +1,65 @@ -+From: Benjamin Berg -+Date: Mon, 4 Jul 2016 14:37:22 +0200 -+Subject: [PATCH] ath9k: Use tsf offset helper in ath9k_hw_reset -+ -+These changes make ath9k_hw_reset more consistent with other places that -+handle the TSF value by using the same helper routine. -+ -+A slight improvement is to not assume that a fixed time of 1.5ms has -+passed for the initval writes when compared to the first write attempt. -+Instead the TSF value is re-calculated which will yield a higher accuracy -+of the restored TSF timer. -+ -+Signed-off-by: Benjamin Berg -+--- -+ -+--- a/drivers/net/wireless/ath/ath9k/hw.c -++++ b/drivers/net/wireless/ath/ath9k/hw.c -+@@ -1832,8 +1832,9 @@ int ath9k_hw_reset(struct ath_hw *ah, st -+ u32 saveLedState; -+ u32 saveDefAntenna; -+ u32 macStaId1; -++ struct timespec tsf_ts; -++ u32 tsf_offset; -+ u64 tsf = 0; -+- s64 usec = 0; -+ int r; -+ bool start_mci_reset = false; -+ bool save_fullsleep = ah->chip_fullsleep; -+@@ -1877,8 +1878,8 @@ int ath9k_hw_reset(struct ath_hw *ah, st -+ macStaId1 = REG_READ(ah, AR_STA_ID1) & AR_STA_ID1_BASE_RATE_11B; -+ -+ /* Save TSF before chip reset, a cold reset clears it */ -++ getrawmonotonic(&tsf_ts); -+ tsf = ath9k_hw_gettsf64(ah); -+- usec = ktime_to_us(ktime_get_raw()); -+ -+ saveLedState = REG_READ(ah, AR_CFG_LED) & -+ (AR_CFG_LED_ASSOC_CTL | AR_CFG_LED_MODE_SEL | -+@@ -1911,8 +1912,8 @@ int ath9k_hw_reset(struct ath_hw *ah, st -+ } -+ -+ /* Restore TSF */ -+- usec = ktime_to_us(ktime_get_raw()) - usec; -+- ath9k_hw_settsf64(ah, tsf + usec); -++ tsf_offset = ath9k_hw_get_tsf_offset(&tsf_ts, NULL); -++ ath9k_hw_settsf64(ah, tsf + tsf_offset); -+ -+ if (AR_SREV_9280_20_OR_LATER(ah)) -+ REG_SET_BIT(ah, AR_GPIO_INPUT_EN_VAL, AR_GPIO_JTAG_DISABLE); -+@@ -1932,12 +1933,11 @@ int ath9k_hw_reset(struct ath_hw *ah, st -+ /* -+ * Some AR91xx SoC devices frequently fail to accept TSF writes -+ * right after the chip reset. When that happens, write a new -+- * value after the initvals have been applied, with an offset -+- * based on measured time difference -++ * value after the initvals have been applied. -+ */ -+ if (AR_SREV_9100(ah) && (ath9k_hw_gettsf64(ah) < tsf)) { -+- tsf += 1500; -+- ath9k_hw_settsf64(ah, tsf); -++ tsf_offset = ath9k_hw_get_tsf_offset(&tsf_ts, NULL); -++ ath9k_hw_settsf64(ah, tsf + tsf_offset); -+ } -+ -+ ath9k_hw_init_mfp(ah); -diff --git a/package/kernel/mac80211/patches/314-mac80211-Requeue-work-after-scan-complete-for-all-VI.patch b/package/kernel/mac80211/patches/314-mac80211-Requeue-work-after-scan-complete-for-all-VI.patch -deleted file mode 100644 -index 5b3efbd..0000000 ---- a/package/kernel/mac80211/patches/314-mac80211-Requeue-work-after-scan-complete-for-all-VI.patch -+++ /dev/null -@@ -1,103 +0,0 @@ --From: Sachin Kulkarni --Date: Tue, 12 Jan 2016 14:30:19 +0530 --Subject: [PATCH] mac80211: Requeue work after scan complete for all VIF -- types. -- --During a sw scan ieee80211_iface_work ignores work items for all vifs. --However after the scan complete work is requeued only for STA, ADHOC --and MESH iftypes. -- --This occasionally results in event processing getting delayed/not --processed for iftype AP when it coexists with a STA. This can result --in data halt and eventually disconnection on the AP interface. -- --Signed-off-by: Sachin Kulkarni --Cc: linux-wireless@vger.kernel.org --Cc: johannes@sipsolutions.net ----- -- ----- a/net/mac80211/ibss.c --+++ b/net/mac80211/ibss.c --@@ -1731,7 +1731,6 @@ void ieee80211_ibss_notify_scan_complete -- if (sdata->vif.type != NL80211_IFTYPE_ADHOC) -- continue; -- sdata->u.ibss.last_scan_completed = jiffies; --- ieee80211_queue_work(&local->hw, &sdata->work); -- } -- mutex_unlock(&local->iflist_mtx); -- } ----- a/net/mac80211/mesh.c --+++ b/net/mac80211/mesh.c --@@ -1369,17 +1369,6 @@ out: -- sdata_unlock(sdata); -- } -- ---void ieee80211_mesh_notify_scan_completed(struct ieee80211_local *local) ---{ --- struct ieee80211_sub_if_data *sdata; --- --- rcu_read_lock(); --- list_for_each_entry_rcu(sdata, &local->interfaces, list) --- if (ieee80211_vif_is_mesh(&sdata->vif) && --- ieee80211_sdata_running(sdata)) --- ieee80211_queue_work(&local->hw, &sdata->work); --- rcu_read_unlock(); ---} -- -- void ieee80211_mesh_init_sdata(struct ieee80211_sub_if_data *sdata) -- { ----- a/net/mac80211/mesh.h --+++ b/net/mac80211/mesh.h --@@ -362,14 +362,10 @@ static inline bool mesh_path_sel_is_hwmp -- return sdata->u.mesh.mesh_pp_id == IEEE80211_PATH_PROTOCOL_HWMP; -- } -- ---void ieee80211_mesh_notify_scan_completed(struct ieee80211_local *local); --- -- void mesh_path_flush_by_iface(struct ieee80211_sub_if_data *sdata); -- void mesh_sync_adjust_tbtt(struct ieee80211_sub_if_data *sdata); -- void ieee80211s_stop(void); -- #else ---static inline void ---ieee80211_mesh_notify_scan_completed(struct ieee80211_local *local) {} -- static inline bool mesh_path_sel_is_hwmp(struct ieee80211_sub_if_data *sdata) -- { return false; } -- static inline void mesh_path_flush_by_iface(struct ieee80211_sub_if_data *sdata) ----- a/net/mac80211/mlme.c --+++ b/net/mac80211/mlme.c --@@ -3978,8 +3978,6 @@ static void ieee80211_restart_sta_timer( -- if (!ieee80211_hw_check(&sdata->local->hw, CONNECTION_MONITOR)) -- ieee80211_queue_work(&sdata->local->hw, -- &sdata->u.mgd.monitor_work); --- /* and do all the other regular work too */ --- ieee80211_queue_work(&sdata->local->hw, &sdata->work); -- } -- } -- ----- a/net/mac80211/scan.c --+++ b/net/mac80211/scan.c --@@ -314,6 +314,7 @@ static void __ieee80211_scan_completed(s -- bool was_scanning = local->scanning; -- struct cfg80211_scan_request *scan_req; -- struct ieee80211_sub_if_data *scan_sdata; --+ struct ieee80211_sub_if_data *sdata; -- -- lockdep_assert_held(&local->mtx); -- --@@ -373,7 +374,15 @@ static void __ieee80211_scan_completed(s -- -- ieee80211_mlme_notify_scan_completed(local); -- ieee80211_ibss_notify_scan_completed(local); --- ieee80211_mesh_notify_scan_completed(local); --+ --+ /* Requeue all the work that might have been ignored while --+ * the scan was in progress --+ */ --+ list_for_each_entry_rcu(sdata, &local->interfaces, list) { --+ if (ieee80211_sdata_running(sdata)) --+ ieee80211_queue_work(&sdata->local->hw, &sdata->work); --+ } --+ -- if (was_scanning) -- ieee80211_start_next_roc(local); -- } -diff --git a/package/kernel/mac80211/patches/315-ath9k-Expose-tsf_adjustment-in-mac80211-tsf-getters-.patch b/package/kernel/mac80211/patches/315-ath9k-Expose-tsf_adjustment-in-mac80211-tsf-getters-.patch -new file mode 100644 -index 0000000..c95ab7e ---- /dev/null -+++ b/package/kernel/mac80211/patches/315-ath9k-Expose-tsf_adjustment-in-mac80211-tsf-getters-.patch -@@ -0,0 +1,32 @@ -+From: Benjamin Berg -+Date: Mon, 4 Jul 2016 14:37:23 +0200 -+Subject: [PATCH] ath9k: Expose tsf_adjustment in mac80211 tsf getters and -+ setters. -+ -+The ath9k driver modifies the TSF for VIFs for the purpose of sending -+beacons in a staggered fashion. This patch exposes this VIF specific -+adjustment of the TSF value to mac80211. Without the change the TSF -+routines handle the hardware TSF value instead of the actual TSF value as -+seen on the air. -+ -+Signed-off-by: Benjamin Berg -+--- -+ -+--- a/drivers/net/wireless/ath/ath9k/main.c -++++ b/drivers/net/wireless/ath/ath9k/main.c -+@@ -1835,6 +1835,7 @@ static u64 ath9k_get_tsf(struct ieee8021 -+ tsf = sc->cur_chan->tsf_val + -+ ath9k_hw_get_tsf_offset(&sc->cur_chan->tsf_ts, NULL); -+ } -++ tsf += le64_to_cpu(avp->tsf_adjust); -+ ath9k_ps_restore(sc); -+ mutex_unlock(&sc->mutex); -+ -+@@ -1850,6 +1851,7 @@ static void ath9k_set_tsf(struct ieee802 -+ -+ mutex_lock(&sc->mutex); -+ ath9k_ps_wakeup(sc); -++ tsf -= le64_to_cpu(avp->tsf_adjust); -+ getrawmonotonic(&avp->chanctx->tsf_ts); -+ if (sc->cur_chan == avp->chanctx) -+ ath9k_hw_settsf64(sc->sc_ah, tsf); -diff --git a/package/kernel/mac80211/patches/315-mac80211-fix-ibss-scan-parameters.patch b/package/kernel/mac80211/patches/315-mac80211-fix-ibss-scan-parameters.patch -deleted file mode 100644 -index 52fecb9..0000000 ---- a/package/kernel/mac80211/patches/315-mac80211-fix-ibss-scan-parameters.patch -+++ /dev/null -@@ -1,57 +0,0 @@ --From: Sara Sharon --Date: Mon, 25 Jan 2016 15:46:35 +0200 --Subject: [PATCH] mac80211: fix ibss scan parameters -- --When joining IBSS a full scan should be initiated in order to search --for existing cell, unless the fixed_channel parameter was set. --A default channel to create the IBSS on if no cell was found is --provided as well. --However - a scan is initiated only on the default channel provided --regardless of whether ifibss->fixed_channel is set or not, with the --obvious result of the cell not joining existing IBSS cell that is --on another channel. -- --Fixes: 76bed0f43b27 ("mac80211: IBSS fix scan request") --Signed-off-by: Sara Sharon --Signed-off-by: Emmanuel Grumbach ----- -- ----- a/net/mac80211/ibss.c --+++ b/net/mac80211/ibss.c --@@ -7,6 +7,7 @@ -- * Copyright 2007, Michael Wu -- * Copyright 2009, Johannes Berg -- * Copyright 2013-2014 Intel Mobile Communications GmbH --+ * Copyright(c) 2016 Intel Deutschland GmbH -- * -- * 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 --@@ -1483,14 +1484,21 @@ static void ieee80211_sta_find_ibss(stru -- -- sdata_info(sdata, "Trigger new scan to find an IBSS to join\n"); -- --- num = ieee80211_ibss_setup_scan_channels(local->hw.wiphy, --- &ifibss->chandef, --- channels, --- ARRAY_SIZE(channels)); -- scan_width = cfg80211_chandef_to_scan_width(&ifibss->chandef); --- ieee80211_request_ibss_scan(sdata, ifibss->ssid, --- ifibss->ssid_len, channels, num, --- scan_width); --+ --+ if (ifibss->fixed_channel) { --+ num = ieee80211_ibss_setup_scan_channels(local->hw.wiphy, --+ &ifibss->chandef, --+ channels, --+ ARRAY_SIZE(channels)); --+ ieee80211_request_ibss_scan(sdata, ifibss->ssid, --+ ifibss->ssid_len, channels, --+ num, scan_width); --+ } else { --+ ieee80211_request_ibss_scan(sdata, ifibss->ssid, --+ ifibss->ssid_len, NULL, --+ 0, scan_width); --+ } -- } else { -- int interval = IEEE80211_SCAN_INTERVAL; -- -diff --git a/package/kernel/mac80211/patches/316-ath9k-Remove-some-defined-constants-to-decrease-verb.patch b/package/kernel/mac80211/patches/316-ath9k-Remove-some-defined-constants-to-decrease-verb.patch -new file mode 100644 -index 0000000..36aaa10 ---- /dev/null -+++ b/package/kernel/mac80211/patches/316-ath9k-Remove-some-defined-constants-to-decrease-verb.patch -@@ -0,0 +1,137 @@ -+From: Benjamin Berg -+Date: Mon, 4 Jul 2016 14:37:24 +0200 -+Subject: [PATCH] ath9k: Remove some #defined constants to decrease -+ verbosity -+ -+The removed ATH9K_SLOT_TIME_X constants simply map the value in microseconds -+to the same integer. These constants were not used consistently, so fix the -+inconsistency issue by replacing all occurances with the integer equivalent. -+ -+Signed-off-by: Benjamin Berg -+--- -+ -+--- a/drivers/net/wireless/ath/ath9k/beacon.c -++++ b/drivers/net/wireless/ath/ath9k/beacon.c -+@@ -50,7 +50,7 @@ static void ath9k_beaconq_config(struct -+ txq = sc->tx.txq_map[IEEE80211_AC_BE]; -+ ath9k_hw_get_txq_props(ah, txq->axq_qnum, &qi_be); -+ qi.tqi_aifs = qi_be.tqi_aifs; -+- if (ah->slottime == ATH9K_SLOT_TIME_20) -++ if (ah->slottime == 20) -+ qi.tqi_cwmin = 2*qi_be.tqi_cwmin; -+ else -+ qi.tqi_cwmin = 4*qi_be.tqi_cwmin; -+--- a/drivers/net/wireless/ath/ath9k/dynack.c -++++ b/drivers/net/wireless/ath/ath9k/dynack.c -+@@ -280,7 +280,7 @@ 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 = ATH9K_SLOT_TIME_9 + 16 + 64; -++ u32 ackto = 9 + 16 + 64; -+ struct ath_dynack *da = &ah->dynack; -+ -+ an->ackto = ackto; -+@@ -315,7 +315,7 @@ EXPORT_SYMBOL(ath_dynack_node_deinit); -+ void ath_dynack_reset(struct ath_hw *ah) -+ { -+ /* ackto = slottime + sifs + air delay */ -+- u32 ackto = ATH9K_SLOT_TIME_9 + 16 + 64; -++ u32 ackto = 9 + 16 + 64; -+ struct ath_dynack *da = &ah->dynack; -+ -+ da->lto = jiffies; -+--- a/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c -++++ b/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c -+@@ -45,7 +45,7 @@ void ath9k_htc_beaconq_config(struct ath -+ * Long slot time : 2x cwmin -+ * Short slot time : 4x cwmin -+ */ -+- if (ah->slottime == ATH9K_SLOT_TIME_20) -++ if (ah->slottime == 20) -+ qi.tqi_cwmin = 2*qi_be.tqi_cwmin; -+ else -+ qi.tqi_cwmin = 4*qi_be.tqi_cwmin; -+--- a/drivers/net/wireless/ath/ath9k/htc_drv_init.c -++++ b/drivers/net/wireless/ath/ath9k/htc_drv_init.c -+@@ -678,7 +678,7 @@ static int ath9k_init_priv(struct ath9k_ -+ -+ for (i = 0; i < ATH9K_HTC_MAX_BCN_VIF; i++) -+ priv->beacon.bslot[i] = NULL; -+- priv->beacon.slottime = ATH9K_SLOT_TIME_9; -++ priv->beacon.slottime = 9; -+ -+ ath9k_cmn_init_channels_rates(common); -+ ath9k_cmn_init_crypto(ah); -+--- a/drivers/net/wireless/ath/ath9k/hw.c -++++ b/drivers/net/wireless/ath/ath9k/hw.c -+@@ -454,7 +454,7 @@ static void ath9k_hw_init_defaults(struc -+ if (AR_SREV_9100(ah)) -+ ah->sta_id1_defaults |= AR_STA_ID1_AR9100_BA_FIX; -+ -+- ah->slottime = ATH9K_SLOT_TIME_9; -++ ah->slottime = 9; -+ ah->globaltxtimeout = (u32) -1; -+ ah->power_mode = ATH9K_PM_UNDEFINED; -+ ah->htc_reset_init = true; -+--- a/drivers/net/wireless/ath/ath9k/init.c -++++ b/drivers/net/wireless/ath/ath9k/init.c -+@@ -372,7 +372,7 @@ static void ath9k_init_misc(struct ath_s -+ -+ common->last_rssi = ATH_RSSI_DUMMY_MARKER; -+ memcpy(common->bssidmask, ath_bcast_mac, ETH_ALEN); -+- sc->beacon.slottime = ATH9K_SLOT_TIME_9; -++ sc->beacon.slottime = 9; -+ -+ for (i = 0; i < ARRAY_SIZE(sc->beacon.bslot); i++) -+ sc->beacon.bslot[i] = NULL; -+--- a/drivers/net/wireless/ath/ath9k/mac.h -++++ b/drivers/net/wireless/ath/ath9k/mac.h -+@@ -65,10 +65,6 @@ -+ #define INIT_SSH_RETRY 32 -+ #define INIT_SLG_RETRY 32 -+ -+-#define ATH9K_SLOT_TIME_6 6 -+-#define ATH9K_SLOT_TIME_9 9 -+-#define ATH9K_SLOT_TIME_20 20 -+- -+ #define ATH9K_TXERR_XRETRY 0x01 -+ #define ATH9K_TXERR_FILT 0x02 -+ #define ATH9K_TXERR_FIFO 0x04 -+--- a/drivers/net/wireless/ath/ath9k/main.c -++++ b/drivers/net/wireless/ath/ath9k/main.c -+@@ -926,7 +926,7 @@ static void ath9k_vif_iter(struct ath9k_ -+ } -+ -+ if (!vif->bss_conf.use_short_slot) -+- iter_data->slottime = ATH9K_SLOT_TIME_20; -++ iter_data->slottime = 20; -+ -+ switch (vif->type) { -+ case NL80211_IFTYPE_AP: -+@@ -999,7 +999,7 @@ void ath9k_calculate_iter_data(struct at -+ */ -+ memset(iter_data, 0, sizeof(*iter_data)); -+ eth_broadcast_addr(iter_data->mask); -+- iter_data->slottime = ATH9K_SLOT_TIME_9; -++ iter_data->slottime = 9; -+ -+ list_for_each_entry(avp, &ctx->vifs, list) -+ ath9k_vif_iter(iter_data, avp->vif->addr, avp->vif); -+@@ -1061,7 +1061,7 @@ static void ath9k_set_offchannel_state(s -+ ah->opmode = vif->type; -+ ah->imask &= ~ATH9K_INT_SWBA; -+ ah->imask &= ~ATH9K_INT_TSFOOR; -+- ah->slottime = ATH9K_SLOT_TIME_9; -++ ah->slottime = 9; -+ -+ ath_hw_setbssidmask(common); -+ ath9k_hw_setopmode(ah); -+@@ -1788,6 +1788,7 @@ static void ath9k_bss_info_changed(struc -+ slottime = 9; -+ else -+ slottime = 20; -++ -+ if (vif->type == NL80211_IFTYPE_AP) { -+ /* -+ * Defer update, so that connected stations can adjust -diff --git a/package/kernel/mac80211/patches/316-net-mac80211-agg-rx.c-fix-use-of-uninitialised-value.patch b/package/kernel/mac80211/patches/316-net-mac80211-agg-rx.c-fix-use-of-uninitialised-value.patch -deleted file mode 100644 -index e78df36..0000000 ---- a/package/kernel/mac80211/patches/316-net-mac80211-agg-rx.c-fix-use-of-uninitialised-value.patch -+++ /dev/null -@@ -1,50 +0,0 @@ --From: Chris Bainbridge --Date: Wed, 27 Jan 2016 15:46:18 +0000 --Subject: [PATCH] net/mac80211/agg-rx.c: fix use of uninitialised values -- --Use kzalloc instead of kmalloc for struct tid_ampdu_rx. Fixes: -- --[ 7.976605] UBSAN: Undefined behaviour in net/mac80211/rx.c:932:29 --[ 7.976608] load of value 2 is not a valid value for type '_Bool' --[ 7.976611] CPU: 3 PID: 1134 Comm: kworker/u16:7 Not tainted 4.5.0-rc1+ #265 --[ 7.976613] Hardware name: Apple Inc. MacBookPro10,2/Mac-AFD8A9D944EA4843, BIOS MBP102.88Z.0106.B0A.1509130955 09/13/2015 --[ 7.976616] Workqueue: phy0 rt2x00usb_work_rxdone --[ 7.976619] 0000000000000004 ffff880254a7ba50 ffffffff8181d866 0000000000000007 --[ 7.976622] ffff880254a7ba78 ffff880254a7ba68 ffffffff8188422d ffffffff8379b500 --[ 7.976626] ffff880254a7bab8 ffffffff81884747 0000000000000202 0000000348620032 --[ 7.976629] Call Trace: --[ 7.976633] [] dump_stack+0x45/0x5f --[ 7.976637] [] ubsan_epilogue+0xd/0x40 --[ 7.976642] [] __ubsan_handle_load_invalid_value+0x67/0x70 --[ 7.976646] [] ieee80211_sta_reorder_release.isra.16+0x5ed/0x730 --[ 7.976650] [] ieee80211_prepare_and_rx_handle+0xd04/0x1c00 --[ 7.976654] [] ? usb_hcd_map_urb_for_dma+0x65e/0x960 --[ 7.976659] [] __ieee80211_rx_handle_packet+0x1f3/0x750 --[ 7.976663] [] ieee80211_rx_napi+0x447/0x990 --[ 7.976667] [] rt2x00lib_rxdone+0x305/0xbd0 --[ 7.976670] [] ? dequeue_task_fair+0x64f/0x1de0 --[ 7.976674] [] ? sched_clock_cpu+0xe6/0x150 --[ 7.976678] [] rt2x00usb_work_rxdone+0x7c/0x140 --[ 7.976682] [] process_one_work+0x226/0x860 --[ 7.976686] [] worker_thread+0x5c/0x680 --[ 7.976690] [] ? process_one_work+0x860/0x860 --[ 7.976693] [] kthread+0xf6/0x150 --[ 7.976697] [] ? kthread_worker_fn+0x310/0x310 --[ 7.976700] [] ret_from_fork+0x3f/0x70 --[ 7.976703] [] ? kthread_worker_fn+0x310/0x310 -- --Link: https://lkml.org/lkml/2016/1/26/230 --Signed-off-by: Chris Bainbridge ----- -- ----- a/net/mac80211/agg-rx.c --+++ b/net/mac80211/agg-rx.c --@@ -327,7 +327,7 @@ void __ieee80211_start_rx_ba_session(str -- } -- -- /* prepare A-MPDU MLME for Rx aggregation */ --- tid_agg_rx = kmalloc(sizeof(struct tid_ampdu_rx), GFP_KERNEL); --+ tid_agg_rx = kzalloc(sizeof(struct tid_ampdu_rx), GFP_KERNEL); -- if (!tid_agg_rx) -- goto end; -- -diff --git a/package/kernel/mac80211/patches/317-ath9k-Fix-beacon-configuration-for-addition-removal-.patch b/package/kernel/mac80211/patches/317-ath9k-Fix-beacon-configuration-for-addition-removal-.patch -new file mode 100644 -index 0000000..360dfbf ---- /dev/null -+++ b/package/kernel/mac80211/patches/317-ath9k-Fix-beacon-configuration-for-addition-removal-.patch -@@ -0,0 +1,544 @@ -+From: Benjamin Berg -+Date: Mon, 4 Jul 2016 14:37:25 +0200 -+Subject: [PATCH] ath9k: Fix beacon configuration for addition/removal of -+ interfaces -+ -+This patch fixes some issues with interface reconfiguration. It could -+for example happen that an AP interface in beacon slot 0 was removed -+leaving an IBSS station in one of the other slots. When this happens -+the driver never sends out the beacon as it only tries to send a beacon -+from slot 0. -+ -+Appart from that the tracking of required changes to the beacon config is -+relatively complicated and prone to errors. -+ -+The approach taken here is to solve reconfiguration issues is to -+reconfigure the beacons when any interface changes. This means that -+the complexity of deciding whether an interface change may modify the -+beacon configuration is gone. It also means that the beacon config will -+be reliably updated when an interface is removed. -+ -+The issue that a single non-AP interface might not be in beacon -+slot 0 and wouldn't be send out is solved by moving it into the -+first slot. The TSF value in hardware is adjusted accordingly so -+that the timestamp of the beacons stay consistent. -+ -+Signed-off-by: Benjamin Berg -+--- -+ -+--- a/drivers/net/wireless/ath/ath9k/ath9k.h -++++ b/drivers/net/wireless/ath/ath9k/ath9k.h -+@@ -637,6 +637,8 @@ struct ath9k_vif_iter_data { -+ int nwds; /* number of WDS vifs */ -+ int nadhocs; /* number of adhoc vifs */ -+ int nocbs; /* number of OCB vifs */ -++ int nbcnvifs; /* number of beaconing vifs */ -++ struct ieee80211_vif *primary_beacon_vif; -+ struct ieee80211_vif *primary_sta; -+ }; -+ -+@@ -685,10 +687,11 @@ struct ath_beacon { -+ }; -+ -+ void ath9k_beacon_tasklet(unsigned long data); -+-void ath9k_beacon_config(struct ath_softc *sc, struct ieee80211_vif *vif, -+- u32 changed); -++void ath9k_beacon_config(struct ath_softc *sc, struct ieee80211_vif *main_vif, -++ bool beacons); -+ void ath9k_beacon_assign_slot(struct ath_softc *sc, struct ieee80211_vif *vif); -+ void ath9k_beacon_remove_slot(struct ath_softc *sc, struct ieee80211_vif *vif); -++void ath9k_beacon_ensure_primary_slot(struct ath_softc *sc); -+ void ath9k_set_beacon(struct ath_softc *sc); -+ bool ath9k_csa_is_finished(struct ath_softc *sc, struct ieee80211_vif *vif); -+ void ath9k_csa_update(struct ath_softc *sc); -+--- a/drivers/net/wireless/ath/ath9k/beacon.c -++++ b/drivers/net/wireless/ath/ath9k/beacon.c -+@@ -209,7 +209,6 @@ void ath9k_beacon_assign_slot(struct ath -+ } -+ -+ sc->beacon.bslot[avp->av_bslot] = vif; -+- sc->nbcnvifs++; -+ -+ ath_dbg(common, CONFIG, "Added interface at beacon slot: %d\n", -+ avp->av_bslot); -+@@ -220,15 +219,12 @@ void ath9k_beacon_remove_slot(struct ath -+ struct ath_common *common = ath9k_hw_common(sc->sc_ah); -+ struct ath_vif *avp = (void *)vif->drv_priv; -+ struct ath_buf *bf = avp->av_bcbuf; -+- struct ath_beacon_config *cur_conf = &sc->cur_chan->beacon; -+ -+ ath_dbg(common, CONFIG, "Removing interface at beacon slot: %d\n", -+ avp->av_bslot); -+ -+ tasklet_disable(&sc->bcon_tasklet); -+ -+- cur_conf->enable_beacon &= ~BIT(avp->av_bslot); -+- -+ if (bf && bf->bf_mpdu) { -+ struct sk_buff *skb = bf->bf_mpdu; -+ dma_unmap_single(sc->dev, bf->bf_buf_addr, -+@@ -240,12 +236,73 @@ void ath9k_beacon_remove_slot(struct ath -+ -+ avp->av_bcbuf = NULL; -+ sc->beacon.bslot[avp->av_bslot] = NULL; -+- sc->nbcnvifs--; -+ list_add_tail(&bf->list, &sc->beacon.bbuf); -+ -+ tasklet_enable(&sc->bcon_tasklet); -+ } -+ -++void ath9k_beacon_ensure_primary_slot(struct ath_softc *sc) -++{ -++ struct ath_common *common = ath9k_hw_common(sc->sc_ah); -++ struct ieee80211_vif *vif; -++ struct ath_vif *avp; -++ s64 tsfadjust; -++ u32 offset; -++ int first_slot = ATH_BCBUF; -++ int slot; -++ -++ tasklet_disable(&sc->bcon_tasklet); -++ -++ /* Find first taken slot. */ -++ for (slot = 0; slot < ATH_BCBUF; slot++) { -++ if (sc->beacon.bslot[slot]) { -++ first_slot = slot; -++ break; -++ } -++ } -++ if (first_slot == 0) -++ goto out; -++ -++ /* Re-enumarate all slots, moving them forward. */ -++ for (slot = 0; slot < ATH_BCBUF; slot++) { -++ if (slot + first_slot < ATH_BCBUF) { -++ vif = sc->beacon.bslot[slot + first_slot]; -++ sc->beacon.bslot[slot] = vif; -++ -++ if (vif) { -++ avp = (void *)vif->drv_priv; -++ avp->av_bslot = slot; -++ } -++ } else { -++ sc->beacon.bslot[slot] = NULL; -++ } -++ } -++ -++ vif = sc->beacon.bslot[0]; -++ if (WARN_ON(!vif)) -++ goto out; -++ -++ /* Get the tsf_adjust value for the new first slot. */ -++ avp = (void *)vif->drv_priv; -++ tsfadjust = le64_to_cpu(avp->tsf_adjust); -++ -++ ath_dbg(common, CONFIG, -++ "Adjusting global TSF after beacon slot reassignment: %lld\n", -++ (signed long long)tsfadjust); -++ -++ /* Modify TSF as required and update the HW. */ -++ avp->chanctx->tsf_val += tsfadjust; -++ if (sc->cur_chan == avp->chanctx) { -++ offset = ath9k_hw_get_tsf_offset(&avp->chanctx->tsf_ts, NULL); -++ ath9k_hw_settsf64(sc->sc_ah, avp->chanctx->tsf_val + offset); -++ } -++ -++ /* The slots tsf_adjust will be updated by ath9k_beacon_config later. */ -++ -++out: -++ tasklet_enable(&sc->bcon_tasklet); -++} -++ -+ static int ath9k_beacon_choose_slot(struct ath_softc *sc) -+ { -+ struct ath_common *common = ath9k_hw_common(sc->sc_ah); -+@@ -274,26 +331,33 @@ static int ath9k_beacon_choose_slot(stru -+ return slot; -+ } -+ -+-static void ath9k_set_tsfadjust(struct ath_softc *sc, struct ieee80211_vif *vif) -++static void ath9k_set_tsfadjust(struct ath_softc *sc, -++ struct ath_beacon_config *cur_conf) -+ { -+ struct ath_common *common = ath9k_hw_common(sc->sc_ah); -+- struct ath_vif *avp = (void *)vif->drv_priv; -+- struct ath_beacon_config *cur_conf = &avp->chanctx->beacon; -+ s64 tsfadjust; -++ int slot; -+ -+- if (avp->av_bslot == 0) -+- return; -++ for (slot = 0; slot < ATH_BCBUF; slot++) { -++ struct ath_vif *avp; -+ -+- /* tsf_adjust is added to the TSF value. We send out the beacon late, -+- * so need to adjust the TSF starting point to be later in time (i.e. -+- * the theoretical first beacon has a TSF of 0 after correction). -+- */ -+- tsfadjust = cur_conf->beacon_interval * avp->av_bslot; -+- tsfadjust = -TU_TO_USEC(tsfadjust) / ATH_BCBUF; -+- avp->tsf_adjust = cpu_to_le64(tsfadjust); -++ if (!sc->beacon.bslot[slot]) -++ continue; -+ -+- ath_dbg(common, CONFIG, "tsfadjust is: %lld for bslot: %d\n", -+- (signed long long)tsfadjust, avp->av_bslot); -++ avp = (void *)sc->beacon.bslot[slot]->drv_priv; -++ -++ /* tsf_adjust is added to the TSF value. We send out the -++ * beacon late, so need to adjust the TSF starting point to be -++ * later in time (i.e. the theoretical first beacon has a TSF -++ * of 0 after correction). -++ */ -++ tsfadjust = cur_conf->beacon_interval * avp->av_bslot; -++ tsfadjust = -TU_TO_USEC(tsfadjust) / ATH_BCBUF; -++ avp->tsf_adjust = cpu_to_le64(tsfadjust); -++ -++ ath_dbg(common, CONFIG, "tsfadjust is: %lld for bslot: %d\n", -++ (signed long long)tsfadjust, avp->av_bslot); -++ } -+ } -+ -+ bool ath9k_csa_is_finished(struct ath_softc *sc, struct ieee80211_vif *vif) -+@@ -447,20 +511,28 @@ void ath9k_beacon_tasklet(unsigned long -+ * Both nexttbtt and intval have to be in usecs. -+ */ -+ static void ath9k_beacon_init(struct ath_softc *sc, u32 nexttbtt, -+- u32 intval, bool reset_tsf) -++ u32 intval) -+ { -+ struct ath_hw *ah = sc->sc_ah; -+ -+ ath9k_hw_disable_interrupts(ah); -+- if (reset_tsf) -+- ath9k_hw_reset_tsf(ah); -+ ath9k_beaconq_config(sc); -+ ath9k_hw_beaconinit(ah, nexttbtt, intval); -++ ah->imask |= ATH9K_INT_SWBA; -+ sc->beacon.bmisscnt = 0; -+ ath9k_hw_set_interrupts(ah); -+ ath9k_hw_enable_interrupts(ah); -+ } -+ -++static void ath9k_beacon_stop(struct ath_softc *sc) -++{ -++ ath9k_hw_disable_interrupts(sc->sc_ah); -++ sc->sc_ah->imask &= ~(ATH9K_INT_SWBA | ATH9K_INT_BMISS); -++ sc->beacon.bmisscnt = 0; -++ ath9k_hw_set_interrupts(sc->sc_ah); -++ ath9k_hw_enable_interrupts(sc->sc_ah); -++} -++ -+ /* -+ * For multi-bss ap support beacons are either staggered evenly over N slots or -+ * burst together. For the former arrange for the SWBA to be delivered for each -+@@ -472,7 +544,7 @@ static void ath9k_beacon_config_ap(struc -+ struct ath_hw *ah = sc->sc_ah; -+ -+ ath9k_cmn_beacon_config_ap(ah, conf, ATH_BCBUF); -+- ath9k_beacon_init(sc, conf->nexttbtt, conf->intval, false); -++ ath9k_beacon_init(sc, conf->nexttbtt, conf->intval); -+ } -+ -+ static void ath9k_beacon_config_sta(struct ath_hw *ah, -+@@ -501,7 +573,7 @@ static void ath9k_beacon_config_adhoc(st -+ -+ ath9k_cmn_beacon_config_adhoc(ah, conf); -+ -+- ath9k_beacon_init(sc, conf->nexttbtt, conf->intval, conf->ibss_creator); -++ ath9k_beacon_init(sc, conf->nexttbtt, conf->intval); -+ -+ /* -+ * Set the global 'beacon has been configured' flag for the -+@@ -511,44 +583,6 @@ static void ath9k_beacon_config_adhoc(st -+ set_bit(ATH_OP_BEACONS, &common->op_flags); -+ } -+ -+-static bool ath9k_allow_beacon_config(struct ath_softc *sc, -+- struct ieee80211_vif *vif) -+-{ -+- struct ath_common *common = ath9k_hw_common(sc->sc_ah); -+- struct ath_vif *avp = (void *)vif->drv_priv; -+- -+- if (ath9k_is_chanctx_enabled()) { -+- /* -+- * If the VIF is not present in the current channel context, -+- * then we can't do the usual opmode checks. Allow the -+- * beacon config for the VIF to be updated in this case and -+- * return immediately. -+- */ -+- if (sc->cur_chan != avp->chanctx) -+- return true; -+- } -+- -+- if (sc->sc_ah->opmode == NL80211_IFTYPE_AP) { -+- if (vif->type != NL80211_IFTYPE_AP) { -+- ath_dbg(common, CONFIG, -+- "An AP interface is already present !\n"); -+- return false; -+- } -+- } -+- -+- if (sc->sc_ah->opmode == NL80211_IFTYPE_STATION) { -+- if ((vif->type == NL80211_IFTYPE_STATION) && -+- test_bit(ATH_OP_BEACONS, &common->op_flags) && -+- vif != sc->cur_chan->primary_sta) { -+- ath_dbg(common, CONFIG, -+- "Beacon already configured for a station interface\n"); -+- return false; -+- } -+- } -+- -+- return true; -+-} -+- -+ static void ath9k_cache_beacon_config(struct ath_softc *sc, -+ struct ath_chanctx *ctx, -+ struct ieee80211_bss_conf *bss_conf) -+@@ -584,87 +618,79 @@ static void ath9k_cache_beacon_config(st -+ if (cur_conf->dtim_period == 0) -+ cur_conf->dtim_period = 1; -+ -++ ath9k_set_tsfadjust(sc, cur_conf); -+ } -+ -+-void ath9k_beacon_config(struct ath_softc *sc, struct ieee80211_vif *vif, -+- u32 changed) -++void ath9k_beacon_config(struct ath_softc *sc, struct ieee80211_vif *main_vif, -++ bool beacons) -+ { -+- struct ieee80211_bss_conf *bss_conf = &vif->bss_conf; -+- struct ath_hw *ah = sc->sc_ah; -+- struct ath_common *common = ath9k_hw_common(ah); -+- struct ath_vif *avp = (void *)vif->drv_priv; -+- struct ath_chanctx *ctx = avp->chanctx; -++ struct ath_hw *ah = sc->sc_ah; -++ struct ath_common *common = ath9k_hw_common(ah); -++ struct ath_vif *avp; -++ struct ath_chanctx *ctx; -+ struct ath_beacon_config *cur_conf; -+ unsigned long flags; -++ bool enabled; -+ bool skip_beacon = false; -+ -+- if (!ctx) -++ if (!beacons) { -++ clear_bit(ATH_OP_BEACONS, &common->op_flags); -++ ath9k_beacon_stop(sc); -+ return; -++ } -+ -+- cur_conf = &avp->chanctx->beacon; -+- if (vif->type == NL80211_IFTYPE_AP) -+- ath9k_set_tsfadjust(sc, vif); -+- -+- if (!ath9k_allow_beacon_config(sc, vif)) -++ if (WARN_ON(!main_vif)) -+ return; -+ -+- if (vif->type == NL80211_IFTYPE_STATION) { -+- ath9k_cache_beacon_config(sc, ctx, bss_conf); -+- if (ctx != sc->cur_chan) -+- return; -++ avp = (void *)main_vif->drv_priv; -++ ctx = avp->chanctx; -++ cur_conf = &ctx->beacon; -++ enabled = cur_conf->enable_beacon; -++ cur_conf->enable_beacon = beacons; -++ -++ if (sc->sc_ah->opmode == NL80211_IFTYPE_STATION) { -++ ath9k_cache_beacon_config(sc, ctx, &main_vif->bss_conf); -+ -+ ath9k_set_beacon(sc); -+ set_bit(ATH_OP_BEACONS, &common->op_flags); -+ return; -+ } -+ -+- /* -+- * Take care of multiple interfaces when -+- * enabling/disabling SWBA. -+- */ -+- if (changed & BSS_CHANGED_BEACON_ENABLED) { -+- bool enabled = cur_conf->enable_beacon; -+- -+- if (!bss_conf->enable_beacon) { -+- cur_conf->enable_beacon &= ~BIT(avp->av_bslot); -+- } else { -+- cur_conf->enable_beacon |= BIT(avp->av_bslot); -+- if (!enabled) -+- ath9k_cache_beacon_config(sc, ctx, bss_conf); -+- } -+- } -+- -+- if (ctx != sc->cur_chan) -+- return; -++ /* Update the beacon configuration. */ -++ ath9k_cache_beacon_config(sc, ctx, &main_vif->bss_conf); -+ -+ /* -+ * Configure the HW beacon registers only when we have a valid -+ * beacon interval. -+ */ -+ if (cur_conf->beacon_interval) { -+- /* -+- * If we are joining an existing IBSS network, start beaconing -+- * only after a TSF-sync has taken place. Ensure that this -+- * happens by setting the appropriate flags. -++ /* Special case to sync the TSF when joining an existing IBSS. -++ * This is only done if no AP interface is active. -++ * Note that mac80211 always resets the TSF when creating a new -++ * IBSS interface. -+ */ -+- if ((changed & BSS_CHANGED_IBSS) && !bss_conf->ibss_creator && -+- bss_conf->enable_beacon) { -++ if (sc->sc_ah->opmode == NL80211_IFTYPE_ADHOC && -++ !enabled && beacons && !main_vif->bss_conf.ibss_creator) { -+ spin_lock_irqsave(&sc->sc_pm_lock, flags); -+ sc->ps_flags |= PS_BEACON_SYNC | PS_WAIT_FOR_BEACON; -+ spin_unlock_irqrestore(&sc->sc_pm_lock, flags); -+ skip_beacon = true; -+- } else { -+- ath9k_set_beacon(sc); -+ } -+ -+ /* -+ * Do not set the ATH_OP_BEACONS flag for IBSS joiner mode -+ * here, it is done in ath9k_beacon_config_adhoc(). -+ */ -+- if (cur_conf->enable_beacon && !skip_beacon) -++ if (beacons && !skip_beacon) { -+ set_bit(ATH_OP_BEACONS, &common->op_flags); -+- else -++ ath9k_set_beacon(sc); -++ } else { -+ clear_bit(ATH_OP_BEACONS, &common->op_flags); -++ ath9k_beacon_stop(sc); -++ } -++ } else { -++ clear_bit(ATH_OP_BEACONS, &common->op_flags); -++ ath9k_beacon_stop(sc); -+ } -+ } -+ -+--- a/drivers/net/wireless/ath/ath9k/common.h -++++ b/drivers/net/wireless/ath/ath9k/common.h -+@@ -50,6 +50,7 @@ -+ #define IEEE80211_MS_TO_TU(x) (((x) * 1000) / 1024) -+ -+ struct ath_beacon_config { -++ struct ieee80211_vif *main_vif; -+ int beacon_interval; -+ u16 dtim_period; -+ u16 bmiss_timeout; -+--- a/drivers/net/wireless/ath/ath9k/main.c -++++ b/drivers/net/wireless/ath/ath9k/main.c -+@@ -910,6 +910,22 @@ static bool ath9k_uses_beacons(int type) -+ } -+ } -+ -++static void ath9k_vif_iter_set_beacon(struct ath9k_vif_iter_data *iter_data, -++ struct ieee80211_vif *vif) -++{ -++ /* Use the first (configured) interface, but prefering AP interfaces. */ -++ if (!iter_data->primary_beacon_vif) { -++ iter_data->primary_beacon_vif = vif; -++ } else { -++ if (iter_data->primary_beacon_vif->type != NL80211_IFTYPE_AP && -++ vif->type == NL80211_IFTYPE_AP) -++ iter_data->primary_beacon_vif = vif; -++ } -++ -++ iter_data->beacons = true; -++ iter_data->nbcnvifs += 1; -++} -++ -+ static void ath9k_vif_iter(struct ath9k_vif_iter_data *iter_data, -+ u8 *mac, struct ieee80211_vif *vif) -+ { -+@@ -931,6 +947,8 @@ static void ath9k_vif_iter(struct ath9k_ -+ switch (vif->type) { -+ case NL80211_IFTYPE_AP: -+ iter_data->naps++; -++ if (vif->bss_conf.enable_beacon) -++ ath9k_vif_iter_set_beacon(iter_data, vif); -+ break; -+ case NL80211_IFTYPE_STATION: -+ iter_data->nstations++; -+@@ -943,12 +961,12 @@ static void ath9k_vif_iter(struct ath9k_ -+ case NL80211_IFTYPE_ADHOC: -+ iter_data->nadhocs++; -+ if (vif->bss_conf.enable_beacon) -+- iter_data->beacons = true; -++ ath9k_vif_iter_set_beacon(iter_data, vif); -+ break; -+ case NL80211_IFTYPE_MESH_POINT: -+ iter_data->nmeshes++; -+ if (vif->bss_conf.enable_beacon) -+- iter_data->beacons = true; -++ ath9k_vif_iter_set_beacon(iter_data, vif); -+ break; -+ case NL80211_IFTYPE_WDS: -+ iter_data->nwds++; -+@@ -1081,7 +1099,6 @@ void ath9k_calculate_summary_state(struc -+ struct ath_hw *ah = sc->sc_ah; -+ struct ath_common *common = ath9k_hw_common(ah); -+ struct ath9k_vif_iter_data iter_data; -+- struct ath_beacon_config *cur_conf; -+ -+ ath_chanctx_check_active(sc, ctx); -+ -+@@ -1103,13 +1120,12 @@ void ath9k_calculate_summary_state(struc -+ ath_hw_setbssidmask(common); -+ -+ if (iter_data.naps > 0) { -+- cur_conf = &ctx->beacon; -+ ath9k_hw_set_tsfadjust(ah, true); -+ ah->opmode = NL80211_IFTYPE_AP; -+- if (cur_conf->enable_beacon) -+- iter_data.beacons = true; -+ } else { -+ ath9k_hw_set_tsfadjust(ah, false); -++ if (iter_data.beacons) -++ ath9k_beacon_ensure_primary_slot(sc); -+ -+ if (iter_data.nmeshes) -+ ah->opmode = NL80211_IFTYPE_MESH_POINT; -+@@ -1134,7 +1150,6 @@ void ath9k_calculate_summary_state(struc -+ ctx->switch_after_beacon = true; -+ } -+ -+- ah->imask &= ~ATH9K_INT_SWBA; -+ if (ah->opmode == NL80211_IFTYPE_STATION) { -+ bool changed = (iter_data.primary_sta != ctx->primary_sta); -+ -+@@ -1151,16 +1166,12 @@ void ath9k_calculate_summary_state(struc -+ if (ath9k_hw_mci_is_enabled(sc->sc_ah)) -+ ath9k_mci_update_wlan_channels(sc, true); -+ } -+- } else if (iter_data.beacons) { -+- ah->imask |= ATH9K_INT_SWBA; -+ } -++ sc->nbcnvifs = iter_data.nbcnvifs; -++ ath9k_beacon_config(sc, iter_data.primary_beacon_vif, -++ iter_data.beacons); -+ ath9k_hw_set_interrupts(ah); -+ -+- if (iter_data.beacons) -+- set_bit(ATH_OP_BEACONS, &common->op_flags); -+- else -+- clear_bit(ATH_OP_BEACONS, &common->op_flags); -+- -+ if (ah->slottime != iter_data.slottime) { -+ ah->slottime = iter_data.slottime; -+ ath9k_hw_init_global_settings(ah); -+@@ -1777,9 +1788,7 @@ static void ath9k_bss_info_changed(struc -+ if ((changed & BSS_CHANGED_BEACON_ENABLED) || -+ (changed & BSS_CHANGED_BEACON_INT) || -+ (changed & BSS_CHANGED_BEACON_INFO)) { -+- ath9k_beacon_config(sc, vif, changed); -+- if (changed & BSS_CHANGED_BEACON_ENABLED) -+- ath9k_calculate_summary_state(sc, avp->chanctx); -++ ath9k_calculate_summary_state(sc, avp->chanctx); -+ } -+ -+ if ((avp->chanctx == sc->cur_chan) && -diff --git a/package/kernel/mac80211/patches/317-mac80211-minstrel_ht-fix-out-of-bound-in-minstrel_ht.patch b/package/kernel/mac80211/patches/317-mac80211-minstrel_ht-fix-out-of-bound-in-minstrel_ht.patch -deleted file mode 100644 -index 5bf53b9..0000000 ---- a/package/kernel/mac80211/patches/317-mac80211-minstrel_ht-fix-out-of-bound-in-minstrel_ht.patch -+++ /dev/null -@@ -1,45 +0,0 @@ --From: Konstantin Khlebnikov --Date: Fri, 29 Jan 2016 11:35:12 +0300 --Subject: [PATCH] mac80211: minstrel_ht: fix out-of-bound in -- minstrel_ht_set_best_prob_rate -- --Patch fixes this splat -- --BUG: KASAN: slab-out-of-bounds in minstrel_ht_update_stats.isra.7+0x6e1/0x9e0 --[mac80211] at addr ffff8800cee640f4 Read of size 4 by task swapper/3/0 -- --Signed-off-by: Konstantin Khlebnikov --Link: http://lkml.kernel.org/r/CALYGNiNyJhSaVnE35qS6UCGaSb2Dx1_i5HcRavuOX14oTz2P+w@mail.gmail.com ----- -- ----- a/net/mac80211/rc80211_minstrel_ht.c --+++ b/net/mac80211/rc80211_minstrel_ht.c --@@ -414,15 +414,16 @@ minstrel_ht_set_best_prob_rate(struct mi -- (max_tp_group != MINSTREL_CCK_GROUP)) -- return; -- --+ 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; --+ -- if (mrs->prob_ewma > MINSTREL_FRAC(75, 100)) { -- cur_tp_avg = minstrel_ht_get_tp_avg(mi, cur_group, cur_idx, -- mrs->prob_ewma); -- if (cur_tp_avg > tmp_tp_avg) -- mi->max_prob_rate = index; -- --- 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_tp_avg = minstrel_ht_get_tp_avg(mi, max_gpr_group, -- max_gpr_idx, -- max_gpr_prob); --@@ -431,7 +432,7 @@ minstrel_ht_set_best_prob_rate(struct mi -- } else { -- if (mrs->prob_ewma > tmp_prob) -- mi->max_prob_rate = index; --- if (mrs->prob_ewma > mg->rates[mg->max_group_prob_rate].prob_ewma) --+ if (mrs->prob_ewma > max_gpr_prob) -- mg->max_group_prob_rate = index; -- } -- } -diff --git a/package/kernel/mac80211/patches/318-brcmfmac-slightly-simplify-building-interface-combin.patch b/package/kernel/mac80211/patches/318-brcmfmac-slightly-simplify-building-interface-combin.patch -new file mode 100644 -index 0000000..d946ecc ---- /dev/null -+++ b/package/kernel/mac80211/patches/318-brcmfmac-slightly-simplify-building-interface-combin.patch -@@ -0,0 +1,108 @@ -+From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= -+Date: Tue, 7 Jun 2016 21:10:18 +0200 -+Subject: [PATCH] brcmfmac: slightly simplify building interface combinations -+MIME-Version: 1.0 -+Content-Type: text/plain; charset=UTF-8 -+Content-Transfer-Encoding: 8bit -+ -+This change reorders some operations in brcmf_setup_ifmodes in hope to -+make it simpler: -+1) It allocates arrays right before filling them. This way it's easier -+ to follow requested array length as it's immediately followed by -+ code filling it. It's easier to check e.g. why we need 4 entries for -+ P2P. Other than that it deduplicates some checks (e.g. for P2P). -+2) It reorders code to first prepare limits and then define a new combo. -+ Previously this was mixed (e.g. we were setting num of channels -+ before preparing limits). -+3) It modifies mbss code to use i variable just like other combos do. -+ -+Signed-off-by: RafaÅ‚ MiÅ‚ecki -+Acked-by: Arend van Spriel -+Signed-off-by: Kalle Valo -+--- -+ -+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c -++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c -+@@ -6284,29 +6284,15 @@ static int brcmf_setup_ifmodes(struct wi -+ if (!combo) -+ goto err; -+ -+- c0_limits = kcalloc(p2p ? 3 : 2, sizeof(*c0_limits), GFP_KERNEL); -+- if (!c0_limits) -+- goto err; -+- -+- if (p2p) { -+- p2p_limits = kcalloc(4, sizeof(*p2p_limits), GFP_KERNEL); -+- if (!p2p_limits) -+- goto err; -+- } -+- -+- if (mbss) { -+- mbss_limits = kcalloc(1, sizeof(*mbss_limits), GFP_KERNEL); -+- if (!mbss_limits) -+- goto err; -+- } -+- -+ wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | -+ BIT(NL80211_IFTYPE_ADHOC) | -+ BIT(NL80211_IFTYPE_AP); -+ -+ c = 0; -+ i = 0; -+- combo[c].num_different_channels = 1; -++ c0_limits = kcalloc(p2p ? 3 : 2, sizeof(*c0_limits), GFP_KERNEL); -++ if (!c0_limits) -++ goto err; -+ c0_limits[i].max = 1; -+ c0_limits[i++].types = BIT(NL80211_IFTYPE_STATION); -+ if (p2p) { -+@@ -6324,6 +6310,7 @@ static int brcmf_setup_ifmodes(struct wi -+ c0_limits[i].max = 1; -+ c0_limits[i++].types = BIT(NL80211_IFTYPE_AP); -+ } -++ combo[c].num_different_channels = 1; -+ combo[c].max_interfaces = i; -+ combo[c].n_limits = i; -+ combo[c].limits = c0_limits; -+@@ -6331,7 +6318,9 @@ static int brcmf_setup_ifmodes(struct wi -+ if (p2p) { -+ c++; -+ i = 0; -+- combo[c].num_different_channels = 1; -++ p2p_limits = kcalloc(4, sizeof(*p2p_limits), GFP_KERNEL); -++ if (!p2p_limits) -++ goto err; -+ p2p_limits[i].max = 1; -+ p2p_limits[i++].types = BIT(NL80211_IFTYPE_STATION); -+ p2p_limits[i].max = 1; -+@@ -6340,6 +6329,7 @@ static int brcmf_setup_ifmodes(struct wi -+ p2p_limits[i++].types = BIT(NL80211_IFTYPE_P2P_CLIENT); -+ p2p_limits[i].max = 1; -+ p2p_limits[i++].types = BIT(NL80211_IFTYPE_P2P_DEVICE); -++ combo[c].num_different_channels = 1; -+ combo[c].max_interfaces = i; -+ combo[c].n_limits = i; -+ combo[c].limits = p2p_limits; -+@@ -6347,14 +6337,19 @@ static int brcmf_setup_ifmodes(struct wi -+ -+ if (mbss) { -+ c++; -++ i = 0; -++ mbss_limits = kcalloc(1, sizeof(*mbss_limits), GFP_KERNEL); -++ if (!mbss_limits) -++ goto err; -++ mbss_limits[i].max = 4; -++ mbss_limits[i++].types = BIT(NL80211_IFTYPE_AP); -+ combo[c].beacon_int_infra_match = true; -+ combo[c].num_different_channels = 1; -+- mbss_limits[0].max = 4; -+- mbss_limits[0].types = BIT(NL80211_IFTYPE_AP); -+ combo[c].max_interfaces = 4; -+- combo[c].n_limits = 1; -++ combo[c].n_limits = i; -+ combo[c].limits = mbss_limits; -+ } -++ -+ wiphy->n_iface_combinations = n_combos; -+ wiphy->iface_combinations = combo; -+ return 0; -diff --git a/package/kernel/mac80211/patches/318-mac80211-move-A-MSDU-skb_linearize-call-to-ieee80211.patch b/package/kernel/mac80211/patches/318-mac80211-move-A-MSDU-skb_linearize-call-to-ieee80211.patch -deleted file mode 100644 -index 655dc4b..0000000 ---- a/package/kernel/mac80211/patches/318-mac80211-move-A-MSDU-skb_linearize-call-to-ieee80211.patch -+++ /dev/null -@@ -1,35 +0,0 @@ --From: Felix Fietkau --Date: Tue, 2 Feb 2016 14:39:08 +0100 --Subject: [PATCH] mac80211: move A-MSDU skb_linearize call to -- ieee80211_amsdu_to_8023s -- --Prepararation for zero-copy A-MSDU support with page fragment SKBs -- --Signed-off-by: Felix Fietkau --Signed-off-by: Johannes Berg ----- -- ----- a/net/mac80211/rx.c --+++ b/net/mac80211/rx.c --@@ -2203,9 +2203,6 @@ ieee80211_rx_h_amsdu(struct ieee80211_rx -- skb->dev = dev; -- __skb_queue_head_init(&frame_list); -- --- if (skb_linearize(skb)) --- return RX_DROP_UNUSABLE; --- -- ieee80211_amsdu_to_8023s(skb, &frame_list, dev->dev_addr, -- rx->sdata->vif.type, -- rx->local->hw.extra_tx_headroom, true); ----- a/net/wireless/util.c --+++ b/net/wireless/util.c --@@ -657,6 +657,9 @@ void ieee80211_amsdu_to_8023s(struct sk_ -- int remaining, err; -- u8 dst[ETH_ALEN], src[ETH_ALEN]; -- --+ if (skb_linearize(skb)) --+ goto out; --+ -- if (has_80211_header) { -- err = ieee80211_data_to_8023(skb, addr, iftype); -- if (err) -diff --git a/package/kernel/mac80211/patches/319-0001-brcmfmac-fix-lockup-when-removing-P2P-interface-afte.patch b/package/kernel/mac80211/patches/319-0001-brcmfmac-fix-lockup-when-removing-P2P-interface-afte.patch -new file mode 100644 -index 0000000..073d012 ---- /dev/null -+++ b/package/kernel/mac80211/patches/319-0001-brcmfmac-fix-lockup-when-removing-P2P-interface-afte.patch -@@ -0,0 +1,154 @@ -+From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= -+Date: Fri, 17 Jun 2016 12:29:21 +0200 -+Subject: [PATCH] brcmfmac: fix lockup when removing P2P interface after -+ event timeout -+MIME-Version: 1.0 -+Content-Type: text/plain; charset=UTF-8 -+Content-Transfer-Encoding: 8bit -+ -+Removing P2P interface is handled by sending a proper request to the -+firmware. On success firmware triggers an event and driver's handler -+removes a matching interface. -+ -+However on event timeout we remove interface directly from the cfg80211 -+callback. Current code doesn't handle this case correctly as it always -+assumes rtnl to be unlocked. -+ -+Fix it by adding an extra rtnl_locked parameter to functions and calling -+unregister_netdevice when needed. -+ -+Signed-off-by: RafaÅ‚ MiÅ‚ecki -+Signed-off-by: Kalle Valo -+--- -+ -+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c -++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c -+@@ -548,12 +548,16 @@ fail: -+ return -EBADE; -+ } -+ -+-static void brcmf_net_detach(struct net_device *ndev) -++static void brcmf_net_detach(struct net_device *ndev, bool rtnl_locked) -+ { -+- if (ndev->reg_state == NETREG_REGISTERED) -+- unregister_netdev(ndev); -+- else -++ if (ndev->reg_state == NETREG_REGISTERED) { -++ if (rtnl_locked) -++ unregister_netdevice(ndev); -++ else -++ unregister_netdev(ndev); -++ } else { -+ brcmf_cfg80211_free_netdev(ndev); -++ } -+ } -+ -+ void brcmf_net_setcarrier(struct brcmf_if *ifp, bool on) -+@@ -651,7 +655,7 @@ struct brcmf_if *brcmf_add_if(struct brc -+ brcmf_err("ERROR: netdev:%s already exists\n", -+ ifp->ndev->name); -+ netif_stop_queue(ifp->ndev); -+- brcmf_net_detach(ifp->ndev); -++ brcmf_net_detach(ifp->ndev, false); -+ drvr->iflist[bsscfgidx] = NULL; -+ } else { -+ brcmf_dbg(INFO, "netdev:%s ignore IF event\n", -+@@ -699,7 +703,8 @@ struct brcmf_if *brcmf_add_if(struct brc -+ return ifp; -+ } -+ -+-static void brcmf_del_if(struct brcmf_pub *drvr, s32 bsscfgidx) -++static void brcmf_del_if(struct brcmf_pub *drvr, s32 bsscfgidx, -++ bool rtnl_locked) -+ { -+ struct brcmf_if *ifp; -+ -+@@ -729,7 +734,7 @@ static void brcmf_del_if(struct brcmf_pu -+ cancel_work_sync(&ifp->multicast_work); -+ cancel_work_sync(&ifp->ndoffload_work); -+ } -+- brcmf_net_detach(ifp->ndev); -++ brcmf_net_detach(ifp->ndev, rtnl_locked); -+ } else { -+ /* Only p2p device interfaces which get dynamically created -+ * end up here. In this case the p2p module should be informed -+@@ -743,14 +748,14 @@ static void brcmf_del_if(struct brcmf_pu -+ } -+ } -+ -+-void brcmf_remove_interface(struct brcmf_if *ifp) -++void brcmf_remove_interface(struct brcmf_if *ifp, bool rtnl_locked) -+ { -+ if (!ifp || WARN_ON(ifp->drvr->iflist[ifp->bsscfgidx] != ifp)) -+ return; -+ brcmf_dbg(TRACE, "Enter, bsscfgidx=%d, ifidx=%d\n", ifp->bsscfgidx, -+ ifp->ifidx); -+ brcmf_fws_del_interface(ifp); -+- brcmf_del_if(ifp->drvr, ifp->bsscfgidx); -++ brcmf_del_if(ifp->drvr, ifp->bsscfgidx, rtnl_locked); -+ } -+ -+ #ifdef CONFIG_INET -+@@ -1057,9 +1062,9 @@ fail: -+ brcmf_fws_deinit(drvr); -+ } -+ if (ifp) -+- brcmf_net_detach(ifp->ndev); -++ brcmf_net_detach(ifp->ndev, false); -+ if (p2p_ifp) -+- brcmf_net_detach(p2p_ifp->ndev); -++ brcmf_net_detach(p2p_ifp->ndev, false); -+ drvr->iflist[0] = NULL; -+ drvr->iflist[1] = NULL; -+ if (drvr->settings->ignore_probe_fail) -+@@ -1128,7 +1133,7 @@ void brcmf_detach(struct device *dev) -+ -+ /* make sure primary interface removed last */ -+ for (i = BRCMF_MAX_IFS-1; i > -1; i--) -+- brcmf_remove_interface(drvr->iflist[i]); -++ brcmf_remove_interface(drvr->iflist[i], false); -+ -+ brcmf_cfg80211_detach(drvr->config); -+ -+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h -++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h -+@@ -216,7 +216,7 @@ struct brcmf_if *brcmf_get_ifp(struct br -+ int brcmf_net_attach(struct brcmf_if *ifp, bool rtnl_locked); -+ struct brcmf_if *brcmf_add_if(struct brcmf_pub *drvr, s32 bsscfgidx, s32 ifidx, -+ bool is_p2pdev, char *name, u8 *mac_addr); -+-void brcmf_remove_interface(struct brcmf_if *ifp); -++void brcmf_remove_interface(struct brcmf_if *ifp, bool rtnl_locked); -+ void brcmf_txflowblock_if(struct brcmf_if *ifp, -+ enum brcmf_netif_stop_reason reason, bool state); -+ void brcmf_txfinalize(struct brcmf_if *ifp, struct sk_buff *txp, bool success); -+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.c -++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.c -+@@ -183,7 +183,7 @@ static void brcmf_fweh_handle_if_event(s -+ err = brcmf_fweh_call_event_handler(ifp, emsg->event_code, emsg, data); -+ -+ if (ifp && ifevent->action == BRCMF_E_IF_DEL) -+- brcmf_remove_interface(ifp); -++ brcmf_remove_interface(ifp, false); -+ } -+ -+ /** -+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c -++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c -+@@ -2289,7 +2289,7 @@ int brcmf_p2p_del_vif(struct wiphy *wiph -+ err = 0; -+ } -+ if (err) -+- brcmf_remove_interface(vif->ifp); -++ brcmf_remove_interface(vif->ifp, true); -+ -+ brcmf_cfg80211_arm_vif_event(cfg, NULL); -+ if (vif->wdev.iftype != NL80211_IFTYPE_P2P_DEVICE) -+@@ -2395,7 +2395,7 @@ void brcmf_p2p_detach(struct brcmf_p2p_i -+ if (vif != NULL) { -+ brcmf_p2p_cancel_remain_on_channel(vif->ifp); -+ brcmf_p2p_deinit_discovery(p2p); -+- brcmf_remove_interface(vif->ifp); -++ brcmf_remove_interface(vif->ifp, false); -+ } -+ /* just set it all to zero */ -+ memset(p2p, 0, sizeof(*p2p)); -diff --git a/package/kernel/mac80211/patches/319-0002-brcmfmac-use-const-char-for-interface-name-in-brcmf_.patch b/package/kernel/mac80211/patches/319-0002-brcmfmac-use-const-char-for-interface-name-in-brcmf_.patch -new file mode 100644 -index 0000000..6d3f3c6 ---- /dev/null -+++ b/package/kernel/mac80211/patches/319-0002-brcmfmac-use-const-char-for-interface-name-in-brcmf_.patch -@@ -0,0 +1,40 @@ -+From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= -+Date: Fri, 17 Jun 2016 12:48:44 +0200 -+Subject: [PATCH] brcmfmac: use const char * for interface name in -+ brcmf_add_if -+MIME-Version: 1.0 -+Content-Type: text/plain; charset=UTF-8 -+Content-Transfer-Encoding: 8bit -+ -+This function can work just fine with const pointer, it only calls -+alloc_netdev which take const as well. Moreover it makes this function -+more flexible as some cfg80211 callback may provide const char * as -+well, e.g. add_virtual_intf. This will be needed for more advanced -+interface management. -+ -+Signed-off-by: RafaÅ‚ MiÅ‚ecki -+Signed-off-by: Kalle Valo -+--- -+ -+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c -++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c -+@@ -638,7 +638,7 @@ fail: -+ } -+ -+ struct brcmf_if *brcmf_add_if(struct brcmf_pub *drvr, s32 bsscfgidx, s32 ifidx, -+- bool is_p2pdev, char *name, u8 *mac_addr) -++ bool is_p2pdev, const char *name, u8 *mac_addr) -+ { -+ struct brcmf_if *ifp; -+ struct net_device *ndev; -+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h -++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h -+@@ -215,7 +215,7 @@ char *brcmf_ifname(struct brcmf_if *ifp) -+ struct brcmf_if *brcmf_get_ifp(struct brcmf_pub *drvr, int ifidx); -+ int brcmf_net_attach(struct brcmf_if *ifp, bool rtnl_locked); -+ struct brcmf_if *brcmf_add_if(struct brcmf_pub *drvr, s32 bsscfgidx, s32 ifidx, -+- bool is_p2pdev, char *name, u8 *mac_addr); -++ bool is_p2pdev, const char *name, u8 *mac_addr); -+ void brcmf_remove_interface(struct brcmf_if *ifp, bool rtnl_locked); -+ void brcmf_txflowblock_if(struct brcmf_if *ifp, -+ enum brcmf_netif_stop_reason reason, bool state); -diff --git a/package/kernel/mac80211/patches/319-0003-brcmfmac-include-also-core.h-header-in-cfg80211.h.patch b/package/kernel/mac80211/patches/319-0003-brcmfmac-include-also-core.h-header-in-cfg80211.h.patch -new file mode 100644 -index 0000000..eeda766 ---- /dev/null -+++ b/package/kernel/mac80211/patches/319-0003-brcmfmac-include-also-core.h-header-in-cfg80211.h.patch -@@ -0,0 +1,33 @@ -+From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= -+Date: Sat, 18 Jun 2016 18:49:38 +0200 -+Subject: [PATCH] brcmfmac: include also core.h header in cfg80211.h -+MIME-Version: 1.0 -+Content-Type: text/plain; charset=UTF-8 -+Content-Transfer-Encoding: 8bit -+ -+This header provides two inline functions using struct brcmf_if so we -+need core.h to avoid: -+ -+drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h: In function ‘ndev_to_prof’: -+drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h:368:13: error: dereferencing pointer to incomplete type -+ return &ifp->vif->profile; -+ ^ -+drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h: In function ‘ndev_to_vif’: -+drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h:374:12: error: dereferencing pointer to incomplete type -+ return ifp->vif; -+ ^ -+ -+Signed-off-by: RafaÅ‚ MiÅ‚ecki -+Signed-off-by: Kalle Valo -+--- -+ -+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h -++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h -+@@ -20,6 +20,7 @@ -+ /* for brcmu_d11inf */ -+ #include -+ -++#include "core.h" -+ #include "fwil_types.h" -+ #include "p2p.h" -+ -diff --git a/package/kernel/mac80211/patches/319-0004-brcmfmac-add-missing-break-when-deleting-P2P_DEVICE.patch b/package/kernel/mac80211/patches/319-0004-brcmfmac-add-missing-break-when-deleting-P2P_DEVICE.patch -new file mode 100644 -index 0000000..3819248 ---- /dev/null -+++ b/package/kernel/mac80211/patches/319-0004-brcmfmac-add-missing-break-when-deleting-P2P_DEVICE.patch -@@ -0,0 +1,27 @@ -+From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= -+Date: Sun, 19 Jun 2016 01:55:57 +0200 -+Subject: [PATCH] brcmfmac: add missing break when deleting P2P_DEVICE -+MIME-Version: 1.0 -+Content-Type: text/plain; charset=UTF-8 -+Content-Transfer-Encoding: 8bit -+ -+We obviously don't want to fall through in that switch. With this change -+1) We wait for event (triggered by p2p_disc) as expected -+2) We remove interface manually on timeout -+3) We return 0 on success instead of -ENOTSUPP -+ -+Signed-off-by: RafaÅ‚ MiÅ‚ecki -+Signed-off-by: Kalle Valo -+--- -+ -+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c -++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c -+@@ -2263,6 +2263,8 @@ int brcmf_p2p_del_vif(struct wiphy *wiph -+ return 0; -+ brcmf_p2p_cancel_remain_on_channel(vif->ifp); -+ brcmf_p2p_deinit_discovery(p2p); -++ break; -++ -+ default: -+ return -ENOTSUPP; -+ } -diff --git a/package/kernel/mac80211/patches/319-0005-brcmfmac-delete-interface-directly-in-code-that-sent.patch b/package/kernel/mac80211/patches/319-0005-brcmfmac-delete-interface-directly-in-code-that-sent.patch -new file mode 100644 -index 0000000..12d7eb4 ---- /dev/null -+++ b/package/kernel/mac80211/patches/319-0005-brcmfmac-delete-interface-directly-in-code-that-sent.patch -@@ -0,0 +1,75 @@ -+From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= -+Date: Wed, 29 Jun 2016 21:54:26 +0200 -+Subject: [PATCH] brcmfmac: delete interface directly in code that sent fw -+ request -+MIME-Version: 1.0 -+Content-Type: text/plain; charset=UTF-8 -+Content-Transfer-Encoding: 8bit -+ -+So far when receiving event about in-firmware-interface removal our -+event worker was notifying listener and afterwards it was removing Linux -+interface. -+ -+First of all it was resulting in slightly unexpected order. The listener -+(del_virtual_intf callback) was (usually) returning with success before -+we even called unregister_netdev(ice). -+ -+Please note this couldn't be simply fixed by changing order of calls in -+brcmf_fweh_handle_if_event as unregistering interface earlier could free -+struct brcmf_if. -+ -+Another problem of current implementation are possible lockups. Focus on -+the time slot between calling event handler and removing Linux -+interface. During that time original caller may leave (unlocking rtnl -+semaphore) *and* another call to the same code may be done (locking it -+again). If that happens our event handler will stuck at removing Linux -+interface, it won't handle another event and will block process holding -+rtnl lock. -+ -+This can be simply solved by unregistering interface in a proper -+callback, right after receiving confirmation event from firmware. This -+only required modifying worker to don't unregister on its own if there -+is someone waiting for the event. -+ -+Signed-off-by: RafaÅ‚ MiÅ‚ecki -+Signed-off-by: Kalle Valo -+--- -+ -+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.c -++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.c -+@@ -18,6 +18,7 @@ -+ #include "brcmu_wifi.h" -+ #include "brcmu_utils.h" -+ -++#include "cfg80211.h" -+ #include "core.h" -+ #include "debug.h" -+ #include "tracepoint.h" -+@@ -182,8 +183,13 @@ static void brcmf_fweh_handle_if_event(s -+ -+ err = brcmf_fweh_call_event_handler(ifp, emsg->event_code, emsg, data); -+ -+- if (ifp && ifevent->action == BRCMF_E_IF_DEL) -+- brcmf_remove_interface(ifp, false); -++ if (ifp && ifevent->action == BRCMF_E_IF_DEL) { -++ bool armed = brcmf_cfg80211_vif_event_armed(drvr->config); -++ -++ /* Default handling in case no-one waits for this event */ -++ if (!armed) -++ brcmf_remove_interface(ifp, false); -++ } -+ } -+ -+ /** -+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c -++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c -+@@ -2290,8 +2290,7 @@ int brcmf_p2p_del_vif(struct wiphy *wiph -+ else -+ err = 0; -+ } -+- if (err) -+- brcmf_remove_interface(vif->ifp, true); -++ brcmf_remove_interface(vif->ifp, true); -+ -+ brcmf_cfg80211_arm_vif_event(cfg, NULL); -+ if (vif->wdev.iftype != NL80211_IFTYPE_P2P_DEVICE) -diff --git a/package/kernel/mac80211/patches/319-0006-brcmfmac-support-removing-AP-interfaces-with-interfa.patch b/package/kernel/mac80211/patches/319-0006-brcmfmac-support-removing-AP-interfaces-with-interfa.patch -new file mode 100644 -index 0000000..2f7165e ---- /dev/null -+++ b/package/kernel/mac80211/patches/319-0006-brcmfmac-support-removing-AP-interfaces-with-interfa.patch -@@ -0,0 +1,84 @@ -+From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= -+Date: Wed, 29 Jun 2016 21:54:27 +0200 -+Subject: [PATCH] brcmfmac: support removing AP interfaces with -+ "interface_remove" -+MIME-Version: 1.0 -+Content-Type: text/plain; charset=UTF-8 -+Content-Transfer-Encoding: 8bit -+ -+New firmwares (e.g. 10.10.69.36 for BCM4366) support "interface_remove" -+for removing interfaces. Try to use this method on cfg80211 request. In -+case of older firmwares (e.g. 7.35.177.56 for BCM43602 as I tested) this -+will just result in firmware rejecting command and this won't change any -+behavior. -+ -+Signed-off-by: RafaÅ‚ MiÅ‚ecki -+Signed-off-by: Kalle Valo -+--- -+ -+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c -++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c -+@@ -785,12 +785,48 @@ s32 brcmf_notify_escan_complete(struct b -+ return err; -+ } -+ -++static int brcmf_cfg80211_del_ap_iface(struct wiphy *wiphy, -++ struct wireless_dev *wdev) -++{ -++ struct brcmf_cfg80211_info *cfg = wiphy_priv(wiphy); -++ struct net_device *ndev = wdev->netdev; -++ struct brcmf_if *ifp = netdev_priv(ndev); -++ int ret; -++ int err; -++ -++ brcmf_cfg80211_arm_vif_event(cfg, ifp->vif); -++ -++ err = brcmf_fil_bsscfg_data_set(ifp, "interface_remove", NULL, 0); -++ if (err) { -++ brcmf_err("interface_remove failed %d\n", err); -++ goto err_unarm; -++ } -++ -++ /* wait for firmware event */ -++ ret = brcmf_cfg80211_wait_vif_event(cfg, BRCMF_E_IF_DEL, -++ BRCMF_VIF_EVENT_TIMEOUT); -++ if (!ret) { -++ brcmf_err("timeout occurred\n"); -++ err = -EIO; -++ goto err_unarm; -++ } -++ -++ brcmf_remove_interface(ifp, true); -++ -++err_unarm: -++ brcmf_cfg80211_arm_vif_event(cfg, NULL); -++ return err; -++} -++ -+ static -+ int brcmf_cfg80211_del_iface(struct wiphy *wiphy, struct wireless_dev *wdev) -+ { -+ struct brcmf_cfg80211_info *cfg = wiphy_priv(wiphy); -+ struct net_device *ndev = wdev->netdev; -+ -++ if (ndev && ndev == cfg_to_ndev(cfg)) -++ return -ENOTSUPP; -++ -+ /* vif event pending in firmware */ -+ if (brcmf_cfg80211_vif_event_armed(cfg)) -+ return -EBUSY; -+@@ -807,12 +843,13 @@ int brcmf_cfg80211_del_iface(struct wiph -+ switch (wdev->iftype) { -+ case NL80211_IFTYPE_ADHOC: -+ case NL80211_IFTYPE_STATION: -+- case NL80211_IFTYPE_AP: -+ case NL80211_IFTYPE_AP_VLAN: -+ case NL80211_IFTYPE_WDS: -+ case NL80211_IFTYPE_MONITOR: -+ case NL80211_IFTYPE_MESH_POINT: -+ return -EOPNOTSUPP; -++ case NL80211_IFTYPE_AP: -++ return brcmf_cfg80211_del_ap_iface(wiphy, wdev); -+ case NL80211_IFTYPE_P2P_CLIENT: -+ case NL80211_IFTYPE_P2P_GO: -+ case NL80211_IFTYPE_P2P_DEVICE: -diff --git a/package/kernel/mac80211/patches/319-cfg80211-add-function-for-802.3-conversion-with-sepa.patch b/package/kernel/mac80211/patches/319-cfg80211-add-function-for-802.3-conversion-with-sepa.patch -deleted file mode 100644 -index b646ab3..0000000 ---- a/package/kernel/mac80211/patches/319-cfg80211-add-function-for-802.3-conversion-with-sepa.patch -+++ /dev/null -@@ -1,186 +0,0 @@ --From: Felix Fietkau --Date: Tue, 2 Feb 2016 14:39:09 +0100 --Subject: [PATCH] cfg80211: add function for 802.3 conversion with separate -- output buffer -- --Use skb_copy_bits in preparation for allowing fragmented skbs -- --Signed-off-by: Felix Fietkau --Signed-off-by: Johannes Berg ----- -- ----- a/net/wireless/util.c --+++ b/net/wireless/util.c --@@ -393,9 +393,9 @@ unsigned int ieee80211_get_hdrlen_from_s -- } -- EXPORT_SYMBOL(ieee80211_get_hdrlen_from_skb); -- ---unsigned int ieee80211_get_mesh_hdrlen(struct ieee80211s_hdr *meshhdr) --+static unsigned int __ieee80211_get_mesh_hdrlen(u8 flags) -- { --- int ae = meshhdr->flags & MESH_FLAGS_AE; --+ int ae = flags & MESH_FLAGS_AE; -- /* 802.11-2012, 8.2.4.7.3 */ -- switch (ae) { -- default: --@@ -407,21 +407,31 @@ unsigned int ieee80211_get_mesh_hdrlen(s -- return 18; -- } -- } --+ --+unsigned int ieee80211_get_mesh_hdrlen(struct ieee80211s_hdr *meshhdr) --+{ --+ return __ieee80211_get_mesh_hdrlen(meshhdr->flags); --+} -- EXPORT_SYMBOL(ieee80211_get_mesh_hdrlen); -- ---int ieee80211_data_to_8023(struct sk_buff *skb, const u8 *addr, --- enum nl80211_iftype iftype) --+static int __ieee80211_data_to_8023(struct sk_buff *skb, struct ethhdr *ehdr, --+ const u8 *addr, enum nl80211_iftype iftype) -- { -- struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; --- u16 hdrlen, ethertype; --- u8 *payload; --- u8 dst[ETH_ALEN]; --- u8 src[ETH_ALEN] __aligned(2); --+ struct { --+ u8 hdr[ETH_ALEN] __aligned(2); --+ __be16 proto; --+ } payload; --+ struct ethhdr tmp; --+ u16 hdrlen; --+ u8 mesh_flags = 0; -- -- if (unlikely(!ieee80211_is_data_present(hdr->frame_control))) -- return -1; -- -- hdrlen = ieee80211_hdrlen(hdr->frame_control); --+ if (skb->len < hdrlen + 8) --+ return -1; -- -- /* convert IEEE 802.11 header + possible LLC headers into Ethernet -- * header --@@ -432,8 +442,11 @@ int ieee80211_data_to_8023(struct sk_buf -- * 1 0 BSSID SA DA n/a -- * 1 1 RA TA DA SA -- */ --- memcpy(dst, ieee80211_get_DA(hdr), ETH_ALEN); --- memcpy(src, ieee80211_get_SA(hdr), ETH_ALEN); --+ memcpy(tmp.h_dest, ieee80211_get_DA(hdr), ETH_ALEN); --+ memcpy(tmp.h_source, ieee80211_get_SA(hdr), ETH_ALEN); --+ --+ if (iftype == NL80211_IFTYPE_MESH_POINT) --+ skb_copy_bits(skb, hdrlen, &mesh_flags, 1); -- -- switch (hdr->frame_control & -- cpu_to_le16(IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) { --@@ -450,44 +463,31 @@ int ieee80211_data_to_8023(struct sk_buf -- iftype != NL80211_IFTYPE_STATION)) -- return -1; -- if (iftype == NL80211_IFTYPE_MESH_POINT) { --- struct ieee80211s_hdr *meshdr = --- (struct ieee80211s_hdr *) (skb->data + hdrlen); --- /* make sure meshdr->flags is on the linear part */ --- if (!pskb_may_pull(skb, hdrlen + 1)) --- return -1; --- if (meshdr->flags & MESH_FLAGS_AE_A4) --+ if (mesh_flags & MESH_FLAGS_AE_A4) -- return -1; --- if (meshdr->flags & MESH_FLAGS_AE_A5_A6) { --+ if (mesh_flags & MESH_FLAGS_AE_A5_A6) { -- skb_copy_bits(skb, hdrlen + -- offsetof(struct ieee80211s_hdr, eaddr1), --- dst, ETH_ALEN); --- skb_copy_bits(skb, hdrlen + --- offsetof(struct ieee80211s_hdr, eaddr2), --- src, ETH_ALEN); --+ tmp.h_dest, 2 * ETH_ALEN); -- } --- hdrlen += ieee80211_get_mesh_hdrlen(meshdr); --+ hdrlen += __ieee80211_get_mesh_hdrlen(mesh_flags); -- } -- break; -- case cpu_to_le16(IEEE80211_FCTL_FROMDS): -- if ((iftype != NL80211_IFTYPE_STATION && -- iftype != NL80211_IFTYPE_P2P_CLIENT && -- iftype != NL80211_IFTYPE_MESH_POINT) || --- (is_multicast_ether_addr(dst) && --- ether_addr_equal(src, addr))) --+ (is_multicast_ether_addr(tmp.h_dest) && --+ ether_addr_equal(tmp.h_source, addr))) -- return -1; -- if (iftype == NL80211_IFTYPE_MESH_POINT) { --- struct ieee80211s_hdr *meshdr = --- (struct ieee80211s_hdr *) (skb->data + hdrlen); --- /* make sure meshdr->flags is on the linear part */ --- if (!pskb_may_pull(skb, hdrlen + 1)) --- return -1; --- if (meshdr->flags & MESH_FLAGS_AE_A5_A6) --+ if (mesh_flags & MESH_FLAGS_AE_A5_A6) -- return -1; --- if (meshdr->flags & MESH_FLAGS_AE_A4) --+ if (mesh_flags & MESH_FLAGS_AE_A4) -- skb_copy_bits(skb, hdrlen + -- offsetof(struct ieee80211s_hdr, eaddr1), --- src, ETH_ALEN); --- hdrlen += ieee80211_get_mesh_hdrlen(meshdr); --+ tmp.h_source, ETH_ALEN); --+ hdrlen += __ieee80211_get_mesh_hdrlen(mesh_flags); -- } -- break; -- case cpu_to_le16(0): --@@ -498,33 +498,33 @@ int ieee80211_data_to_8023(struct sk_buf -- break; -- } -- --- if (!pskb_may_pull(skb, hdrlen + 8)) --- return -1; --- --- payload = skb->data + hdrlen; --- ethertype = (payload[6] << 8) | payload[7]; --+ skb_copy_bits(skb, hdrlen, &payload, sizeof(payload)); --+ tmp.h_proto = payload.proto; -- --- if (likely((ether_addr_equal(payload, rfc1042_header) && --- ethertype != ETH_P_AARP && ethertype != ETH_P_IPX) || --- ether_addr_equal(payload, bridge_tunnel_header))) { --+ if (likely((ether_addr_equal(payload.hdr, rfc1042_header) && --+ tmp.h_proto != htons(ETH_P_AARP) && --+ tmp.h_proto != htons(ETH_P_IPX)) || --+ ether_addr_equal(payload.hdr, bridge_tunnel_header))) -- /* remove RFC1042 or Bridge-Tunnel encapsulation and -- * replace EtherType */ --- skb_pull(skb, hdrlen + 6); --- memcpy(skb_push(skb, ETH_ALEN), src, ETH_ALEN); --- memcpy(skb_push(skb, ETH_ALEN), dst, ETH_ALEN); --- } else { --- struct ethhdr *ehdr; --- __be16 len; --+ hdrlen += ETH_ALEN + 2; --+ else --+ tmp.h_proto = htons(skb->len); -- --- skb_pull(skb, hdrlen); --- len = htons(skb->len); --+ pskb_pull(skb, hdrlen); --+ --+ if (!ehdr) -- ehdr = (struct ethhdr *) skb_push(skb, sizeof(struct ethhdr)); --- memcpy(ehdr->h_dest, dst, ETH_ALEN); --- memcpy(ehdr->h_source, src, ETH_ALEN); --- ehdr->h_proto = len; --- } --+ memcpy(ehdr, &tmp, sizeof(tmp)); --+ -- return 0; -- } --+ --+int ieee80211_data_to_8023(struct sk_buff *skb, const u8 *addr, --+ enum nl80211_iftype iftype) --+{ --+ return __ieee80211_data_to_8023(skb, NULL, addr, iftype); --+} -- EXPORT_SYMBOL(ieee80211_data_to_8023); -- -- int ieee80211_data_from_8023(struct sk_buff *skb, const u8 *addr, -diff --git a/package/kernel/mac80211/patches/320-ath9k-Switch-to-using-mac80211-intermediate-software.patch b/package/kernel/mac80211/patches/320-ath9k-Switch-to-using-mac80211-intermediate-software.patch -new file mode 100644 -index 0000000..f8b8f86 ---- /dev/null -+++ b/package/kernel/mac80211/patches/320-ath9k-Switch-to-using-mac80211-intermediate-software.patch -@@ -0,0 +1,871 @@ -+From: =?UTF-8?q?Toke=20H=C3=B8iland-J=C3=B8rgensen?= -+Date: Wed, 6 Jul 2016 21:34:17 +0200 -+Subject: [PATCH] ath9k: Switch to using mac80211 intermediate software queues. -+MIME-Version: 1.0 -+Content-Type: text/plain; charset=UTF-8 -+Content-Transfer-Encoding: 8bit -+ -+This switches ath9k over to using the mac80211 intermediate software -+queueing mechanism for data packets. It removes the queueing inside the -+driver, except for the retry queue, and instead pulls from mac80211 when -+a packet is needed. The retry queue is used to store a packet that was -+pulled but can't be sent immediately. -+ -+The old code path in ath_tx_start that would queue packets has been -+removed completely, as has the qlen limit tunables (since there's no -+longer a queue in the driver to limit). -+ -+Based on Tim's original patch set, but reworked quite thoroughly. -+ -+Cc: Tim Shepard -+Cc: Felix Fietkau -+Signed-off-by: Toke Høiland-Jørgensen -+--- -+ -+--- a/drivers/net/wireless/ath/ath9k/ath9k.h -++++ b/drivers/net/wireless/ath/ath9k/ath9k.h -+@@ -91,7 +91,6 @@ int ath_descdma_setup(struct ath_softc * -+ #define ATH_RXBUF 512 -+ #define ATH_TXBUF 512 -+ #define ATH_TXBUF_RESERVE 5 -+-#define ATH_MAX_QDEPTH (ATH_TXBUF / 4 - ATH_TXBUF_RESERVE) -+ #define ATH_TXMAXTRY 13 -+ #define ATH_MAX_SW_RETRIES 30 -+ -+@@ -145,7 +144,9 @@ int ath_descdma_setup(struct ath_softc * -+ #define BAW_WITHIN(_start, _bawsz, _seqno) \ -+ ((((_seqno) - (_start)) & 4095) < (_bawsz)) -+ -+-#define ATH_AN_2_TID(_an, _tidno) (&(_an)->tid[(_tidno)]) -++#define ATH_STA_2_TID(_sta, _tidno) ((struct ath_atx_tid *)(_sta)->txq[_tidno]->drv_priv) -++#define ATH_VIF_2_TID(_vif) ((struct ath_atx_tid *)(_vif)->txq->drv_priv) -++#define ATH_AN_2_TID(_an, _tidno) ((_an)->sta ? ATH_STA_2_TID((_an)->sta, _tidno) : ATH_VIF_2_TID((_an)->vif)) -+ -+ #define IS_HT_RATE(rate) (rate & 0x80) -+ #define IS_CCK_RATE(rate) ((rate >= 0x18) && (rate <= 0x1e)) -+@@ -164,7 +165,6 @@ struct ath_txq { -+ spinlock_t axq_lock; -+ u32 axq_depth; -+ u32 axq_ampdu_depth; -+- bool stopped; -+ bool axq_tx_inprogress; -+ struct list_head txq_fifo[ATH_TXFIFO_DEPTH]; -+ u8 txq_headidx; -+@@ -232,7 +232,6 @@ struct ath_buf { -+ -+ struct ath_atx_tid { -+ struct list_head list; -+- struct sk_buff_head buf_q; -+ struct sk_buff_head retry_q; -+ struct ath_node *an; -+ struct ath_txq *txq; -+@@ -247,13 +246,13 @@ struct ath_atx_tid { -+ s8 bar_index; -+ bool active; -+ bool clear_ps_filter; -++ bool has_queued; -+ }; -+ -+ struct ath_node { -+ struct ath_softc *sc; -+ struct ieee80211_sta *sta; /* station struct we're part of */ -+ struct ieee80211_vif *vif; /* interface with which we're associated */ -+- struct ath_atx_tid tid[IEEE80211_NUM_TIDS]; -+ -+ u16 maxampdu; -+ u8 mpdudensity; -+@@ -276,7 +275,6 @@ struct ath_tx_control { -+ struct ath_node *an; -+ struct ieee80211_sta *sta; -+ u8 paprd; -+- bool force_channel; -+ }; -+ -+ -+@@ -293,7 +291,6 @@ struct ath_tx { -+ struct ath_descdma txdma; -+ struct ath_txq *txq_map[IEEE80211_NUM_ACS]; -+ struct ath_txq *uapsdq; -+- u32 txq_max_pending[IEEE80211_NUM_ACS]; -+ u16 max_aggr_framelen[IEEE80211_NUM_ACS][4][32]; -+ }; -+ -+@@ -585,6 +582,7 @@ void ath9k_release_buffered_frames(struc -+ u16 tids, int nframes, -+ enum ieee80211_frame_release_type reason, -+ bool more_data); -++void ath9k_wake_tx_queue(struct ieee80211_hw *hw, struct ieee80211_txq *queue); -+ -+ /********/ -+ /* VIFs */ -+--- a/drivers/net/wireless/ath/ath9k/channel.c -++++ b/drivers/net/wireless/ath/ath9k/channel.c -+@@ -1007,7 +1007,6 @@ static void ath_scan_send_probe(struct a -+ goto error; -+ -+ txctl.txq = sc->tx.txq_map[IEEE80211_AC_VO]; -+- txctl.force_channel = true; -+ if (ath_tx_start(sc->hw, skb, &txctl)) -+ goto error; -+ -+@@ -1130,7 +1129,6 @@ ath_chanctx_send_vif_ps_frame(struct ath -+ memset(&txctl, 0, sizeof(txctl)); -+ txctl.txq = sc->tx.txq_map[IEEE80211_AC_VO]; -+ txctl.sta = sta; -+- txctl.force_channel = true; -+ if (ath_tx_start(sc->hw, skb, &txctl)) { -+ ieee80211_free_txskb(sc->hw, skb); -+ return false; -+--- a/drivers/net/wireless/ath/ath9k/debug.c -++++ b/drivers/net/wireless/ath/ath9k/debug.c -+@@ -600,7 +600,6 @@ static int read_file_xmit(struct seq_fil -+ PR("MPDUs XRetried: ", xretries); -+ PR("Aggregates: ", a_aggr); -+ PR("AMPDUs Queued HW:", a_queued_hw); -+- PR("AMPDUs Queued SW:", a_queued_sw); -+ PR("AMPDUs Completed:", a_completed); -+ PR("AMPDUs Retried: ", a_retries); -+ PR("AMPDUs XRetried: ", a_xretries); -+@@ -629,8 +628,7 @@ static void print_queue(struct ath_softc -+ seq_printf(file, "%s: %d ", "qnum", txq->axq_qnum); -+ seq_printf(file, "%s: %2d ", "qdepth", txq->axq_depth); -+ seq_printf(file, "%s: %2d ", "ampdu-depth", txq->axq_ampdu_depth); -+- seq_printf(file, "%s: %3d ", "pending", txq->pending_frames); -+- seq_printf(file, "%s: %d\n", "stopped", txq->stopped); -++ seq_printf(file, "%s: %3d\n", "pending", txq->pending_frames); -+ -+ ath_txq_unlock(sc, txq); -+ } -+@@ -1208,7 +1206,6 @@ static const char ath9k_gstrings_stats[] -+ AMKSTR(d_tx_mpdu_xretries), -+ AMKSTR(d_tx_aggregates), -+ AMKSTR(d_tx_ampdus_queued_hw), -+- AMKSTR(d_tx_ampdus_queued_sw), -+ AMKSTR(d_tx_ampdus_completed), -+ AMKSTR(d_tx_ampdu_retries), -+ AMKSTR(d_tx_ampdu_xretries), -+@@ -1288,7 +1285,6 @@ void ath9k_get_et_stats(struct ieee80211 -+ AWDATA(xretries); -+ AWDATA(a_aggr); -+ AWDATA(a_queued_hw); -+- AWDATA(a_queued_sw); -+ AWDATA(a_completed); -+ AWDATA(a_retries); -+ AWDATA(a_xretries); -+@@ -1346,14 +1342,6 @@ int ath9k_init_debug(struct ath_hw *ah) -+ read_file_xmit); -+ debugfs_create_devm_seqfile(sc->dev, "queues", sc->debug.debugfs_phy, -+ read_file_queues); -+- debugfs_create_u32("qlen_bk", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy, -+- &sc->tx.txq_max_pending[IEEE80211_AC_BK]); -+- debugfs_create_u32("qlen_be", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy, -+- &sc->tx.txq_max_pending[IEEE80211_AC_BE]); -+- debugfs_create_u32("qlen_vi", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy, -+- &sc->tx.txq_max_pending[IEEE80211_AC_VI]); -+- debugfs_create_u32("qlen_vo", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy, -+- &sc->tx.txq_max_pending[IEEE80211_AC_VO]); -+ debugfs_create_devm_seqfile(sc->dev, "misc", sc->debug.debugfs_phy, -+ read_file_misc); -+ debugfs_create_devm_seqfile(sc->dev, "reset", sc->debug.debugfs_phy, -+--- a/drivers/net/wireless/ath/ath9k/debug.h -++++ b/drivers/net/wireless/ath/ath9k/debug.h -+@@ -147,7 +147,6 @@ struct ath_interrupt_stats { -+ * @completed: Total MPDUs (non-aggr) completed -+ * @a_aggr: Total no. of aggregates queued -+ * @a_queued_hw: Total AMPDUs queued to hardware -+- * @a_queued_sw: Total AMPDUs queued to software queues -+ * @a_completed: Total AMPDUs completed -+ * @a_retries: No. of AMPDUs retried (SW) -+ * @a_xretries: No. of AMPDUs dropped due to xretries -+@@ -174,7 +173,6 @@ struct ath_tx_stats { -+ u32 xretries; -+ u32 a_aggr; -+ u32 a_queued_hw; -+- u32 a_queued_sw; -+ u32 a_completed; -+ u32 a_retries; -+ u32 a_xretries; -+--- a/drivers/net/wireless/ath/ath9k/debug_sta.c -++++ b/drivers/net/wireless/ath/ath9k/debug_sta.c -+@@ -52,8 +52,8 @@ static ssize_t read_file_node_aggr(struc -+ "TID", "SEQ_START", "SEQ_NEXT", "BAW_SIZE", -+ "BAW_HEAD", "BAW_TAIL", "BAR_IDX", "SCHED", "PAUSED"); -+ -+- for (tidno = 0, tid = &an->tid[tidno]; -+- tidno < IEEE80211_NUM_TIDS; tidno++, tid++) { -++ for (tidno = 0; tidno < IEEE80211_NUM_TIDS; tidno++) { -++ tid = ATH_STA_2_TID(an->sta, tidno); -+ txq = tid->txq; -+ ath_txq_lock(sc, txq); -+ if (tid->active) { -+--- a/drivers/net/wireless/ath/ath9k/init.c -++++ b/drivers/net/wireless/ath/ath9k/init.c -+@@ -358,7 +358,6 @@ static int ath9k_init_queues(struct ath_ -+ for (i = 0; i < IEEE80211_NUM_ACS; i++) { -+ sc->tx.txq_map[i] = ath_txq_setup(sc, ATH9K_TX_QUEUE_DATA, i); -+ sc->tx.txq_map[i]->mac80211_qnum = i; -+- sc->tx.txq_max_pending[i] = ATH_MAX_QDEPTH; -+ } -+ return 0; -+ } -+@@ -873,6 +872,7 @@ static void ath9k_set_hw_capab(struct at -+ hw->max_rate_tries = 10; -+ hw->sta_data_size = sizeof(struct ath_node); -+ hw->vif_data_size = sizeof(struct ath_vif); -++ hw->txq_data_size = sizeof(struct ath_atx_tid); -+ hw->extra_tx_headroom = 4; -+ -+ hw->wiphy->available_antennas_rx = BIT(ah->caps.max_rxchains) - 1; -+--- a/drivers/net/wireless/ath/ath9k/main.c -++++ b/drivers/net/wireless/ath/ath9k/main.c -+@@ -2695,4 +2695,5 @@ struct ieee80211_ops ath9k_ops = { -+ .sw_scan_start = ath9k_sw_scan_start, -+ .sw_scan_complete = ath9k_sw_scan_complete, -+ .get_txpower = ath9k_get_txpower, -++ .wake_tx_queue = ath9k_wake_tx_queue, -+ }; -+--- a/drivers/net/wireless/ath/ath9k/xmit.c -++++ b/drivers/net/wireless/ath/ath9k/xmit.c -+@@ -65,6 +65,8 @@ static struct ath_buf *ath_tx_setup_buff -+ struct ath_txq *txq, -+ struct ath_atx_tid *tid, -+ struct sk_buff *skb); -++static int ath_tx_prepare(struct ieee80211_hw *hw, struct sk_buff *skb, -++ struct ath_tx_control *txctl); -+ -+ enum { -+ MCS_HT20, -+@@ -118,6 +120,26 @@ static void ath_tx_queue_tid(struct ath_ -+ list_add_tail(&tid->list, list); -+ } -+ -++void ath9k_wake_tx_queue(struct ieee80211_hw *hw, struct ieee80211_txq *queue) -++{ -++ struct ath_softc *sc = hw->priv; -++ struct ath_common *common = ath9k_hw_common(sc->sc_ah); -++ struct ath_atx_tid *tid = (struct ath_atx_tid *) queue->drv_priv; -++ struct ath_txq *txq = tid->txq; -++ -++ ath_dbg(common, QUEUE, "Waking TX queue: %pM (%d)\n", -++ queue->sta ? queue->sta->addr : queue->vif->addr, -++ tid->tidno); -++ -++ ath_txq_lock(sc, txq); -++ -++ tid->has_queued = true; -++ ath_tx_queue_tid(sc, txq, tid); -++ ath_txq_schedule(sc, txq); -++ -++ ath_txq_unlock(sc, txq); -++} -++ -+ static struct ath_frame_info *get_frame_info(struct sk_buff *skb) -+ { -+ struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); -+@@ -160,7 +182,6 @@ static void ath_set_rates(struct ieee802 -+ static void ath_txq_skb_done(struct ath_softc *sc, struct ath_txq *txq, -+ struct sk_buff *skb) -+ { -+- struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); -+ struct ath_frame_info *fi = get_frame_info(skb); -+ int q = fi->txq; -+ -+@@ -171,14 +192,6 @@ static void ath_txq_skb_done(struct ath_ -+ if (WARN_ON(--txq->pending_frames < 0)) -+ txq->pending_frames = 0; -+ -+- if (txq->stopped && -+- txq->pending_frames < sc->tx.txq_max_pending[q]) { -+- if (ath9k_is_chanctx_enabled()) -+- ieee80211_wake_queue(sc->hw, info->hw_queue); -+- else -+- ieee80211_wake_queue(sc->hw, q); -+- txq->stopped = false; -+- } -+ } -+ -+ static struct ath_atx_tid * -+@@ -188,9 +201,47 @@ ath_get_skb_tid(struct ath_softc *sc, st -+ return ATH_AN_2_TID(an, tidno); -+ } -+ -++static struct sk_buff * -++ath_tid_pull(struct ath_atx_tid *tid) -++{ -++ struct ath_softc *sc = tid->an->sc; -++ struct ieee80211_hw *hw = sc->hw; -++ struct ath_tx_control txctl = { -++ .txq = tid->txq, -++ .sta = tid->an->sta, -++ }; -++ struct sk_buff *skb; -++ struct ath_frame_info *fi; -++ int q; -++ -++ if (!tid->has_queued) -++ return NULL; -++ -++ skb = ieee80211_tx_dequeue(hw, container_of((void*)tid, struct ieee80211_txq, drv_priv)); -++ if (!skb) { -++ tid->has_queued = false; -++ return NULL; -++ } -++ -++ if (ath_tx_prepare(hw, skb, &txctl)) { -++ ieee80211_free_txskb(hw, skb); -++ return NULL; -++ } -++ -++ q = skb_get_queue_mapping(skb); -++ if (tid->txq == sc->tx.txq_map[q]) { -++ fi = get_frame_info(skb); -++ fi->txq = q; -++ ++tid->txq->pending_frames; -++ } -++ -++ return skb; -++ } -++ -++ -+ static bool ath_tid_has_buffered(struct ath_atx_tid *tid) -+ { -+- return !skb_queue_empty(&tid->buf_q) || !skb_queue_empty(&tid->retry_q); -++ return !skb_queue_empty(&tid->retry_q) || tid->has_queued; -+ } -+ -+ static struct sk_buff *ath_tid_dequeue(struct ath_atx_tid *tid) -+@@ -199,46 +250,11 @@ static struct sk_buff *ath_tid_dequeue(s -+ -+ skb = __skb_dequeue(&tid->retry_q); -+ if (!skb) -+- skb = __skb_dequeue(&tid->buf_q); -++ skb = ath_tid_pull(tid); -+ -+ return skb; -+ } -+ -+-/* -+- * ath_tx_tid_change_state: -+- * - clears a-mpdu flag of previous session -+- * - force sequence number allocation to fix next BlockAck Window -+- */ -+-static void -+-ath_tx_tid_change_state(struct ath_softc *sc, struct ath_atx_tid *tid) -+-{ -+- struct ath_txq *txq = tid->txq; -+- struct ieee80211_tx_info *tx_info; -+- struct sk_buff *skb, *tskb; -+- struct ath_buf *bf; -+- struct ath_frame_info *fi; -+- -+- skb_queue_walk_safe(&tid->buf_q, skb, tskb) { -+- fi = get_frame_info(skb); -+- bf = fi->bf; -+- -+- tx_info = IEEE80211_SKB_CB(skb); -+- tx_info->flags &= ~IEEE80211_TX_CTL_AMPDU; -+- -+- if (bf) -+- continue; -+- -+- bf = ath_tx_setup_buffer(sc, txq, tid, skb); -+- if (!bf) { -+- __skb_unlink(skb, &tid->buf_q); -+- ath_txq_skb_done(sc, txq, skb); -+- ieee80211_free_txskb(sc->hw, skb); -+- continue; -+- } -+- } -+- -+-} -+- -+ static void ath_tx_flush_tid(struct ath_softc *sc, struct ath_atx_tid *tid) -+ { -+ struct ath_txq *txq = tid->txq; -+@@ -873,20 +889,16 @@ static int ath_compute_num_delims(struct -+ -+ static struct ath_buf * -+ ath_tx_get_tid_subframe(struct ath_softc *sc, struct ath_txq *txq, -+- struct ath_atx_tid *tid, struct sk_buff_head **q) -++ struct ath_atx_tid *tid) -+ { -+ struct ieee80211_tx_info *tx_info; -+ struct ath_frame_info *fi; -+- struct sk_buff *skb; -++ struct sk_buff *skb, *first_skb = NULL; -+ struct ath_buf *bf; -+ u16 seqno; -+ -+ while (1) { -+- *q = &tid->retry_q; -+- if (skb_queue_empty(*q)) -+- *q = &tid->buf_q; -+- -+- skb = skb_peek(*q); -++ skb = ath_tid_dequeue(tid); -+ if (!skb) -+ break; -+ -+@@ -898,7 +910,6 @@ ath_tx_get_tid_subframe(struct ath_softc -+ bf->bf_state.stale = false; -+ -+ if (!bf) { -+- __skb_unlink(skb, *q); -+ ath_txq_skb_done(sc, txq, skb); -+ ieee80211_free_txskb(sc->hw, skb); -+ continue; -+@@ -927,8 +938,19 @@ ath_tx_get_tid_subframe(struct ath_softc -+ seqno = bf->bf_state.seqno; -+ -+ /* do not step over block-ack window */ -+- if (!BAW_WITHIN(tid->seq_start, tid->baw_size, seqno)) -++ if (!BAW_WITHIN(tid->seq_start, tid->baw_size, seqno)) { -++ __skb_queue_tail(&tid->retry_q, skb); -++ -++ /* If there are other skbs in the retry q, they are -++ * probably within the BAW, so loop immediately to get -++ * one of them. Otherwise the queue can get stuck. */ -++ if (!skb_queue_is_first(&tid->retry_q, skb) && skb != first_skb) { -++ if(!first_skb) /* infinite loop prevention */ -++ first_skb = skb; -++ continue; -++ } -+ break; -++ } -+ -+ if (tid->bar_index > ATH_BA_INDEX(tid->seq_start, seqno)) { -+ struct ath_tx_status ts = {}; -+@@ -936,7 +958,6 @@ ath_tx_get_tid_subframe(struct ath_softc -+ -+ INIT_LIST_HEAD(&bf_head); -+ list_add(&bf->list, &bf_head); -+- __skb_unlink(skb, *q); -+ ath_tx_update_baw(sc, tid, seqno); -+ ath_tx_complete_buf(sc, bf, txq, &bf_head, &ts, 0); -+ continue; -+@@ -948,11 +969,10 @@ ath_tx_get_tid_subframe(struct ath_softc -+ return NULL; -+ } -+ -+-static bool -++static int -+ ath_tx_form_aggr(struct ath_softc *sc, struct ath_txq *txq, -+ struct ath_atx_tid *tid, struct list_head *bf_q, -+- struct ath_buf *bf_first, struct sk_buff_head *tid_q, -+- int *aggr_len) -++ struct ath_buf *bf_first) -+ { -+ #define PADBYTES(_len) ((4 - ((_len) % 4)) % 4) -+ struct ath_buf *bf = bf_first, *bf_prev = NULL; -+@@ -962,12 +982,13 @@ ath_tx_form_aggr(struct ath_softc *sc, s -+ struct ieee80211_tx_info *tx_info; -+ struct ath_frame_info *fi; -+ struct sk_buff *skb; -+- bool closed = false; -++ -+ -+ bf = bf_first; -+ aggr_limit = ath_lookup_rate(sc, bf, tid); -+ -+- do { -++ while (bf) -++ { -+ skb = bf->bf_mpdu; -+ fi = get_frame_info(skb); -+ -+@@ -976,12 +997,12 @@ ath_tx_form_aggr(struct ath_softc *sc, s -+ if (nframes) { -+ if (aggr_limit < al + bpad + al_delta || -+ ath_lookup_legacy(bf) || nframes >= h_baw) -+- break; -++ goto stop; -+ -+ tx_info = IEEE80211_SKB_CB(bf->bf_mpdu); -+ if ((tx_info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE) || -+ !(tx_info->flags & IEEE80211_TX_CTL_AMPDU)) -+- break; -++ goto stop; -+ } -+ -+ /* add padding for previous frame to aggregation length */ -+@@ -1003,20 +1024,18 @@ ath_tx_form_aggr(struct ath_softc *sc, s -+ ath_tx_addto_baw(sc, tid, bf); -+ bf->bf_state.ndelim = ndelim; -+ -+- __skb_unlink(skb, tid_q); -+ list_add_tail(&bf->list, bf_q); -+ if (bf_prev) -+ bf_prev->bf_next = bf; -+ -+ bf_prev = bf; -+ -+- bf = ath_tx_get_tid_subframe(sc, txq, tid, &tid_q); -+- if (!bf) { -+- closed = true; -+- break; -+- } -+- } while (ath_tid_has_buffered(tid)); -+- -++ bf = ath_tx_get_tid_subframe(sc, txq, tid); -++ } -++ goto finish; -++stop: -++ __skb_queue_tail(&tid->retry_q, bf->bf_mpdu); -++finish: -+ bf = bf_first; -+ bf->bf_lastbf = bf_prev; -+ -+@@ -1027,9 +1046,7 @@ ath_tx_form_aggr(struct ath_softc *sc, s -+ TX_STAT_INC(txq->axq_qnum, a_aggr); -+ } -+ -+- *aggr_len = al; -+- -+- return closed; -++ return al; -+ #undef PADBYTES -+ } -+ -+@@ -1406,18 +1423,15 @@ static void ath_tx_fill_desc(struct ath_ -+ static void -+ ath_tx_form_burst(struct ath_softc *sc, struct ath_txq *txq, -+ struct ath_atx_tid *tid, struct list_head *bf_q, -+- struct ath_buf *bf_first, struct sk_buff_head *tid_q) -++ struct ath_buf *bf_first) -+ { -+ struct ath_buf *bf = bf_first, *bf_prev = NULL; -+- struct sk_buff *skb; -+ int nframes = 0; -+ -+ do { -+ struct ieee80211_tx_info *tx_info; -+- skb = bf->bf_mpdu; -+ -+ nframes++; -+- __skb_unlink(skb, tid_q); -+ list_add_tail(&bf->list, bf_q); -+ if (bf_prev) -+ bf_prev->bf_next = bf; -+@@ -1426,13 +1440,15 @@ ath_tx_form_burst(struct ath_softc *sc, -+ if (nframes >= 2) -+ break; -+ -+- bf = ath_tx_get_tid_subframe(sc, txq, tid, &tid_q); -++ bf = ath_tx_get_tid_subframe(sc, txq, tid); -+ if (!bf) -+ break; -+ -+ tx_info = IEEE80211_SKB_CB(bf->bf_mpdu); -+- if (tx_info->flags & IEEE80211_TX_CTL_AMPDU) -++ if (tx_info->flags & IEEE80211_TX_CTL_AMPDU) { -++ __skb_queue_tail(&tid->retry_q, bf->bf_mpdu); -+ break; -++ } -+ -+ ath_set_rates(tid->an->vif, tid->an->sta, bf, false); -+ } while (1); -+@@ -1443,34 +1459,33 @@ static bool ath_tx_sched_aggr(struct ath -+ { -+ struct ath_buf *bf; -+ struct ieee80211_tx_info *tx_info; -+- struct sk_buff_head *tid_q; -+ struct list_head bf_q; -+ int aggr_len = 0; -+- bool aggr, last = true; -++ bool aggr; -+ -+ if (!ath_tid_has_buffered(tid)) -+ return false; -+ -+ INIT_LIST_HEAD(&bf_q); -+ -+- bf = ath_tx_get_tid_subframe(sc, txq, tid, &tid_q); -++ bf = ath_tx_get_tid_subframe(sc, txq, tid); -+ if (!bf) -+ return false; -+ -+ tx_info = IEEE80211_SKB_CB(bf->bf_mpdu); -+ aggr = !!(tx_info->flags & IEEE80211_TX_CTL_AMPDU); -+ if ((aggr && txq->axq_ampdu_depth >= ATH_AGGR_MIN_QDEPTH) || -+- (!aggr && txq->axq_depth >= ATH_NON_AGGR_MIN_QDEPTH)) { -++ (!aggr && txq->axq_depth >= ATH_NON_AGGR_MIN_QDEPTH)) { -++ __skb_queue_tail(&tid->retry_q, bf->bf_mpdu); -+ *stop = true; -+ return false; -+ } -+ -+ ath_set_rates(tid->an->vif, tid->an->sta, bf, false); -+ if (aggr) -+- last = ath_tx_form_aggr(sc, txq, tid, &bf_q, bf, -+- tid_q, &aggr_len); -++ aggr_len = ath_tx_form_aggr(sc, txq, tid, &bf_q, bf); -+ else -+- ath_tx_form_burst(sc, txq, tid, &bf_q, bf, tid_q); -++ ath_tx_form_burst(sc, txq, tid, &bf_q, bf); -+ -+ if (list_empty(&bf_q)) -+ return false; -+@@ -1513,9 +1528,6 @@ int ath_tx_aggr_start(struct ath_softc * -+ an->mpdudensity = density; -+ } -+ -+- /* force sequence number allocation for pending frames */ -+- ath_tx_tid_change_state(sc, txtid); -+- -+ txtid->active = true; -+ *ssn = txtid->seq_start = txtid->seq_next; -+ txtid->bar_index = -1; -+@@ -1540,7 +1552,6 @@ void ath_tx_aggr_stop(struct ath_softc * -+ ath_txq_lock(sc, txq); -+ txtid->active = false; -+ ath_tx_flush_tid(sc, txtid); -+- ath_tx_tid_change_state(sc, txtid); -+ ath_txq_unlock_complete(sc, txq); -+ } -+ -+@@ -1550,14 +1561,12 @@ void ath_tx_aggr_sleep(struct ieee80211_ -+ struct ath_common *common = ath9k_hw_common(sc->sc_ah); -+ struct ath_atx_tid *tid; -+ struct ath_txq *txq; -+- bool buffered; -+ int tidno; -+ -+ ath_dbg(common, XMIT, "%s called\n", __func__); -+ -+- for (tidno = 0, tid = &an->tid[tidno]; -+- tidno < IEEE80211_NUM_TIDS; tidno++, tid++) { -+- -++ for (tidno = 0; tidno < IEEE80211_NUM_TIDS; tidno++) { -++ tid = ATH_AN_2_TID(an, tidno); -+ txq = tid->txq; -+ -+ ath_txq_lock(sc, txq); -+@@ -1567,13 +1576,12 @@ void ath_tx_aggr_sleep(struct ieee80211_ -+ continue; -+ } -+ -+- buffered = ath_tid_has_buffered(tid); -++ if (!skb_queue_empty(&tid->retry_q)) -++ ieee80211_sta_set_buffered(sta, tid->tidno, true); -+ -+ list_del_init(&tid->list); -+ -+ ath_txq_unlock(sc, txq); -+- -+- ieee80211_sta_set_buffered(sta, tidno, buffered); -+ } -+ } -+ -+@@ -1586,19 +1594,16 @@ void ath_tx_aggr_wakeup(struct ath_softc -+ -+ ath_dbg(common, XMIT, "%s called\n", __func__); -+ -+- for (tidno = 0, tid = &an->tid[tidno]; -+- tidno < IEEE80211_NUM_TIDS; tidno++, tid++) { -+- -++ for (tidno = 0; tidno < IEEE80211_NUM_TIDS; tidno++) { -++ tid = ATH_AN_2_TID(an, tidno); -+ txq = tid->txq; -+ -+ ath_txq_lock(sc, txq); -+ tid->clear_ps_filter = true; -+- -+ if (ath_tid_has_buffered(tid)) { -+ ath_tx_queue_tid(sc, txq, tid); -+ ath_txq_schedule(sc, txq); -+ } -+- -+ ath_txq_unlock_complete(sc, txq); -+ } -+ } -+@@ -1621,11 +1626,6 @@ void ath_tx_aggr_resume(struct ath_softc -+ -+ tid->baw_size = IEEE80211_MIN_AMPDU_BUF << sta->ht_cap.ampdu_factor; -+ -+- if (ath_tid_has_buffered(tid)) { -+- ath_tx_queue_tid(sc, txq, tid); -+- ath_txq_schedule(sc, txq); -+- } -+- -+ ath_txq_unlock_complete(sc, txq); -+ } -+ -+@@ -1641,7 +1641,6 @@ void ath9k_release_buffered_frames(struc -+ struct ieee80211_tx_info *info; -+ struct list_head bf_q; -+ struct ath_buf *bf_tail = NULL, *bf; -+- struct sk_buff_head *tid_q; -+ int sent = 0; -+ int i; -+ -+@@ -1656,11 +1655,10 @@ void ath9k_release_buffered_frames(struc -+ -+ ath_txq_lock(sc, tid->txq); -+ while (nframes > 0) { -+- bf = ath_tx_get_tid_subframe(sc, sc->tx.uapsdq, tid, &tid_q); -++ bf = ath_tx_get_tid_subframe(sc, sc->tx.uapsdq, tid); -+ if (!bf) -+ break; -+ -+- __skb_unlink(bf->bf_mpdu, tid_q); -+ list_add_tail(&bf->list, &bf_q); -+ ath_set_rates(tid->an->vif, tid->an->sta, bf, true); -+ if (bf_isampdu(bf)) { -+@@ -1675,7 +1673,7 @@ void ath9k_release_buffered_frames(struc -+ sent++; -+ TX_STAT_INC(txq->axq_qnum, a_queued_hw); -+ -+- if (an->sta && !ath_tid_has_buffered(tid)) -++ if (an->sta && skb_queue_empty(&tid->retry_q)) -+ ieee80211_sta_set_buffered(an->sta, i, false); -+ } -+ ath_txq_unlock_complete(sc, tid->txq); -+@@ -1902,13 +1900,7 @@ bool ath_drain_all_txq(struct ath_softc -+ if (!ATH_TXQ_SETUP(sc, i)) -+ continue; -+ -+- /* -+- * The caller will resume queues with ieee80211_wake_queues. -+- * Mark the queue as not stopped to prevent ath_tx_complete -+- * from waking the queue too early. -+- */ -+ txq = &sc->tx.txq[i]; -+- txq->stopped = false; -+ ath_draintxq(sc, txq); -+ } -+ -+@@ -2308,15 +2300,12 @@ int ath_tx_start(struct ieee80211_hw *hw -+ struct ath_txq *txq = txctl->txq; -+ struct ath_atx_tid *tid = NULL; -+ struct ath_buf *bf; -+- bool queue, ps_resp; -++ bool ps_resp; -+ int q, ret; -+ -+ if (vif) -+ avp = (void *)vif->drv_priv; -+ -+- if (info->flags & IEEE80211_TX_CTL_TX_OFFCHAN) -+- txctl->force_channel = true; -+- -+ ps_resp = !!(info->control.flags & IEEE80211_TX_CTRL_PS_RESPONSE); -+ -+ ret = ath_tx_prepare(hw, skb, txctl); -+@@ -2331,63 +2320,13 @@ int ath_tx_start(struct ieee80211_hw *hw -+ -+ q = skb_get_queue_mapping(skb); -+ -++ if (ps_resp) -++ txq = sc->tx.uapsdq; -++ -+ ath_txq_lock(sc, txq); -+ if (txq == sc->tx.txq_map[q]) { -+ fi->txq = q; -+- if (++txq->pending_frames > sc->tx.txq_max_pending[q] && -+- !txq->stopped) { -+- if (ath9k_is_chanctx_enabled()) -+- ieee80211_stop_queue(sc->hw, info->hw_queue); -+- else -+- ieee80211_stop_queue(sc->hw, q); -+- txq->stopped = true; -+- } -+- } -+- -+- queue = ieee80211_is_data_present(hdr->frame_control); -+- -+- /* If chanctx, queue all null frames while NOA could be there */ -+- if (ath9k_is_chanctx_enabled() && -+- ieee80211_is_nullfunc(hdr->frame_control) && -+- !txctl->force_channel) -+- queue = true; -+- -+- /* Force queueing of all frames that belong to a virtual interface on -+- * a different channel context, to ensure that they are sent on the -+- * correct channel. -+- */ -+- if (((avp && avp->chanctx != sc->cur_chan) || -+- sc->cur_chan->stopped) && !txctl->force_channel) { -+- if (!txctl->an) -+- txctl->an = &avp->mcast_node; -+- queue = true; -+- ps_resp = false; -+- } -+- -+- if (txctl->an && queue) -+- tid = ath_get_skb_tid(sc, txctl->an, skb); -+- -+- if (ps_resp) { -+- ath_txq_unlock(sc, txq); -+- txq = sc->tx.uapsdq; -+- ath_txq_lock(sc, txq); -+- } else if (txctl->an && queue) { -+- WARN_ON(tid->txq != txctl->txq); -+- -+- if (info->flags & IEEE80211_TX_CTL_CLEAR_PS_FILT) -+- tid->clear_ps_filter = true; -+- -+- /* -+- * Add this frame to software queue for scheduling later -+- * for aggregation. -+- */ -+- TX_STAT_INC(txq->axq_qnum, a_queued_sw); -+- __skb_queue_tail(&tid->buf_q, skb); -+- if (!txctl->an->sleeping) -+- ath_tx_queue_tid(sc, txq, tid); -+- -+- ath_txq_schedule(sc, txq); -+- goto out; -++ ++txq->pending_frames; -+ } -+ -+ bf = ath_tx_setup_buffer(sc, txq, tid, skb); -+@@ -2871,9 +2810,8 @@ void ath_tx_node_init(struct ath_softc * -+ struct ath_atx_tid *tid; -+ int tidno, acno; -+ -+- for (tidno = 0, tid = &an->tid[tidno]; -+- tidno < IEEE80211_NUM_TIDS; -+- tidno++, tid++) { -++ for (tidno = 0; tidno < IEEE80211_NUM_TIDS; tidno++) { -++ tid = ATH_AN_2_TID(an, tidno); -+ tid->an = an; -+ tid->tidno = tidno; -+ tid->seq_start = tid->seq_next = 0; -+@@ -2881,11 +2819,14 @@ void ath_tx_node_init(struct ath_softc * -+ tid->baw_head = tid->baw_tail = 0; -+ tid->active = false; -+ tid->clear_ps_filter = true; -+- __skb_queue_head_init(&tid->buf_q); -++ tid->has_queued = false; -+ __skb_queue_head_init(&tid->retry_q); -+ INIT_LIST_HEAD(&tid->list); -+ acno = TID_TO_WME_AC(tidno); -+ tid->txq = sc->tx.txq_map[acno]; -++ -++ if (!an->sta) -++ break; /* just one multicast ath_atx_tid */ -+ } -+ } -+ -+@@ -2895,9 +2836,8 @@ void ath_tx_node_cleanup(struct ath_soft -+ struct ath_txq *txq; -+ int tidno; -+ -+- for (tidno = 0, tid = &an->tid[tidno]; -+- tidno < IEEE80211_NUM_TIDS; tidno++, tid++) { -+- -++ for (tidno = 0; tidno < IEEE80211_NUM_TIDS; tidno++) { -++ tid = ATH_AN_2_TID(an, tidno); -+ txq = tid->txq; -+ -+ ath_txq_lock(sc, txq); -+@@ -2909,6 +2849,9 @@ void ath_tx_node_cleanup(struct ath_soft -+ tid->active = false; -+ -+ ath_txq_unlock(sc, txq); -++ -++ if (!an->sta) -++ break; /* just one multicast ath_atx_tid */ -+ } -+ } -+ -diff --git a/package/kernel/mac80211/patches/320-cfg80211-add-support-for-non-linear-skbs-in-ieee8021.patch b/package/kernel/mac80211/patches/320-cfg80211-add-support-for-non-linear-skbs-in-ieee8021.patch -deleted file mode 100644 -index 2eeed22..0000000 ---- a/package/kernel/mac80211/patches/320-cfg80211-add-support-for-non-linear-skbs-in-ieee8021.patch -+++ /dev/null -@@ -1,159 +0,0 @@ --From: Felix Fietkau --Date: Tue, 2 Feb 2016 14:39:10 +0100 --Subject: [PATCH] cfg80211: add support for non-linear skbs in -- ieee80211_amsdu_to_8023s -- --Signed-off-by: Felix Fietkau --Signed-off-by: Johannes Berg ----- -- ----- a/net/wireless/util.c --+++ b/net/wireless/util.c --@@ -644,73 +644,75 @@ int ieee80211_data_from_8023(struct sk_b -- } -- EXPORT_SYMBOL(ieee80211_data_from_8023); -- --+static struct sk_buff * --+__ieee80211_amsdu_copy(struct sk_buff *skb, unsigned int hlen, --+ int offset, int len) --+{ --+ struct sk_buff *frame; --+ --+ if (skb->len - offset < len) --+ return NULL; --+ --+ /* --+ * Allocate and reserve two bytes more for payload --+ * alignment since sizeof(struct ethhdr) is 14. --+ */ --+ frame = dev_alloc_skb(hlen + sizeof(struct ethhdr) + 2 + len); --+ --+ skb_reserve(frame, hlen + sizeof(struct ethhdr) + 2); --+ skb_copy_bits(skb, offset, skb_put(frame, len), len); --+ --+ return frame; --+} -- -- void ieee80211_amsdu_to_8023s(struct sk_buff *skb, struct sk_buff_head *list, -- const u8 *addr, enum nl80211_iftype iftype, -- const unsigned int extra_headroom, -- bool has_80211_header) -- { --+ unsigned int hlen = ALIGN(extra_headroom, 4); -- struct sk_buff *frame = NULL; -- u16 ethertype; -- u8 *payload; --- const struct ethhdr *eth; --- int remaining, err; --- u8 dst[ETH_ALEN], src[ETH_ALEN]; --- --- if (skb_linearize(skb)) --- goto out; --+ int offset = 0, remaining, err; --+ struct ethhdr eth; --+ bool reuse_skb = true; --+ bool last = false; -- -- if (has_80211_header) { --- err = ieee80211_data_to_8023(skb, addr, iftype); --+ err = __ieee80211_data_to_8023(skb, ð, addr, iftype); -- if (err) -- goto out; --- --- /* skip the wrapping header */ --- eth = (struct ethhdr *) skb_pull(skb, sizeof(struct ethhdr)); --- if (!eth) --- goto out; --- } else { --- eth = (struct ethhdr *) skb->data; -- } -- --- while (skb != frame) { --+ while (!last) { --+ unsigned int subframe_len; --+ int len; -- u8 padding; --- __be16 len = eth->h_proto; --- unsigned int subframe_len = sizeof(struct ethhdr) + ntohs(len); --- --- remaining = skb->len; --- memcpy(dst, eth->h_dest, ETH_ALEN); --- memcpy(src, eth->h_source, ETH_ALEN); -- --+ skb_copy_bits(skb, offset, ð, sizeof(eth)); --+ len = ntohs(eth.h_proto); --+ subframe_len = sizeof(struct ethhdr) + len; -- padding = (4 - subframe_len) & 0x3; --+ -- /* the last MSDU has no padding */ --+ remaining = skb->len - offset; -- if (subframe_len > remaining) -- goto purge; -- --- skb_pull(skb, sizeof(struct ethhdr)); --+ offset += sizeof(struct ethhdr); -- /* reuse skb for the last subframe */ --- if (remaining <= subframe_len + padding) --+ last = remaining <= subframe_len + padding; --+ if (!skb_is_nonlinear(skb) && last) { --+ skb_pull(skb, offset); -- frame = skb; --- else { --- unsigned int hlen = ALIGN(extra_headroom, 4); --- /* --- * Allocate and reserve two bytes more for payload --- * alignment since sizeof(struct ethhdr) is 14. --- */ --- frame = dev_alloc_skb(hlen + subframe_len + 2); --+ reuse_skb = true; --+ } else { --+ frame = __ieee80211_amsdu_copy(skb, hlen, offset, len); -- if (!frame) -- goto purge; -- --- skb_reserve(frame, hlen + sizeof(struct ethhdr) + 2); --- memcpy(skb_put(frame, ntohs(len)), skb->data, --- ntohs(len)); --- --- eth = (struct ethhdr *)skb_pull(skb, ntohs(len) + --- padding); --- if (!eth) { --- dev_kfree_skb(frame); --- goto purge; --- } --+ offset += len + padding; -- } -- -- skb_reset_network_header(frame); --@@ -719,24 +721,20 @@ void ieee80211_amsdu_to_8023s(struct sk_ -- -- payload = frame->data; -- ethertype = (payload[6] << 8) | payload[7]; --- -- if (likely((ether_addr_equal(payload, rfc1042_header) && -- ethertype != ETH_P_AARP && ethertype != ETH_P_IPX) || -- ether_addr_equal(payload, bridge_tunnel_header))) { --- /* remove RFC1042 or Bridge-Tunnel --- * encapsulation and replace EtherType */ --- skb_pull(frame, 6); --- memcpy(skb_push(frame, ETH_ALEN), src, ETH_ALEN); --- memcpy(skb_push(frame, ETH_ALEN), dst, ETH_ALEN); --- } else { --- memcpy(skb_push(frame, sizeof(__be16)), &len, --- sizeof(__be16)); --- memcpy(skb_push(frame, ETH_ALEN), src, ETH_ALEN); --- memcpy(skb_push(frame, ETH_ALEN), dst, ETH_ALEN); --+ eth.h_proto = htons(ethertype); --+ skb_pull(frame, ETH_ALEN + 2); -- } --+ --+ memcpy(skb_push(frame, sizeof(eth)), ð, sizeof(eth)); -- __skb_queue_tail(list, frame); -- } -- --+ if (!reuse_skb) --+ dev_kfree_skb(skb); --+ -- return; -- -- purge: -diff --git a/package/kernel/mac80211/patches/321-ath9k_hw-reset-AHB-WMAC-interface-on-AR91xx.patch b/package/kernel/mac80211/patches/321-ath9k_hw-reset-AHB-WMAC-interface-on-AR91xx.patch -new file mode 100644 -index 0000000..9caa76d ---- /dev/null -+++ b/package/kernel/mac80211/patches/321-ath9k_hw-reset-AHB-WMAC-interface-on-AR91xx.patch -@@ -0,0 +1,25 @@ -+From: Felix Fietkau -+Date: Sat, 9 Jul 2016 15:25:24 +0200 -+Subject: [PATCH] ath9k_hw: reset AHB-WMAC interface on AR91xx -+ -+Should fix a few stability issues -+ -+Signed-off-by: Felix Fietkau -+--- -+ -+--- a/drivers/net/wireless/ath/ath9k/hw.c -++++ b/drivers/net/wireless/ath/ath9k/hw.c -+@@ -1398,8 +1398,12 @@ static bool ath9k_hw_set_reset(struct at -+ if (!AR_SREV_9100(ah)) -+ REG_WRITE(ah, AR_RC, 0); -+ -+- if (AR_SREV_9100(ah)) -++ if (AR_SREV_9100(ah)) { -++ /* Reset the AHB-WMAC interface */ -++ if (ah->external_reset) -++ ah->external_reset(); -+ udelay(50); -++ } -+ -+ return true; -+ } -diff --git a/package/kernel/mac80211/patches/321-mac80211-Parse-legacy-and-HT-rate-in-injected-frames.patch b/package/kernel/mac80211/patches/321-mac80211-Parse-legacy-and-HT-rate-in-injected-frames.patch -deleted file mode 100644 -index c4155a1..0000000 ---- a/package/kernel/mac80211/patches/321-mac80211-Parse-legacy-and-HT-rate-in-injected-frames.patch -+++ /dev/null -@@ -1,155 +0,0 @@ --From: Sven Eckelmann --Date: Tue, 26 Jan 2016 17:11:13 +0100 --Subject: [PATCH] mac80211: Parse legacy and HT rate in injected frames -- --Drivers/devices without their own rate control algorithm can get the --information what rates they should use from either the radiotap header of --injected frames or from the rate control algorithm. But the parsing of the --legacy rate information from the radiotap header was removed in commit --e6a9854b05c1 ("mac80211/drivers: rewrite the rate control API"). -- --The removal of this feature heavily reduced the usefulness of frame --injection when wanting to simulate specific transmission behavior. Having --rate parsing together with MCS rates and retry support allows a fine --grained selection of the tx behavior of injected frames for these kind of --tests. -- --Signed-off-by: Sven Eckelmann --Cc: Simon Wunderlich --Signed-off-by: Johannes Berg ----- -- ----- a/include/net/mac80211.h --+++ b/include/net/mac80211.h --@@ -708,12 +708,14 @@ enum mac80211_tx_info_flags { -- * protocol frame (e.g. EAP) -- * @IEEE80211_TX_CTRL_PS_RESPONSE: This frame is a response to a poll -- * frame (PS-Poll or uAPSD). --+ * @IEEE80211_TX_CTRL_RATE_INJECT: This frame is injected with rate information -- * -- * These flags are used in tx_info->control.flags. -- */ -- enum mac80211_tx_control_flags { -- IEEE80211_TX_CTRL_PORT_CTRL_PROTO = BIT(0), -- IEEE80211_TX_CTRL_PS_RESPONSE = BIT(1), --+ IEEE80211_TX_CTRL_RATE_INJECT = BIT(2), -- }; -- -- /* ----- a/net/mac80211/tx.c --+++ b/net/mac80211/tx.c --@@ -710,6 +710,10 @@ ieee80211_tx_h_rate_ctrl(struct ieee8021 -- -- info->control.short_preamble = txrc.short_preamble; -- --+ /* don't ask rate control when rate already injected via radiotap */ --+ if (info->control.flags & IEEE80211_TX_CTRL_RATE_INJECT) --+ return TX_CONTINUE; --+ -- if (tx->sta) -- assoc = test_sta_flag(tx->sta, WLAN_STA_ASSOC); -- --@@ -1665,15 +1669,24 @@ void ieee80211_xmit(struct ieee80211_sub -- ieee80211_tx(sdata, sta, skb, false); -- } -- ---static bool ieee80211_parse_tx_radiotap(struct sk_buff *skb) --+static bool ieee80211_parse_tx_radiotap(struct ieee80211_local *local, --+ struct sk_buff *skb) -- { -- struct ieee80211_radiotap_iterator iterator; -- struct ieee80211_radiotap_header *rthdr = -- (struct ieee80211_radiotap_header *) skb->data; -- struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); --+ struct ieee80211_supported_band *sband = --+ local->hw.wiphy->bands[info->band]; -- int ret = ieee80211_radiotap_iterator_init(&iterator, rthdr, skb->len, -- NULL); -- u16 txflags; --+ u16 rate = 0; --+ bool rate_found = false; --+ u8 rate_retries = 0; --+ u16 rate_flags = 0; --+ u8 mcs_known, mcs_flags; --+ int i; -- -- info->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT | -- IEEE80211_TX_CTL_DONTFRAG; --@@ -1724,6 +1737,35 @@ static bool ieee80211_parse_tx_radiotap( -- info->flags |= IEEE80211_TX_CTL_NO_ACK; -- break; -- --+ case IEEE80211_RADIOTAP_RATE: --+ rate = *iterator.this_arg; --+ rate_flags = 0; --+ rate_found = true; --+ break; --+ --+ case IEEE80211_RADIOTAP_DATA_RETRIES: --+ rate_retries = *iterator.this_arg; --+ break; --+ --+ case IEEE80211_RADIOTAP_MCS: --+ mcs_known = iterator.this_arg[0]; --+ mcs_flags = iterator.this_arg[1]; --+ if (!(mcs_known & IEEE80211_RADIOTAP_MCS_HAVE_MCS)) --+ break; --+ --+ rate_found = true; --+ rate = iterator.this_arg[2]; --+ rate_flags = IEEE80211_TX_RC_MCS; --+ --+ if (mcs_known & IEEE80211_RADIOTAP_MCS_HAVE_GI && --+ mcs_flags & IEEE80211_RADIOTAP_MCS_SGI) --+ rate_flags |= IEEE80211_TX_RC_SHORT_GI; --+ --+ if (mcs_known & IEEE80211_RADIOTAP_MCS_HAVE_BW && --+ mcs_flags & IEEE80211_RADIOTAP_MCS_BW_40) --+ rate_flags |= IEEE80211_TX_RC_40_MHZ_WIDTH; --+ break; --+ -- /* -- * Please update the file -- * Documentation/networking/mac80211-injection.txt --@@ -1738,6 +1780,32 @@ static bool ieee80211_parse_tx_radiotap( -- if (ret != -ENOENT) /* ie, if we didn't simply run out of fields */ -- return false; -- --+ if (rate_found) { --+ info->control.flags |= IEEE80211_TX_CTRL_RATE_INJECT; --+ --+ for (i = 0; i < IEEE80211_TX_MAX_RATES; i++) { --+ info->control.rates[i].idx = -1; --+ info->control.rates[i].flags = 0; --+ info->control.rates[i].count = 0; --+ } --+ --+ if (rate_flags & IEEE80211_TX_RC_MCS) { --+ info->control.rates[0].idx = rate; --+ } else { --+ for (i = 0; i < sband->n_bitrates; i++) { --+ if (rate * 5 != sband->bitrates[i].bitrate) --+ continue; --+ --+ info->control.rates[0].idx = i; --+ break; --+ } --+ } --+ --+ info->control.rates[0].flags = rate_flags; --+ info->control.rates[0].count = min_t(u8, rate_retries + 1, --+ local->hw.max_rate_tries); --+ } --+ -- /* -- * remove the radiotap header -- * iterator->_max_length was sanity-checked against --@@ -1819,7 +1887,7 @@ netdev_tx_t ieee80211_monitor_start_xmit -- IEEE80211_TX_CTL_INJECTED; -- -- /* process and remove the injection radiotap header */ --- if (!ieee80211_parse_tx_radiotap(skb)) --+ if (!ieee80211_parse_tx_radiotap(local, skb)) -- goto fail; -- -- rcu_read_lock(); -diff --git a/package/kernel/mac80211/patches/322-ath9k_hw-issue-external-reset-for-QCA9550.patch b/package/kernel/mac80211/patches/322-ath9k_hw-issue-external-reset-for-QCA9550.patch -new file mode 100644 -index 0000000..5d4e849 ---- /dev/null -+++ b/package/kernel/mac80211/patches/322-ath9k_hw-issue-external-reset-for-QCA9550.patch -@@ -0,0 +1,125 @@ -+From: Felix Fietkau -+Date: Sat, 9 Jul 2016 15:26:44 +0200 -+Subject: [PATCH] ath9k_hw: issue external reset for QCA9550 -+ -+The RTC interface on the SoC needs to be reset along with the rest of -+the WMAC. -+ -+Signed-off-by: Felix Fietkau -+--- -+ -+--- a/drivers/net/wireless/ath/ath9k/hw.c -++++ b/drivers/net/wireless/ath/ath9k/hw.c -+@@ -1275,39 +1275,56 @@ void ath9k_hw_get_delta_slope_vals(struc -+ *coef_exponent = coef_exp - 16; -+ } -+ -+-/* AR9330 WAR: -+- * call external reset function to reset WMAC if: -+- * - doing a cold reset -+- * - we have pending frames in the TX queues. -+- */ -+-static bool ath9k_hw_ar9330_reset_war(struct ath_hw *ah, int type) -++static bool ath9k_hw_need_external_reset(struct ath_hw *ah, int type) -+ { -+- int i, npend = 0; -++ int i; -+ -+- for (i = 0; i < AR_NUM_QCU; i++) { -+- npend = ath9k_hw_numtxpending(ah, i); -+- if (npend) -+- break; -++ if (type == ATH9K_RESET_COLD) -++ return true; -++ -++ if (AR_SREV_9550(ah)) -++ return true; -++ -++ /* AR9330 WAR: -++ * call external reset function to reset WMAC if: -++ * - doing a cold reset -++ * - we have pending frames in the TX queues. -++ */ -++ if (AR_SREV_9330(ah)) { -++ for (i = 0; i < AR_NUM_QCU; i++) { -++ if (ath9k_hw_numtxpending(ah, i)) -++ return true; -++ } -+ } -+ -+- if (ah->external_reset && -+- (npend || type == ATH9K_RESET_COLD)) { -+- int reset_err = 0; -++ return false; -++} -+ -+- ath_dbg(ath9k_hw_common(ah), RESET, -+- "reset MAC via external reset\n"); -++static bool ath9k_hw_external_reset(struct ath_hw *ah, int type) -++{ -++ int err; -+ -+- reset_err = ah->external_reset(); -+- if (reset_err) { -+- ath_err(ath9k_hw_common(ah), -+- "External reset failed, err=%d\n", -+- reset_err); -+- return false; -+- } -++ if (!ah->external_reset || !ath9k_hw_need_external_reset(ah, type)) -++ return true; -+ -+- REG_WRITE(ah, AR_RTC_RESET, 1); -++ ath_dbg(ath9k_hw_common(ah), RESET, -++ "reset MAC via external reset\n"); -++ -++ err = ah->external_reset(); -++ if (err) { -++ ath_err(ath9k_hw_common(ah), -++ "External reset failed, err=%d\n", err); -++ return false; -++ } -++ -++ if (AR_SREV_9550(ah)) { -++ REG_WRITE(ah, AR_RTC_RESET, 0); -++ udelay(10); -+ } -+ -++ REG_WRITE(ah, AR_RTC_RESET, 1); -++ udelay(10); -++ -+ return true; -+ } -+ -+@@ -1360,24 +1377,23 @@ static bool ath9k_hw_set_reset(struct at -+ rst_flags |= AR_RTC_RC_MAC_COLD; -+ } -+ -+- if (AR_SREV_9330(ah)) { -+- if (!ath9k_hw_ar9330_reset_war(ah, type)) -+- return false; -+- } -+- -+ if (ath9k_hw_mci_is_enabled(ah)) -+ ar9003_mci_check_gpm_offset(ah); -+ -+ /* DMA HALT added to resolve ar9300 and ar9580 bus error during -+- * RTC_RC reg read -++ * RTC_RC reg read. Also needed for AR9550 external reset -+ */ -+- if (AR_SREV_9300(ah) || AR_SREV_9580(ah)) { -++ if (AR_SREV_9300(ah) || AR_SREV_9580(ah) || AR_SREV_9550(ah)) { -+ REG_SET_BIT(ah, AR_CFG, AR_CFG_HALT_REQ); -+ ath9k_hw_wait(ah, AR_CFG, AR_CFG_HALT_ACK, AR_CFG_HALT_ACK, -+ 20 * AH_WAIT_TIMEOUT); -+- REG_CLR_BIT(ah, AR_CFG, AR_CFG_HALT_REQ); -+ } -+ -++ ath9k_hw_external_reset(ah, type); -++ -++ if (AR_SREV_9300(ah) || AR_SREV_9580(ah)) -++ REG_CLR_BIT(ah, AR_CFG, AR_CFG_HALT_REQ); -++ -+ REG_WRITE(ah, AR_RTC_RC, rst_flags); -+ -+ REGWRITE_BUFFER_FLUSH(ah); -diff --git a/package/kernel/mac80211/patches/322-mac80211-add-A-MSDU-tx-support.patch b/package/kernel/mac80211/patches/322-mac80211-add-A-MSDU-tx-support.patch -deleted file mode 100644 -index e7bfb9c..0000000 ---- a/package/kernel/mac80211/patches/322-mac80211-add-A-MSDU-tx-support.patch -+++ /dev/null -@@ -1,317 +0,0 @@ --From: Felix Fietkau --Date: Fri, 5 Feb 2016 01:38:51 +0100 --Subject: [PATCH] mac80211: add A-MSDU tx support -- --Requires software tx queueing support. frag_list support (for zero-copy) --is optional. -- --Signed-off-by: Felix Fietkau ----- -- ----- a/include/net/mac80211.h --+++ b/include/net/mac80211.h --@@ -709,6 +709,7 @@ enum mac80211_tx_info_flags { -- * @IEEE80211_TX_CTRL_PS_RESPONSE: This frame is a response to a poll -- * frame (PS-Poll or uAPSD). -- * @IEEE80211_TX_CTRL_RATE_INJECT: This frame is injected with rate information --+ * @IEEE80211_TX_CTRL_AMSDU: This frame is an A-MSDU frame -- * -- * These flags are used in tx_info->control.flags. -- */ --@@ -716,6 +717,7 @@ enum mac80211_tx_control_flags { -- IEEE80211_TX_CTRL_PORT_CTRL_PROTO = BIT(0), -- IEEE80211_TX_CTRL_PS_RESPONSE = BIT(1), -- IEEE80211_TX_CTRL_RATE_INJECT = BIT(2), --+ IEEE80211_TX_CTRL_AMSDU = BIT(3), -- }; -- -- /* --@@ -1728,6 +1730,7 @@ struct ieee80211_sta_rates { -- * size is min(max_amsdu_len, 7935) bytes. -- * Both additional HT limits must be enforced by the low level driver. -- * This is defined by the spec (IEEE 802.11-2012 section 8.3.2.2 NOTE 2). --+ * @max_rc_amsdu_len: Maximum A-MSDU size in bytes recommended by rate control. -- * @txq: per-TID data TX queues (if driver uses the TXQ abstraction) -- */ -- struct ieee80211_sta { --@@ -1748,6 +1751,7 @@ struct ieee80211_sta { -- bool mfp; -- u8 max_amsdu_subframes; -- u16 max_amsdu_len; --+ u16 max_rc_amsdu_len; -- -- struct ieee80211_txq *txq[IEEE80211_NUM_TIDS]; -- --@@ -1961,6 +1965,15 @@ struct ieee80211_txq { -- * order and does not need to manage its own reorder buffer or BA session -- * timeout. -- * --+ * @IEEE80211_HW_TX_AMSDU: Hardware (or driver) supports software aggregated --+ * A-MSDU frames. Requires software tx queueing and fast-xmit support. --+ * When not using minstrel/minstrel_ht rate control, the driver should --+ * limit the maximum A-MSDU size based on the current tx rate by setting --+ * max_rc_amsdu_len in struct ieee80211_sta. --+ * --+ * @IEEE80211_HW_TX_FRAG_LIST: Hardware (or driver) supports sending frag_list --+ * skbs, needed for zero-copy software A-MSDU. --+ * -- * @NUM_IEEE80211_HW_FLAGS: number of hardware flags, used for sizing arrays -- */ -- enum ieee80211_hw_flags { --@@ -1998,6 +2011,8 @@ enum ieee80211_hw_flags { -- IEEE80211_HW_BEACON_TX_STATUS, -- IEEE80211_HW_NEEDS_UNIQUE_STA_ADDR, -- IEEE80211_HW_SUPPORTS_REORDERING_BUFFER, --+ IEEE80211_HW_TX_AMSDU, --+ IEEE80211_HW_TX_FRAG_LIST, -- -- /* keep last, obviously */ -- NUM_IEEE80211_HW_FLAGS --@@ -2070,6 +2085,9 @@ enum ieee80211_hw_flags { -- * size is smaller (an example is LinkSys WRT120N with FW v1.0.07 -- * build 002 Jun 18 2012). -- * --+ * @max_tx_fragments: maximum number of tx buffers per (A)-MSDU, sum --+ * of 1 + skb_shinfo(skb)->nr_frags for each skb in the frag_list. --+ * -- * @offchannel_tx_hw_queue: HW queue ID to use for offchannel TX -- * (if %IEEE80211_HW_QUEUE_CONTROL is set) -- * --@@ -2124,6 +2142,7 @@ struct ieee80211_hw { -- u8 max_rate_tries; -- u8 max_rx_aggregation_subframes; -- u8 max_tx_aggregation_subframes; --+ u8 max_tx_fragments; -- u8 offchannel_tx_hw_queue; -- u8 radiotap_mcs_details; -- u16 radiotap_vht_details; ----- a/net/mac80211/agg-tx.c --+++ b/net/mac80211/agg-tx.c --@@ -935,6 +935,7 @@ void ieee80211_process_addba_resp(struct -- size_t len) -- { -- struct tid_ampdu_tx *tid_tx; --+ struct ieee80211_txq *txq; -- u16 capab, tid; -- u8 buf_size; -- bool amsdu; --@@ -945,6 +946,10 @@ void ieee80211_process_addba_resp(struct -- buf_size = (capab & IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK) >> 6; -- buf_size = min(buf_size, local->hw.max_tx_aggregation_subframes); -- --+ txq = sta->sta.txq[tid]; --+ if (!amsdu && txq) --+ set_bit(IEEE80211_TXQ_NO_AMSDU, &to_txq_info(txq)->flags); --+ -- mutex_lock(&sta->ampdu_mlme.mtx); -- -- tid_tx = rcu_dereference_protected_tid_tx(sta, tid); ----- a/net/mac80211/debugfs.c --+++ b/net/mac80211/debugfs.c --@@ -127,6 +127,8 @@ static const char *hw_flag_names[NUM_IEE -- FLAG(BEACON_TX_STATUS), -- FLAG(NEEDS_UNIQUE_STA_ADDR), -- FLAG(SUPPORTS_REORDERING_BUFFER), --+ FLAG(TX_AMSDU), --+ FLAG(TX_FRAG_LIST), -- -- /* keep last for the build bug below */ -- (void *)0x1 ----- a/net/mac80211/ieee80211_i.h --+++ b/net/mac80211/ieee80211_i.h --@@ -799,6 +799,7 @@ struct mac80211_qos_map { -- enum txq_info_flags { -- IEEE80211_TXQ_STOP, -- IEEE80211_TXQ_AMPDU, --+ IEEE80211_TXQ_NO_AMSDU, -- }; -- -- struct txq_info { ----- a/net/mac80211/tx.c --+++ b/net/mac80211/tx.c --@@ -1318,6 +1318,10 @@ struct sk_buff *ieee80211_tx_dequeue(str -- out: -- spin_unlock_bh(&txqi->queue.lock); -- --+ if (skb && skb_has_frag_list(skb) && --+ !ieee80211_hw_check(&local->hw, TX_FRAG_LIST)) --+ skb_linearize(skb); --+ -- return skb; -- } -- EXPORT_SYMBOL(ieee80211_tx_dequeue); --@@ -2757,6 +2761,163 @@ void ieee80211_clear_fast_xmit(struct st -- kfree_rcu(fast_tx, rcu_head); -- } -- --+static bool ieee80211_amsdu_realloc_pad(struct ieee80211_local *local, --+ struct sk_buff *skb, int headroom, --+ int *subframe_len) --+{ --+ int amsdu_len = *subframe_len + sizeof(struct ethhdr); --+ int padding = (4 - amsdu_len) & 3; --+ --+ if (skb_headroom(skb) < headroom || skb_tailroom(skb) < padding) { --+ I802_DEBUG_INC(local->tx_expand_skb_head); --+ --+ if (pskb_expand_head(skb, headroom, padding, GFP_ATOMIC)) { --+ wiphy_debug(local->hw.wiphy, --+ "failed to reallocate TX buffer\n"); --+ return false; --+ } --+ } --+ --+ if (padding) { --+ *subframe_len += padding; --+ memset(skb_put(skb, padding), 0, padding); --+ } --+ --+ return true; --+} --+ --+static bool ieee80211_amsdu_prepare_head(struct ieee80211_sub_if_data *sdata, --+ struct ieee80211_fast_tx *fast_tx, --+ struct sk_buff *skb) --+{ --+ struct ieee80211_local *local = sdata->local; --+ struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); --+ struct ieee80211_hdr *hdr; --+ struct ethhdr amsdu_hdr; --+ int hdr_len = fast_tx->hdr_len - sizeof(rfc1042_header); --+ int subframe_len = skb->len - hdr_len; --+ void *data; --+ u8 *qc; --+ --+ if (info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE) --+ return false; --+ --+ if (info->control.flags & IEEE80211_TX_CTRL_AMSDU) --+ return true; --+ --+ if (!ieee80211_amsdu_realloc_pad(local, skb, sizeof(amsdu_hdr), --+ &subframe_len)) --+ return false; --+ --+ amsdu_hdr.h_proto = cpu_to_be16(subframe_len); --+ memcpy(amsdu_hdr.h_source, skb->data + fast_tx->sa_offs, ETH_ALEN); --+ memcpy(amsdu_hdr.h_dest, skb->data + fast_tx->da_offs, ETH_ALEN); --+ --+ data = skb_push(skb, sizeof(amsdu_hdr)); --+ memmove(data, data + sizeof(amsdu_hdr), hdr_len); --+ memcpy(data + hdr_len, &amsdu_hdr, sizeof(amsdu_hdr)); --+ --+ hdr = data; --+ qc = ieee80211_get_qos_ctl(hdr); --+ *qc |= IEEE80211_QOS_CTL_A_MSDU_PRESENT; --+ --+ info->control.flags |= IEEE80211_TX_CTRL_AMSDU; --+ --+ return true; --+} --+ --+static bool ieee80211_amsdu_aggregate(struct ieee80211_sub_if_data *sdata, --+ struct sta_info *sta, --+ struct ieee80211_fast_tx *fast_tx, --+ struct sk_buff *skb) --+{ --+ struct ieee80211_local *local = sdata->local; --+ u8 tid = skb->priority & IEEE80211_QOS_CTL_TAG1D_MASK; --+ struct ieee80211_txq *txq = sta->sta.txq[tid]; --+ struct txq_info *txqi; --+ struct sk_buff **frag_tail, *head; --+ int subframe_len = skb->len - ETH_ALEN; --+ 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; --+ __be16 len; --+ void *data; --+ bool ret = false; --+ int n = 1, nfrags; --+ --+ if (!ieee80211_hw_check(&local->hw, TX_AMSDU)) --+ return false; --+ --+ if (!txq) --+ return false; --+ --+ txqi = to_txq_info(txq); --+ if (test_bit(IEEE80211_TXQ_NO_AMSDU, &txqi->flags)) --+ return false; --+ --+ if (sta->sta.max_rc_amsdu_len) --+ max_amsdu_len = min_t(int, max_amsdu_len, --+ sta->sta.max_rc_amsdu_len); --+ --+ spin_lock_bh(&txqi->queue.lock); --+ --+ head = skb_peek_tail(&txqi->queue); --+ if (!head) --+ goto out; --+ --+ if (skb->len + head->len > max_amsdu_len) --+ goto out; --+ --+ /* --+ * HT A-MPDU limits maximum MPDU size to 4095 bytes. Since aggregation --+ * sessions are started/stopped without txq flush, use the limit here --+ * to avoid having to de-aggregate later. --+ */ --+ if (skb->len + head->len > 4095 && --+ !sta->sta.vht_cap.vht_supported) --+ goto out; --+ --+ if (!ieee80211_amsdu_prepare_head(sdata, fast_tx, head)) --+ goto out; --+ --+ nfrags = 1 + skb_shinfo(skb)->nr_frags; --+ nfrags += 1 + skb_shinfo(head)->nr_frags; --+ frag_tail = &skb_shinfo(head)->frag_list; --+ while (*frag_tail) { --+ nfrags += 1 + skb_shinfo(*frag_tail)->nr_frags; --+ frag_tail = &(*frag_tail)->next; --+ n++; --+ } --+ --+ if (max_subframes && n > max_subframes) --+ goto out; --+ --+ if (max_frags && nfrags > max_frags) --+ goto out; --+ --+ if (!ieee80211_amsdu_realloc_pad(local, skb, sizeof(rfc1042_header) + 2, --+ &subframe_len)) --+ return false; --+ --+ ret = true; --+ data = skb_push(skb, ETH_ALEN + 2); --+ memmove(data, data + ETH_ALEN + 2, 2 * ETH_ALEN); --+ --+ data += 2 * ETH_ALEN; --+ len = cpu_to_be16(subframe_len); --+ memcpy(data, &len, 2); --+ memcpy(data + 2, rfc1042_header, sizeof(rfc1042_header)); --+ --+ head->len += skb->len; --+ head->data_len += skb->len; --+ *frag_tail = skb; --+ --+out: --+ spin_unlock_bh(&txqi->queue.lock); --+ --+ return ret; --+} --+ -- static bool ieee80211_xmit_fast(struct ieee80211_sub_if_data *sdata, -- struct net_device *dev, struct sta_info *sta, -- struct ieee80211_fast_tx *fast_tx, --@@ -2811,6 +2972,10 @@ static bool ieee80211_xmit_fast(struct i -- -- ieee80211_tx_stats(dev, skb->len + extra_head); -- --+ if ((hdr->frame_control & cpu_to_le16(IEEE80211_STYPE_QOS_DATA)) && --+ ieee80211_amsdu_aggregate(sdata, sta, fast_tx, skb)) --+ return true; --+ -- /* will not be crypto-handled beyond what we do here, so use false -- * 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/323-0000-brcmfmac-fix-setting-primary-channel-for-80-MHz-widt.patch b/package/kernel/mac80211/patches/323-0000-brcmfmac-fix-setting-primary-channel-for-80-MHz-widt.patch -deleted file mode 100644 -index 9277b2c..0000000 ---- a/package/kernel/mac80211/patches/323-0000-brcmfmac-fix-setting-primary-channel-for-80-MHz-widt.patch -+++ /dev/null -@@ -1,64 +0,0 @@ --From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= --Date: Wed, 20 Jan 2016 16:46:04 +0100 --Subject: [PATCH] brcmfmac: fix setting primary channel for 80 MHz width --MIME-Version: 1.0 --Content-Type: text/plain; charset=UTF-8 --Content-Transfer-Encoding: 8bit -- --First of all it changes the way we calculate primary channel offset. If --we use e.g. 80 MHz channel with primary frequency 5180 MHz (which means --center frequency is 5210 MHz) it makes sense to calculate primary offset --as -30 MHz. --Then it fixes values we compare primary_offset with. We were comparing --offset in MHz against -2 or 2 which was resulting in picking a wrong --primary channel. -- --Signed-off-by: RafaÅ‚ MiÅ‚ecki --Signed-off-by: Kalle Valo ----- -- ----- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c --+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c --@@ -247,7 +247,7 @@ static u16 chandef_to_chanspec(struct br -- brcmf_dbg(TRACE, "chandef: control %d center %d width %d\n", -- ch->chan->center_freq, ch->center_freq1, ch->width); -- ch_inf.chnum = ieee80211_frequency_to_channel(ch->center_freq1); --- primary_offset = ch->center_freq1 - ch->chan->center_freq; --+ primary_offset = ch->chan->center_freq - ch->center_freq1; -- switch (ch->width) { -- case NL80211_CHAN_WIDTH_20: -- case NL80211_CHAN_WIDTH_20_NOHT: --@@ -256,24 +256,21 @@ static u16 chandef_to_chanspec(struct br -- break; -- case NL80211_CHAN_WIDTH_40: -- ch_inf.bw = BRCMU_CHAN_BW_40; --- if (primary_offset < 0) --+ if (primary_offset > 0) -- ch_inf.sb = BRCMU_CHAN_SB_U; -- else -- ch_inf.sb = BRCMU_CHAN_SB_L; -- break; -- case NL80211_CHAN_WIDTH_80: -- ch_inf.bw = BRCMU_CHAN_BW_80; --- if (primary_offset < 0) { --- if (primary_offset < -CH_10MHZ_APART) --- ch_inf.sb = BRCMU_CHAN_SB_UU; --- else --- ch_inf.sb = BRCMU_CHAN_SB_UL; --- } else { --- if (primary_offset > CH_10MHZ_APART) --- ch_inf.sb = BRCMU_CHAN_SB_LL; --- else --- ch_inf.sb = BRCMU_CHAN_SB_LU; --- } --+ if (primary_offset == -30) --+ ch_inf.sb = BRCMU_CHAN_SB_LL; --+ else if (primary_offset == -10) --+ ch_inf.sb = BRCMU_CHAN_SB_LU; --+ else if (primary_offset == 10) --+ ch_inf.sb = BRCMU_CHAN_SB_UL; --+ else --+ ch_inf.sb = BRCMU_CHAN_SB_UU; -- break; -- case NL80211_CHAN_WIDTH_80P80: -- case NL80211_CHAN_WIDTH_160: -diff --git a/package/kernel/mac80211/patches/323-0001-brcmfmac-analyze-descriptors-of-current-component-on.patch b/package/kernel/mac80211/patches/323-0001-brcmfmac-analyze-descriptors-of-current-component-on.patch -deleted file mode 100644 -index d7018da..0000000 ---- a/package/kernel/mac80211/patches/323-0001-brcmfmac-analyze-descriptors-of-current-component-on.patch -+++ /dev/null -@@ -1,51 +0,0 @@ --From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= --Date: Tue, 26 Jan 2016 17:57:01 +0100 --Subject: [PATCH] brcmfmac: analyze descriptors of current component only --MIME-Version: 1.0 --Content-Type: text/plain; charset=UTF-8 --Content-Transfer-Encoding: 8bit -- --So far we were looking for address descriptors without a check for --crossing current component border. In case of dealing with unsupported --descriptor or descriptor missing at all the code would incorrectly get --data from another component. -- --Consider this binary-described component from BCM4366 EROM: --4bf83b01 TAG==CI CID==0x83b --20080201 TAG==CI PORTS==0+1 WRAPPERS==0+1 --18400035 TAG==ADDR SZ_SZD TYPE_SLAVE --00050000 --18107085 TAG==ADDR SZ_4K TYPE_SWRAP -- --Driver was assigning invalid base address to this core: --brcmfmac: [6 ] core 0x83b:32 base 0x18109000 wrap 0x18107000 --which came from totally different component defined in EROM: --43b36701 TAG==CI CID==0x367 --00000201 TAG==CI PORTS==0+1 WRAPPERS==0+0 --18109005 TAG==ADDR SZ_4K TYPE_SLAVE -- --This change will also allow us to support components without wrapper --address in the future. -- --Signed-off-by: RafaÅ‚ MiÅ‚ecki --Signed-off-by: Kalle Valo ----- -- ----- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c --+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c --@@ -803,7 +803,14 @@ static int brcmf_chip_dmp_get_regaddr(st -- *eromaddr -= 4; -- return -EFAULT; -- } --- } while (desc != DMP_DESC_ADDRESS); --+ } while (desc != DMP_DESC_ADDRESS && --+ desc != DMP_DESC_COMPONENT); --+ --+ /* stop if we crossed current component border */ --+ if (desc == DMP_DESC_COMPONENT) { --+ *eromaddr -= 4; --+ return 0; --+ } -- -- /* skip upper 32-bit address descriptor */ -- if (val & DMP_DESC_ADDRSIZE_GT32) -diff --git a/package/kernel/mac80211/patches/323-0002-brcmfmac-allow-storing-PMU-core-without-wrapper-addr.patch b/package/kernel/mac80211/patches/323-0002-brcmfmac-allow-storing-PMU-core-without-wrapper-addr.patch -deleted file mode 100644 -index 045ab49..0000000 ---- a/package/kernel/mac80211/patches/323-0002-brcmfmac-allow-storing-PMU-core-without-wrapper-addr.patch -+++ /dev/null -@@ -1,28 +0,0 @@ --From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= --Date: Tue, 26 Jan 2016 17:57:02 +0100 --Subject: [PATCH] brcmfmac: allow storing PMU core without wrapper address --MIME-Version: 1.0 --Content-Type: text/plain; charset=UTF-8 --Content-Transfer-Encoding: 8bit -- --Separated PMU core can be found in new devices and should be used for --accessing PMU registers (which were routed through ChipCommon so far). --This core is one of exceptions that doesn't have or need wrapper address --to be still safely accessible. -- --Signed-off-by: RafaÅ‚ MiÅ‚ecki --Signed-off-by: Kalle Valo ----- -- ----- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c --+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c --@@ -883,7 +883,8 @@ int brcmf_chip_dmp_erom_scan(struct brcm -- rev = (val & DMP_COMP_REVISION) >> DMP_COMP_REVISION_S; -- -- /* need core with ports */ --- if (nmw + nsw == 0) --+ if (nmw + nsw == 0 && --+ id != BCMA_CORE_PMU) -- continue; -- -- /* try to obtain register address info */ -diff --git a/package/kernel/mac80211/patches/323-0003-brcmfmac-read-extended-capabilities-of-ChipCommon-co.patch b/package/kernel/mac80211/patches/323-0003-brcmfmac-read-extended-capabilities-of-ChipCommon-co.patch -deleted file mode 100644 -index 7b7ba4f..0000000 ---- a/package/kernel/mac80211/patches/323-0003-brcmfmac-read-extended-capabilities-of-ChipCommon-co.patch -+++ /dev/null -@@ -1,43 +0,0 @@ --From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= --Date: Tue, 26 Jan 2016 17:57:03 +0100 --Subject: [PATCH] brcmfmac: read extended capabilities of ChipCommon core --MIME-Version: 1.0 --Content-Type: text/plain; charset=UTF-8 --Content-Transfer-Encoding: 8bit -- --This is an extra bitfield with info about some present hardware. -- --Signed-off-by: RafaÅ‚ MiÅ‚ecki --Signed-off-by: Kalle Valo ----- -- ----- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c --+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c --@@ -1025,6 +1025,9 @@ static int brcmf_chip_setup(struct brcmf -- /* get chipcommon capabilites */ -- pub->cc_caps = chip->ops->read32(chip->ctx, -- CORE_CC_REG(base, capabilities)); --+ pub->cc_caps_ext = chip->ops->read32(chip->ctx, --+ CORE_CC_REG(base, --+ capabilities_ext)); -- -- /* get pmu caps & rev */ -- if (pub->cc_caps & CC_CAP_PMU) { ----- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.h --+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.h --@@ -27,6 +27,7 @@ -- * @chip: chip identifier. -- * @chiprev: chip revision. -- * @cc_caps: chipcommon core capabilities. --+ * @cc_caps_ext: chipcommon core extended capabilities. -- * @pmucaps: PMU capabilities. -- * @pmurev: PMU revision. -- * @rambase: RAM base address (only applicable for ARM CR4 chips). --@@ -38,6 +39,7 @@ struct brcmf_chip { -- u32 chip; -- u32 chiprev; -- u32 cc_caps; --+ u32 cc_caps_ext; -- u32 pmucaps; -- u32 pmurev; -- u32 rambase; -diff --git a/package/kernel/mac80211/patches/323-0004-brcmfmac-access-PMU-registers-using-standalone-PMU-c.patch b/package/kernel/mac80211/patches/323-0004-brcmfmac-access-PMU-registers-using-standalone-PMU-c.patch -deleted file mode 100644 -index 2af6fd9..0000000 ---- a/package/kernel/mac80211/patches/323-0004-brcmfmac-access-PMU-registers-using-standalone-PMU-c.patch -+++ /dev/null -@@ -1,148 +0,0 @@ --From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= --Date: Tue, 26 Jan 2016 17:57:04 +0100 --Subject: [PATCH] brcmfmac: access PMU registers using standalone PMU core if -- available --MIME-Version: 1.0 --Content-Type: text/plain; charset=UTF-8 --Content-Transfer-Encoding: 8bit -- --On recent Broadcom chipsets PMU is present as separated core and it --can't be accessed using ChipCommon anymore as it fails with e.g.: --[ 18.198412] Unhandled fault: imprecise external abort (0x1406) at 0xb6da200f -- --Add a new helper function that will return a proper core that should be --used for accessing PMU registers. -- --Signed-off-by: RafaÅ‚ MiÅ‚ecki --Signed-off-by: Kalle Valo ----- -- ----- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c --+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c --@@ -1014,6 +1014,7 @@ static int brcmf_chip_setup(struct brcmf -- { -- struct brcmf_chip *pub; -- struct brcmf_core_priv *cc; --+ struct brcmf_core *pmu; -- u32 base; -- u32 val; -- int ret = 0; --@@ -1030,9 +1031,10 @@ static int brcmf_chip_setup(struct brcmf -- capabilities_ext)); -- -- /* get pmu caps & rev */ --+ pmu = brcmf_chip_get_pmu(pub); /* after reading cc_caps_ext */ -- if (pub->cc_caps & CC_CAP_PMU) { -- val = chip->ops->read32(chip->ctx, --- CORE_CC_REG(base, pmucapabilities)); --+ CORE_CC_REG(pmu->base, pmucapabilities)); -- pub->pmurev = val & PCAP_REV_MASK; -- pub->pmucaps = val; -- } --@@ -1131,6 +1133,23 @@ struct brcmf_core *brcmf_chip_get_chipco -- return &cc->pub; -- } -- --+struct brcmf_core *brcmf_chip_get_pmu(struct brcmf_chip *pub) --+{ --+ struct brcmf_core *cc = brcmf_chip_get_chipcommon(pub); --+ struct brcmf_core *pmu; --+ --+ /* See if there is separated PMU core available */ --+ if (cc->rev >= 35 && --+ pub->cc_caps_ext & BCMA_CC_CAP_EXT_AOB_PRESENT) { --+ pmu = brcmf_chip_get_core(pub, BCMA_CORE_PMU); --+ if (pmu) --+ return pmu; --+ } --+ --+ /* Fallback to ChipCommon core for older hardware */ --+ return cc; --+} --+ -- bool brcmf_chip_iscoreup(struct brcmf_core *pub) -- { -- struct brcmf_core_priv *core; --@@ -1301,6 +1320,7 @@ bool brcmf_chip_sr_capable(struct brcmf_ -- { -- u32 base, addr, reg, pmu_cc3_mask = ~0; -- struct brcmf_chip_priv *chip; --+ struct brcmf_core *pmu = brcmf_chip_get_pmu(pub); -- -- brcmf_dbg(TRACE, "Enter\n"); -- --@@ -1320,9 +1340,9 @@ bool brcmf_chip_sr_capable(struct brcmf_ -- case BRCM_CC_4335_CHIP_ID: -- case BRCM_CC_4339_CHIP_ID: -- /* read PMU chipcontrol register 3 */ --- addr = CORE_CC_REG(base, chipcontrol_addr); --+ addr = CORE_CC_REG(pmu->base, chipcontrol_addr); -- chip->ops->write32(chip->ctx, addr, 3); --- addr = CORE_CC_REG(base, chipcontrol_data); --+ addr = CORE_CC_REG(pmu->base, chipcontrol_data); -- reg = chip->ops->read32(chip->ctx, addr); -- return (reg & pmu_cc3_mask) != 0; -- case BRCM_CC_43430_CHIP_ID: --@@ -1330,12 +1350,12 @@ bool brcmf_chip_sr_capable(struct brcmf_ -- reg = chip->ops->read32(chip->ctx, addr); -- return reg != 0; -- default: --- addr = CORE_CC_REG(base, pmucapabilities_ext); --+ addr = CORE_CC_REG(pmu->base, pmucapabilities_ext); -- reg = chip->ops->read32(chip->ctx, addr); -- if ((reg & PCAPEXT_SR_SUPPORTED_MASK) == 0) -- return false; -- --- addr = CORE_CC_REG(base, retention_ctl); --+ 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; ----- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.h --+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.h --@@ -85,6 +85,7 @@ struct brcmf_chip *brcmf_chip_attach(voi -- void brcmf_chip_detach(struct brcmf_chip *chip); -- struct brcmf_core *brcmf_chip_get_core(struct brcmf_chip *chip, u16 coreid); -- struct brcmf_core *brcmf_chip_get_chipcommon(struct brcmf_chip *chip); --+struct brcmf_core *brcmf_chip_get_pmu(struct brcmf_chip *pub); -- bool brcmf_chip_iscoreup(struct brcmf_core *core); -- void brcmf_chip_coredisable(struct brcmf_core *core, u32 prereset, u32 reset); -- void brcmf_chip_resetcore(struct brcmf_core *core, u32 prereset, u32 reset, ----- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c --+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c --@@ -3615,7 +3615,6 @@ brcmf_sdio_drivestrengthinit(struct brcm -- const struct sdiod_drive_str *str_tab = NULL; -- u32 str_mask; -- u32 str_shift; --- u32 base; -- u32 i; -- u32 drivestrength_sel = 0; -- u32 cc_data_temp; --@@ -3658,14 +3657,15 @@ brcmf_sdio_drivestrengthinit(struct brcm -- } -- -- if (str_tab != NULL) { --+ struct brcmf_core *pmu = brcmf_chip_get_pmu(ci); --+ -- for (i = 0; str_tab[i].strength != 0; i++) { -- if (drivestrength >= str_tab[i].strength) { -- drivestrength_sel = str_tab[i].sel; -- break; -- } -- } --- base = brcmf_chip_get_chipcommon(ci)->base; --- addr = CORE_CC_REG(base, chipcontrol_addr); --+ addr = CORE_CC_REG(pmu->base, chipcontrol_addr); -- brcmf_sdiod_regwl(sdiodev, addr, 1, NULL); -- cc_data_temp = brcmf_sdiod_regrl(sdiodev, addr, NULL); -- cc_data_temp &= ~str_mask; --@@ -3835,8 +3835,7 @@ brcmf_sdio_probe_attach(struct brcmf_sdi -- goto fail; -- -- /* set PMUControl so a backplane reset does PMU state reload */ --- reg_addr = CORE_CC_REG(brcmf_chip_get_chipcommon(bus->ci)->base, --- pmucontrol); --+ reg_addr = CORE_CC_REG(brcmf_chip_get_pmu(bus->ci)->base, pmucontrol); -- reg_val = brcmf_sdiod_regrl(bus->sdiodev, reg_addr, &err); -- if (err) -- goto fail; -diff --git a/package/kernel/mac80211/patches/323-0005-brcmfmac-add-support-for-14e4-4365-PCI-ID-with-BCM43.patch b/package/kernel/mac80211/patches/323-0005-brcmfmac-add-support-for-14e4-4365-PCI-ID-with-BCM43.patch -deleted file mode 100644 -index 35887fc..0000000 ---- a/package/kernel/mac80211/patches/323-0005-brcmfmac-add-support-for-14e4-4365-PCI-ID-with-BCM43.patch -+++ /dev/null -@@ -1,38 +0,0 @@ --From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= --Date: Tue, 26 Jan 2016 17:57:05 +0100 --Subject: [PATCH] brcmfmac: add support for 14e4:4365 PCI ID with BCM4366 -- chipset --MIME-Version: 1.0 --Content-Type: text/plain; charset=UTF-8 --Content-Transfer-Encoding: 8bit -- --On Broadcom ARM routers BCM4366 cards are available with 14e4:4365 ID. --Unfortunately this ID was already used by Broadcom for cards with --BCM43142, a totally different chipset requiring SoftMAC driver. To avoid --a conflict between brcmfmac and bcma use more specific ID entry with --subvendor and subdevice specified. -- --Signed-off-by: RafaÅ‚ MiÅ‚ecki --Signed-off-by: Kalle Valo ----- -- ----- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c --+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c --@@ -1951,6 +1951,9 @@ static const struct dev_pm_ops brcmf_pci -- -- #define BRCMF_PCIE_DEVICE(dev_id) { BRCM_PCIE_VENDOR_ID_BROADCOM, dev_id,\ -- PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_NETWORK_OTHER << 8, 0xffff00, 0 } --+#define BRCMF_PCIE_DEVICE_SUB(dev_id, subvend, subdev) { \ --+ BRCM_PCIE_VENDOR_ID_BROADCOM, dev_id,\ --+ subvend, subdev, PCI_CLASS_NETWORK_OTHER << 8, 0xffff00, 0 } -- -- static struct pci_device_id brcmf_pcie_devid_table[] = { -- BRCMF_PCIE_DEVICE(BRCM_PCIE_4350_DEVICE_ID), --@@ -1966,6 +1969,7 @@ static struct pci_device_id brcmf_pcie_d -- BRCMF_PCIE_DEVICE(BRCM_PCIE_4365_DEVICE_ID), -- BRCMF_PCIE_DEVICE(BRCM_PCIE_4365_2G_DEVICE_ID), -- BRCMF_PCIE_DEVICE(BRCM_PCIE_4365_5G_DEVICE_ID), --+ BRCMF_PCIE_DEVICE_SUB(0x4365, BRCM_PCIE_VENDOR_ID_BROADCOM, 0x4365), -- BRCMF_PCIE_DEVICE(BRCM_PCIE_4366_DEVICE_ID), -- BRCMF_PCIE_DEVICE(BRCM_PCIE_4366_2G_DEVICE_ID), -- BRCMF_PCIE_DEVICE(BRCM_PCIE_4366_5G_DEVICE_ID), -diff --git a/package/kernel/mac80211/patches/323-ath9k-Fix-programming-of-minCCA-power-threshold.patch b/package/kernel/mac80211/patches/323-ath9k-Fix-programming-of-minCCA-power-threshold.patch -new file mode 100644 -index 0000000..59ac29b ---- /dev/null -+++ b/package/kernel/mac80211/patches/323-ath9k-Fix-programming-of-minCCA-power-threshold.patch -@@ -0,0 +1,26 @@ -+From: Sven Eckelmann -+Date: Fri, 17 Jun 2016 11:58:20 +0200 -+Subject: [PATCH] ath9k: Fix programming of minCCA power threshold -+ -+The function ar9003_hw_apply_minccapwr_thresh takes as second parameter not -+a pointer to the channel but a boolean value describing whether the channel -+is 2.4GHz or not. This broke (according to the origin commit) the ETSI -+regulatory compliance on 5GHz channels. -+ -+Fixes: 3533bf6b15a0 ("ath9k: Fix regulatory compliance") -+Signed-off-by: Sven Eckelmann -+Cc: Simon Wunderlich -+Cc: Sujith Manoharan -+--- -+ -+--- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c -++++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c -+@@ -4175,7 +4175,7 @@ static void ath9k_hw_ar9300_set_board_va -+ if (!AR_SREV_9330(ah) && !AR_SREV_9340(ah) && !AR_SREV_9531(ah)) -+ ar9003_hw_internal_regulator_apply(ah); -+ ar9003_hw_apply_tuning_caps(ah); -+- ar9003_hw_apply_minccapwr_thresh(ah, chan); -++ ar9003_hw_apply_minccapwr_thresh(ah, is2ghz); -+ ar9003_hw_txend_to_xpa_off_apply(ah, is2ghz); -+ ar9003_hw_thermometer_apply(ah); -+ ar9003_hw_thermo_cal_apply(ah); -diff --git a/package/kernel/mac80211/patches/324-ath9k_hw-fix-spectral-scan-on-AR9285-and-newer.patch b/package/kernel/mac80211/patches/324-ath9k_hw-fix-spectral-scan-on-AR9285-and-newer.patch -new file mode 100644 -index 0000000..b6f4868 ---- /dev/null -+++ b/package/kernel/mac80211/patches/324-ath9k_hw-fix-spectral-scan-on-AR9285-and-newer.patch -@@ -0,0 +1,86 @@ -+From: Felix Fietkau -+Date: Mon, 11 Jul 2016 10:34:37 +0200 -+Subject: [PATCH] ath9k_hw: fix spectral scan on AR9285 and newer -+ -+The register layout of AR_PHY_SPECTRAL_SCAN has changed, only AR9280 -+uses the old layout -+ -+Signed-off-by: Felix Fietkau -+--- -+ -+--- a/drivers/net/wireless/ath/ath9k/ar9002_phy.c -++++ b/drivers/net/wireless/ath/ath9k/ar9002_phy.c -+@@ -476,6 +476,7 @@ static void ar9002_hw_set_bt_ant_diversi -+ static void ar9002_hw_spectral_scan_config(struct ath_hw *ah, -+ struct ath_spec_scan *param) -+ { -++ u32 repeat_bit; -+ u8 count; -+ -+ if (!param->enabled) { -+@@ -486,12 +487,15 @@ static void ar9002_hw_spectral_scan_conf -+ REG_SET_BIT(ah, AR_PHY_RADAR_0, AR_PHY_RADAR_0_FFT_ENA); -+ REG_SET_BIT(ah, AR_PHY_SPECTRAL_SCAN, AR_PHY_SPECTRAL_SCAN_ENABLE); -+ -++ if (AR_SREV_9280(ah)) -++ repeat_bit = AR_PHY_SPECTRAL_SCAN_SHORT_REPEAT; -++ else -++ repeat_bit = AR_PHY_SPECTRAL_SCAN_SHORT_REPEAT_KIWI; -++ -+ if (param->short_repeat) -+- REG_SET_BIT(ah, AR_PHY_SPECTRAL_SCAN, -+- AR_PHY_SPECTRAL_SCAN_SHORT_REPEAT); -++ REG_SET_BIT(ah, AR_PHY_SPECTRAL_SCAN, repeat_bit); -+ else -+- REG_CLR_BIT(ah, AR_PHY_SPECTRAL_SCAN, -+- AR_PHY_SPECTRAL_SCAN_SHORT_REPEAT); -++ REG_CLR_BIT(ah, AR_PHY_SPECTRAL_SCAN, repeat_bit); -+ -+ /* on AR92xx, the highest bit of count will make the the chip send -+ * spectral samples endlessly. Check if this really was intended, -+@@ -499,15 +503,25 @@ static void ar9002_hw_spectral_scan_conf -+ */ -+ count = param->count; -+ if (param->endless) { -+- if (AR_SREV_9271(ah)) -+- count = 0; -+- else -++ if (AR_SREV_9280(ah)) -+ count = 0x80; -++ else -++ count = 0; -+ } else if (count & 0x80) -+ count = 0x7f; -++ else if (!count) -++ count = 1; -++ -++ if (AR_SREV_9280(ah)) { -++ REG_RMW_FIELD(ah, AR_PHY_SPECTRAL_SCAN, -++ AR_PHY_SPECTRAL_SCAN_COUNT, count); -++ } else { -++ REG_RMW_FIELD(ah, AR_PHY_SPECTRAL_SCAN, -++ AR_PHY_SPECTRAL_SCAN_COUNT_KIWI, count); -++ REG_SET_BIT(ah, AR_PHY_SPECTRAL_SCAN, -++ AR_PHY_SPECTRAL_SCAN_PHYERR_MASK_SELECT); -++ } -+ -+- REG_RMW_FIELD(ah, AR_PHY_SPECTRAL_SCAN, -+- AR_PHY_SPECTRAL_SCAN_COUNT, count); -+ REG_RMW_FIELD(ah, AR_PHY_SPECTRAL_SCAN, -+ AR_PHY_SPECTRAL_SCAN_PERIOD, param->period); -+ REG_RMW_FIELD(ah, AR_PHY_SPECTRAL_SCAN, -+--- a/drivers/net/wireless/ath/ath9k/ar9002_phy.h -++++ b/drivers/net/wireless/ath/ath9k/ar9002_phy.h -+@@ -177,8 +177,11 @@ -+ #define AR_PHY_SPECTRAL_SCAN_PERIOD_S 8 -+ #define AR_PHY_SPECTRAL_SCAN_COUNT 0x00FF0000 /* Number of reports, reg 68, bits 16-23*/ -+ #define AR_PHY_SPECTRAL_SCAN_COUNT_S 16 -++#define AR_PHY_SPECTRAL_SCAN_COUNT_KIWI 0x0FFF0000 /* Number of reports, reg 68, bits 16-27*/ -++#define AR_PHY_SPECTRAL_SCAN_COUNT_KIWI_S 16 -+ #define AR_PHY_SPECTRAL_SCAN_SHORT_REPEAT 0x01000000 /* Short repeat, reg 68, bit 24*/ -+-#define AR_PHY_SPECTRAL_SCAN_SHORT_REPEAT_S 24 /* Short repeat, reg 68, bit 24*/ -++#define AR_PHY_SPECTRAL_SCAN_SHORT_REPEAT_KIWI 0x10000000 /* Short repeat, reg 68, bit 28*/ -++#define AR_PHY_SPECTRAL_SCAN_PHYERR_MASK_SELECT 0x40000000 -+ -+ #define AR_PHY_RX_DELAY 0x9914 -+ #define AR_PHY_SEARCH_START_DELAY 0x9918 -diff --git a/package/kernel/mac80211/patches/324-brcmfmac-treat-NULL-character-in-NVRAM-as-separator.patch b/package/kernel/mac80211/patches/324-brcmfmac-treat-NULL-character-in-NVRAM-as-separator.patch -deleted file mode 100644 -index 6ce60f1..0000000 ---- a/package/kernel/mac80211/patches/324-brcmfmac-treat-NULL-character-in-NVRAM-as-separator.patch -+++ /dev/null -@@ -1,32 +0,0 @@ --From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= --Date: Sun, 31 Jan 2016 12:14:34 +0100 --Subject: [PATCH] brcmfmac: treat NULL character in NVRAM as separator --MIME-Version: 1.0 --Content-Type: text/plain; charset=UTF-8 --Content-Transfer-Encoding: 8bit -- --Platform NVRAM (stored on a flash partition) has entries separated by a --NULL (\0) char. Our parsing code switches from VALUE state to IDLE --whenever it meets a NULL (\0). When that happens our IDLE handler should --simply consume it and analyze whatever is placed ahead. -- --This fixes harmless warnings spamming debugging output: --[ 155.165624] brcmfmac: brcmf_nvram_handle_idle warning: ln=1:col=20: ignoring invalid character --[ 155.180806] brcmfmac: brcmf_nvram_handle_idle warning: ln=1:col=44: ignoring invalid character --[ 155.195971] brcmfmac: brcmf_nvram_handle_idle warning: ln=1:col=63: ignoring invalid character -- --Signed-off-by: RafaÅ‚ MiÅ‚ecki --Signed-off-by: Kalle Valo ----- -- ----- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c --+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c --@@ -93,7 +93,7 @@ static enum nvram_parser_state brcmf_nvr -- c = nvp->data[nvp->pos]; -- if (c == '\n') -- return COMMENT; --- if (is_whitespace(c)) --+ if (is_whitespace(c) || c == '\0') -- goto proceed; -- if (c == '#') -- return COMMENT; -diff --git a/package/kernel/mac80211/patches/325-ath9k_hw-fix-duplicate-and-partially-wrong-definitio.patch b/package/kernel/mac80211/patches/325-ath9k_hw-fix-duplicate-and-partially-wrong-definitio.patch -new file mode 100644 -index 0000000..6685f33 ---- /dev/null -+++ b/package/kernel/mac80211/patches/325-ath9k_hw-fix-duplicate-and-partially-wrong-definitio.patch -@@ -0,0 +1,57 @@ -+From: Felix Fietkau -+Date: Mon, 11 Jul 2016 11:31:39 +0200 -+Subject: [PATCH] ath9k_hw: fix duplicate (and partially wrong) definition -+ of AR_CH0_THERM -+ -+AR_PHY_65NM_CH0_THERM and AR_CH0_THERM were supposed to refer to the -+same register, however they had different SREV checks. -+ -+Remove the duplicate and use the checks. Since there were other SREV -+checks present in the only place that uses this, this will probaby not -+affect runtime behavior. -+ -+Signed-off-by: Felix Fietkau -+--- -+ -+--- a/drivers/net/wireless/ath/ath9k/ar9003_phy.h -++++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.h -+@@ -689,13 +689,6 @@ -+ #define AR_CH0_TOP_XPABIASLVL (AR_SREV_9550(ah) ? 0x3c0 : 0x300) -+ #define AR_CH0_TOP_XPABIASLVL_S (AR_SREV_9550(ah) ? 6 : 8) -+ -+-#define AR_CH0_THERM (AR_SREV_9300(ah) ? 0x16290 : \ -+- ((AR_SREV_9485(ah) ? 0x1628c : 0x16294))) -+-#define AR_CH0_THERM_XPABIASLVL_MSB 0x3 -+-#define AR_CH0_THERM_XPABIASLVL_MSB_S 0 -+-#define AR_CH0_THERM_XPASHORT2GND 0x4 -+-#define AR_CH0_THERM_XPASHORT2GND_S 2 -+- -+ #define AR_SWITCH_TABLE_COM_ALL (0xffff) -+ #define AR_SWITCH_TABLE_COM_ALL_S (0) -+ #define AR_SWITCH_TABLE_COM_AR9462_ALL (0xffffff) -+@@ -712,15 +705,17 @@ -+ #define AR_SWITCH_TABLE_ALL (0xfff) -+ #define AR_SWITCH_TABLE_ALL_S (0) -+ -+-#define AR_PHY_65NM_CH0_THERM (AR_SREV_9300(ah) ? 0x16290 :\ -+- ((AR_SREV_9462(ah) || AR_SREV_9565(ah)) ? 0x16294 : 0x1628c)) -++#define AR_CH0_THERM (AR_SREV_9300(ah) ? 0x16290 :\ -++ ((AR_SREV_9462(ah) || AR_SREV_9565(ah)) ? 0x16294 : 0x1628c)) -++#define AR_CH0_THERM_XPABIASLVL_MSB 0x3 -++#define AR_CH0_THERM_XPABIASLVL_MSB_S 0 -++#define AR_CH0_THERM_XPASHORT2GND 0x4 -++#define AR_CH0_THERM_XPASHORT2GND_S 2 -+ -+-#define AR_PHY_65NM_CH0_THERM_LOCAL 0x80000000 -+-#define AR_PHY_65NM_CH0_THERM_LOCAL_S 31 -+-#define AR_PHY_65NM_CH0_THERM_START 0x20000000 -+-#define AR_PHY_65NM_CH0_THERM_START_S 29 -+-#define AR_PHY_65NM_CH0_THERM_SAR_ADC_OUT 0x0000ff00 -+-#define AR_PHY_65NM_CH0_THERM_SAR_ADC_OUT_S 8 -++#define AR_CH0_THERM_LOCAL 0x80000000 -++#define AR_CH0_THERM_START 0x20000000 -++#define AR_CH0_THERM_SAR_ADC_OUT 0x0000ff00 -++#define AR_CH0_THERM_SAR_ADC_OUT_S 8 -+ -+ #define AR_CH0_TOP2 (AR_SREV_9300(ah) ? 0x1628c : \ -+ (AR_SREV_9462(ah) ? 0x16290 : 0x16284)) -diff --git a/package/kernel/mac80211/patches/325-brcmfmac-sdio-Increase-the-default-timeouts-a-bit.patch b/package/kernel/mac80211/patches/325-brcmfmac-sdio-Increase-the-default-timeouts-a-bit.patch -deleted file mode 100644 -index 012dea1..0000000 ---- a/package/kernel/mac80211/patches/325-brcmfmac-sdio-Increase-the-default-timeouts-a-bit.patch -+++ /dev/null -@@ -1,41 +0,0 @@ --From: Sjoerd Simons --Date: Mon, 25 Jan 2016 11:47:29 +0100 --Subject: [PATCH] brcmfmac: sdio: Increase the default timeouts a bit -- --On a Radxa Rock2 board with a Ampak AP6335 (Broadcom 4339 core) it seems --the card responds very quickly most of the time, unfortunately during --initialisation it sometimes seems to take just a bit over 2 seconds to --respond. -- --This results intialization failing with message like: -- brcmf_c_preinit_dcmds: Retreiving cur_etheraddr failed, -52 -- brcmf_bus_start: failed: -52 -- brcmf_sdio_firmware_callback: dongle is not responding -- --Increasing the timeout to allow for a bit more headroom allows the --card to initialize reliably. -- --A quick search online after diagnosing/fixing this showed that Google --has a similar patch in their ChromeOS tree, so this doesn't seem --specific to the board I'm using. -- --Signed-off-by: Sjoerd Simons --Reviewed-by: Julian Calaby --Acked-by: Arend van Spriel --Reviewed-by: Douglas Anderson --Signed-off-by: Kalle Valo ----- -- ----- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c --+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c --@@ -45,8 +45,8 @@ -- #include "chip.h" -- #include "firmware.h" -- ---#define DCMD_RESP_TIMEOUT msecs_to_jiffies(2000) ---#define CTL_DONE_TIMEOUT msecs_to_jiffies(2000) --+#define DCMD_RESP_TIMEOUT msecs_to_jiffies(2500) --+#define CTL_DONE_TIMEOUT msecs_to_jiffies(2500) -- -- #ifdef DEBUG -- -diff --git a/package/kernel/mac80211/patches/326-ath9k-make-NF-load-complete-quickly-and-reliably.patch b/package/kernel/mac80211/patches/326-ath9k-make-NF-load-complete-quickly-and-reliably.patch -deleted file mode 100644 -index 71f7a40..0000000 ---- a/package/kernel/mac80211/patches/326-ath9k-make-NF-load-complete-quickly-and-reliably.patch -+++ /dev/null -@@ -1,87 +0,0 @@ --From: Miaoqing Pan --Date: Fri, 5 Feb 2016 09:45:50 +0800 --Subject: [PATCH] ath9k: make NF load complete quickly and reliably -- --Make NF load complete quickly and reliably. NF load execution --is delayed by HW to end of frame if frame Rx or Tx is ongoing. --Increasing timeout to max frame duration. If NF cal is ongoing --before NF load, stop it before load, and restart it afterwards. -- --Signed-off-by: Miaoqing Pan ----- -- ----- a/drivers/net/wireless/ath/ath9k/calib.c --+++ b/drivers/net/wireless/ath/ath9k/calib.c --@@ -241,6 +241,7 @@ int ath9k_hw_loadnf(struct ath_hw *ah, s -- u8 chainmask = (ah->rxchainmask << 3) | ah->rxchainmask; -- struct ath_common *common = ath9k_hw_common(ah); -- s16 default_nf = ath9k_hw_get_default_nf(ah, chan); --+ u32 bb_agc_ctl = REG_READ(ah, AR_PHY_AGC_CONTROL); -- -- if (ah->caldata) -- h = ah->caldata->nfCalHist; --@@ -264,6 +265,16 @@ int ath9k_hw_loadnf(struct ath_hw *ah, s -- } -- -- /* --+ * stop NF cal if ongoing to ensure NF load completes immediately --+ * (or after end rx/tx frame if ongoing) --+ */ --+ if (bb_agc_ctl & AR_PHY_AGC_CONTROL_NF) { --+ REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_NF); --+ REG_RMW_BUFFER_FLUSH(ah); --+ ENABLE_REG_RMW_BUFFER(ah); --+ } --+ --+ /* -- * Load software filtered NF value into baseband internal minCCApwr -- * variable. -- */ --@@ -276,18 +287,33 @@ int ath9k_hw_loadnf(struct ath_hw *ah, s -- -- /* -- * Wait for load to complete, should be fast, a few 10s of us. --- * The max delay was changed from an original 250us to 10000us --- * since 250us often results in NF load timeout and causes deaf --- * condition during stress testing 12/12/2009 --+ * The max delay was changed from an original 250us to 22.2 msec. --+ * This would increase timeout to the longest possible frame --+ * (11n max length 22.1 msec) -- */ --- for (j = 0; j < 10000; j++) { --+ for (j = 0; j < 22200; j++) { -- if ((REG_READ(ah, AR_PHY_AGC_CONTROL) & --- AR_PHY_AGC_CONTROL_NF) == 0) --+ AR_PHY_AGC_CONTROL_NF) == 0) -- break; -- udelay(10); -- } -- -- /* --+ * Restart NF so it can continue. --+ */ --+ if (bb_agc_ctl & AR_PHY_AGC_CONTROL_NF) { --+ ENABLE_REG_RMW_BUFFER(ah); --+ if (bb_agc_ctl & AR_PHY_AGC_CONTROL_ENABLE_NF) --+ REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, --+ AR_PHY_AGC_CONTROL_ENABLE_NF); --+ if (bb_agc_ctl & AR_PHY_AGC_CONTROL_NO_UPDATE_NF) --+ REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, --+ AR_PHY_AGC_CONTROL_NO_UPDATE_NF); --+ REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_NF); --+ REG_RMW_BUFFER_FLUSH(ah); --+ } --+ --+ /* -- * We timed out waiting for the noisefloor to load, probably due to an -- * in-progress rx. Simply return here and allow the load plenty of time -- * to complete before the next calibration interval. We need to avoid --@@ -296,7 +322,7 @@ int ath9k_hw_loadnf(struct ath_hw *ah, s -- * here, the baseband nf cal will just be capped by our present -- * noisefloor until the next calibration timer. -- */ --- if (j == 10000) { --+ if (j == 22200) { -- ath_dbg(common, ANY, -- "Timeout while waiting for nf to load: AR_PHY_AGC_CONTROL=0x%x\n", -- REG_READ(ah, AR_PHY_AGC_CONTROL)); -diff --git a/package/kernel/mac80211/patches/326-ath9k_hw-simplify-ar9003_hw_per_calibration.patch b/package/kernel/mac80211/patches/326-ath9k_hw-simplify-ar9003_hw_per_calibration.patch -new file mode 100644 -index 0000000..999d993 ---- /dev/null -+++ b/package/kernel/mac80211/patches/326-ath9k_hw-simplify-ar9003_hw_per_calibration.patch -@@ -0,0 +1,88 @@ -+From: Felix Fietkau -+Date: Mon, 11 Jul 2016 11:34:47 +0200 -+Subject: [PATCH] ath9k_hw: simplify ar9003_hw_per_calibration -+ -+Reduce indentation, use a variable to save a few pointer dereferences -+ -+Signed-off-by: Felix Fietkau -+--- -+ -+--- a/drivers/net/wireless/ath/ath9k/ar9003_calib.c -++++ b/drivers/net/wireless/ath/ath9k/ar9003_calib.c -+@@ -75,50 +75,49 @@ static bool ar9003_hw_per_calibration(st -+ struct ath9k_cal_list *currCal) -+ { -+ struct ath9k_hw_cal_data *caldata = ah->caldata; -+- /* Cal is assumed not done until explicitly set below */ -+- bool iscaldone = false; -++ const struct ath9k_percal_data *cur_caldata = currCal->calData; -+ -+ /* Calibration in progress. */ -+ if (currCal->calState == CAL_RUNNING) { -+ /* Check to see if it has finished. */ -+- if (!(REG_READ(ah, AR_PHY_TIMING4) & AR_PHY_TIMING4_DO_CAL)) { -+- /* -+- * Accumulate cal measures for active chains -+- */ -+- currCal->calData->calCollect(ah); -+- ah->cal_samples++; -++ if (REG_READ(ah, AR_PHY_TIMING4) & AR_PHY_TIMING4_DO_CAL) -++ return false; -+ -+- if (ah->cal_samples >= -+- currCal->calData->calNumSamples) { -+- unsigned int i, numChains = 0; -+- for (i = 0; i < AR9300_MAX_CHAINS; i++) { -+- if (rxchainmask & (1 << i)) -+- numChains++; -+- } -++ /* -++ * Accumulate cal measures for active chains -++ */ -++ cur_caldata->calCollect(ah); -++ ah->cal_samples++; -+ -+- /* -+- * Process accumulated data -+- */ -+- currCal->calData->calPostProc(ah, numChains); -++ if (ah->cal_samples >= cur_caldata->calNumSamples) { -++ unsigned int i, numChains = 0; -++ for (i = 0; i < AR9300_MAX_CHAINS; i++) { -++ if (rxchainmask & (1 << i)) -++ numChains++; -++ } -+ -+- /* Calibration has finished. */ -+- caldata->CalValid |= currCal->calData->calType; -+- currCal->calState = CAL_DONE; -+- iscaldone = true; -+- } else { -++ /* -++ * Process accumulated data -++ */ -++ cur_caldata->calPostProc(ah, numChains); -++ -++ /* Calibration has finished. */ -++ caldata->CalValid |= cur_caldata->calType; -++ currCal->calState = CAL_DONE; -++ return true; -++ } else { -+ /* -+ * Set-up collection of another sub-sample until we -+ * get desired number -+ */ -+ ar9003_hw_setup_calibration(ah, currCal); -+- } -+ } -+- } else if (!(caldata->CalValid & currCal->calData->calType)) { -++ } else if (!(caldata->CalValid & cur_caldata->calType)) { -+ /* If current cal is marked invalid in channel, kick it off */ -+ ath9k_hw_reset_calibration(ah, currCal); -+ } -+ -+- return iscaldone; -++ return false; -+ } -+ -+ static int ar9003_hw_calibrate(struct ath_hw *ah, struct ath9k_channel *chan, -diff --git a/package/kernel/mac80211/patches/327-ath9k_hw-get-rid-of-some-duplicate-code-in-calibrati.patch b/package/kernel/mac80211/patches/327-ath9k_hw-get-rid-of-some-duplicate-code-in-calibrati.patch -new file mode 100644 -index 0000000..b7f3823 ---- /dev/null -+++ b/package/kernel/mac80211/patches/327-ath9k_hw-get-rid-of-some-duplicate-code-in-calibrati.patch -@@ -0,0 +1,94 @@ -+From: Felix Fietkau -+Date: Mon, 11 Jul 2016 11:35:20 +0200 -+Subject: [PATCH] ath9k_hw: get rid of some duplicate code in calibration -+ init -+ -+Remove a misleading debug message as well -+ -+Signed-off-by: Felix Fietkau -+--- -+ -+--- a/drivers/net/wireless/ath/ath9k/ar9003_calib.c -++++ b/drivers/net/wireless/ath/ath9k/ar9003_calib.c -+@@ -1373,6 +1373,26 @@ static void ar9003_hw_cl_cal_post_proc(s -+ } -+ } -+ -++static void ar9003_hw_init_cal_common(struct ath_hw *ah) -++{ -++ struct ath9k_hw_cal_data *caldata = ah->caldata; -++ -++ /* Initialize list pointers */ -++ ah->cal_list = ah->cal_list_last = ah->cal_list_curr = NULL; -++ -++ INIT_CAL(&ah->iq_caldata); -++ INSERT_CAL(ah, &ah->iq_caldata); -++ -++ /* Initialize current pointer to first element in list */ -++ ah->cal_list_curr = ah->cal_list; -++ -++ if (ah->cal_list_curr) -++ ath9k_hw_reset_calibration(ah, ah->cal_list_curr); -++ -++ if (caldata) -++ caldata->CalValid = 0; -++} -++ -+ static bool ar9003_hw_init_cal_pcoem(struct ath_hw *ah, -+ struct ath9k_channel *chan) -+ { -+@@ -1532,21 +1552,7 @@ skip_tx_iqcal: -+ /* Revert chainmask to runtime parameters */ -+ ar9003_hw_set_chain_masks(ah, ah->rxchainmask, ah->txchainmask); -+ -+- /* Initialize list pointers */ -+- ah->cal_list = ah->cal_list_last = ah->cal_list_curr = NULL; -+- -+- INIT_CAL(&ah->iq_caldata); -+- INSERT_CAL(ah, &ah->iq_caldata); -+- ath_dbg(common, CALIBRATE, "enabling IQ Calibration\n"); -+- -+- /* Initialize current pointer to first element in list */ -+- ah->cal_list_curr = ah->cal_list; -+- -+- if (ah->cal_list_curr) -+- ath9k_hw_reset_calibration(ah, ah->cal_list_curr); -+- -+- if (caldata) -+- caldata->CalValid = 0; -++ ar9003_hw_init_cal_common(ah); -+ -+ return true; -+ } -+@@ -1577,8 +1583,6 @@ static bool do_ar9003_agc_cal(struct ath -+ static bool ar9003_hw_init_cal_soc(struct ath_hw *ah, -+ struct ath9k_channel *chan) -+ { -+- struct ath_common *common = ath9k_hw_common(ah); -+- struct ath9k_hw_cal_data *caldata = ah->caldata; -+ bool txiqcal_done = false; -+ bool status = true; -+ bool run_agc_cal = false, sep_iq_cal = false; -+@@ -1676,21 +1680,7 @@ skip_tx_iqcal: -+ /* Revert chainmask to runtime parameters */ -+ ar9003_hw_set_chain_masks(ah, ah->rxchainmask, ah->txchainmask); -+ -+- /* Initialize list pointers */ -+- ah->cal_list = ah->cal_list_last = ah->cal_list_curr = NULL; -+- -+- INIT_CAL(&ah->iq_caldata); -+- INSERT_CAL(ah, &ah->iq_caldata); -+- ath_dbg(common, CALIBRATE, "enabling IQ Calibration\n"); -+- -+- /* Initialize current pointer to first element in list */ -+- ah->cal_list_curr = ah->cal_list; -+- -+- if (ah->cal_list_curr) -+- ath9k_hw_reset_calibration(ah, ah->cal_list_curr); -+- -+- if (caldata) -+- caldata->CalValid = 0; -++ ar9003_hw_init_cal_common(ah); -+ -+ return true; -+ } -diff --git a/package/kernel/mac80211/patches/327-mac80211-Remove-MPP-table-entries-with-MPath.patch b/package/kernel/mac80211/patches/327-mac80211-Remove-MPP-table-entries-with-MPath.patch -deleted file mode 100644 -index f7f9df9..0000000 ---- a/package/kernel/mac80211/patches/327-mac80211-Remove-MPP-table-entries-with-MPath.patch -+++ /dev/null -@@ -1,54 +0,0 @@ --From: Henning Rogge --Date: Wed, 3 Feb 2016 13:58:36 +0100 --Subject: [PATCH] mac80211: Remove MPP table entries with MPath -- --Make the mesh_path_del() function remove all mpp table entries --that are proxied by the removed mesh path. -- --Acked-by: Bob Copeland --Signed-off-by: Henning Rogge --Signed-off-by: Johannes Berg ----- -- ----- a/net/mac80211/mesh_pathtbl.c --+++ b/net/mac80211/mesh_pathtbl.c --@@ -835,6 +835,29 @@ void mesh_path_flush_by_nexthop(struct s -- rcu_read_unlock(); -- } -- --+static void mpp_flush_by_proxy(struct ieee80211_sub_if_data *sdata, --+ const u8 *proxy) --+{ --+ struct mesh_table *tbl; --+ struct mesh_path *mpp; --+ struct mpath_node *node; --+ int i; --+ --+ rcu_read_lock(); --+ read_lock_bh(&pathtbl_resize_lock); --+ tbl = resize_dereference_mpp_paths(); --+ for_each_mesh_entry(tbl, node, i) { --+ mpp = node->mpath; --+ if (ether_addr_equal(mpp->mpp, proxy)) { --+ spin_lock(&tbl->hashwlock[i]); --+ __mesh_path_del(tbl, node); --+ spin_unlock(&tbl->hashwlock[i]); --+ } --+ } --+ read_unlock_bh(&pathtbl_resize_lock); --+ rcu_read_unlock(); --+} --+ -- static void table_flush_by_iface(struct mesh_table *tbl, -- struct ieee80211_sub_if_data *sdata) -- { --@@ -892,6 +915,9 @@ int mesh_path_del(struct ieee80211_sub_i -- int hash_idx; -- int err = 0; -- --+ /* flush relevant mpp entries first */ --+ mpp_flush_by_proxy(sdata, addr); --+ -- read_lock_bh(&pathtbl_resize_lock); -- tbl = resize_dereference_mesh_paths(); -- hash_idx = mesh_table_hash(addr, sdata, tbl); -diff --git a/package/kernel/mac80211/patches/328-ath9k_hw-implement-temperature-compensation-support-.patch b/package/kernel/mac80211/patches/328-ath9k_hw-implement-temperature-compensation-support-.patch -new file mode 100644 -index 0000000..cff32ad ---- /dev/null -+++ b/package/kernel/mac80211/patches/328-ath9k_hw-implement-temperature-compensation-support-.patch -@@ -0,0 +1,97 @@ -+From: Felix Fietkau -+Date: Mon, 11 Jul 2016 11:35:55 +0200 -+Subject: [PATCH] ath9k_hw: implement temperature compensation support for -+ AR9003+ -+ -+Signed-off-by: Felix Fietkau -+--- -+ -+--- a/drivers/net/wireless/ath/ath9k/ar9003_calib.c -++++ b/drivers/net/wireless/ath/ath9k/ar9003_calib.c -+@@ -33,6 +33,7 @@ struct coeff { -+ -+ enum ar9003_cal_types { -+ IQ_MISMATCH_CAL = BIT(0), -++ TEMP_COMP_CAL = BIT(1), -+ }; -+ -+ static void ar9003_hw_setup_calibration(struct ath_hw *ah, -+@@ -58,6 +59,12 @@ static void ar9003_hw_setup_calibration( -+ /* Kick-off cal */ -+ REG_SET_BIT(ah, AR_PHY_TIMING4, AR_PHY_TIMING4_DO_CAL); -+ break; -++ case TEMP_COMP_CAL: -++ ath_dbg(common, CALIBRATE, -++ "starting Temperature Compensation Calibration\n"); -++ REG_SET_BIT(ah, AR_CH0_THERM, AR_CH0_THERM_LOCAL); -++ REG_SET_BIT(ah, AR_CH0_THERM, AR_CH0_THERM_START); -++ break; -+ default: -+ ath_err(common, "Invalid calibration type\n"); -+ break; -+@@ -86,7 +93,8 @@ static bool ar9003_hw_per_calibration(st -+ /* -+ * Accumulate cal measures for active chains -+ */ -+- cur_caldata->calCollect(ah); -++ if (cur_caldata->calCollect) -++ cur_caldata->calCollect(ah); -+ ah->cal_samples++; -+ -+ if (ah->cal_samples >= cur_caldata->calNumSamples) { -+@@ -99,7 +107,8 @@ static bool ar9003_hw_per_calibration(st -+ /* -+ * Process accumulated data -+ */ -+- cur_caldata->calPostProc(ah, numChains); -++ if (cur_caldata->calPostProc) -++ cur_caldata->calPostProc(ah, numChains); -+ -+ /* Calibration has finished. */ -+ caldata->CalValid |= cur_caldata->calType; -+@@ -314,9 +323,16 @@ static const struct ath9k_percal_data iq -+ ar9003_hw_iqcalibrate -+ }; -+ -++static const struct ath9k_percal_data temp_cal_single_sample = { -++ TEMP_COMP_CAL, -++ MIN_CAL_SAMPLES, -++ PER_MAX_LOG_COUNT, -++}; -++ -+ static void ar9003_hw_init_cal_settings(struct ath_hw *ah) -+ { -+ ah->iq_caldata.calData = &iq_cal_single_sample; -++ ah->temp_caldata.calData = &temp_cal_single_sample; -+ -+ if (AR_SREV_9300_20_OR_LATER(ah)) { -+ ah->enabled_cals |= TX_IQ_CAL; -+@@ -324,7 +340,7 @@ static void ar9003_hw_init_cal_settings( -+ ah->enabled_cals |= TX_IQ_ON_AGC_CAL; -+ } -+ -+- ah->supp_cals = IQ_MISMATCH_CAL; -++ ah->supp_cals = IQ_MISMATCH_CAL | TEMP_COMP_CAL; -+ } -+ -+ #define OFF_UPPER_LT 24 -+@@ -1383,6 +1399,9 @@ static void ar9003_hw_init_cal_common(st -+ INIT_CAL(&ah->iq_caldata); -+ INSERT_CAL(ah, &ah->iq_caldata); -+ -++ INIT_CAL(&ah->temp_caldata); -++ INSERT_CAL(ah, &ah->temp_caldata); -++ -+ /* Initialize current pointer to first element in list */ -+ ah->cal_list_curr = ah->cal_list; -+ -+--- a/drivers/net/wireless/ath/ath9k/hw.h -++++ b/drivers/net/wireless/ath/ath9k/hw.h -+@@ -830,6 +830,7 @@ struct ath_hw { -+ /* Calibration */ -+ u32 supp_cals; -+ struct ath9k_cal_list iq_caldata; -++ struct ath9k_cal_list temp_caldata; -+ struct ath9k_cal_list adcgain_caldata; -+ struct ath9k_cal_list adcdc_caldata; -+ struct ath9k_cal_list *cal_list; -diff --git a/package/kernel/mac80211/patches/328-mac80211-let-unused-MPP-table-entries-timeout.patch b/package/kernel/mac80211/patches/328-mac80211-let-unused-MPP-table-entries-timeout.patch -deleted file mode 100644 -index 740993c..0000000 ---- a/package/kernel/mac80211/patches/328-mac80211-let-unused-MPP-table-entries-timeout.patch -+++ /dev/null -@@ -1,104 +0,0 @@ --From: Henning Rogge --Date: Wed, 3 Feb 2016 13:58:37 +0100 --Subject: [PATCH] mac80211: let unused MPP table entries timeout -- --Remember the last time when a mpp table entry is used for --rx or tx and remove them after MESH_PATH_EXPIRE time. -- --Acked-by: Bob Copeland --Signed-off-by: Henning Rogge --Signed-off-by: Johannes Berg ----- -- ----- a/net/mac80211/mesh_pathtbl.c --+++ b/net/mac80211/mesh_pathtbl.c --@@ -942,6 +942,46 @@ enddel: -- } -- -- /** --+ * mpp_path_del - delete a mesh proxy path from the table --+ * --+ * @addr: addr address (ETH_ALEN length) --+ * @sdata: local subif --+ * --+ * Returns: 0 if successful --+ */ --+static int mpp_path_del(struct ieee80211_sub_if_data *sdata, const u8 *addr) --+{ --+ struct mesh_table *tbl; --+ struct mesh_path *mpath; --+ struct mpath_node *node; --+ struct hlist_head *bucket; --+ int hash_idx; --+ int err = 0; --+ --+ read_lock_bh(&pathtbl_resize_lock); --+ tbl = resize_dereference_mpp_paths(); --+ hash_idx = mesh_table_hash(addr, sdata, tbl); --+ bucket = &tbl->hash_buckets[hash_idx]; --+ --+ spin_lock(&tbl->hashwlock[hash_idx]); --+ hlist_for_each_entry(node, bucket, list) { --+ mpath = node->mpath; --+ if (mpath->sdata == sdata && --+ ether_addr_equal(addr, mpath->dst)) { --+ __mesh_path_del(tbl, node); --+ goto enddel; --+ } --+ } --+ --+ err = -ENXIO; --+enddel: --+ mesh_paths_generation++; --+ spin_unlock(&tbl->hashwlock[hash_idx]); --+ read_unlock_bh(&pathtbl_resize_lock); --+ return err; --+} --+ --+/** -- * mesh_path_tx_pending - sends pending frames in a mesh path queue -- * -- * @mpath: mesh path to activate --@@ -1157,6 +1197,17 @@ void mesh_path_expire(struct ieee80211_s -- time_after(jiffies, mpath->exp_time + MESH_PATH_EXPIRE)) -- mesh_path_del(mpath->sdata, mpath->dst); -- } --+ --+ tbl = rcu_dereference(mpp_paths); --+ for_each_mesh_entry(tbl, node, i) { --+ if (node->mpath->sdata != sdata) --+ continue; --+ mpath = node->mpath; --+ if ((!(mpath->flags & MESH_PATH_FIXED)) && --+ time_after(jiffies, mpath->exp_time + MESH_PATH_EXPIRE)) --+ mpp_path_del(mpath->sdata, mpath->dst); --+ } --+ -- rcu_read_unlock(); -- } -- ----- a/net/mac80211/rx.c --+++ b/net/mac80211/rx.c --@@ -2291,6 +2291,7 @@ ieee80211_rx_h_mesh_fwding(struct ieee80 -- spin_lock_bh(&mppath->state_lock); -- if (!ether_addr_equal(mppath->mpp, mpp_addr)) -- memcpy(mppath->mpp, mpp_addr, ETH_ALEN); --+ mppath->exp_time = jiffies; -- spin_unlock_bh(&mppath->state_lock); -- } -- rcu_read_unlock(); ----- a/net/mac80211/tx.c --+++ b/net/mac80211/tx.c --@@ -2171,8 +2171,11 @@ static struct sk_buff *ieee80211_build_h -- mpp_lookup = true; -- } -- --- if (mpp_lookup) --+ if (mpp_lookup) { -- mppath = mpp_path_lookup(sdata, skb->data); --+ if (mppath) --+ mppath->exp_time = jiffies; --+ } -- -- if (mppath && mpath) -- mesh_path_del(mpath->sdata, mpath->dst); -diff --git a/package/kernel/mac80211/patches/329-mac80211-Unify-mesh-and-mpp-path-removal-function.patch b/package/kernel/mac80211/patches/329-mac80211-Unify-mesh-and-mpp-path-removal-function.patch -deleted file mode 100644 -index 0c36b1d..0000000 ---- a/package/kernel/mac80211/patches/329-mac80211-Unify-mesh-and-mpp-path-removal-function.patch -+++ /dev/null -@@ -1,143 +0,0 @@ --From: Henning Rogge --Date: Wed, 3 Feb 2016 13:58:38 +0100 --Subject: [PATCH] mac80211: Unify mesh and mpp path removal function -- --mpp_path_del() and mesh_path_del() are mostly the same function. --Move common code into a new static function. -- --Acked-by: Bob Copeland --Signed-off-by: Henning Rogge --Signed-off-by: Johannes Berg ----- -- ----- a/net/mac80211/mesh_pathtbl.c --+++ b/net/mac80211/mesh_pathtbl.c --@@ -55,16 +55,21 @@ int mpp_paths_generation; -- static DEFINE_RWLOCK(pathtbl_resize_lock); -- -- --+static inline struct mesh_table *resize_dereference_paths( --+ struct mesh_table __rcu *table) --+{ --+ return rcu_dereference_protected(table, --+ lockdep_is_held(&pathtbl_resize_lock)); --+} --+ -- static inline struct mesh_table *resize_dereference_mesh_paths(void) -- { --- return rcu_dereference_protected(mesh_paths, --- lockdep_is_held(&pathtbl_resize_lock)); --+ return resize_dereference_paths(mesh_paths); -- } -- -- static inline struct mesh_table *resize_dereference_mpp_paths(void) -- { --- return rcu_dereference_protected(mpp_paths, --- lockdep_is_held(&pathtbl_resize_lock)); --+ return resize_dereference_paths(mpp_paths); -- } -- -- /* --@@ -899,14 +904,17 @@ void mesh_path_flush_by_iface(struct iee -- } -- -- /** --- * mesh_path_del - delete a mesh path from the table --+ * table_path_del - delete a path from the mesh or mpp table -- * --- * @addr: dst address (ETH_ALEN length) --+ * @tbl: mesh or mpp path table -- * @sdata: local subif --+ * @addr: dst address (ETH_ALEN length) -- * -- * Returns: 0 if successful -- */ ---int mesh_path_del(struct ieee80211_sub_if_data *sdata, const u8 *addr) --+static int table_path_del(struct mesh_table __rcu *rcu_tbl, --+ struct ieee80211_sub_if_data *sdata, --+ const u8 *addr) -- { -- struct mesh_table *tbl; -- struct mesh_path *mpath; --@@ -915,11 +923,7 @@ int mesh_path_del(struct ieee80211_sub_i -- int hash_idx; -- int err = 0; -- --- /* flush relevant mpp entries first */ --- mpp_flush_by_proxy(sdata, addr); --- --- read_lock_bh(&pathtbl_resize_lock); --- tbl = resize_dereference_mesh_paths(); --+ tbl = resize_dereference_paths(rcu_tbl); -- hash_idx = mesh_table_hash(addr, sdata, tbl); -- bucket = &tbl->hash_buckets[hash_idx]; -- --@@ -935,9 +939,30 @@ int mesh_path_del(struct ieee80211_sub_i -- -- err = -ENXIO; -- enddel: --- mesh_paths_generation++; -- spin_unlock(&tbl->hashwlock[hash_idx]); --+ return err; --+} --+ --+/** --+ * mesh_path_del - delete a mesh path from the table --+ * --+ * @addr: dst address (ETH_ALEN length) --+ * @sdata: local subif --+ * --+ * Returns: 0 if successful --+ */ --+int mesh_path_del(struct ieee80211_sub_if_data *sdata, const u8 *addr) --+{ --+ int err = 0; --+ --+ /* flush relevant mpp entries first */ --+ mpp_flush_by_proxy(sdata, addr); --+ --+ read_lock_bh(&pathtbl_resize_lock); --+ err = table_path_del(mesh_paths, sdata, addr); --+ mesh_paths_generation++; -- read_unlock_bh(&pathtbl_resize_lock); --+ -- return err; -- } -- --@@ -951,33 +976,13 @@ enddel: -- */ -- static int mpp_path_del(struct ieee80211_sub_if_data *sdata, const u8 *addr) -- { --- struct mesh_table *tbl; --- struct mesh_path *mpath; --- struct mpath_node *node; --- struct hlist_head *bucket; --- int hash_idx; -- int err = 0; -- -- read_lock_bh(&pathtbl_resize_lock); --- tbl = resize_dereference_mpp_paths(); --- hash_idx = mesh_table_hash(addr, sdata, tbl); --- bucket = &tbl->hash_buckets[hash_idx]; --- --- spin_lock(&tbl->hashwlock[hash_idx]); --- hlist_for_each_entry(node, bucket, list) { --- mpath = node->mpath; --- if (mpath->sdata == sdata && --- ether_addr_equal(addr, mpath->dst)) { --- __mesh_path_del(tbl, node); --- goto enddel; --- } --- } --- --- err = -ENXIO; ---enddel: --- mesh_paths_generation++; --- spin_unlock(&tbl->hashwlock[hash_idx]); --+ err = table_path_del(mpp_paths, sdata, addr); --+ mpp_paths_generation++; -- read_unlock_bh(&pathtbl_resize_lock); --+ -- return err; -- } -- -diff --git a/package/kernel/mac80211/patches/329-mac80211-fix-check-for-buffered-powersave-frames-wit.patch b/package/kernel/mac80211/patches/329-mac80211-fix-check-for-buffered-powersave-frames-wit.patch -new file mode 100644 -index 0000000..38e541c ---- /dev/null -+++ b/package/kernel/mac80211/patches/329-mac80211-fix-check-for-buffered-powersave-frames-wit.patch -@@ -0,0 +1,21 @@ -+From: Felix Fietkau -+Date: Mon, 11 Jul 2016 15:07:06 +0200 -+Subject: [PATCH] mac80211: fix check for buffered powersave frames with txq -+ -+The logic was inverted here, set the bit if frames are pending. -+ -+Fixes: ba8c3d6f16a1 ("mac80211: add an intermediate software queue implementation") -+Signed-off-by: Felix Fietkau -+--- -+ -+--- a/net/mac80211/rx.c -++++ b/net/mac80211/rx.c -+@@ -1268,7 +1268,7 @@ static void sta_ps_start(struct sta_info -+ for (tid = 0; tid < ARRAY_SIZE(sta->sta.txq); tid++) { -+ struct txq_info *txqi = to_txq_info(sta->sta.txq[tid]); -+ -+- if (!txqi->tin.backlog_packets) -++ if (txqi->tin.backlog_packets) -+ set_bit(tid, &sta->txq_buffered_tids); -+ else -+ clear_bit(tid, &sta->txq_buffered_tids); -diff --git a/package/kernel/mac80211/patches/330-ath10k-fix-rx-status-reporting-for-A-MSDU-subframes.patch b/package/kernel/mac80211/patches/330-ath10k-fix-rx-status-reporting-for-A-MSDU-subframes.patch -new file mode 100644 -index 0000000..a6031b9 ---- /dev/null -+++ b/package/kernel/mac80211/patches/330-ath10k-fix-rx-status-reporting-for-A-MSDU-subframes.patch -@@ -0,0 +1,36 @@ -+From: Felix Fietkau -+Date: Sun, 17 Jul 2016 12:49:59 +0200 -+Subject: [PATCH] ath10k: fix rx status reporting for A-MSDU subframes -+ -+Patch by Nagarajan, Ashok Raj -+ -+Signed-off-by: Felix Fietkau -+--- -+ -+--- a/drivers/net/wireless/ath/ath10k/htt_rx.c -++++ b/drivers/net/wireless/ath/ath10k/htt_rx.c -+@@ -1525,7 +1525,7 @@ static void ath10k_htt_rx_h_filter(struc -+ static int ath10k_htt_rx_handle_amsdu(struct ath10k_htt *htt) -+ { -+ struct ath10k *ar = htt->ar; -+- static struct ieee80211_rx_status rx_status; -++ struct ieee80211_rx_status *rx_status = &htt->rx_status; -+ struct sk_buff_head amsdu; -+ int ret; -+ -+@@ -1549,11 +1549,11 @@ static int ath10k_htt_rx_handle_amsdu(st -+ return ret; -+ } -+ -+- ath10k_htt_rx_h_ppdu(ar, &amsdu, &rx_status, 0xffff); -++ ath10k_htt_rx_h_ppdu(ar, &amsdu, rx_status, 0xffff); -+ ath10k_htt_rx_h_unchain(ar, &amsdu, ret > 0); -+- ath10k_htt_rx_h_filter(ar, &amsdu, &rx_status); -+- ath10k_htt_rx_h_mpdu(ar, &amsdu, &rx_status); -+- ath10k_htt_rx_h_deliver(ar, &amsdu, &rx_status); -++ ath10k_htt_rx_h_filter(ar, &amsdu, rx_status); -++ ath10k_htt_rx_h_mpdu(ar, &amsdu, rx_status); -++ ath10k_htt_rx_h_deliver(ar, &amsdu, rx_status); -+ -+ return 0; -+ } -diff --git a/package/kernel/mac80211/patches/330-mac80211-minstrel-Change-expected-throughput-unit-ba.patch b/package/kernel/mac80211/patches/330-mac80211-minstrel-Change-expected-throughput-unit-ba.patch -deleted file mode 100644 -index 4dc6d66..0000000 ---- a/package/kernel/mac80211/patches/330-mac80211-minstrel-Change-expected-throughput-unit-ba.patch -+++ /dev/null -@@ -1,51 +0,0 @@ --From: Sven Eckelmann --Date: Tue, 2 Feb 2016 08:12:26 +0100 --Subject: [PATCH] mac80211: minstrel: Change expected throughput unit back to -- Kbps -- --The change from cur_tp to the function --minstrel_get_tp_avg/minstrel_ht_get_tp_avg changed the unit used for the --current throughput. For example in minstrel_ht the correct --conversion between them would be: -- -- mrs->cur_tp / 10 == minstrel_ht_get_tp_avg(..). -- --This factor 10 must also be included in the calculation of --minstrel_get_expected_throughput and minstrel_ht_get_expected_throughput to --return values with the unit [Kbps] instead of [10Kbps]. Otherwise routing --algorithms like B.A.T.M.A.N. V will make incorrect decision based on these --values. Its kernel based implementation expects expected_throughput always --to have the unit [Kbps] and not sometimes [10Kbps] and sometimes [Kbps]. -- --The same requirement has iw or olsrdv2's nl80211 based statistics module --which retrieve the same data via NL80211_STA_INFO_TX_BITRATE. -- --Cc: stable@vger.kernel.org --Fixes: 6a27b2c40b48 ("mac80211: restructure per-rate throughput calculation into function") --Signed-off-by: Sven Eckelmann --Signed-off-by: Johannes Berg ----- -- ----- a/net/mac80211/rc80211_minstrel.c --+++ b/net/mac80211/rc80211_minstrel.c --@@ -711,7 +711,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); --+ tmp_cur_tp = minstrel_get_tp_avg(&mi->r[idx], tmp_mrs->prob_ewma) * 10; -- tmp_cur_tp = tmp_cur_tp * 1200 * 8 / 1024; -- -- return tmp_cur_tp; ----- a/net/mac80211/rc80211_minstrel_ht.c --+++ b/net/mac80211/rc80211_minstrel_ht.c --@@ -1335,7 +1335,8 @@ static u32 minstrel_ht_get_expected_thro -- prob = mi->groups[i].rates[j].prob_ewma; -- -- /* convert tp_avg from pkt per second in kbps */ --- tp_avg = minstrel_ht_get_tp_avg(mi, i, j, prob) * AVG_PKT_SIZE * 8 / 1024; --+ tp_avg = minstrel_ht_get_tp_avg(mi, i, j, prob) * 10; --+ tp_avg = tp_avg * AVG_PKT_SIZE * 8 / 1024; -- -- return tp_avg; -- } -diff --git a/package/kernel/mac80211/patches/331-brcmfmac-Increase-nr-of-supported-flowrings.patch b/package/kernel/mac80211/patches/331-brcmfmac-Increase-nr-of-supported-flowrings.patch -deleted file mode 100644 -index 1fd016f..0000000 ---- a/package/kernel/mac80211/patches/331-brcmfmac-Increase-nr-of-supported-flowrings.patch -+++ /dev/null -@@ -1,307 +0,0 @@ --From: Hante Meuleman --Date: Sun, 7 Feb 2016 18:08:24 +0100 --Subject: [PATCH] brcmfmac: Increase nr of supported flowrings. --MIME-Version: 1.0 --Content-Type: text/plain; charset=UTF-8 --Content-Transfer-Encoding: 8bit -- --New generation devices have firmware which has more than 256 flowrings. --E.g. following debugging message comes from 14e4:4365 BCM4366: --[ 194.606245] brcmfmac: brcmf_pcie_init_ringbuffers Nr of flowrings is 264 -- --At various code places (related to flowrings) we were using u8 which --could lead to storing wrong number or infinite loops when indexing with --this type. This issue was quite easy to spot in brcmf_flowring_detach --where it led to infinite loop e.g. on failed initialization. -- --This patch switches code to proper types and increases the maximum --number of supported flowrings to 512. -- --Originally this change was sent in September 2015, but back it was --causing a regression on BCM43602 resulting in: --Unable to handle kernel NULL pointer dereference at virtual address ... -- --The reason for this regression was missing update (s/u8/u16) of struct --brcmf_flowring_ring. This problem was handled in 9f64df9 ("brcmfmac: Fix --bug in flowring management."). Starting with that it's safe to apply --this original patch as it doesn't cause a regression anymore. -- --This patch fixes an infinite loop on BCM4366 which is supported since --4.4 so it makes sense to apply it to stable 4.4+. -- --Cc: # 4.4+ --Reviewed-by: Arend Van Spriel --Reviewed-by: Franky (Zhenhui) Lin --Reviewed-by: Pieter-Paul Giesberts --Signed-off-by: Hante Meuleman --Signed-off-by: Arend van Spriel --Signed-off-by: RafaÅ‚ MiÅ‚ecki ----- -- ----- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/flowring.c --+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/flowring.c --@@ -32,7 +32,7 @@ -- #define BRCMF_FLOWRING_LOW (BRCMF_FLOWRING_HIGH - 256) -- #define BRCMF_FLOWRING_INVALID_IFIDX 0xff -- ---#define BRCMF_FLOWRING_HASH_AP(da, fifo, ifidx) (da[5] + fifo + ifidx * 16) --+#define BRCMF_FLOWRING_HASH_AP(da, fifo, ifidx) (da[5] * 2 + fifo + ifidx * 16) -- #define BRCMF_FLOWRING_HASH_STA(fifo, ifidx) (fifo + ifidx * 16) -- -- static const u8 brcmf_flowring_prio2fifo[] = { --@@ -68,7 +68,7 @@ u32 brcmf_flowring_lookup(struct brcmf_f -- u8 prio, u8 ifidx) -- { -- struct brcmf_flowring_hash *hash; --- u8 hash_idx; --+ u16 hash_idx; -- u32 i; -- bool found; -- bool sta; --@@ -88,6 +88,7 @@ u32 brcmf_flowring_lookup(struct brcmf_f -- } -- hash_idx = sta ? BRCMF_FLOWRING_HASH_STA(fifo, ifidx) : -- BRCMF_FLOWRING_HASH_AP(mac, fifo, ifidx); --+ hash_idx &= (BRCMF_FLOWRING_HASHSIZE - 1); -- found = false; -- hash = flow->hash; -- for (i = 0; i < BRCMF_FLOWRING_HASHSIZE; i++) { --@@ -98,6 +99,7 @@ u32 brcmf_flowring_lookup(struct brcmf_f -- break; -- } -- hash_idx++; --+ hash_idx &= (BRCMF_FLOWRING_HASHSIZE - 1); -- } -- if (found) -- return hash[hash_idx].flowid; --@@ -111,7 +113,7 @@ u32 brcmf_flowring_create(struct brcmf_f -- { -- struct brcmf_flowring_ring *ring; -- struct brcmf_flowring_hash *hash; --- u8 hash_idx; --+ u16 hash_idx; -- u32 i; -- bool found; -- u8 fifo; --@@ -131,6 +133,7 @@ u32 brcmf_flowring_create(struct brcmf_f -- } -- hash_idx = sta ? BRCMF_FLOWRING_HASH_STA(fifo, ifidx) : -- BRCMF_FLOWRING_HASH_AP(mac, fifo, ifidx); --+ hash_idx &= (BRCMF_FLOWRING_HASHSIZE - 1); -- found = false; -- hash = flow->hash; -- for (i = 0; i < BRCMF_FLOWRING_HASHSIZE; i++) { --@@ -140,6 +143,7 @@ u32 brcmf_flowring_create(struct brcmf_f -- break; -- } -- hash_idx++; --+ hash_idx &= (BRCMF_FLOWRING_HASHSIZE - 1); -- } -- if (found) { -- for (i = 0; i < flow->nrofrings; i++) { --@@ -169,7 +173,7 @@ u32 brcmf_flowring_create(struct brcmf_f -- } -- -- ---u8 brcmf_flowring_tid(struct brcmf_flowring *flow, u8 flowid) --+u8 brcmf_flowring_tid(struct brcmf_flowring *flow, u16 flowid) -- { -- struct brcmf_flowring_ring *ring; -- --@@ -179,7 +183,7 @@ u8 brcmf_flowring_tid(struct brcmf_flowr -- } -- -- ---static void brcmf_flowring_block(struct brcmf_flowring *flow, u8 flowid, --+static void brcmf_flowring_block(struct brcmf_flowring *flow, u16 flowid, -- bool blocked) -- { -- struct brcmf_flowring_ring *ring; --@@ -228,10 +232,10 @@ static void brcmf_flowring_block(struct -- } -- -- ---void brcmf_flowring_delete(struct brcmf_flowring *flow, u8 flowid) --+void brcmf_flowring_delete(struct brcmf_flowring *flow, u16 flowid) -- { -- struct brcmf_flowring_ring *ring; --- u8 hash_idx; --+ u16 hash_idx; -- struct sk_buff *skb; -- -- ring = flow->rings[flowid]; --@@ -253,7 +257,7 @@ void brcmf_flowring_delete(struct brcmf_ -- } -- -- ---u32 brcmf_flowring_enqueue(struct brcmf_flowring *flow, u8 flowid, --+u32 brcmf_flowring_enqueue(struct brcmf_flowring *flow, u16 flowid, -- struct sk_buff *skb) -- { -- struct brcmf_flowring_ring *ring; --@@ -279,7 +283,7 @@ u32 brcmf_flowring_enqueue(struct brcmf_ -- } -- -- ---struct sk_buff *brcmf_flowring_dequeue(struct brcmf_flowring *flow, u8 flowid) --+struct sk_buff *brcmf_flowring_dequeue(struct brcmf_flowring *flow, u16 flowid) -- { -- struct brcmf_flowring_ring *ring; -- struct sk_buff *skb; --@@ -300,7 +304,7 @@ struct sk_buff *brcmf_flowring_dequeue(s -- } -- -- ---void brcmf_flowring_reinsert(struct brcmf_flowring *flow, u8 flowid, --+void brcmf_flowring_reinsert(struct brcmf_flowring *flow, u16 flowid, -- struct sk_buff *skb) -- { -- struct brcmf_flowring_ring *ring; --@@ -311,7 +315,7 @@ void brcmf_flowring_reinsert(struct brcm -- } -- -- ---u32 brcmf_flowring_qlen(struct brcmf_flowring *flow, u8 flowid) --+u32 brcmf_flowring_qlen(struct brcmf_flowring *flow, u16 flowid) -- { -- struct brcmf_flowring_ring *ring; -- --@@ -326,7 +330,7 @@ u32 brcmf_flowring_qlen(struct brcmf_flo -- } -- -- ---void brcmf_flowring_open(struct brcmf_flowring *flow, u8 flowid) --+void brcmf_flowring_open(struct brcmf_flowring *flow, u16 flowid) -- { -- struct brcmf_flowring_ring *ring; -- --@@ -340,10 +344,10 @@ void brcmf_flowring_open(struct brcmf_fl -- } -- -- ---u8 brcmf_flowring_ifidx_get(struct brcmf_flowring *flow, u8 flowid) --+u8 brcmf_flowring_ifidx_get(struct brcmf_flowring *flow, u16 flowid) -- { -- struct brcmf_flowring_ring *ring; --- u8 hash_idx; --+ u16 hash_idx; -- -- ring = flow->rings[flowid]; -- hash_idx = ring->hash_id; --@@ -384,7 +388,7 @@ void brcmf_flowring_detach(struct brcmf_ -- struct brcmf_pub *drvr = bus_if->drvr; -- struct brcmf_flowring_tdls_entry *search; -- struct brcmf_flowring_tdls_entry *remove; --- u8 flowid; --+ u16 flowid; -- -- for (flowid = 0; flowid < flow->nrofrings; flowid++) { -- if (flow->rings[flowid]) --@@ -408,7 +412,7 @@ void brcmf_flowring_configure_addr_mode( -- struct brcmf_bus *bus_if = dev_get_drvdata(flow->dev); -- struct brcmf_pub *drvr = bus_if->drvr; -- u32 i; --- u8 flowid; --+ u16 flowid; -- -- if (flow->addr_mode[ifidx] != addr_mode) { -- for (i = 0; i < ARRAY_SIZE(flow->hash); i++) { --@@ -434,7 +438,7 @@ void brcmf_flowring_delete_peer(struct b -- struct brcmf_flowring_tdls_entry *prev; -- struct brcmf_flowring_tdls_entry *search; -- u32 i; --- u8 flowid; --+ u16 flowid; -- bool sta; -- -- sta = (flow->addr_mode[ifidx] == ADDR_INDIRECT); ----- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/flowring.h --+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/flowring.h --@@ -16,7 +16,7 @@ -- #define BRCMFMAC_FLOWRING_H -- -- ---#define BRCMF_FLOWRING_HASHSIZE 256 --+#define BRCMF_FLOWRING_HASHSIZE 512 /* has to be 2^x */ -- #define BRCMF_FLOWRING_INVALID_ID 0xFFFFFFFF -- -- --@@ -24,7 +24,7 @@ struct brcmf_flowring_hash { -- u8 mac[ETH_ALEN]; -- u8 fifo; -- u8 ifidx; --- u8 flowid; --+ u16 flowid; -- }; -- -- enum ring_status { --@@ -61,16 +61,16 @@ u32 brcmf_flowring_lookup(struct brcmf_f -- u8 prio, u8 ifidx); -- u32 brcmf_flowring_create(struct brcmf_flowring *flow, u8 da[ETH_ALEN], -- u8 prio, u8 ifidx); ---void brcmf_flowring_delete(struct brcmf_flowring *flow, u8 flowid); ---void brcmf_flowring_open(struct brcmf_flowring *flow, u8 flowid); ---u8 brcmf_flowring_tid(struct brcmf_flowring *flow, u8 flowid); ---u32 brcmf_flowring_enqueue(struct brcmf_flowring *flow, u8 flowid, --+void brcmf_flowring_delete(struct brcmf_flowring *flow, u16 flowid); --+void brcmf_flowring_open(struct brcmf_flowring *flow, u16 flowid); --+u8 brcmf_flowring_tid(struct brcmf_flowring *flow, u16 flowid); --+u32 brcmf_flowring_enqueue(struct brcmf_flowring *flow, u16 flowid, -- struct sk_buff *skb); ---struct sk_buff *brcmf_flowring_dequeue(struct brcmf_flowring *flow, u8 flowid); ---void brcmf_flowring_reinsert(struct brcmf_flowring *flow, u8 flowid, --+struct sk_buff *brcmf_flowring_dequeue(struct brcmf_flowring *flow, u16 flowid); --+void brcmf_flowring_reinsert(struct brcmf_flowring *flow, u16 flowid, -- struct sk_buff *skb); ---u32 brcmf_flowring_qlen(struct brcmf_flowring *flow, u8 flowid); ---u8 brcmf_flowring_ifidx_get(struct brcmf_flowring *flow, u8 flowid); --+u32 brcmf_flowring_qlen(struct brcmf_flowring *flow, u16 flowid); --+u8 brcmf_flowring_ifidx_get(struct brcmf_flowring *flow, u16 flowid); -- struct brcmf_flowring *brcmf_flowring_attach(struct device *dev, u16 nrofrings); -- void brcmf_flowring_detach(struct brcmf_flowring *flow); -- void brcmf_flowring_configure_addr_mode(struct brcmf_flowring *flow, int ifidx, ----- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c --+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c --@@ -677,7 +677,7 @@ static u32 brcmf_msgbuf_flowring_create( -- } -- -- ---static void brcmf_msgbuf_txflow(struct brcmf_msgbuf *msgbuf, u8 flowid) --+static void brcmf_msgbuf_txflow(struct brcmf_msgbuf *msgbuf, u16 flowid) -- { -- struct brcmf_flowring *flow = msgbuf->flow; -- struct brcmf_commonring *commonring; --@@ -1310,7 +1310,7 @@ int brcmf_proto_msgbuf_rx_trigger(struct -- } -- -- ---void brcmf_msgbuf_delete_flowring(struct brcmf_pub *drvr, u8 flowid) --+void brcmf_msgbuf_delete_flowring(struct brcmf_pub *drvr, u16 flowid) -- { -- struct brcmf_msgbuf *msgbuf = (struct brcmf_msgbuf *)drvr->proto->pd; -- struct msgbuf_tx_flowring_delete_req *delete; --@@ -1415,6 +1415,13 @@ int brcmf_proto_msgbuf_attach(struct brc -- u32 count; -- -- if_msgbuf = drvr->bus_if->msgbuf; --+ --+ if (if_msgbuf->nrof_flowrings >= BRCMF_FLOWRING_HASHSIZE) { --+ brcmf_err("driver not configured for this many flowrings %d\n", --+ if_msgbuf->nrof_flowrings); --+ if_msgbuf->nrof_flowrings = BRCMF_FLOWRING_HASHSIZE - 1; --+ } --+ -- msgbuf = kzalloc(sizeof(*msgbuf), GFP_KERNEL); -- if (!msgbuf) -- goto fail; ----- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.h --+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.h --@@ -33,7 +33,7 @@ -- -- -- int brcmf_proto_msgbuf_rx_trigger(struct device *dev); ---void brcmf_msgbuf_delete_flowring(struct brcmf_pub *drvr, u8 flowid); --+void brcmf_msgbuf_delete_flowring(struct brcmf_pub *drvr, u16 flowid); -- int brcmf_proto_msgbuf_attach(struct brcmf_pub *drvr); -- void brcmf_proto_msgbuf_detach(struct brcmf_pub *drvr); -- #else -diff --git a/package/kernel/mac80211/patches/332-cfg80211-fix-faulty-variable-initialization-in-ieee8.patch b/package/kernel/mac80211/patches/332-cfg80211-fix-faulty-variable-initialization-in-ieee8.patch -deleted file mode 100644 -index e414f23..0000000 ---- a/package/kernel/mac80211/patches/332-cfg80211-fix-faulty-variable-initialization-in-ieee8.patch -+++ /dev/null -@@ -1,22 +0,0 @@ --From: Felix Fietkau --Date: Mon, 8 Feb 2016 14:24:36 +0100 --Subject: [PATCH] cfg80211: fix faulty variable initialization in -- ieee80211_amsdu_to_8023s -- --reuse_skb is set to true if the code decides to use the last segment. --Fixes a memory leak -- --Signed-off-by: Felix Fietkau ----- -- ----- a/net/wireless/util.c --+++ b/net/wireless/util.c --@@ -676,7 +676,7 @@ void ieee80211_amsdu_to_8023s(struct sk_ -- u8 *payload; -- int offset = 0, remaining, err; -- struct ethhdr eth; --- bool reuse_skb = true; --+ bool reuse_skb = false; -- bool last = false; -- -- if (has_80211_header) { -diff --git a/package/kernel/mac80211/patches/333-cfg80211-reuse-existing-page-fragments-in-A-MSDU-rx.patch b/package/kernel/mac80211/patches/333-cfg80211-reuse-existing-page-fragments-in-A-MSDU-rx.patch -deleted file mode 100644 -index 6e2d0cf..0000000 ---- a/package/kernel/mac80211/patches/333-cfg80211-reuse-existing-page-fragments-in-A-MSDU-rx.patch -+++ /dev/null -@@ -1,132 +0,0 @@ --From: Felix Fietkau --Date: Mon, 8 Feb 2016 14:33:19 +0100 --Subject: [PATCH] cfg80211: reuse existing page fragments in A-MSDU rx -- --This massively reduces data copying and thus improves rx performance -- --Signed-off-by: Felix Fietkau ----- -- ----- a/net/wireless/util.c --+++ b/net/wireless/util.c --@@ -644,23 +644,93 @@ int ieee80211_data_from_8023(struct sk_b -- } -- EXPORT_SYMBOL(ieee80211_data_from_8023); -- --+static void --+__frame_add_frag(struct sk_buff *skb, struct page *page, --+ void *ptr, int len, int size) --+{ --+ struct skb_shared_info *sh = skb_shinfo(skb); --+ int page_offset; --+ --+ atomic_inc(&page->_count); --+ page_offset = ptr - page_address(page); --+ skb_add_rx_frag(skb, sh->nr_frags, page, page_offset, len, size); --+} --+ --+static void --+__ieee80211_amsdu_copy_frag(struct sk_buff *skb, struct sk_buff *frame, --+ int offset, int len) --+{ --+ struct skb_shared_info *sh = skb_shinfo(skb); --+ const skb_frag_t *frag = &sh->frags[-1]; --+ struct page *frag_page; --+ void *frag_ptr; --+ int frag_len, frag_size; --+ int head_size = skb->len - skb->data_len; --+ int cur_len; --+ --+ frag_page = virt_to_head_page(skb->head); --+ frag_ptr = skb->data; --+ frag_size = head_size; --+ --+ while (offset >= frag_size) { --+ offset -= frag_size; --+ frag++; --+ frag_page = skb_frag_page(frag); --+ frag_ptr = skb_frag_address(frag); --+ frag_size = skb_frag_size(frag); --+ } --+ --+ frag_ptr += offset; --+ frag_len = frag_size - offset; --+ --+ cur_len = min(len, frag_len); --+ --+ __frame_add_frag(frame, frag_page, frag_ptr, cur_len, frag_size); --+ len -= cur_len; --+ --+ while (len > 0) { --+ frag++; --+ frag_len = skb_frag_size(frag); --+ cur_len = min(len, frag_len); --+ __frame_add_frag(frame, skb_frag_page(frag), --+ skb_frag_address(frag), cur_len, frag_len); --+ len -= cur_len; --+ } --+} --+ -- static struct sk_buff * -- __ieee80211_amsdu_copy(struct sk_buff *skb, unsigned int hlen, --- int offset, int len) --+ int offset, int len, bool reuse_frag) -- { -- struct sk_buff *frame; --+ int cur_len = len; -- -- if (skb->len - offset < len) -- return NULL; -- -- /* --+ * When reusing framents, copy some data to the head to simplify --+ * ethernet header handling and speed up protocol header processing --+ * in the stack later. --+ */ --+ if (reuse_frag) --+ cur_len = min_t(int, len, 32); --+ --+ /* -- * Allocate and reserve two bytes more for payload -- * alignment since sizeof(struct ethhdr) is 14. -- */ --- frame = dev_alloc_skb(hlen + sizeof(struct ethhdr) + 2 + len); --+ frame = dev_alloc_skb(hlen + sizeof(struct ethhdr) + 2 + cur_len); -- -- skb_reserve(frame, hlen + sizeof(struct ethhdr) + 2); --- skb_copy_bits(skb, offset, skb_put(frame, len), len); --+ skb_copy_bits(skb, offset, skb_put(frame, cur_len), cur_len); --+ --+ len -= cur_len; --+ if (!len) --+ return frame; --+ --+ offset += cur_len; --+ __ieee80211_amsdu_copy_frag(skb, frame, offset, len); -- -- return frame; -- } --@@ -676,6 +746,7 @@ void ieee80211_amsdu_to_8023s(struct sk_ -- u8 *payload; -- int offset = 0, remaining, err; -- struct ethhdr eth; --+ bool reuse_frag = skb->head_frag && !skb_has_frag_list(skb); -- bool reuse_skb = false; -- bool last = false; -- --@@ -703,12 +774,13 @@ void ieee80211_amsdu_to_8023s(struct sk_ -- offset += sizeof(struct ethhdr); -- /* reuse skb for the last subframe */ -- last = remaining <= subframe_len + padding; --- if (!skb_is_nonlinear(skb) && last) { --+ if (!skb_is_nonlinear(skb) && !reuse_frag && last) { -- skb_pull(skb, offset); -- frame = skb; -- reuse_skb = true; -- } else { --- frame = __ieee80211_amsdu_copy(skb, hlen, offset, len); --+ frame = __ieee80211_amsdu_copy(skb, hlen, offset, len, --+ reuse_frag); -- if (!frame) -- goto purge; -- -diff --git a/package/kernel/mac80211/patches/334-mac80211-fix-wiphy-supported_band-access.patch b/package/kernel/mac80211/patches/334-mac80211-fix-wiphy-supported_band-access.patch -deleted file mode 100644 -index f8f4f09..0000000 ---- a/package/kernel/mac80211/patches/334-mac80211-fix-wiphy-supported_band-access.patch -+++ /dev/null -@@ -1,36 +0,0 @@ --From: Lorenzo Bianconi --Date: Wed, 10 Feb 2016 16:08:17 +0100 --Subject: [PATCH] mac80211: fix wiphy supported_band access -- --Fix wiphy supported_band access in tx radiotap parsing. In particular, --info->band is always set to 0 (IEEE80211_BAND_2GHZ) since it has not --assigned yet. This cause a kernel crash on 5GHz only devices. --Move ieee80211_parse_tx_radiotap() after info->band assignment -- --Signed-off-by: Lorenzo Bianconi ----- -- ----- a/net/mac80211/tx.c --+++ b/net/mac80211/tx.c --@@ -1890,10 +1890,6 @@ netdev_tx_t ieee80211_monitor_start_xmit -- info->flags = IEEE80211_TX_CTL_REQ_TX_STATUS | -- IEEE80211_TX_CTL_INJECTED; -- --- /* process and remove the injection radiotap header */ --- if (!ieee80211_parse_tx_radiotap(local, skb)) --- goto fail; --- -- rcu_read_lock(); -- -- /* --@@ -1955,6 +1951,10 @@ netdev_tx_t ieee80211_monitor_start_xmit -- goto fail_rcu; -- -- info->band = chandef->chan->band; --+ /* process and remove the injection radiotap header */ --+ if (!ieee80211_parse_tx_radiotap(local, skb)) --+ goto fail_rcu; --+ -- ieee80211_xmit(sdata, NULL, skb); -- rcu_read_unlock(); -- -diff --git a/package/kernel/mac80211/patches/335-mac80211-minstrel_ht-set-A-MSDU-tx-limits-based-on-s.patch b/package/kernel/mac80211/patches/335-mac80211-minstrel_ht-set-A-MSDU-tx-limits-based-on-s.patch -deleted file mode 100644 -index acaacf7..0000000 ---- a/package/kernel/mac80211/patches/335-mac80211-minstrel_ht-set-A-MSDU-tx-limits-based-on-s.patch -+++ /dev/null -@@ -1,61 +0,0 @@ --From: Felix Fietkau --Date: Thu, 18 Feb 2016 19:30:05 +0100 --Subject: [PATCH] mac80211: minstrel_ht: set A-MSDU tx limits based on selected -- max_prob_rate -- --Prevents excessive A-MSDU aggregation at low data rates or bad --conditions. -- --Signed-off-by: Felix Fietkau ----- -- ----- a/net/mac80211/rc80211_minstrel_ht.c --+++ b/net/mac80211/rc80211_minstrel_ht.c --@@ -883,6 +883,39 @@ minstrel_ht_set_rate(struct minstrel_pri -- ratetbl->rate[offset].flags = flags; -- } -- --+static int --+minstrel_ht_get_max_amsdu_len(struct minstrel_ht_sta *mi) --+{ --+ 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; --+ --+ /* Disable A-MSDU if max_prob_rate is bad */ --+ if (mi->groups[group].rates[rate].prob_ewma < MINSTREL_FRAC(50, 100)) --+ return 1; --+ --+ /* If the rate is slower than single-stream MCS1, make A-MSDU limit small */ --+ if (g->duration[rate] > 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)) --+ return 1500; --+ --+ /* --+ * If the rate is slower than single-stream MCS7, limit A-MSDU to twice --+ * the usual data packet size --+ */ --+ if (g->duration[rate] > MCS_DURATION(1, 0, 260)) --+ return 3000; --+ --+ /* unlimited */ --+ return 0; --+} --+ -- static void -- minstrel_ht_update_rates(struct minstrel_priv *mp, struct minstrel_ht_sta *mi) -- { --@@ -907,6 +940,7 @@ minstrel_ht_update_rates(struct minstrel -- minstrel_ht_set_rate(mp, mi, rates, i++, mi->max_prob_rate); -- } -- --+ mi->sta->max_rc_amsdu_len = minstrel_ht_get_max_amsdu_len(mi); -- rates->rate[i].idx = -1; -- rate_control_set_rates(mp->hw, mi->sta, rates); -- } -diff --git a/package/kernel/mac80211/patches/336-mac80211-minstrel_ht-set-default-tx-aggregation-time.patch b/package/kernel/mac80211/patches/336-mac80211-minstrel_ht-set-default-tx-aggregation-time.patch -deleted file mode 100644 -index 32a2ad6..0000000 ---- a/package/kernel/mac80211/patches/336-mac80211-minstrel_ht-set-default-tx-aggregation-time.patch -+++ /dev/null -@@ -1,31 +0,0 @@ --From: Felix Fietkau --Date: Thu, 18 Feb 2016 19:45:33 +0100 --Subject: [PATCH] mac80211: minstrel_ht: set default tx aggregation timeout to -- 0 -- --The value 5000 was put here with the addition of the timeout field to --ieee80211_start_tx_ba_session. It was originally added in mac80211 to --save resources for drivers like iwlwifi, which only supports a limited --number of concurrent aggregation sessions. -- --Since iwlwifi does not use minstrel_ht and other drivers don't need --this, 0 is a better default - especially since there have been --recent reports of aggregation setup related issues reproduced with --ath9k. This should improve stability without causing any adverse --effects. -- --Cc: stable@vger.kernel.org --Signed-off-by: Felix Fietkau ----- -- ----- a/net/mac80211/rc80211_minstrel_ht.c --+++ b/net/mac80211/rc80211_minstrel_ht.c --@@ -692,7 +692,7 @@ minstrel_aggr_check(struct ieee80211_sta -- if (likely(sta->ampdu_mlme.tid_tx[tid])) -- return; -- --- ieee80211_start_tx_ba_session(pubsta, tid, 5000); --+ ieee80211_start_tx_ba_session(pubsta, tid, 0); -- } -- -- static void -diff --git a/package/kernel/mac80211/patches/337-mac80211-minstrel_ht-fix-a-logic-error-in-RTS-CTS-ha.patch b/package/kernel/mac80211/patches/337-mac80211-minstrel_ht-fix-a-logic-error-in-RTS-CTS-ha.patch -deleted file mode 100644 -index 229351b..0000000 ---- a/package/kernel/mac80211/patches/337-mac80211-minstrel_ht-fix-a-logic-error-in-RTS-CTS-ha.patch -+++ /dev/null -@@ -1,26 +0,0 @@ --From: Felix Fietkau --Date: Wed, 24 Feb 2016 12:03:13 +0100 --Subject: [PATCH] mac80211: minstrel_ht: fix a logic error in RTS/CTS handling --MIME-Version: 1.0 --Content-Type: text/plain; charset=UTF-8 --Content-Transfer-Encoding: 8bit -- --RTS/CTS needs to be enabled if the rate is a fallback rate *or* if it's --a dual-stream rate and the sta is in dynamic SMPS mode. -- --Fixes: a3ebb4e1b763 ("mac80211: minstrel_ht: handle peers in dynamic SMPS") --Reported-by: Matías Richart --Signed-off-by: Felix Fietkau ----- -- ----- a/net/mac80211/rc80211_minstrel_ht.c --+++ b/net/mac80211/rc80211_minstrel_ht.c --@@ -872,7 +872,7 @@ minstrel_ht_set_rate(struct minstrel_pri -- * - if station is in dynamic SMPS (and streams > 1) -- * - for fallback rates, to increase chances of getting through -- */ --- if (offset > 0 && --+ if (offset > 0 || -- (mi->sta->smps_mode == IEEE80211_SMPS_DYNAMIC && -- group->streams > 1)) { -- ratetbl->rate[offset].count = ratetbl->rate[offset].count_rts; -diff --git a/package/kernel/mac80211/patches/338-mac80211-Fix-Public-Action-frame-RX-in-AP-mode.patch b/package/kernel/mac80211/patches/338-mac80211-Fix-Public-Action-frame-RX-in-AP-mode.patch -deleted file mode 100644 -index 56cd94a..0000000 ---- a/package/kernel/mac80211/patches/338-mac80211-Fix-Public-Action-frame-RX-in-AP-mode.patch -+++ /dev/null -@@ -1,35 +0,0 @@ --From: Jouni Malinen --Date: Tue, 1 Mar 2016 00:29:00 +0200 --Subject: [PATCH] mac80211: Fix Public Action frame RX in AP mode -- --Public Action frames use special rules for how the BSSID field (Address --3) is set. A wildcard BSSID is used in cases where the transmitter and --recipient are not members of the same BSS. As such, we need to accept --Public Action frames with wildcard BSSID. -- --Commit db8e17324553 ("mac80211: ignore frames between TDLS peers when --operating as AP") added a rule that drops Action frames to TDLS-peers --based on an Action frame having different DA (Address 1) and BSSID --(Address 3) values. This is not correct since it misses the possibility --of BSSID being a wildcard BSSID in which case the Address 1 would not --necessarily match. -- --Fix this by allowing mac80211 to accept wildcard BSSID in an Action --frame when in AP mode. -- --Fixes: db8e17324553 ("mac80211: ignore frames between TDLS peers when operating as AP") --Cc: stable@vger.kernel.org --Signed-off-by: Jouni Malinen --Signed-off-by: Johannes Berg ----- -- ----- a/net/mac80211/rx.c --+++ b/net/mac80211/rx.c --@@ -3374,6 +3374,7 @@ static bool ieee80211_accept_frame(struc -- return false; -- /* ignore action frames to TDLS-peers */ -- if (ieee80211_is_action(hdr->frame_control) && --+ !is_broadcast_ether_addr(bssid) && -- !ether_addr_equal(bssid, hdr->addr1)) -- return false; -- } -diff --git a/package/kernel/mac80211/patches/339-cfg80211-add-radiotap-VHT-info-to-rtap_namespace_siz.patch b/package/kernel/mac80211/patches/339-cfg80211-add-radiotap-VHT-info-to-rtap_namespace_siz.patch -deleted file mode 100644 -index 15d6cd0..0000000 ---- a/package/kernel/mac80211/patches/339-cfg80211-add-radiotap-VHT-info-to-rtap_namespace_siz.patch -+++ /dev/null -@@ -1,21 +0,0 @@ --From: Lorenzo Bianconi --Date: Fri, 19 Feb 2016 11:43:04 +0100 --Subject: [PATCH] cfg80211: add radiotap VHT info to rtap_namespace_sizes -- --Add IEEE80211_RADIOTAP_VHT entry to rtap_namespace_sizes array in order to --define alignment and size of VHT info in tx radiotap -- --Signed-off-by: Lorenzo Bianconi --Signed-off-by: Johannes Berg ----- -- ----- a/net/wireless/radiotap.c --+++ b/net/wireless/radiotap.c --@@ -43,6 +43,7 @@ static const struct radiotap_align_size -- [IEEE80211_RADIOTAP_DATA_RETRIES] = { .align = 1, .size = 1, }, -- [IEEE80211_RADIOTAP_MCS] = { .align = 1, .size = 3, }, -- [IEEE80211_RADIOTAP_AMPDU_STATUS] = { .align = 4, .size = 8, }, --+ [IEEE80211_RADIOTAP_VHT] = { .align = 2, .size = 12, }, -- /* -- * add more here as they are defined in radiotap.h -- */ -diff --git a/package/kernel/mac80211/patches/340-mac80211-fix-parsing-of-40Mhz-in-injected-radiotap-h.patch b/package/kernel/mac80211/patches/340-mac80211-fix-parsing-of-40Mhz-in-injected-radiotap-h.patch -deleted file mode 100644 -index de1b386..0000000 ---- a/package/kernel/mac80211/patches/340-mac80211-fix-parsing-of-40Mhz-in-injected-radiotap-h.patch -+++ /dev/null -@@ -1,36 +0,0 @@ --From: Sven Eckelmann --Date: Wed, 24 Feb 2016 16:25:49 +0100 --Subject: [PATCH] mac80211: fix parsing of 40Mhz in injected radiotap -- header -- --The MCS bandwidth part of the radiotap header is 2 bits wide. The full 2 --bit have to compared against IEEE80211_RADIOTAP_MCS_BW_40 and not only if --the first bit is set. Otherwise IEEE80211_RADIOTAP_MCS_BW_40 can be --confused with IEEE80211_RADIOTAP_MCS_BW_20U. -- --Fixes: 5ec3aed9ba4c ("mac80211: Parse legacy and HT rate in injected frames") --Signed-off-by: Sven Eckelmann ----- -- ----- a/net/mac80211/tx.c --+++ b/net/mac80211/tx.c --@@ -1689,7 +1689,7 @@ static bool ieee80211_parse_tx_radiotap( -- bool rate_found = false; -- u8 rate_retries = 0; -- u16 rate_flags = 0; --- u8 mcs_known, mcs_flags; --+ u8 mcs_known, mcs_flags, mcs_bw; -- int i; -- -- info->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT | --@@ -1765,8 +1765,9 @@ static bool ieee80211_parse_tx_radiotap( -- mcs_flags & IEEE80211_RADIOTAP_MCS_SGI) -- rate_flags |= IEEE80211_TX_RC_SHORT_GI; -- --+ mcs_bw = mcs_flags & IEEE80211_RADIOTAP_MCS_BW_MASK; -- if (mcs_known & IEEE80211_RADIOTAP_MCS_HAVE_BW && --- mcs_flags & IEEE80211_RADIOTAP_MCS_BW_40) --+ mcs_bw == IEEE80211_RADIOTAP_MCS_BW_40) -- rate_flags |= IEEE80211_TX_RC_40_MHZ_WIDTH; -- break; -- -diff --git a/package/kernel/mac80211/patches/341-mac80211-parse-VHT-info-in-injected-frames.patch b/package/kernel/mac80211/patches/341-mac80211-parse-VHT-info-in-injected-frames.patch -deleted file mode 100644 -index ac1f251..0000000 ---- a/package/kernel/mac80211/patches/341-mac80211-parse-VHT-info-in-injected-frames.patch -+++ /dev/null -@@ -1,65 +0,0 @@ --From: Lorenzo Bianconi --Date: Tue, 23 Feb 2016 15:43:35 +0100 --Subject: [PATCH] mac80211: parse VHT info in injected frames -- --Add VHT radiotap parsing support to ieee80211_parse_tx_radiotap(). --That capability has been tested using a d-link dir-860l rev b1 running --OpenWrt trunk and mt76 driver -- --Signed-off-by: Lorenzo Bianconi ----- -- ----- a/net/mac80211/tx.c --+++ b/net/mac80211/tx.c --@@ -1690,6 +1690,8 @@ static bool ieee80211_parse_tx_radiotap( -- u8 rate_retries = 0; -- u16 rate_flags = 0; -- u8 mcs_known, mcs_flags, mcs_bw; --+ u16 vht_known; --+ u8 vht_mcs = 0, vht_nss = 0; -- int i; -- -- info->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT | --@@ -1771,6 +1773,32 @@ static bool ieee80211_parse_tx_radiotap( -- rate_flags |= IEEE80211_TX_RC_40_MHZ_WIDTH; -- break; -- --+ case IEEE80211_RADIOTAP_VHT: --+ vht_known = get_unaligned_le16(iterator.this_arg); --+ rate_found = true; --+ --+ rate_flags = IEEE80211_TX_RC_VHT_MCS; --+ if ((vht_known & IEEE80211_RADIOTAP_VHT_KNOWN_GI) && --+ (iterator.this_arg[2] & --+ IEEE80211_RADIOTAP_VHT_FLAG_SGI)) --+ rate_flags |= IEEE80211_TX_RC_SHORT_GI; --+ if (vht_known & --+ IEEE80211_RADIOTAP_VHT_KNOWN_BANDWIDTH) { --+ if (iterator.this_arg[3] == 1) --+ rate_flags |= --+ IEEE80211_TX_RC_40_MHZ_WIDTH; --+ else if (iterator.this_arg[3] == 4) --+ rate_flags |= --+ IEEE80211_TX_RC_80_MHZ_WIDTH; --+ else if (iterator.this_arg[3] == 11) --+ rate_flags |= --+ IEEE80211_TX_RC_160_MHZ_WIDTH; --+ } --+ --+ vht_mcs = iterator.this_arg[4] >> 4; --+ vht_nss = iterator.this_arg[4] & 0xF; --+ break; --+ -- /* -- * Please update the file -- * Documentation/networking/mac80211-injection.txt --@@ -1796,6 +1824,9 @@ static bool ieee80211_parse_tx_radiotap( -- -- if (rate_flags & IEEE80211_TX_RC_MCS) { -- info->control.rates[0].idx = rate; --+ } else if (rate_flags & IEEE80211_TX_RC_VHT_MCS) { --+ ieee80211_rate_set_vht(info->control.rates, vht_mcs, --+ vht_nss); -- } else { -- for (i = 0; i < sband->n_bitrates; i++) { -- if (rate * 5 != sband->bitrates[i].bitrate) -diff --git a/package/kernel/mac80211/patches/342-mac80211-do-not-pass-injected-frames-without-a-valid.patch b/package/kernel/mac80211/patches/342-mac80211-do-not-pass-injected-frames-without-a-valid.patch -deleted file mode 100644 -index d7452c2..0000000 ---- a/package/kernel/mac80211/patches/342-mac80211-do-not-pass-injected-frames-without-a-valid.patch -+++ /dev/null -@@ -1,23 +0,0 @@ --From: Felix Fietkau --Date: Wed, 2 Mar 2016 15:51:40 +0100 --Subject: [PATCH] mac80211: do not pass injected frames without a valid rate to -- the driver -- --Fall back to rate control if the requested bitrate was not found. -- --Fixes: dfdfc2beb0dd ("mac80211: Parse legacy and HT rate in injected frames") --Signed-off-by: Felix Fietkau ----- -- ----- a/net/mac80211/tx.c --+++ b/net/mac80211/tx.c --@@ -1837,6 +1837,9 @@ static bool ieee80211_parse_tx_radiotap( -- } -- } -- --+ if (info->control.rates[0].idx < 0) --+ info->control.flags &= ~IEEE80211_TX_CTRL_RATE_INJECT; --+ -- info->control.rates[0].flags = rate_flags; -- info->control.rates[0].count = min_t(u8, rate_retries + 1, -- local->hw.max_rate_tries); -diff --git a/package/kernel/mac80211/patches/343-mac80211-minstrel_ht-improve-sample-rate-skip-logic.patch b/package/kernel/mac80211/patches/343-mac80211-minstrel_ht-improve-sample-rate-skip-logic.patch -deleted file mode 100644 -index 55ff817..0000000 ---- a/package/kernel/mac80211/patches/343-mac80211-minstrel_ht-improve-sample-rate-skip-logic.patch -+++ /dev/null -@@ -1,77 +0,0 @@ --From: Felix Fietkau --Date: Thu, 3 Mar 2016 23:20:06 +0100 --Subject: [PATCH] mac80211: minstrel_ht: improve sample rate skip logic -- --There were a few issues that were slowing down the process of finding --the optimal rate, especially on devices with multi-rate retry --limitations: -- --When max_tp_rate[0] was slower than max_tp_rate[1], the code did not --sample max_tp_rate[1], which would often allow it to switch places with --max_tp_rate[0] (e.g. if only the first sampling attempts were bad, but the --rate is otherwise good). -- --Also, sample attempts of rates between max_tp_rate[0] and [1] were being --ignored in this case, because the code only checked if the rate was --slower than [1]. -- --Fix this by checking against the fastest / second fastest max_tp_rate --instead of assuming a specific order between the two. -- --In my tests this patch significantly reduces the time until minstrel_ht --finds the optimal rate right after assoc -- --Signed-off-by: Felix Fietkau ----- -- ----- a/net/mac80211/rc80211_minstrel_ht.c --+++ b/net/mac80211/rc80211_minstrel_ht.c --@@ -958,6 +958,7 @@ minstrel_get_sample_rate(struct minstrel -- struct minstrel_rate_stats *mrs; -- struct minstrel_mcs_group_data *mg; -- unsigned int sample_dur, sample_group, cur_max_tp_streams; --+ int tp_rate1, tp_rate2; -- int sample_idx = 0; -- -- if (mi->sample_wait > 0) { --@@ -979,14 +980,22 @@ minstrel_get_sample_rate(struct minstrel -- mrs = &mg->rates[sample_idx]; -- sample_idx += sample_group * MCS_GROUP_RATES; -- --+ /* Set tp_rate1, tp_rate2 to the highest / second highest max_tp_rate */ --+ if (minstrel_get_duration(mi->max_tp_rate[0]) > --+ minstrel_get_duration(mi->max_tp_rate[1])) { --+ tp_rate1 = mi->max_tp_rate[1]; --+ tp_rate2 = mi->max_tp_rate[0]; --+ } else { --+ tp_rate1 = mi->max_tp_rate[0]; --+ tp_rate2 = mi->max_tp_rate[1]; --+ } --+ -- /* -- * Sampling might add some overhead (RTS, no aggregation) --- * to the frame. Hence, don't use sampling for the currently --- * used rates. --+ * to the frame. Hence, don't use sampling for the highest currently --+ * used highest throughput or probability rate. -- */ --- if (sample_idx == mi->max_tp_rate[0] || --- sample_idx == mi->max_tp_rate[1] || --- sample_idx == mi->max_prob_rate) --+ if (sample_idx == mi->max_tp_rate[0] || sample_idx == mi->max_prob_rate) -- return -1; -- -- /* --@@ -1001,10 +1010,10 @@ minstrel_get_sample_rate(struct minstrel -- * if the link is working perfectly. -- */ -- --- cur_max_tp_streams = minstrel_mcs_groups[mi->max_tp_rate[0] / --+ 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(mi->max_tp_rate[1]) && --+ if (sample_dur >= minstrel_get_duration(tp_rate2) && -- (cur_max_tp_streams - 1 < -- minstrel_mcs_groups[sample_group].streams || -- sample_dur >= minstrel_get_duration(mi->max_prob_rate))) { -diff --git a/package/kernel/mac80211/patches/344-0001-brcmfmac-change-function-name-for-brcmf_cfg80211_wai.patch b/package/kernel/mac80211/patches/344-0001-brcmfmac-change-function-name-for-brcmf_cfg80211_wai.patch -deleted file mode 100644 -index e3427de..0000000 ---- a/package/kernel/mac80211/patches/344-0001-brcmfmac-change-function-name-for-brcmf_cfg80211_wai.patch -+++ /dev/null -@@ -1,99 +0,0 @@ --From: Arend van Spriel --Date: Wed, 17 Feb 2016 11:26:50 +0100 --Subject: [PATCH] brcmfmac: change function name for -- brcmf_cfg80211_wait_vif_event_timeout() -- --Dropping the '_timeout' from the function name as the fact that a timeout --value is passed makes it obvious a timeout is used. Also helps to keep code --lines a bit shorter and easier to stick to 80 char boundary. -- --Reviewed-by: Hante Meuleman --Reviewed-by: Pieter-Paul Giesberts --Signed-off-by: Arend van Spriel --Signed-off-by: Kalle Valo ----- -- ----- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c --+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c --@@ -564,8 +564,8 @@ struct wireless_dev *brcmf_ap_add_vif(st -- } -- -- /* wait for firmware event */ --- err = brcmf_cfg80211_wait_vif_event_timeout(cfg, BRCMF_E_IF_ADD, --- BRCMF_VIF_EVENT_TIMEOUT); --+ err = brcmf_cfg80211_wait_vif_event(cfg, BRCMF_E_IF_ADD, --+ BRCMF_VIF_EVENT_TIMEOUT); -- brcmf_cfg80211_arm_vif_event(cfg, NULL); -- if (!err) { -- brcmf_err("timeout occurred\n"); --@@ -6395,8 +6395,9 @@ bool brcmf_cfg80211_vif_event_armed(stru -- -- return armed; -- } ---int brcmf_cfg80211_wait_vif_event_timeout(struct brcmf_cfg80211_info *cfg, --- u8 action, ulong timeout) --+ --+int brcmf_cfg80211_wait_vif_event(struct brcmf_cfg80211_info *cfg, --+ u8 action, ulong timeout) -- { -- struct brcmf_cfg80211_vif_event *event = &cfg->vif_event; -- ----- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h --+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h --@@ -402,8 +402,8 @@ bool brcmf_get_vif_state_any(struct brcm -- void brcmf_cfg80211_arm_vif_event(struct brcmf_cfg80211_info *cfg, -- struct brcmf_cfg80211_vif *vif); -- bool brcmf_cfg80211_vif_event_armed(struct brcmf_cfg80211_info *cfg); ---int brcmf_cfg80211_wait_vif_event_timeout(struct brcmf_cfg80211_info *cfg, --- u8 action, ulong timeout); --+int brcmf_cfg80211_wait_vif_event(struct brcmf_cfg80211_info *cfg, --+ u8 action, ulong timeout); -- s32 brcmf_notify_escan_complete(struct brcmf_cfg80211_info *cfg, -- struct brcmf_if *ifp, bool aborted, -- bool fw_abort); ----- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c --+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c --@@ -1988,8 +1988,8 @@ int brcmf_p2p_ifchange(struct brcmf_cfg8 -- brcmf_cfg80211_arm_vif_event(cfg, NULL); -- return err; -- } --- err = brcmf_cfg80211_wait_vif_event_timeout(cfg, BRCMF_E_IF_CHANGE, --- BRCMF_VIF_EVENT_TIMEOUT); --+ err = brcmf_cfg80211_wait_vif_event(cfg, BRCMF_E_IF_CHANGE, --+ BRCMF_VIF_EVENT_TIMEOUT); -- brcmf_cfg80211_arm_vif_event(cfg, NULL); -- if (!err) { -- brcmf_err("No BRCMF_E_IF_CHANGE event received\n"); --@@ -2090,8 +2090,8 @@ static struct wireless_dev *brcmf_p2p_cr -- } -- -- /* wait for firmware event */ --- err = brcmf_cfg80211_wait_vif_event_timeout(p2p->cfg, BRCMF_E_IF_ADD, --- BRCMF_VIF_EVENT_TIMEOUT); --+ err = brcmf_cfg80211_wait_vif_event(p2p->cfg, BRCMF_E_IF_ADD, --+ BRCMF_VIF_EVENT_TIMEOUT); -- brcmf_cfg80211_arm_vif_event(p2p->cfg, NULL); -- brcmf_fweh_p2pdev_setup(pri_ifp, false); -- if (!err) { --@@ -2180,8 +2180,8 @@ struct wireless_dev *brcmf_p2p_add_vif(s -- } -- -- /* wait for firmware event */ --- err = brcmf_cfg80211_wait_vif_event_timeout(cfg, BRCMF_E_IF_ADD, --- BRCMF_VIF_EVENT_TIMEOUT); --+ err = brcmf_cfg80211_wait_vif_event(cfg, BRCMF_E_IF_ADD, --+ BRCMF_VIF_EVENT_TIMEOUT); -- brcmf_cfg80211_arm_vif_event(cfg, NULL); -- if (!err) { -- brcmf_err("timeout occurred\n"); --@@ -2274,8 +2274,8 @@ int brcmf_p2p_del_vif(struct wiphy *wiph -- } -- if (!err) { -- /* wait for firmware event */ --- err = brcmf_cfg80211_wait_vif_event_timeout(cfg, BRCMF_E_IF_DEL, --- BRCMF_VIF_EVENT_TIMEOUT); --+ err = brcmf_cfg80211_wait_vif_event(cfg, BRCMF_E_IF_DEL, --+ BRCMF_VIF_EVENT_TIMEOUT); -- if (!err) -- err = -EIO; -- else -diff --git a/package/kernel/mac80211/patches/344-0002-brcmfmac-Limit-memory-allocs-to-64K.patch b/package/kernel/mac80211/patches/344-0002-brcmfmac-Limit-memory-allocs-to-64K.patch -deleted file mode 100644 -index 9c336f7..0000000 ---- a/package/kernel/mac80211/patches/344-0002-brcmfmac-Limit-memory-allocs-to-64K.patch -+++ /dev/null -@@ -1,127 +0,0 @@ --From: Hante Meuleman --Date: Wed, 17 Feb 2016 11:26:51 +0100 --Subject: [PATCH] brcmfmac: Limit memory allocs to <64K -- --Some systems have problems with allocating memory allocation larger --then 64K. Often on unload/load or suspend/resume a failure is --reported: Could not allocate wiphy device. This patch makes the --escan intermediate storage buf dynamically allocated, and smaller --than 64K. -- --Reviewed-by: Arend Van Spriel --Reviewed-by: Franky (Zhenhui) Lin --Reviewed-by: Pieter-Paul Giesberts --Signed-off-by: Hante Meuleman --Signed-off-by: Arend van Spriel --Signed-off-by: Kalle Valo ----- -- ----- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c --+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c --@@ -1125,7 +1125,7 @@ brcmf_cfg80211_escan(struct wiphy *wiphy -- -- /* Arm scan timeout timer */ -- mod_timer(&cfg->escan_timeout, jiffies + --- WL_ESCAN_TIMER_INTERVAL_MS * HZ / 1000); --+ BRCMF_ESCAN_TIMER_INTERVAL_MS * HZ / 1000); -- -- return 0; -- --@@ -3020,7 +3020,7 @@ brcmf_cfg80211_escan_handler(struct brcm -- -- list = (struct brcmf_scan_results *) -- cfg->escan_info.escan_buf; --- if (bi_length > WL_ESCAN_BUF_SIZE - list->buflen) { --+ if (bi_length > BRCMF_ESCAN_BUF_SIZE - list->buflen) { -- brcmf_err("Buffer is too small: ignoring\n"); -- goto exit; -- } --@@ -3033,8 +3033,8 @@ brcmf_cfg80211_escan_handler(struct brcm -- bss_info_le)) -- goto exit; -- } --- memcpy(&(cfg->escan_info.escan_buf[list->buflen]), --- bss_info_le, bi_length); --+ memcpy(&cfg->escan_info.escan_buf[list->buflen], bss_info_le, --+ bi_length); -- list->version = le32_to_cpu(bss_info_le->version); -- list->buflen += bi_length; -- list->count++; --@@ -5402,14 +5402,14 @@ static void brcmf_deinit_priv_mem(struct -- { -- kfree(cfg->conf); -- cfg->conf = NULL; --- kfree(cfg->escan_ioctl_buf); --- cfg->escan_ioctl_buf = NULL; -- kfree(cfg->extra_buf); -- cfg->extra_buf = NULL; -- kfree(cfg->wowl.nd); -- cfg->wowl.nd = NULL; -- kfree(cfg->wowl.nd_info); -- cfg->wowl.nd_info = NULL; --+ kfree(cfg->escan_info.escan_buf); --+ cfg->escan_info.escan_buf = NULL; -- } -- -- static s32 brcmf_init_priv_mem(struct brcmf_cfg80211_info *cfg) --@@ -5417,9 +5417,6 @@ static s32 brcmf_init_priv_mem(struct br -- cfg->conf = kzalloc(sizeof(*cfg->conf), GFP_KERNEL); -- if (!cfg->conf) -- goto init_priv_mem_out; --- cfg->escan_ioctl_buf = kzalloc(BRCMF_DCMD_MEDLEN, GFP_KERNEL); --- if (!cfg->escan_ioctl_buf) --- goto init_priv_mem_out; -- cfg->extra_buf = kzalloc(WL_EXTRA_BUF_MAX, GFP_KERNEL); -- if (!cfg->extra_buf) -- goto init_priv_mem_out; --@@ -5431,6 +5428,9 @@ static s32 brcmf_init_priv_mem(struct br -- GFP_KERNEL); -- if (!cfg->wowl.nd_info) -- goto init_priv_mem_out; --+ cfg->escan_info.escan_buf = kzalloc(BRCMF_ESCAN_BUF_SIZE, GFP_KERNEL); --+ if (!cfg->escan_info.escan_buf) --+ goto init_priv_mem_out; -- -- return 0; -- ----- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h --+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h --@@ -28,8 +28,11 @@ -- #define WL_ROAM_TRIGGER_LEVEL -75 -- #define WL_ROAM_DELTA 20 -- ---#define WL_ESCAN_BUF_SIZE (1024 * 64) ---#define WL_ESCAN_TIMER_INTERVAL_MS 10000 /* E-Scan timeout */ --+/* Keep BRCMF_ESCAN_BUF_SIZE below 64K (65536). Allocing over 64K can be --+ * problematic on some systems and should be avoided. --+ */ --+#define BRCMF_ESCAN_BUF_SIZE 65000 --+#define BRCMF_ESCAN_TIMER_INTERVAL_MS 10000 /* E-Scan timeout */ -- -- #define WL_ESCAN_ACTION_START 1 -- #define WL_ESCAN_ACTION_CONTINUE 2 --@@ -205,7 +208,7 @@ enum wl_escan_state { -- -- struct escan_info { -- u32 escan_state; --- u8 escan_buf[WL_ESCAN_BUF_SIZE]; --+ u8 *escan_buf; -- struct wiphy *wiphy; -- struct brcmf_if *ifp; -- s32 (*run)(struct brcmf_cfg80211_info *cfg, struct brcmf_if *ifp, --@@ -278,7 +281,6 @@ struct brcmf_cfg80211_wowl { -- * @escan_info: escan information. -- * @escan_timeout: Timer for catch scan timeout. -- * @escan_timeout_work: scan timeout worker. --- * @escan_ioctl_buf: dongle command buffer for escan commands. -- * @vif_list: linked list of vif instances. -- * @vif_cnt: number of vif instances. -- * @vif_event: vif event signalling. --@@ -309,7 +311,6 @@ struct brcmf_cfg80211_info { -- struct escan_info escan_info; -- struct timer_list escan_timeout; -- struct work_struct escan_timeout_work; --- u8 *escan_ioctl_buf; -- struct list_head vif_list; -- struct brcmf_cfg80211_vif_event vif_event; -- struct completion vif_disabled; -diff --git a/package/kernel/mac80211/patches/344-0003-brcmfmac-check-for-wowl-support-before-enumerating-f.patch b/package/kernel/mac80211/patches/344-0003-brcmfmac-check-for-wowl-support-before-enumerating-f.patch -deleted file mode 100644 -index ee3d9f3..0000000 ---- a/package/kernel/mac80211/patches/344-0003-brcmfmac-check-for-wowl-support-before-enumerating-f.patch -+++ /dev/null -@@ -1,29 +0,0 @@ --From: Franky Lin --Date: Wed, 17 Feb 2016 11:26:52 +0100 --Subject: [PATCH] brcmfmac: check for wowl support before enumerating feature -- flag -- --In some cases wiphy->wowlan could be NULL if firmware doesn't have the --support. Driver should check for support before walking down the feature --flags. -- --Reviewed-by: Arend Van Spriel --Reviewed-by: Pieter-Paul Giesberts --Reviewed-by: Hante Meuleman --Signed-off-by: Franky Lin --Signed-off-by: Arend van Spriel --Signed-off-by: Kalle Valo ----- -- ----- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c --+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c --@@ -6594,7 +6594,8 @@ struct brcmf_cfg80211_info *brcmf_cfg802 -- if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_SCAN_RANDOM_MAC)) { -- wiphy->features |= NL80211_FEATURE_SCHED_SCAN_RANDOM_MAC_ADDR; -- #ifdef CONFIG_PM --- if (wiphy->wowlan->flags & WIPHY_WOWLAN_NET_DETECT) --+ if (wiphy->wowlan && --+ wiphy->wowlan->flags & WIPHY_WOWLAN_NET_DETECT) -- wiphy->features |= NL80211_FEATURE_ND_RANDOM_MAC_ADDR; -- #endif -- } -diff --git a/package/kernel/mac80211/patches/344-0004-brcmfmac-Configure-country-code-using-device-specifi.patch b/package/kernel/mac80211/patches/344-0004-brcmfmac-Configure-country-code-using-device-specifi.patch -deleted file mode 100644 -index c52cac8..0000000 ---- a/package/kernel/mac80211/patches/344-0004-brcmfmac-Configure-country-code-using-device-specifi.patch -+++ /dev/null -@@ -1,214 +0,0 @@ --From: Hante Meuleman --Date: Wed, 17 Feb 2016 11:26:53 +0100 --Subject: [PATCH] brcmfmac: Configure country code using device specific -- settings -- --Country code configuration in a device is a device specific --operation. For this the country code as specified by reg notifier --(iso3166 alpha2) needs to be translated to a device specific --country locale and revision number. This patch adds this --translation and puts a placeholder in the device specific settings --where the translation table can be stored. Additional patches will --be needed to read these tables from for example device platform --data. -- --Reviewed-by: Arend Van Spriel --Reviewed-by: Franky (Zhenhui) Lin --Reviewed-by: Pieter-Paul Giesberts --Signed-off-by: Hante Meuleman --Signed-off-by: Arend van Spriel --Signed-off-by: Kalle Valo ----- -- ----- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c --+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c --@@ -6405,28 +6405,85 @@ int brcmf_cfg80211_wait_vif_event(struct -- vif_event_equals(event, action), timeout); -- } -- --+static s32 brcmf_translate_country_code(struct brcmf_pub *drvr, char alpha2[2], --+ struct brcmf_fil_country_le *ccreq) --+{ --+ struct cc_translate *country_codes; --+ struct cc_entry *cc; --+ s32 found_index; --+ int i; --+ --+ country_codes = drvr->settings->country_codes; --+ if (!country_codes) { --+ brcmf_dbg(TRACE, "No country codes configured for device\n"); --+ return -EINVAL; --+ } --+ --+ if ((alpha2[0] == ccreq->country_abbrev[0]) && --+ (alpha2[1] == ccreq->country_abbrev[1])) { --+ brcmf_dbg(TRACE, "Country code already set\n"); --+ return -EAGAIN; --+ } --+ --+ found_index = -1; --+ for (i = 0; i < country_codes->table_size; i++) { --+ cc = &country_codes->table[i]; --+ if ((cc->iso3166[0] == '\0') && (found_index == -1)) --+ found_index = i; --+ if ((cc->iso3166[0] == alpha2[0]) && --+ (cc->iso3166[1] == alpha2[1])) { --+ found_index = i; --+ break; --+ } --+ } --+ if (found_index == -1) { --+ brcmf_dbg(TRACE, "No country code match found\n"); --+ return -EINVAL; --+ } --+ memset(ccreq, 0, sizeof(*ccreq)); --+ ccreq->rev = cpu_to_le32(country_codes->table[found_index].rev); --+ memcpy(ccreq->ccode, country_codes->table[found_index].cc, --+ BRCMF_COUNTRY_BUF_SZ); --+ ccreq->country_abbrev[0] = alpha2[0]; --+ ccreq->country_abbrev[1] = alpha2[1]; --+ ccreq->country_abbrev[2] = 0; --+ --+ return 0; --+} --+ -- static void brcmf_cfg80211_reg_notifier(struct wiphy *wiphy, -- struct regulatory_request *req) -- { -- struct brcmf_cfg80211_info *cfg = wiphy_priv(wiphy); -- struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg)); -- struct brcmf_fil_country_le ccreq; --+ s32 err; -- int i; -- --- brcmf_dbg(TRACE, "enter: initiator=%d, alpha=%c%c\n", req->initiator, --- req->alpha2[0], req->alpha2[1]); --- -- /* ignore non-ISO3166 country codes */ -- for (i = 0; i < sizeof(req->alpha2); i++) -- if (req->alpha2[i] < 'A' || req->alpha2[i] > 'Z') { --- brcmf_err("not a ISO3166 code\n"); --+ brcmf_err("not a ISO3166 code (0x%02x 0x%02x)\n", --+ req->alpha2[0], req->alpha2[1]); -- return; -- } --- memset(&ccreq, 0, sizeof(ccreq)); --- ccreq.rev = cpu_to_le32(-1); --- memcpy(ccreq.ccode, req->alpha2, sizeof(req->alpha2)); --- if (brcmf_fil_iovar_data_set(ifp, "country", &ccreq, sizeof(ccreq))) { --- brcmf_err("firmware rejected country setting\n"); --+ --+ brcmf_dbg(TRACE, "Enter: initiator=%d, alpha=%c%c\n", req->initiator, --+ req->alpha2[0], req->alpha2[1]); --+ --+ err = brcmf_fil_iovar_data_get(ifp, "country", &ccreq, sizeof(ccreq)); --+ if (err) { --+ brcmf_err("Country code iovar returned err = %d\n", err); --+ return; --+ } --+ --+ err = brcmf_translate_country_code(ifp->drvr, req->alpha2, &ccreq); --+ if (err) --+ return; --+ --+ err = brcmf_fil_iovar_data_set(ifp, "country", &ccreq, sizeof(ccreq)); --+ if (err) { --+ brcmf_err("Firmware rejected country setting\n"); -- return; -- } -- brcmf_setup_wiphybands(wiphy); ----- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c --+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c --@@ -230,10 +230,8 @@ void brcmf_mp_attach(void) -- int brcmf_mp_device_attach(struct brcmf_pub *drvr) -- { -- drvr->settings = kzalloc(sizeof(*drvr->settings), GFP_ATOMIC); --- if (!drvr->settings) { --- brcmf_err("Failed to alloca storage space for settings\n"); --+ if (!drvr->settings) -- return -ENOMEM; --- } -- -- drvr->settings->sdiod_txglomsz = brcmf_sdiod_txglomsz; -- drvr->settings->p2p_enable = !!brcmf_p2p_enable; ----- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.h --+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.h --@@ -15,6 +15,8 @@ -- #ifndef BRCMFMAC_COMMON_H -- #define BRCMFMAC_COMMON_H -- --+#include "fwil_types.h" --+ -- extern const u8 ALLFFMAC[ETH_ALEN]; -- -- #define BRCMF_FW_ALTPATH_LEN 256 --@@ -39,6 +41,33 @@ struct brcmf_mp_global_t { -- extern struct brcmf_mp_global_t brcmf_mp_global; -- -- /** --+ * struct cc_entry - Struct for translating user space country code (iso3166) to --+ * firmware country code and revision. --+ * --+ * @iso3166: iso3166 alpha 2 country code string. --+ * @cc: firmware country code string. --+ * @rev: firmware country code revision. --+ */ --+struct cc_entry { --+ char iso3166[BRCMF_COUNTRY_BUF_SZ]; --+ char cc[BRCMF_COUNTRY_BUF_SZ]; --+ s32 rev; --+}; --+ --+/** --+ * struct cc_translate - Struct for translating country codes as set by user --+ * space to a country code and rev which can be used by --+ * firmware. --+ * --+ * @table_size: number of entries in table (> 0) --+ * @table: dynamic array of 1 or more elements with translation information. --+ */ --+struct cc_translate { --+ int table_size; --+ struct cc_entry table[0]; --+}; --+ --+/** -- * struct brcmf_mp_device - Device module paramaters. -- * -- * @sdiod_txglomsz: SDIO txglom size. --@@ -47,6 +76,7 @@ extern struct brcmf_mp_global_t brcmf_mp -- * @feature_disable: Feature_disable bitmask. -- * @fcmode: FWS flow control. -- * @roamoff: Firmware roaming off? --+ * @country_codes: If available, pointer to struct for translating country codes -- */ -- struct brcmf_mp_device { -- int sdiod_txglomsz; --@@ -56,6 +86,7 @@ struct brcmf_mp_device { -- int fcmode; -- bool roamoff; -- bool ignore_probe_fail; --+ struct cc_translate *country_codes; -- }; -- -- void brcmf_mp_attach(void); ----- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil_types.h --+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil_types.h --@@ -134,6 +134,8 @@ -- #define BRCMF_PFN_MAC_OUI_ONLY BIT(0) -- #define BRCMF_PFN_SET_MAC_UNASSOC BIT(1) -- --+#define BRCMF_MCSSET_LEN 16 --+ -- /* join preference types for join_pref iovar */ -- enum brcmf_join_pref_types { -- BRCMF_JOIN_PREF_RSSI = 1, --@@ -279,7 +281,7 @@ struct brcmf_bss_info_le { -- __le32 reserved32[1]; /* Reserved for expansion of BSS properties */ -- u8 flags; /* flags */ -- u8 reserved[3]; /* Reserved for expansion of BSS properties */ --- u8 basic_mcs[MCSSET_LEN]; /* 802.11N BSS required MCS set */ --+ u8 basic_mcs[BRCMF_MCSSET_LEN]; /* 802.11N BSS required MCS set */ -- -- __le16 ie_offset; /* offset at which IEs start, from beginning */ -- __le32 ie_length; /* byte length of Information Elements */ -diff --git a/package/kernel/mac80211/patches/344-0005-brcmfmac-Add-length-checks-on-firmware-events.patch b/package/kernel/mac80211/patches/344-0005-brcmfmac-Add-length-checks-on-firmware-events.patch -deleted file mode 100644 -index 3e2e350..0000000 ---- a/package/kernel/mac80211/patches/344-0005-brcmfmac-Add-length-checks-on-firmware-events.patch -+++ /dev/null -@@ -1,283 +0,0 @@ --From: Hante Meuleman --Date: Wed, 17 Feb 2016 11:26:54 +0100 --Subject: [PATCH] brcmfmac: Add length checks on firmware events -- --Add additional length checks on firmware events to create more --robust code. -- --Reviewed-by: Arend Van Spriel --Reviewed-by: Franky (Zhenhui) Lin --Reviewed-by: Pieter-Paul Giesberts --Reviewed-by: Lei Zhang --Signed-off-by: Hante Meuleman --Signed-off-by: Arend van Spriel --Signed-off-by: Kalle Valo ----- -- ----- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c --+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c --@@ -3092,6 +3092,11 @@ brcmf_notify_sched_scan_results(struct b -- -- brcmf_dbg(SCAN, "Enter\n"); -- --+ if (e->datalen < (sizeof(*pfn_result) + sizeof(*netinfo))) { --+ brcmf_dbg(SCAN, "Event data to small. Ignore\n"); --+ return 0; --+ } --+ -- if (e->event_code == BRCMF_E_PFN_NET_LOST) { -- brcmf_dbg(SCAN, "PFN NET LOST event. Do Nothing\n"); -- return 0; --@@ -3415,6 +3420,11 @@ brcmf_wowl_nd_results(struct brcmf_if *i -- -- brcmf_dbg(SCAN, "Enter\n"); -- --+ if (e->datalen < (sizeof(*pfn_result) + sizeof(*netinfo))) { --+ brcmf_dbg(SCAN, "Event data to small. Ignore\n"); --+ return 0; --+ } --+ -- pfn_result = (struct brcmf_pno_scanresults_le *)data; -- -- if (e->event_code == BRCMF_E_PFN_NET_LOST) { ----- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.c --+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.c --@@ -26,50 +26,6 @@ -- #include "fwil.h" -- -- /** --- * struct brcm_ethhdr - broadcom specific ether header. --- * --- * @subtype: subtype for this packet. --- * @length: TODO: length of appended data. --- * @version: version indication. --- * @oui: OUI of this packet. --- * @usr_subtype: subtype for this OUI. --- */ ---struct brcm_ethhdr { --- __be16 subtype; --- __be16 length; --- u8 version; --- u8 oui[3]; --- __be16 usr_subtype; ---} __packed; --- ---struct brcmf_event_msg_be { --- __be16 version; --- __be16 flags; --- __be32 event_type; --- __be32 status; --- __be32 reason; --- __be32 auth_type; --- __be32 datalen; --- u8 addr[ETH_ALEN]; --- char ifname[IFNAMSIZ]; --- u8 ifidx; --- u8 bsscfgidx; ---} __packed; --- ---/** --- * struct brcmf_event - contents of broadcom event packet. --- * --- * @eth: standard ether header. --- * @hdr: broadcom specific ether header. --- * @msg: common part of the actual event message. --- */ ---struct brcmf_event { --- struct ethhdr eth; --- struct brcm_ethhdr hdr; --- struct brcmf_event_msg_be msg; ---} __packed; --- ---/** -- * struct brcmf_fweh_queue_item - event item on event queue. -- * -- * @q: list element for queuing. --@@ -85,6 +41,7 @@ struct brcmf_fweh_queue_item { -- u8 ifidx; -- u8 ifaddr[ETH_ALEN]; -- struct brcmf_event_msg_be emsg; --+ u32 datalen; -- u8 data[0]; -- }; -- --@@ -294,6 +251,11 @@ static void brcmf_fweh_event_worker(stru -- brcmf_dbg_hex_dump(BRCMF_EVENT_ON(), event->data, -- min_t(u32, emsg.datalen, 64), -- "event payload, len=%d\n", emsg.datalen); --+ if (emsg.datalen > event->datalen) { --+ brcmf_err("event invalid length header=%d, msg=%d\n", --+ event->datalen, emsg.datalen); --+ goto event_free; --+ } -- -- /* special handling of interface event */ -- if (event->code == BRCMF_E_IF) { --@@ -439,7 +401,8 @@ int brcmf_fweh_activate_events(struct br -- * dispatch the event to a registered handler (using worker). -- */ -- void brcmf_fweh_process_event(struct brcmf_pub *drvr, --- struct brcmf_event *event_packet) --+ struct brcmf_event *event_packet, --+ u32 packet_len) -- { -- enum brcmf_fweh_event_code code; -- struct brcmf_fweh_info *fweh = &drvr->fweh; --@@ -459,6 +422,9 @@ void brcmf_fweh_process_event(struct brc -- if (code != BRCMF_E_IF && !fweh->evt_handler[code]) -- return; -- --+ if (datalen > BRCMF_DCMD_MAXLEN) --+ return; --+ -- if (in_interrupt()) -- alloc_flag = GFP_ATOMIC; -- --@@ -472,6 +438,7 @@ void brcmf_fweh_process_event(struct brc -- /* use memcpy to get aligned event message */ -- memcpy(&event->emsg, &event_packet->msg, sizeof(event->emsg)); -- memcpy(event->data, data, datalen); --+ event->datalen = datalen; -- memcpy(event->ifaddr, event_packet->eth.h_dest, ETH_ALEN); -- -- brcmf_fweh_queue_event(fweh, event); ----- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.h --+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.h --@@ -27,7 +27,6 @@ -- struct brcmf_pub; -- struct brcmf_if; -- struct brcmf_cfg80211_info; ---struct brcmf_event; -- -- /* list of firmware events */ -- #define BRCMF_FWEH_EVENT_ENUM_DEFLIST \ --@@ -180,13 +179,55 @@ enum brcmf_fweh_event_code { -- /** -- * definitions for event packet validation. -- */ ---#define BRCMF_EVENT_OUI_OFFSET 19 ---#define BRCM_OUI "\x00\x10\x18" ---#define DOT11_OUI_LEN 3 ---#define BCMILCP_BCM_SUBTYPE_EVENT 1 --+#define BRCM_OUI "\x00\x10\x18" --+#define BCMILCP_BCM_SUBTYPE_EVENT 1 -- -- -- /** --+ * struct brcm_ethhdr - broadcom specific ether header. --+ * --+ * @subtype: subtype for this packet. --+ * @length: TODO: length of appended data. --+ * @version: version indication. --+ * @oui: OUI of this packet. --+ * @usr_subtype: subtype for this OUI. --+ */ --+struct brcm_ethhdr { --+ __be16 subtype; --+ __be16 length; --+ u8 version; --+ u8 oui[3]; --+ __be16 usr_subtype; --+} __packed; --+ --+struct brcmf_event_msg_be { --+ __be16 version; --+ __be16 flags; --+ __be32 event_type; --+ __be32 status; --+ __be32 reason; --+ __be32 auth_type; --+ __be32 datalen; --+ u8 addr[ETH_ALEN]; --+ char ifname[IFNAMSIZ]; --+ u8 ifidx; --+ u8 bsscfgidx; --+} __packed; --+ --+/** --+ * struct brcmf_event - contents of broadcom event packet. --+ * --+ * @eth: standard ether header. --+ * @hdr: broadcom specific ether header. --+ * @msg: common part of the actual event message. --+ */ --+struct brcmf_event { --+ struct ethhdr eth; --+ struct brcm_ethhdr hdr; --+ struct brcmf_event_msg_be msg; --+} __packed; --+ --+/** -- * struct brcmf_event_msg - firmware event message. -- * -- * @version: version information. --@@ -256,34 +297,35 @@ void brcmf_fweh_unregister(struct brcmf_ -- enum brcmf_fweh_event_code code); -- int brcmf_fweh_activate_events(struct brcmf_if *ifp); -- void brcmf_fweh_process_event(struct brcmf_pub *drvr, --- struct brcmf_event *event_packet); --+ struct brcmf_event *event_packet, --+ u32 packet_len); -- 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 brcmf_event *event_packet; --- u8 *data; -- u16 usr_stype; -- -- /* only process events when protocol matches */ -- if (skb->protocol != cpu_to_be16(ETH_P_LINK_CTL)) -- return; -- --+ if ((skb->len + ETH_HLEN) < sizeof(*event_packet)) --+ return; --+ -- /* check for BRCM oui match */ -- event_packet = (struct brcmf_event *)skb_mac_header(skb); --- data = (u8 *)event_packet; --- data += BRCMF_EVENT_OUI_OFFSET; --- if (memcmp(BRCM_OUI, data, DOT11_OUI_LEN)) --+ if (memcmp(BRCM_OUI, &event_packet->hdr.oui[0], --+ sizeof(event_packet->hdr.oui))) -- return; -- -- /* final match on usr_subtype */ --- data += DOT11_OUI_LEN; --- usr_stype = get_unaligned_be16(data); --+ usr_stype = get_unaligned_be16(&event_packet->hdr.usr_subtype); -- if (usr_stype != BCMILCP_BCM_SUBTYPE_EVENT) -- return; -- --- brcmf_fweh_process_event(drvr, event_packet); --+ brcmf_fweh_process_event(drvr, event_packet, skb->len + ETH_HLEN); -- } -- -- #endif /* FWEH_H_ */ ----- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c --+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c --@@ -1361,6 +1361,11 @@ int brcmf_p2p_notify_action_frame_rx(str -- u16 mgmt_type; -- u8 action; -- --+ if (e->datalen < sizeof(*rxframe)) { --+ brcmf_dbg(SCAN, "Event data to small. Ignore\n"); --+ return 0; --+ } --+ -- ch.chspec = be16_to_cpu(rxframe->chanspec); -- cfg->d11inf.decchspec(&ch); -- /* Check if wpa_supplicant has registered for this frame */ --@@ -1858,6 +1863,11 @@ s32 brcmf_p2p_notify_rx_mgmt_p2p_probere -- brcmf_dbg(INFO, "Enter: event %d reason %d\n", e->event_code, -- e->reason); -- --+ if (e->datalen < sizeof(*rxframe)) { --+ brcmf_dbg(SCAN, "Event data to small. Ignore\n"); --+ return 0; --+ } --+ -- ch.chspec = be16_to_cpu(rxframe->chanspec); -- cfg->d11inf.decchspec(&ch); -- -diff --git a/package/kernel/mac80211/patches/344-0006-brcmfmac-add-neighbor-discovery-offload-ip-address-t.patch b/package/kernel/mac80211/patches/344-0006-brcmfmac-add-neighbor-discovery-offload-ip-address-t.patch -deleted file mode 100644 -index 888ad5b..0000000 ---- a/package/kernel/mac80211/patches/344-0006-brcmfmac-add-neighbor-discovery-offload-ip-address-t.patch -+++ /dev/null -@@ -1,333 +0,0 @@ --From: Franky Lin --Date: Wed, 17 Feb 2016 11:26:55 +0100 --Subject: [PATCH] brcmfmac: add neighbor discovery offload ip address table -- configuration -- --Configure ipv6 address for neighbor discovery offload ip table in --firmware obtained through ipv6 address notification callback. -- --Reviewed-by: Hante Meuleman --Reviewed-by: Pieter-Paul Giesberts --Signed-off-by: Franky Lin --Signed-off-by: Arend van Spriel --Signed-off-by: Kalle Valo ----- -- ----- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c --+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c --@@ -456,7 +456,7 @@ send_key_to_dongle(struct brcmf_if *ifp, -- } -- -- static s32 ---brcmf_configure_arp_offload(struct brcmf_if *ifp, bool enable) --+brcmf_configure_arp_nd_offload(struct brcmf_if *ifp, bool enable) -- { -- s32 err; -- u32 mode; --@@ -484,6 +484,15 @@ brcmf_configure_arp_offload(struct brcmf -- enable, mode); -- } -- --+ err = brcmf_fil_iovar_int_set(ifp, "ndoe", enable); --+ if (err) { --+ brcmf_dbg(TRACE, "failed to configure (%d) ND offload err = %d\n", --+ enable, err); --+ err = 0; --+ } else --+ brcmf_dbg(TRACE, "successfully configured (%d) ND offload to 0x%x\n", --+ enable, mode); --+ -- return err; -- } -- --@@ -3543,7 +3552,7 @@ static s32 brcmf_cfg80211_resume(struct -- brcmf_report_wowl_wakeind(wiphy, ifp); -- brcmf_fil_iovar_int_set(ifp, "wowl_clear", 0); -- brcmf_config_wowl_pattern(ifp, "clr", NULL, 0, NULL, 0); --- brcmf_configure_arp_offload(ifp, true); --+ brcmf_configure_arp_nd_offload(ifp, true); -- brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PM, -- cfg->wowl.pre_pmmode); -- cfg->wowl.active = false; --@@ -3567,7 +3576,7 @@ static void brcmf_configure_wowl(struct -- -- brcmf_dbg(TRACE, "Suspend, wowl config.\n"); -- --- brcmf_configure_arp_offload(ifp, false); --+ brcmf_configure_arp_nd_offload(ifp, false); -- brcmf_fil_cmd_int_get(ifp, BRCMF_C_GET_PM, &cfg->wowl.pre_pmmode); -- brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PM, PM_MAX); -- --@@ -4336,7 +4345,7 @@ brcmf_cfg80211_start_ap(struct wiphy *wi -- -- if (!mbss) { -- brcmf_set_mpc(ifp, 0); --- brcmf_configure_arp_offload(ifp, false); --+ brcmf_configure_arp_nd_offload(ifp, false); -- } -- -- /* find the RSN_IE */ --@@ -4482,7 +4491,7 @@ brcmf_cfg80211_start_ap(struct wiphy *wi -- exit: -- if ((err) && (!mbss)) { -- brcmf_set_mpc(ifp, 1); --- brcmf_configure_arp_offload(ifp, true); --+ brcmf_configure_arp_nd_offload(ifp, true); -- } -- return err; -- } --@@ -4540,7 +4549,7 @@ static int brcmf_cfg80211_stop_ap(struct -- brcmf_err("bss_enable config failed %d\n", err); -- } -- brcmf_set_mpc(ifp, 1); --- brcmf_configure_arp_offload(ifp, true); --+ brcmf_configure_arp_nd_offload(ifp, true); -- clear_bit(BRCMF_VIF_STATUS_AP_CREATED, &ifp->vif->sme_state); -- brcmf_net_setcarrier(ifp, false); -- --@@ -6287,7 +6296,7 @@ static s32 brcmf_config_dongle(struct br -- if (err) -- goto default_conf_out; -- --- brcmf_configure_arp_offload(ifp, true); --+ brcmf_configure_arp_nd_offload(ifp, true); -- -- cfg->dongle_up = true; -- default_conf_out: ----- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c --+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c --@@ -20,6 +20,8 @@ -- #include -- #include -- #include --+#include --+#include -- #include -- #include -- --@@ -172,6 +174,35 @@ _brcmf_set_mac_address(struct work_struc -- } -- } -- --+#if IS_ENABLED(CONFIG_IPV6) --+static void _brcmf_update_ndtable(struct work_struct *work) --+{ --+ struct brcmf_if *ifp; --+ 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) { --+ brcmf_dbg(TRACE, "fail to clear nd ip table err:%d\n", ret); --+ return; --+ } --+ --+ for (i = 0; i < ifp->ipv6addr_idx; i++) { --+ ret = brcmf_fil_iovar_data_set(ifp, "nd_hostip", --+ &ifp->ipv6_addr_tbl[i], --+ sizeof(struct in6_addr)); --+ if (ret) --+ brcmf_err("add nd ip err %d\n", ret); --+ } --+} --+#else --+static void _brcmf_update_ndtable(struct work_struct *work) --+{ --+} --+#endif --+ -- static int brcmf_netdev_set_mac_address(struct net_device *ndev, void *addr) -- { -- struct brcmf_if *ifp = netdev_priv(ndev); --@@ -685,6 +716,7 @@ int brcmf_net_attach(struct brcmf_if *if -- -- INIT_WORK(&ifp->setmacaddr_work, _brcmf_set_mac_address); -- INIT_WORK(&ifp->multicast_work, _brcmf_set_multicast_list); --+ INIT_WORK(&ifp->ndoffload_work, _brcmf_update_ndtable); -- -- if (rtnl_locked) -- err = register_netdevice(ndev); --@@ -884,6 +916,7 @@ static void brcmf_del_if(struct brcmf_pu -- if (ifp->ndev->netdev_ops == &brcmf_netdev_ops_pri) { -- cancel_work_sync(&ifp->setmacaddr_work); -- cancel_work_sync(&ifp->multicast_work); --+ cancel_work_sync(&ifp->ndoffload_work); -- } -- brcmf_net_detach(ifp->ndev); -- } else { --@@ -1025,6 +1058,56 @@ static int brcmf_inetaddr_changed(struct -- } -- #endif -- --+#if IS_ENABLED(CONFIG_IPV6) --+static int brcmf_inet6addr_changed(struct notifier_block *nb, --+ unsigned long action, void *data) --+{ --+ struct brcmf_pub *drvr = container_of(nb, struct brcmf_pub, --+ inet6addr_notifier); --+ struct inet6_ifaddr *ifa = data; --+ struct brcmf_if *ifp; --+ int i; --+ struct in6_addr *table; --+ --+ /* Only handle primary interface */ --+ ifp = drvr->iflist[0]; --+ if (!ifp) --+ return NOTIFY_DONE; --+ if (ifp->ndev != ifa->idev->dev) --+ return NOTIFY_DONE; --+ --+ table = ifp->ipv6_addr_tbl; --+ for (i = 0; i < NDOL_MAX_ENTRIES; i++) --+ if (ipv6_addr_equal(&ifa->addr, &table[i])) --+ break; --+ --+ switch (action) { --+ case NETDEV_UP: --+ if (i == NDOL_MAX_ENTRIES) { --+ if (ifp->ipv6addr_idx < NDOL_MAX_ENTRIES) { --+ table[ifp->ipv6addr_idx++] = ifa->addr; --+ } else { --+ for (i = 0; i < NDOL_MAX_ENTRIES - 1; i++) --+ table[i] = table[i + 1]; --+ table[NDOL_MAX_ENTRIES - 1] = ifa->addr; --+ } --+ } --+ break; --+ case NETDEV_DOWN: --+ if (i < NDOL_MAX_ENTRIES) --+ for (; i < ifp->ipv6addr_idx; i++) --+ table[i] = table[i + 1]; --+ break; --+ default: --+ break; --+ } --+ --+ schedule_work(&ifp->ndoffload_work); --+ --+ return NOTIFY_OK; --+} --+#endif --+ -- int brcmf_attach(struct device *dev) -- { -- struct brcmf_pub *drvr = NULL; --@@ -1164,30 +1247,41 @@ int brcmf_bus_start(struct device *dev) -- #ifdef CONFIG_INET -- drvr->inetaddr_notifier.notifier_call = brcmf_inetaddr_changed; -- ret = register_inetaddr_notifier(&drvr->inetaddr_notifier); --+ if (ret) --+ goto fail; --+ --+#if IS_ENABLED(CONFIG_IPV6) --+ drvr->inet6addr_notifier.notifier_call = brcmf_inet6addr_changed; --+ ret = register_inet6addr_notifier(&drvr->inet6addr_notifier); --+ if (ret) { --+ unregister_inetaddr_notifier(&drvr->inetaddr_notifier); --+ goto fail; --+ } -- #endif --+#endif /* CONFIG_INET */ --+ --+ return 0; -- -- fail: --- if (ret < 0) { --- brcmf_err("failed: %d\n", ret); --- if (drvr->config) { --- brcmf_cfg80211_detach(drvr->config); --- drvr->config = NULL; --- } --- if (drvr->fws) { --- brcmf_fws_del_interface(ifp); --- brcmf_fws_deinit(drvr); --- } --- if (ifp) --- brcmf_net_detach(ifp->ndev); --- if (p2p_ifp) --- brcmf_net_detach(p2p_ifp->ndev); --- drvr->iflist[0] = NULL; --- drvr->iflist[1] = NULL; --- if (brcmf_ignoring_probe_fail(drvr)) --- ret = 0; --- return ret; --+ brcmf_err("failed: %d\n", ret); --+ if (drvr->config) { --+ brcmf_cfg80211_detach(drvr->config); --+ drvr->config = NULL; --+ } --+ if (drvr->fws) { --+ brcmf_fws_del_interface(ifp); --+ brcmf_fws_deinit(drvr); -- } --- return 0; --+ if (ifp) --+ brcmf_net_detach(ifp->ndev); --+ if (p2p_ifp) --+ brcmf_net_detach(p2p_ifp->ndev); --+ drvr->iflist[0] = NULL; --+ drvr->iflist[1] = NULL; --+ if (brcmf_ignoring_probe_fail(drvr)) --+ ret = 0; --+ --+ return ret; -- } -- -- void brcmf_bus_add_txhdrlen(struct device *dev, uint len) --@@ -1237,6 +1331,10 @@ void brcmf_detach(struct device *dev) -- unregister_inetaddr_notifier(&drvr->inetaddr_notifier); -- #endif -- --+#if IS_ENABLED(CONFIG_IPV6) --+ unregister_inet6addr_notifier(&drvr->inet6addr_notifier); --+#endif --+ -- /* stop firmware event handling */ -- brcmf_fweh_detach(drvr); -- if (drvr->config) ----- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h --+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h --@@ -48,6 +48,8 @@ -- */ -- #define BRCMF_DRIVER_FIRMWARE_VERSION_LEN 32 -- --+#define NDOL_MAX_ENTRIES 8 --+ -- /** -- * struct brcmf_ampdu_rx_reorder - AMPDU receive reorder info -- * --@@ -143,6 +145,7 @@ struct brcmf_pub { -- #endif -- -- struct notifier_block inetaddr_notifier; --+ struct notifier_block inet6addr_notifier; -- struct brcmf_mp_device *settings; -- }; -- --@@ -175,6 +178,7 @@ enum brcmf_netif_stop_reason { -- * @stats: interface specific network statistics. -- * @setmacaddr_work: worker object for setting mac address. -- * @multicast_work: worker object for multicast provisioning. --+ * @ndoffload_work: worker object for neighbor discovery offload configuration. -- * @fws_desc: interface specific firmware-signalling descriptor. -- * @ifidx: interface index in device firmware. -- * @bsscfgidx: index of bss associated with this interface. --@@ -191,6 +195,7 @@ struct brcmf_if { -- struct net_device_stats stats; -- struct work_struct setmacaddr_work; -- struct work_struct multicast_work; --+ struct work_struct ndoffload_work; -- struct brcmf_fws_mac_descriptor *fws_desc; -- int ifidx; -- s32 bsscfgidx; --@@ -199,6 +204,8 @@ struct brcmf_if { -- spinlock_t netif_stop_lock; -- atomic_t pend_8021x_cnt; -- wait_queue_head_t pend_8021x_wait; --+ struct in6_addr ipv6_addr_tbl[NDOL_MAX_ENTRIES]; --+ u8 ipv6addr_idx; -- }; -- -- struct brcmf_skb_reorder_data { -diff --git a/package/kernel/mac80211/patches/344-0007-brcmfmac-check-return-for-ARP-ip-setting-iovar.patch b/package/kernel/mac80211/patches/344-0007-brcmfmac-check-return-for-ARP-ip-setting-iovar.patch -deleted file mode 100644 -index 68de8ed..0000000 ---- a/package/kernel/mac80211/patches/344-0007-brcmfmac-check-return-for-ARP-ip-setting-iovar.patch -+++ /dev/null -@@ -1,38 +0,0 @@ --From: Franky Lin --Date: Wed, 17 Feb 2016 11:26:56 +0100 --Subject: [PATCH] brcmfmac: check return for ARP ip setting iovar -- --The return value of iovar set function should be saved and checked. -- --Reviewed-by: Pieter-Paul Giesberts --Reviewed-by: Hante Meuleman --Signed-off-by: Franky Lin --Signed-off-by: Arend van Spriel --Signed-off-by: Kalle Valo ----- -- ----- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c --+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c --@@ -1039,14 +1039,14 @@ static int brcmf_inetaddr_changed(struct -- return NOTIFY_OK; -- } -- for (i = 0; i < ARPOL_MAX_ENTRIES; i++) { --- if (addr_table[i] != 0) { --- brcmf_fil_iovar_data_set(ifp, --- "arp_hostip", &addr_table[i], --- sizeof(addr_table[i])); --- if (ret) --- brcmf_err("add arp ip err %d\n", --- ret); --- } --+ if (addr_table[i] == 0) --+ continue; --+ ret = brcmf_fil_iovar_data_set(ifp, "arp_hostip", --+ &addr_table[i], --+ sizeof(addr_table[i])); --+ if (ret) --+ brcmf_err("add arp ip err %d\n", --+ ret); -- } -- } -- break; -diff --git a/package/kernel/mac80211/patches/344-0008-brcmfmac-use-device-memsize-config-from-fw-if-define.patch b/package/kernel/mac80211/patches/344-0008-brcmfmac-use-device-memsize-config-from-fw-if-define.patch -deleted file mode 100644 -index 3de0f64..0000000 ---- a/package/kernel/mac80211/patches/344-0008-brcmfmac-use-device-memsize-config-from-fw-if-define.patch -+++ /dev/null -@@ -1,73 +0,0 @@ --From: Hante Meuleman --Date: Wed, 17 Feb 2016 11:26:57 +0100 --Subject: [PATCH] brcmfmac: use device memsize config from fw if defined -- --Newer type pcie devices have memory which get shared between fw and --hw. The division of this memory is done firmware compile time. As a --result the ramsize as used by driver needs to be adjusted for this. --This is done by reading the memory size from the firmware. -- --Reviewed-by: Arend Van Spriel --Reviewed-by: Franky (Zhenhui) Lin --Reviewed-by: Pieter-Paul Giesberts --Signed-off-by: Hante Meuleman --Signed-off-by: Arend van Spriel --Signed-off-by: Kalle Valo ----- -- ----- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c --+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c --@@ -207,6 +207,10 @@ static struct brcmf_firmware_mapping brc -- #define BRCMF_PCIE_CFGREG_REG_BAR3_CONFIG 0x4F4 -- #define BRCMF_PCIE_LINK_STATUS_CTRL_ASPM_ENAB 3 -- --+/* Magic number at a magic location to find RAM size */ --+#define BRCMF_RAMSIZE_MAGIC 0x534d4152 /* SMAR */ --+#define BRCMF_RAMSIZE_OFFSET 0x6c --+ -- -- struct brcmf_pcie_console { -- u32 base_addr; --@@ -1412,6 +1416,28 @@ static const struct brcmf_bus_ops brcmf_ -- }; -- -- --+static void --+brcmf_pcie_adjust_ramsize(struct brcmf_pciedev_info *devinfo, u8 *data, --+ u32 data_len) --+{ --+ __le32 *field; --+ u32 newsize; --+ --+ if (data_len < BRCMF_RAMSIZE_OFFSET + 8) --+ return; --+ --+ field = (__le32 *)&data[BRCMF_RAMSIZE_OFFSET]; --+ if (le32_to_cpup(field) != BRCMF_RAMSIZE_MAGIC) --+ return; --+ field++; --+ newsize = le32_to_cpup(field); --+ --+ brcmf_dbg(PCIE, "Found ramsize info in FW, adjusting to 0x%x\n", --+ newsize); --+ devinfo->ci->ramsize = newsize; --+} --+ --+ -- static int -- brcmf_pcie_init_share_ram_info(struct brcmf_pciedev_info *devinfo, -- u32 sharedram_addr) --@@ -1694,6 +1720,13 @@ static void brcmf_pcie_setup(struct devi -- -- brcmf_pcie_attach(devinfo); -- --+ /* Some of the firmwares have the size of the memory of the device --+ * defined inside the firmware. This is because part of the memory in --+ * the device is shared and the devision is determined by FW. Parse --+ * the firmware and adjust the chip memory size now. --+ */ --+ brcmf_pcie_adjust_ramsize(devinfo, (u8 *)fw->data, fw->size); --+ -- ret = brcmf_pcie_download_fw_nvram(devinfo, fw, nvram, nvram_len); -- if (ret) -- goto fail; -diff --git a/package/kernel/mac80211/patches/344-0009-brcmfmac-use-bar1-window-size-as-provided-by-pci-sub.patch b/package/kernel/mac80211/patches/344-0009-brcmfmac-use-bar1-window-size-as-provided-by-pci-sub.patch -deleted file mode 100644 -index ca03ffe..0000000 ---- a/package/kernel/mac80211/patches/344-0009-brcmfmac-use-bar1-window-size-as-provided-by-pci-sub.patch -+++ /dev/null -@@ -1,58 +0,0 @@ --From: Hante Meuleman --Date: Wed, 17 Feb 2016 11:26:58 +0100 --Subject: [PATCH] brcmfmac: use bar1 window size as provided by pci subsystem -- --The PCIE bar1 window size is specified by chip. Currently the --ioremap of bar1 was using a define which always matched the size --of bar1, but newer chips can have a different bar1 sizes. With --this patch the ioremap will be called with the by chip provided --window size. -- --Reviewed-by: Arend Van Spriel --Reviewed-by: Franky (Zhenhui) Lin --Reviewed-by: Pieter-Paul Giesberts --Signed-off-by: Hante Meuleman --Signed-off-by: Arend van Spriel --Signed-off-by: Kalle Valo ----- -- ----- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c --+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c --@@ -72,7 +72,6 @@ static struct brcmf_firmware_mapping brc -- -- #define BRCMF_PCIE_FW_UP_TIMEOUT 2000 /* msec */ -- ---#define BRCMF_PCIE_TCM_MAP_SIZE (4096 * 1024) -- #define BRCMF_PCIE_REG_MAP_SIZE (32 * 1024) -- -- /* backplane addres space accessed by BAR0 */ --@@ -252,7 +251,6 @@ struct brcmf_pciedev_info { -- char nvram_name[BRCMF_FW_NAME_LEN]; -- void __iomem *regs; -- void __iomem *tcm; --- u32 tcm_size; -- u32 ram_base; -- u32 ram_size; -- struct brcmf_chip *ci; --@@ -1592,8 +1590,7 @@ static int brcmf_pcie_get_resource(struc -- } -- -- devinfo->regs = ioremap_nocache(bar0_addr, BRCMF_PCIE_REG_MAP_SIZE); --- devinfo->tcm = ioremap_nocache(bar1_addr, BRCMF_PCIE_TCM_MAP_SIZE); --- devinfo->tcm_size = BRCMF_PCIE_TCM_MAP_SIZE; --+ devinfo->tcm = ioremap_nocache(bar1_addr, bar1_size); -- -- if (!devinfo->regs || !devinfo->tcm) { -- brcmf_err("ioremap() failed (%p,%p)\n", devinfo->regs, --@@ -1602,8 +1599,9 @@ static int brcmf_pcie_get_resource(struc -- } -- brcmf_dbg(PCIE, "Phys addr : reg space = %p base addr %#016llx\n", -- devinfo->regs, (unsigned long long)bar0_addr); --- brcmf_dbg(PCIE, "Phys addr : mem space = %p base addr %#016llx\n", --- devinfo->tcm, (unsigned long long)bar1_addr); --+ brcmf_dbg(PCIE, "Phys addr : mem space = %p base addr %#016llx size 0x%x\n", --+ devinfo->tcm, (unsigned long long)bar1_addr, --+ (unsigned int)bar1_size); -- -- return 0; -- } -diff --git a/package/kernel/mac80211/patches/344-0010-brcmfmac-add-support-for-the-PCIE-4366c0-chip.patch b/package/kernel/mac80211/patches/344-0010-brcmfmac-add-support-for-the-PCIE-4366c0-chip.patch -deleted file mode 100644 -index e4a8f30..0000000 ---- a/package/kernel/mac80211/patches/344-0010-brcmfmac-add-support-for-the-PCIE-4366c0-chip.patch -+++ /dev/null -@@ -1,34 +0,0 @@ --From: Hante Meuleman --Date: Wed, 17 Feb 2016 11:26:59 +0100 --Subject: [PATCH] brcmfmac: add support for the PCIE 4366c0 chip -- --A newer version of the 4366 PCIE chip has been released. Add --support for this version of the chip. -- --Reviewed-by: Arend Van Spriel --Reviewed-by: Pieter-Paul Giesberts --Signed-off-by: Hante Meuleman --Signed-off-by: Arend van Spriel --Signed-off-by: Kalle Valo ----- -- ----- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c --+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c --@@ -53,6 +53,7 @@ BRCMF_FW_NVRAM_DEF(4358, "brcmfmac4358-p -- BRCMF_FW_NVRAM_DEF(4359, "brcmfmac4359-pcie.bin", "brcmfmac4359-pcie.txt"); -- BRCMF_FW_NVRAM_DEF(4365B, "brcmfmac4365b-pcie.bin", "brcmfmac4365b-pcie.txt"); -- BRCMF_FW_NVRAM_DEF(4366B, "brcmfmac4366b-pcie.bin", "brcmfmac4366b-pcie.txt"); --+BRCMF_FW_NVRAM_DEF(4366C, "brcmfmac4366c-pcie.bin", "brcmfmac4366c-pcie.txt"); -- BRCMF_FW_NVRAM_DEF(4371, "brcmfmac4371-pcie.bin", "brcmfmac4371-pcie.txt"); -- -- static struct brcmf_firmware_mapping brcmf_pcie_fwnames[] = { --@@ -66,7 +67,8 @@ static struct brcmf_firmware_mapping brc -- BRCMF_FW_NVRAM_ENTRY(BRCM_CC_4358_CHIP_ID, 0xFFFFFFFF, 4358), -- BRCMF_FW_NVRAM_ENTRY(BRCM_CC_4359_CHIP_ID, 0xFFFFFFFF, 4359), -- BRCMF_FW_NVRAM_ENTRY(BRCM_CC_4365_CHIP_ID, 0xFFFFFFFF, 4365B), --- BRCMF_FW_NVRAM_ENTRY(BRCM_CC_4366_CHIP_ID, 0xFFFFFFFF, 4366B), --+ BRCMF_FW_NVRAM_ENTRY(BRCM_CC_4366_CHIP_ID, 0x0000000F, 4366B), --+ BRCMF_FW_NVRAM_ENTRY(BRCM_CC_4366_CHIP_ID, 0xFFFFFFF0, 4366C), -- BRCMF_FW_NVRAM_ENTRY(BRCM_CC_4371_CHIP_ID, 0xFFFFFFFF, 4371), -- }; -- -diff --git a/package/kernel/mac80211/patches/344-0011-brcmfmac-remove-pcie-gen1-support.patch b/package/kernel/mac80211/patches/344-0011-brcmfmac-remove-pcie-gen1-support.patch -deleted file mode 100644 -index f99f6db..0000000 ---- a/package/kernel/mac80211/patches/344-0011-brcmfmac-remove-pcie-gen1-support.patch -+++ /dev/null -@@ -1,221 +0,0 @@ --From: Hante Meuleman --Date: Wed, 17 Feb 2016 11:27:00 +0100 --Subject: [PATCH] brcmfmac: remove pcie gen1 support -- --The PCIE bus driver supports older gen1 (v1) chips, but there is no --actual device which is using this older pcie core which is supported --by brcmfmac. Remove all gen1 related code. -- --Reviewed-by: Arend Van Spriel --Reviewed-by: Franky (Zhenhui) Lin --Reviewed-by: Pieter-Paul Giesberts --Signed-off-by: Hante Meuleman --Signed-off-by: Arend van Spriel --Signed-off-by: Kalle Valo ----- -- ----- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c --+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c --@@ -100,9 +100,6 @@ static struct brcmf_firmware_mapping brc -- #define BRCMF_PCIE_PCIE2REG_CONFIGDATA 0x124 -- #define BRCMF_PCIE_PCIE2REG_H2D_MAILBOX 0x140 -- ---#define BRCMF_PCIE_GENREV1 1 ---#define BRCMF_PCIE_GENREV2 2 --- -- #define BRCMF_PCIE2_INTA 0x01 -- #define BRCMF_PCIE2_INTB 0x02 -- --@@ -257,9 +254,7 @@ struct brcmf_pciedev_info { -- u32 ram_size; -- struct brcmf_chip *ci; -- u32 coreid; --- u32 generic_corerev; -- struct brcmf_pcie_shared_info shared; --- void (*ringbell)(struct brcmf_pciedev_info *devinfo); -- wait_queue_head_t mbdata_resp_wait; -- bool mbdata_completed; -- bool irq_allocated; --@@ -746,68 +741,22 @@ static void brcmf_pcie_bus_console_read( -- } -- -- ---static __used void brcmf_pcie_ringbell_v1(struct brcmf_pciedev_info *devinfo) ---{ --- u32 reg_value; --- --- brcmf_dbg(PCIE, "RING !\n"); --- reg_value = brcmf_pcie_read_reg32(devinfo, --- BRCMF_PCIE_PCIE2REG_MAILBOXINT); --- reg_value |= BRCMF_PCIE2_INTB; --- brcmf_pcie_write_reg32(devinfo, BRCMF_PCIE_PCIE2REG_MAILBOXINT, --- reg_value); ---} --- --- ---static void brcmf_pcie_ringbell_v2(struct brcmf_pciedev_info *devinfo) ---{ --- brcmf_dbg(PCIE, "RING !\n"); --- /* Any arbitrary value will do, lets use 1 */ --- brcmf_pcie_write_reg32(devinfo, BRCMF_PCIE_PCIE2REG_H2D_MAILBOX, 1); ---} --- --- -- static void brcmf_pcie_intr_disable(struct brcmf_pciedev_info *devinfo) -- { --- if (devinfo->generic_corerev == BRCMF_PCIE_GENREV1) --- pci_write_config_dword(devinfo->pdev, BRCMF_PCIE_REG_INTMASK, --- 0); --- else --- brcmf_pcie_write_reg32(devinfo, BRCMF_PCIE_PCIE2REG_MAILBOXMASK, --- 0); --+ brcmf_pcie_write_reg32(devinfo, BRCMF_PCIE_PCIE2REG_MAILBOXMASK, 0); -- } -- -- -- static void brcmf_pcie_intr_enable(struct brcmf_pciedev_info *devinfo) -- { --- if (devinfo->generic_corerev == BRCMF_PCIE_GENREV1) --- pci_write_config_dword(devinfo->pdev, BRCMF_PCIE_REG_INTMASK, --- BRCMF_PCIE_INT_DEF); --- else --- brcmf_pcie_write_reg32(devinfo, BRCMF_PCIE_PCIE2REG_MAILBOXMASK, --- BRCMF_PCIE_MB_INT_D2H_DB | --- BRCMF_PCIE_MB_INT_FN0_0 | --- BRCMF_PCIE_MB_INT_FN0_1); --+ brcmf_pcie_write_reg32(devinfo, BRCMF_PCIE_PCIE2REG_MAILBOXMASK, --+ BRCMF_PCIE_MB_INT_D2H_DB | --+ BRCMF_PCIE_MB_INT_FN0_0 | --+ BRCMF_PCIE_MB_INT_FN0_1); -- } -- -- ---static irqreturn_t brcmf_pcie_quick_check_isr_v1(int irq, void *arg) ---{ --- struct brcmf_pciedev_info *devinfo = (struct brcmf_pciedev_info *)arg; --- u32 status; --- --- status = 0; --- pci_read_config_dword(devinfo->pdev, BRCMF_PCIE_REG_INTSTATUS, &status); --- if (status) { --- brcmf_pcie_intr_disable(devinfo); --- brcmf_dbg(PCIE, "Enter\n"); --- return IRQ_WAKE_THREAD; --- } --- return IRQ_NONE; ---} --- --- ---static irqreturn_t brcmf_pcie_quick_check_isr_v2(int irq, void *arg) --+static irqreturn_t brcmf_pcie_quick_check_isr(int irq, void *arg) -- { -- struct brcmf_pciedev_info *devinfo = (struct brcmf_pciedev_info *)arg; -- --@@ -820,29 +769,7 @@ static irqreturn_t brcmf_pcie_quick_chec -- } -- -- ---static irqreturn_t brcmf_pcie_isr_thread_v1(int irq, void *arg) ---{ --- struct brcmf_pciedev_info *devinfo = (struct brcmf_pciedev_info *)arg; --- const struct pci_dev *pdev = devinfo->pdev; --- u32 status; --- --- devinfo->in_irq = true; --- status = 0; --- pci_read_config_dword(pdev, BRCMF_PCIE_REG_INTSTATUS, &status); --- brcmf_dbg(PCIE, "Enter %x\n", status); --- if (status) { --- pci_write_config_dword(pdev, BRCMF_PCIE_REG_INTSTATUS, status); --- if (devinfo->state == BRCMFMAC_PCIE_STATE_UP) --- brcmf_proto_msgbuf_rx_trigger(&devinfo->pdev->dev); --- } --- if (devinfo->state == BRCMFMAC_PCIE_STATE_UP) --- brcmf_pcie_intr_enable(devinfo); --- devinfo->in_irq = false; --- return IRQ_HANDLED; ---} --- --- ---static irqreturn_t brcmf_pcie_isr_thread_v2(int irq, void *arg) --+static irqreturn_t brcmf_pcie_isr_thread(int irq, void *arg) -- { -- struct brcmf_pciedev_info *devinfo = (struct brcmf_pciedev_info *)arg; -- u32 status; --@@ -879,28 +806,14 @@ static int brcmf_pcie_request_irq(struct -- brcmf_pcie_intr_disable(devinfo); -- -- brcmf_dbg(PCIE, "Enter\n"); --- /* is it a v1 or v2 implementation */ --+ -- pci_enable_msi(pdev); --- if (devinfo->generic_corerev == BRCMF_PCIE_GENREV1) { --- if (request_threaded_irq(pdev->irq, --- brcmf_pcie_quick_check_isr_v1, --- brcmf_pcie_isr_thread_v1, --- IRQF_SHARED, "brcmf_pcie_intr", --- devinfo)) { --- pci_disable_msi(pdev); --- brcmf_err("Failed to request IRQ %d\n", pdev->irq); --- return -EIO; --- } --- } else { --- if (request_threaded_irq(pdev->irq, --- brcmf_pcie_quick_check_isr_v2, --- brcmf_pcie_isr_thread_v2, --- IRQF_SHARED, "brcmf_pcie_intr", --- devinfo)) { --- pci_disable_msi(pdev); --- brcmf_err("Failed to request IRQ %d\n", pdev->irq); --- return -EIO; --- } --+ if (request_threaded_irq(pdev->irq, brcmf_pcie_quick_check_isr, --+ brcmf_pcie_isr_thread, IRQF_SHARED, --+ "brcmf_pcie_intr", devinfo)) { --+ pci_disable_msi(pdev); --+ brcmf_err("Failed to request IRQ %d\n", pdev->irq); --+ return -EIO; -- } -- devinfo->irq_allocated = true; -- return 0; --@@ -931,16 +844,9 @@ static void brcmf_pcie_release_irq(struc -- if (devinfo->in_irq) -- brcmf_err("Still in IRQ (processing) !!!\n"); -- --- if (devinfo->generic_corerev == BRCMF_PCIE_GENREV1) { --- status = 0; --- pci_read_config_dword(pdev, BRCMF_PCIE_REG_INTSTATUS, &status); --- pci_write_config_dword(pdev, BRCMF_PCIE_REG_INTSTATUS, status); --- } else { --- status = brcmf_pcie_read_reg32(devinfo, --- BRCMF_PCIE_PCIE2REG_MAILBOXINT); --- brcmf_pcie_write_reg32(devinfo, BRCMF_PCIE_PCIE2REG_MAILBOXINT, --- status); --- } --+ status = brcmf_pcie_read_reg32(devinfo, BRCMF_PCIE_PCIE2REG_MAILBOXINT); --+ brcmf_pcie_write_reg32(devinfo, BRCMF_PCIE_PCIE2REG_MAILBOXINT, status); --+ -- devinfo->irq_allocated = false; -- } -- --@@ -989,7 +895,9 @@ static int brcmf_pcie_ring_mb_ring_bell( -- if (devinfo->state != BRCMFMAC_PCIE_STATE_UP) -- return -EIO; -- --- devinfo->ringbell(devinfo); --+ brcmf_dbg(PCIE, "RING !\n"); --+ /* Any arbitrary value will do, lets use 1 */ --+ brcmf_pcie_write_reg32(devinfo, BRCMF_PCIE_PCIE2REG_H2D_MAILBOX, 1); -- -- return 0; -- } --@@ -1503,9 +1411,6 @@ static int brcmf_pcie_download_fw_nvram( -- u32 address; -- u32 resetintr; -- --- devinfo->ringbell = brcmf_pcie_ringbell_v2; --- devinfo->generic_corerev = BRCMF_PCIE_GENREV2; --- -- brcmf_dbg(PCIE, "Halt ARM.\n"); -- err = brcmf_pcie_enter_download_state(devinfo); -- if (err) -diff --git a/package/kernel/mac80211/patches/344-0012-brcmfmac-increase-timeout-for-tx-eapol.patch b/package/kernel/mac80211/patches/344-0012-brcmfmac-increase-timeout-for-tx-eapol.patch -deleted file mode 100644 -index 4adfc2d..0000000 ---- a/package/kernel/mac80211/patches/344-0012-brcmfmac-increase-timeout-for-tx-eapol.patch -+++ /dev/null -@@ -1,30 +0,0 @@ --From: Hante Meuleman --Date: Wed, 17 Feb 2016 11:27:01 +0100 --Subject: [PATCH] brcmfmac: increase timeout for tx eapol -- --When keys get set and updated this has to happen after eapol got --transmitted (without key or old key) before the key can be updated. --To make sure the order of sending eapol and configuring key is done --correctly a timeout for tx of eapol is applied. This timeout is set --to 50 msec, which is not always enough. Especially in AP mode and --key updates the timeout may need to be much longer because client(s) --can be in powersave. Increase the timeout from 50 to 950 msec. -- --Reviewed-by: Arend Van Spriel --Reviewed-by: Pieter-Paul Giesberts --Signed-off-by: Hante Meuleman --Signed-off-by: Arend van Spriel --Signed-off-by: Kalle Valo ----- -- ----- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c --+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c --@@ -42,7 +42,7 @@ MODULE_AUTHOR("Broadcom Corporation"); -- MODULE_DESCRIPTION("Broadcom 802.11 wireless LAN fullmac driver."); -- MODULE_LICENSE("Dual BSD/GPL"); -- ---#define MAX_WAIT_FOR_8021X_TX msecs_to_jiffies(50) --+#define MAX_WAIT_FOR_8021X_TX msecs_to_jiffies(950) -- -- /* AMPDU rx reordering definitions */ -- #define BRCMF_RXREORDER_FLOWID_OFFSET 0 -diff --git a/package/kernel/mac80211/patches/344-0013-brcmfmac-move-module-init-and-exit-to-common.patch b/package/kernel/mac80211/patches/344-0013-brcmfmac-move-module-init-and-exit-to-common.patch -deleted file mode 100644 -index bd62781..0000000 ---- a/package/kernel/mac80211/patches/344-0013-brcmfmac-move-module-init-and-exit-to-common.patch -+++ /dev/null -@@ -1,135 +0,0 @@ --From: Hante Meuleman --Date: Wed, 17 Feb 2016 11:27:02 +0100 --Subject: [PATCH] brcmfmac: move module init and exit to common -- --In preparation of module parameters for all devices the module init --and exit routines are moved to the common file. -- --Reviewed-by: Arend Van Spriel --Reviewed-by: Franky (Zhenhui) Lin --Reviewed-by: Pieter-Paul Giesberts --Signed-off-by: Hante Meuleman --Signed-off-by: Arend van Spriel --Signed-off-by: Kalle Valo ----- -- ----- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c --+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c --@@ -28,6 +28,10 @@ -- #include "tracepoint.h" -- #include "common.h" -- --+MODULE_AUTHOR("Broadcom Corporation"); --+MODULE_DESCRIPTION("Broadcom 802.11 wireless LAN fullmac driver."); --+MODULE_LICENSE("Dual BSD/GPL"); --+ -- const u8 ALLFFMAC[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; -- -- #define BRCMF_DEFAULT_SCAN_CHANNEL_TIME 40 --@@ -221,7 +225,7 @@ void __brcmf_dbg(u32 level, const char * -- } -- #endif -- ---void brcmf_mp_attach(void) --+static void brcmf_mp_attach(void) -- { -- strlcpy(brcmf_mp_global.firmware_path, brcmf_firmware_path, -- BRCMF_FW_ALTPATH_LEN); --@@ -249,3 +253,33 @@ void brcmf_mp_device_detach(struct brcmf -- kfree(drvr->settings); -- } -- --+static int __init brcmfmac_module_init(void) --+{ --+ int err; --+ --+ /* Initialize debug system first */ --+ brcmf_debugfs_init(); --+ --+#ifdef CPTCFG_BRCMFMAC_SDIO --+ brcmf_sdio_init(); --+#endif --+ /* Initialize global module paramaters */ --+ brcmf_mp_attach(); --+ --+ /* Continue the initialization by registering the different busses */ --+ err = brcmf_core_init(); --+ if (err) --+ brcmf_debugfs_exit(); --+ --+ return err; --+} --+ --+static void __exit brcmfmac_module_exit(void) --+{ --+ brcmf_core_exit(); --+ brcmf_debugfs_exit(); --+} --+ --+module_init(brcmfmac_module_init); --+module_exit(brcmfmac_module_exit); --+ ----- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.h --+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.h --@@ -89,7 +89,6 @@ struct brcmf_mp_device { -- struct cc_translate *country_codes; -- }; -- ---void brcmf_mp_attach(void); -- int brcmf_mp_device_attach(struct brcmf_pub *drvr); -- void brcmf_mp_device_detach(struct brcmf_pub *drvr); -- #ifdef DEBUG ----- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c --+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c --@@ -38,10 +38,6 @@ -- #include "pcie.h" -- #include "common.h" -- ---MODULE_AUTHOR("Broadcom Corporation"); ---MODULE_DESCRIPTION("Broadcom 802.11 wireless LAN fullmac driver."); ---MODULE_LICENSE("Dual BSD/GPL"); --- -- #define MAX_WAIT_FOR_8021X_TX msecs_to_jiffies(950) -- -- /* AMPDU rx reordering definitions */ --@@ -1422,19 +1418,15 @@ static void brcmf_driver_register(struct -- } -- static DECLARE_WORK(brcmf_driver_work, brcmf_driver_register); -- ---static int __init brcmfmac_module_init(void) --+int __init brcmf_core_init(void) -- { --- brcmf_debugfs_init(); ---#ifdef CPTCFG_BRCMFMAC_SDIO --- brcmf_sdio_init(); ---#endif -- if (!schedule_work(&brcmf_driver_work)) -- return -EBUSY; -- -- return 0; -- } -- ---static void __exit brcmfmac_module_exit(void) --+void __exit brcmf_core_exit(void) -- { -- cancel_work_sync(&brcmf_driver_work); -- --@@ -1447,8 +1439,5 @@ static void __exit brcmfmac_module_exit( -- #ifdef CPTCFG_BRCMFMAC_PCIE -- brcmf_pcie_exit(); -- #endif --- brcmf_debugfs_exit(); -- } -- ---module_init(brcmfmac_module_init); ---module_exit(brcmfmac_module_exit); ----- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h --+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h --@@ -227,5 +227,7 @@ void brcmf_txflowblock_if(struct brcmf_i -- void brcmf_txfinalize(struct brcmf_if *ifp, struct sk_buff *txp, bool success); -- void brcmf_netif_rx(struct brcmf_if *ifp, struct sk_buff *skb); -- void brcmf_net_setcarrier(struct brcmf_if *ifp, bool on); --+int __init brcmf_core_init(void); --+void __exit brcmf_core_exit(void); -- -- #endif /* BRCMFMAC_CORE_H */ -diff --git a/package/kernel/mac80211/patches/344-0014-brcmfmac-add-wowl-gtk-rekeying-offload-support.patch b/package/kernel/mac80211/patches/344-0014-brcmfmac-add-wowl-gtk-rekeying-offload-support.patch -deleted file mode 100644 -index 577ca8e..0000000 ---- a/package/kernel/mac80211/patches/344-0014-brcmfmac-add-wowl-gtk-rekeying-offload-support.patch -+++ /dev/null -@@ -1,260 +0,0 @@ --From: Hante Meuleman --Date: Wed, 17 Feb 2016 11:27:03 +0100 --Subject: [PATCH] brcmfmac: add wowl gtk rekeying offload support -- --This patch adds support for gtk rekeying offload and for gtk --rekeying failure during wowl mode. -- --Reviewed-by: Arend Van Spriel --Reviewed-by: Franky (Zhenhui) Lin --Reviewed-by: Pieter-Paul Giesberts --Signed-off-by: Hante Meuleman --Signed-off-by: Arend van Spriel --Signed-off-by: Kalle Valo ----- -- ----- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c --+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c --@@ -3526,6 +3526,10 @@ static void brcmf_report_wowl_wakeind(st -- else -- wakeup_data.net_detect = cfg->wowl.nd_info; -- } --+ if (wakeind & BRCMF_WOWL_GTK_FAILURE) { --+ brcmf_dbg(INFO, "WOWL Wake indicator: BRCMF_WOWL_GTK_FAILURE\n"); --+ wakeup_data.gtk_rekey_failure = true; --+ } -- } else { -- wakeup = NULL; -- } --@@ -3607,6 +3611,8 @@ static void brcmf_configure_wowl(struct -- brcmf_fweh_register(cfg->pub, BRCMF_E_PFN_NET_FOUND, -- brcmf_wowl_nd_results); -- } --+ if (wowl->gtk_rekey_failure) --+ wowl_config |= BRCMF_WOWL_GTK_FAILURE; -- if (!test_bit(BRCMF_VIF_STATUS_CONNECTED, &ifp->vif->sme_state)) -- wowl_config |= BRCMF_WOWL_UNASSOC; -- --@@ -4874,7 +4880,32 @@ static int brcmf_cfg80211_tdls_oper(stru -- return ret; -- } -- ---static struct cfg80211_ops wl_cfg80211_ops = { --+#ifdef CONFIG_PM --+static int --+brcmf_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *ndev, --+ struct cfg80211_gtk_rekey_data *gtk) --+{ --+ struct brcmf_if *ifp = netdev_priv(ndev); --+ struct brcmf_gtk_keyinfo_le gtk_le; --+ int ret; --+ --+ brcmf_dbg(TRACE, "Enter, bssidx=%d\n", ifp->bsscfgidx); --+ --+ memcpy(gtk_le.kck, gtk->kck, sizeof(gtk_le.kck)); --+ memcpy(gtk_le.kek, gtk->kek, sizeof(gtk_le.kek)); --+ memcpy(gtk_le.replay_counter, gtk->replay_ctr, --+ sizeof(gtk_le.replay_counter)); --+ --+ 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); --+ --+ return ret; --+} --+#endif --+ --+static struct cfg80211_ops brcmf_cfg80211_ops = { -- .add_virtual_intf = brcmf_cfg80211_add_iface, -- .del_virtual_intf = brcmf_cfg80211_del_iface, -- .change_virtual_intf = brcmf_cfg80211_change_iface, --@@ -6139,19 +6170,18 @@ static void brcmf_wiphy_wowl_params(stru -- { -- #ifdef CONFIG_PM -- struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); --- s32 err; --- u32 wowl_cap; -- -- if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_PNO)) { --- err = brcmf_fil_iovar_int_get(ifp, "wowl_cap", &wowl_cap); --- if (!err) { --- if (wowl_cap & BRCMF_WOWL_PFN_FOUND) { --- brcmf_wowlan_support.flags |= --- WIPHY_WOWLAN_NET_DETECT; --- init_waitqueue_head(&cfg->wowl.nd_data_wait); --- } --+ if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_WOWL_ND)) { --+ brcmf_wowlan_support.flags |= WIPHY_WOWLAN_NET_DETECT; --+ init_waitqueue_head(&cfg->wowl.nd_data_wait); -- } -- } --+ if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_WOWL_GTK)) { --+ brcmf_wowlan_support.flags |= WIPHY_WOWLAN_SUPPORTS_GTK_REKEY; --+ brcmf_wowlan_support.flags |= WIPHY_WOWLAN_GTK_REKEY_FAILURE; --+ } --+ -- wiphy->wowlan = &brcmf_wowlan_support; -- #endif -- } --@@ -6538,6 +6568,7 @@ struct brcmf_cfg80211_info *brcmf_cfg802 -- struct net_device *ndev = brcmf_get_ifp(drvr, 0)->ndev; -- struct brcmf_cfg80211_info *cfg; -- struct wiphy *wiphy; --+ struct cfg80211_ops *ops; -- struct brcmf_cfg80211_vif *vif; -- struct brcmf_if *ifp; -- s32 err = 0; --@@ -6549,8 +6580,17 @@ struct brcmf_cfg80211_info *brcmf_cfg802 -- return NULL; -- } -- --+ ops = kzalloc(sizeof(*ops), GFP_KERNEL); --+ if (!ops) --+ return NULL; --+ --+ memcpy(ops, &brcmf_cfg80211_ops, sizeof(*ops)); -- ifp = netdev_priv(ndev); --- wiphy = wiphy_new(&wl_cfg80211_ops, sizeof(struct brcmf_cfg80211_info)); --+#ifdef CONFIG_PM --+ if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_WOWL_GTK)) --+ ops->set_rekey_data = brcmf_cfg80211_set_rekey_data; --+#endif --+ wiphy = wiphy_new(ops, sizeof(struct brcmf_cfg80211_info)); -- if (!wiphy) { -- brcmf_err("Could not allocate wiphy device\n"); -- return NULL; --@@ -6560,6 +6600,7 @@ struct brcmf_cfg80211_info *brcmf_cfg802 -- -- cfg = wiphy_priv(wiphy); -- cfg->wiphy = wiphy; --+ cfg->ops = ops; -- cfg->pub = drvr; -- init_vif_event(&cfg->vif_event); -- INIT_LIST_HEAD(&cfg->vif_list); --@@ -6686,6 +6727,7 @@ priv_out: -- ifp->vif = NULL; -- wiphy_out: -- brcmf_free_wiphy(wiphy); --+ kfree(ops); -- return NULL; -- } -- --@@ -6696,6 +6738,7 @@ void brcmf_cfg80211_detach(struct brcmf_ -- -- brcmf_btcoex_detach(cfg); -- wiphy_unregister(cfg->wiphy); --+ kfree(cfg->ops); -- wl_deinit_priv(cfg); -- brcmf_free_wiphy(cfg->wiphy); -- } ----- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h --+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h --@@ -256,6 +256,7 @@ struct brcmf_cfg80211_wowl { -- * struct brcmf_cfg80211_info - dongle private data of cfg80211 interface -- * -- * @wiphy: wiphy object for cfg80211 interface. --+ * @ops: pointer to copy of ops as registered with wiphy object. -- * @conf: dongle configuration. -- * @p2p: peer-to-peer specific information. -- * @btcoex: Bluetooth coexistence information. --@@ -288,6 +289,7 @@ 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/feature.c --+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c --@@ -136,6 +136,7 @@ void brcmf_feat_attach(struct brcmf_pub -- { -- struct brcmf_if *ifp = brcmf_get_ifp(drvr, 0); -- struct brcmf_pno_macaddr_le pfn_mac; --+ u32 wowl_cap; -- s32 err; -- -- brcmf_feat_firmware_capabilities(ifp); --@@ -143,6 +144,17 @@ void brcmf_feat_attach(struct brcmf_pub -- brcmf_feat_iovar_int_get(ifp, BRCMF_FEAT_PNO, "pfn"); -- if (drvr->bus_if->wowl_supported) -- brcmf_feat_iovar_int_get(ifp, BRCMF_FEAT_WOWL, "wowl"); --+ if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_WOWL)) { --+ err = brcmf_fil_iovar_int_get(ifp, "wowl_cap", &wowl_cap); --+ if (!err) { --+ if (wowl_cap & BRCMF_WOWL_PFN_FOUND) --+ ifp->drvr->feat_flags |= --+ BIT(BRCMF_FEAT_WOWL_ND); --+ if (wowl_cap & BRCMF_WOWL_GTK_FAILURE) --+ ifp->drvr->feat_flags |= --+ BIT(BRCMF_FEAT_WOWL_GTK); --+ } --+ } -- /* MBSS does not work for 43362 */ -- if (drvr->bus_if->chip == BRCM_CC_43362_CHIP_ID) -- ifp->drvr->feat_flags &= ~BIT(BRCMF_FEAT_MBSS); ----- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.h --+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.h --@@ -27,6 +27,8 @@ -- * RSDB: Real Simultaneous Dual Band -- * TDLS: Tunneled Direct Link Setup -- * SCAN_RANDOM_MAC: Random MAC during (net detect) scheduled scan. --+ * WOWL_ND: WOWL net detect (PNO) --+ * WOWL_GTK: (WOWL) GTK rekeying offload -- */ -- #define BRCMF_FEAT_LIST \ -- BRCMF_FEAT_DEF(MBSS) \ --@@ -36,7 +38,9 @@ -- BRCMF_FEAT_DEF(P2P) \ -- BRCMF_FEAT_DEF(RSDB) \ -- BRCMF_FEAT_DEF(TDLS) \ --- BRCMF_FEAT_DEF(SCAN_RANDOM_MAC) --+ BRCMF_FEAT_DEF(SCAN_RANDOM_MAC) \ --+ BRCMF_FEAT_DEF(WOWL_ND) \ --+ BRCMF_FEAT_DEF(WOWL_GTK) -- -- /* -- * Quirks: ----- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil_types.h --+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil_types.h --@@ -111,7 +111,9 @@ -- /* Wakeup if received matched secured pattern: */ -- #define BRCMF_WOWL_SECURE (1 << 25) -- /* Wakeup on finding preferred network */ ---#define BRCMF_WOWL_PFN_FOUND (1 << 26) --+#define BRCMF_WOWL_PFN_FOUND (1 << 27) --+/* Wakeup on receiving pairwise key EAP packets: */ --+#define WIPHY_WOWL_EAP_PK (1 << 28) -- /* Link Down indication in WoWL mode: */ -- #define BRCMF_WOWL_LINKDOWN (1 << 31) -- --@@ -136,6 +138,10 @@ -- -- #define BRCMF_MCSSET_LEN 16 -- --+#define BRCMF_RSN_KCK_LENGTH 16 --+#define BRCMF_RSN_KEK_LENGTH 16 --+#define BRCMF_RSN_REPLAY_LEN 8 --+ -- /* join preference types for join_pref iovar */ -- enum brcmf_join_pref_types { -- BRCMF_JOIN_PREF_RSSI = 1, --@@ -789,4 +795,17 @@ struct brcmf_pktcnt_le { -- __le32 rx_ocast_good_pkt; -- }; -- --+/** --+ * struct brcmf_gtk_keyinfo_le - GTP rekey data --+ * --+ * @kck: key confirmation key. --+ * @kek: key encryption key. --+ * @replay_counter: replay counter. --+ */ --+struct brcmf_gtk_keyinfo_le { --+ u8 kck[BRCMF_RSN_KCK_LENGTH]; --+ u8 kek[BRCMF_RSN_KEK_LENGTH]; --+ u8 replay_counter[BRCMF_RSN_REPLAY_LEN]; --+}; --+ -- #endif /* FWIL_TYPES_H_ */ -diff --git a/package/kernel/mac80211/patches/344-0015-brcmfmac-move-platform-data-retrieval-code-to-common.patch b/package/kernel/mac80211/patches/344-0015-brcmfmac-move-platform-data-retrieval-code-to-common.patch -deleted file mode 100644 -index 2685238..0000000 ---- a/package/kernel/mac80211/patches/344-0015-brcmfmac-move-platform-data-retrieval-code-to-common.patch -+++ /dev/null -@@ -1,385 +0,0 @@ --From: Hante Meuleman --Date: Wed, 17 Feb 2016 11:27:04 +0100 --Subject: [PATCH] brcmfmac: move platform data retrieval code to common -- --In preparation of module parameters for all devices the module --platform data retrieval is moved from sdio to common. It is still --only used for sdio devices. -- --Reviewed-by: Arend Van Spriel --Reviewed-by: Franky (Zhenhui) Lin --Reviewed-by: Pieter-Paul Giesberts --Signed-off-by: Hante Meuleman --Signed-off-by: Arend van Spriel --Signed-off-by: Kalle Valo ----- -- ----- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c --+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c --@@ -27,8 +27,6 @@ -- #include -- #include -- #include ---#include ---#include -- #include -- #include -- #include --@@ -46,7 +44,6 @@ -- #include "bus.h" -- #include "debug.h" -- #include "sdio.h" ---#include "of.h" -- #include "core.h" -- #include "common.h" -- --@@ -106,18 +103,18 @@ static void brcmf_sdiod_dummy_irqhandler -- -- int brcmf_sdiod_intr_register(struct brcmf_sdio_dev *sdiodev) -- { --+ struct brcmfmac_sdio_platform_data *pdata; -- int ret = 0; -- u8 data; -- u32 addr, gpiocontrol; -- unsigned long flags; -- --- if ((sdiodev->pdata) && (sdiodev->pdata->oob_irq_supported)) { --+ pdata = sdiodev->pdata; --+ if ((pdata) && (pdata->oob_irq_supported)) { -- brcmf_dbg(SDIO, "Enter, register OOB IRQ %d\n", --- sdiodev->pdata->oob_irq_nr); --- ret = request_irq(sdiodev->pdata->oob_irq_nr, --- brcmf_sdiod_oob_irqhandler, --- sdiodev->pdata->oob_irq_flags, --- "brcmf_oob_intr", --+ pdata->oob_irq_nr); --+ ret = request_irq(pdata->oob_irq_nr, brcmf_sdiod_oob_irqhandler, --+ pdata->oob_irq_flags, "brcmf_oob_intr", -- &sdiodev->func[1]->dev); -- if (ret != 0) { -- brcmf_err("request_irq failed %d\n", ret); --@@ -129,7 +126,7 @@ int brcmf_sdiod_intr_register(struct brc -- sdiodev->irq_en = true; -- spin_unlock_irqrestore(&sdiodev->irq_en_lock, flags); -- --- ret = enable_irq_wake(sdiodev->pdata->oob_irq_nr); --+ ret = enable_irq_wake(pdata->oob_irq_nr); -- if (ret != 0) { -- brcmf_err("enable_irq_wake failed %d\n", ret); -- return ret; --@@ -158,7 +155,7 @@ int brcmf_sdiod_intr_register(struct brc -- -- /* redirect, configure and enable io for interrupt signal */ -- data = SDIO_SEPINT_MASK | SDIO_SEPINT_OE; --- if (sdiodev->pdata->oob_irq_flags & IRQF_TRIGGER_HIGH) --+ if (pdata->oob_irq_flags & IRQF_TRIGGER_HIGH) -- data |= SDIO_SEPINT_ACT_HI; -- brcmf_sdiod_regwb(sdiodev, SDIO_CCCR_BRCM_SEPINT, data, &ret); -- --@@ -176,9 +173,12 @@ int brcmf_sdiod_intr_register(struct brc -- -- int brcmf_sdiod_intr_unregister(struct brcmf_sdio_dev *sdiodev) -- { --+ struct brcmfmac_sdio_platform_data *pdata; --+ -- brcmf_dbg(SDIO, "Entering\n"); -- --- if ((sdiodev->pdata) && (sdiodev->pdata->oob_irq_supported)) { --+ pdata = sdiodev->pdata; --+ if ((pdata) && (pdata->oob_irq_supported)) { -- sdio_claim_host(sdiodev->func[1]); -- brcmf_sdiod_regwb(sdiodev, SDIO_CCCR_BRCM_SEPINT, 0, NULL); -- brcmf_sdiod_regwb(sdiodev, SDIO_CCCR_IENx, 0, NULL); --@@ -187,11 +187,10 @@ int brcmf_sdiod_intr_unregister(struct b -- if (sdiodev->oob_irq_requested) { -- sdiodev->oob_irq_requested = false; -- if (sdiodev->irq_wake) { --- disable_irq_wake(sdiodev->pdata->oob_irq_nr); --+ disable_irq_wake(pdata->oob_irq_nr); -- sdiodev->irq_wake = false; -- } --- free_irq(sdiodev->pdata->oob_irq_nr, --- &sdiodev->func[1]->dev); --+ free_irq(pdata->oob_irq_nr, &sdiodev->func[1]->dev); -- sdiodev->irq_en = false; -- } -- } else { --@@ -1103,8 +1102,6 @@ static const struct sdio_device_id brcmf -- }; -- MODULE_DEVICE_TABLE(sdio, brcmf_sdmmc_ids); -- ---static struct brcmfmac_sdio_platform_data *brcmfmac_sdio_pdata; --- -- -- static void brcmf_sdiod_acpi_set_power_manageable(struct device *dev, -- int val) --@@ -1167,10 +1164,7 @@ static int brcmf_ops_sdio_probe(struct s -- dev_set_drvdata(&func->dev, bus_if); -- dev_set_drvdata(&sdiodev->func[1]->dev, bus_if); -- sdiodev->dev = &sdiodev->func[1]->dev; --- sdiodev->pdata = brcmfmac_sdio_pdata; --- --- if (!sdiodev->pdata) --- brcmf_of_probe(sdiodev); --+ sdiodev->pdata = brcmf_get_module_param(sdiodev->dev); -- -- #ifdef CONFIG_PM_SLEEP -- /* wowl can be supported when KEEP_POWER is true and (WAKE_SDIO_IRQ --@@ -1296,7 +1290,7 @@ static const struct dev_pm_ops brcmf_sdi -- static struct sdio_driver brcmf_sdmmc_driver = { -- .probe = brcmf_ops_sdio_probe, -- .remove = brcmf_ops_sdio_remove, --- .name = BRCMFMAC_SDIO_PDATA_NAME, --+ .name = KBUILD_MODNAME, -- .id_table = brcmf_sdmmc_ids, -- .drv = { -- .owner = THIS_MODULE, --@@ -1306,37 +1300,6 @@ static struct sdio_driver brcmf_sdmmc_dr -- }, -- }; -- ---static int __init brcmf_sdio_pd_probe(struct platform_device *pdev) ---{ --- brcmf_dbg(SDIO, "Enter\n"); --- --- brcmfmac_sdio_pdata = dev_get_platdata(&pdev->dev); --- --- if (brcmfmac_sdio_pdata->power_on) --- brcmfmac_sdio_pdata->power_on(); --- --- return 0; ---} --- ---static int brcmf_sdio_pd_remove(struct platform_device *pdev) ---{ --- brcmf_dbg(SDIO, "Enter\n"); --- --- if (brcmfmac_sdio_pdata->power_off) --- brcmfmac_sdio_pdata->power_off(); --- --- sdio_unregister_driver(&brcmf_sdmmc_driver); --- --- return 0; ---} --- ---static struct platform_driver brcmf_sdio_pd = { --- .remove = brcmf_sdio_pd_remove, --- .driver = { --- .name = BRCMFMAC_SDIO_PDATA_NAME, --- } ---}; --- -- void brcmf_sdio_register(void) -- { -- int ret; --@@ -1350,19 +1313,6 @@ void brcmf_sdio_exit(void) -- { -- brcmf_dbg(SDIO, "Enter\n"); -- --- if (brcmfmac_sdio_pdata) --- platform_driver_unregister(&brcmf_sdio_pd); --- else --- sdio_unregister_driver(&brcmf_sdmmc_driver); --+ sdio_unregister_driver(&brcmf_sdmmc_driver); -- } -- ---void __init brcmf_sdio_init(void) ---{ --- int ret; --- --- brcmf_dbg(SDIO, "Enter\n"); --- --- ret = platform_driver_probe(&brcmf_sdio_pd, brcmf_sdio_pd_probe); --- if (ret == -ENODEV) --- brcmf_dbg(SDIO, "No platform data available.\n"); ---} ----- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c --+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c --@@ -27,6 +27,7 @@ -- #include "fwil_types.h" -- #include "tracepoint.h" -- #include "common.h" --+#include "of.h" -- -- MODULE_AUTHOR("Broadcom Corporation"); -- MODULE_DESCRIPTION("Broadcom 802.11 wireless LAN fullmac driver."); --@@ -79,6 +80,7 @@ module_param_named(ignore_probe_fail, br -- MODULE_PARM_DESC(ignore_probe_fail, "always succeed probe for debugging"); -- #endif -- --+static struct brcmfmac_sdio_platform_data *brcmfmac_pdata; -- struct brcmf_mp_global_t brcmf_mp_global; -- -- int brcmf_c_preinit_dcmds(struct brcmf_if *ifp) --@@ -231,6 +233,13 @@ static void brcmf_mp_attach(void) -- BRCMF_FW_ALTPATH_LEN); -- } -- --+struct brcmfmac_sdio_platform_data *brcmf_get_module_param(struct device *dev) --+{ --+ if (!brcmfmac_pdata) --+ brcmf_of_probe(dev, &brcmfmac_pdata); --+ return brcmfmac_pdata; --+} --+ -- int brcmf_mp_device_attach(struct brcmf_pub *drvr) -- { -- drvr->settings = kzalloc(sizeof(*drvr->settings), GFP_ATOMIC); --@@ -253,6 +262,35 @@ void brcmf_mp_device_detach(struct brcmf -- kfree(drvr->settings); -- } -- --+static int __init brcmf_common_pd_probe(struct platform_device *pdev) --+{ --+ brcmf_dbg(INFO, "Enter\n"); --+ --+ brcmfmac_pdata = dev_get_platdata(&pdev->dev); --+ --+ if (brcmfmac_pdata->power_on) --+ brcmfmac_pdata->power_on(); --+ --+ return 0; --+} --+ --+static int brcmf_common_pd_remove(struct platform_device *pdev) --+{ --+ brcmf_dbg(INFO, "Enter\n"); --+ --+ if (brcmfmac_pdata->power_off) --+ brcmfmac_pdata->power_off(); --+ --+ return 0; --+} --+ --+static struct platform_driver brcmf_pd = { --+ .remove = brcmf_common_pd_remove, --+ .driver = { --+ .name = BRCMFMAC_SDIO_PDATA_NAME, --+ } --+}; --+ -- static int __init brcmfmac_module_init(void) -- { -- int err; --@@ -260,16 +298,21 @@ static int __init brcmfmac_module_init(v -- /* Initialize debug system first */ -- brcmf_debugfs_init(); -- ---#ifdef CPTCFG_BRCMFMAC_SDIO --- brcmf_sdio_init(); ---#endif --+ /* Get the platform data (if available) for our devices */ --+ err = platform_driver_probe(&brcmf_pd, brcmf_common_pd_probe); --+ if (err == -ENODEV) --+ brcmf_dbg(INFO, "No platform data available.\n"); --+ -- /* Initialize global module paramaters */ -- brcmf_mp_attach(); -- -- /* Continue the initialization by registering the different busses */ -- err = brcmf_core_init(); --- if (err) --+ if (err) { -- brcmf_debugfs_exit(); --+ if (brcmfmac_pdata) --+ platform_driver_unregister(&brcmf_pd); --+ } -- -- return err; -- } --@@ -277,6 +320,8 @@ static int __init brcmfmac_module_init(v -- static void __exit brcmfmac_module_exit(void) -- { -- brcmf_core_exit(); --+ if (brcmfmac_pdata) --+ platform_driver_unregister(&brcmf_pd); -- brcmf_debugfs_exit(); -- } -- ----- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.h --+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.h --@@ -15,6 +15,8 @@ -- #ifndef BRCMFMAC_COMMON_H -- #define BRCMFMAC_COMMON_H -- --+#include --+#include -- #include "fwil_types.h" -- -- extern const u8 ALLFFMAC[ETH_ALEN]; --@@ -89,6 +91,7 @@ struct brcmf_mp_device { -- struct cc_translate *country_codes; -- }; -- --+struct brcmfmac_sdio_platform_data *brcmf_get_module_param(struct device *dev); -- int brcmf_mp_device_attach(struct brcmf_pub *drvr); -- void brcmf_mp_device_detach(struct brcmf_pub *drvr); -- #ifdef DEBUG ----- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.c --+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.c --@@ -16,17 +16,16 @@ -- #include -- #include -- #include ---#include ---#include ---#include -- -- #include -- #include "debug.h" ---#include "sdio.h" --+#include "core.h" --+#include "common.h" --+#include "of.h" -- ---void brcmf_of_probe(struct brcmf_sdio_dev *sdiodev) --+void --+brcmf_of_probe(struct device *dev, struct brcmfmac_sdio_platform_data **sdio) -- { --- struct device *dev = sdiodev->dev; -- struct device_node *np = dev->of_node; -- int irq; -- u32 irqf; --@@ -35,12 +34,12 @@ void brcmf_of_probe(struct brcmf_sdio_de -- if (!np || !of_device_is_compatible(np, "brcm,bcm4329-fmac")) -- return; -- --- sdiodev->pdata = devm_kzalloc(dev, sizeof(*sdiodev->pdata), GFP_KERNEL); --- if (!sdiodev->pdata) --+ *sdio = devm_kzalloc(dev, sizeof(*sdio), GFP_KERNEL); --+ if (!(*sdio)) -- return; -- -- if (of_property_read_u32(np, "brcm,drive-strength", &val) == 0) --- sdiodev->pdata->drive_strength = val; --+ (*sdio)->drive_strength = val; -- -- /* make sure there are interrupts defined in the node */ -- if (!of_find_property(np, "interrupts", NULL)) --@@ -53,7 +52,7 @@ void brcmf_of_probe(struct brcmf_sdio_de -- } -- irqf = irqd_get_trigger_type(irq_get_irq_data(irq)); -- --- sdiodev->pdata->oob_irq_supported = true; --- sdiodev->pdata->oob_irq_nr = irq; --- sdiodev->pdata->oob_irq_flags = irqf; --+ (*sdio)->oob_irq_supported = true; --+ (*sdio)->oob_irq_nr = irq; --+ (*sdio)->oob_irq_flags = irqf; -- } ----- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.h --+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.h --@@ -14,9 +14,11 @@ -- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -- */ -- #ifdef CONFIG_OF ---void brcmf_of_probe(struct brcmf_sdio_dev *sdiodev); --+void --+brcmf_of_probe(struct device *dev, struct brcmfmac_sdio_platform_data **sdio); -- #else ---static void brcmf_of_probe(struct brcmf_sdio_dev *sdiodev) --+static void brcmf_of_probe(struct device *dev, --+ struct brcmfmac_sdio_platform_data **sdio) -- { -- } -- #endif /* CONFIG_OF */ -diff --git a/package/kernel/mac80211/patches/344-0016-brcmfmac-keep-ARP-and-ND-offload-enabled-during-WOWL.patch b/package/kernel/mac80211/patches/344-0016-brcmfmac-keep-ARP-and-ND-offload-enabled-during-WOWL.patch -deleted file mode 100644 -index 4e789cf..0000000 ---- a/package/kernel/mac80211/patches/344-0016-brcmfmac-keep-ARP-and-ND-offload-enabled-during-WOWL.patch -+++ /dev/null -@@ -1,69 +0,0 @@ --From: Hante Meuleman --Date: Wed, 17 Feb 2016 11:27:05 +0100 --Subject: [PATCH] brcmfmac: keep ARP and ND offload enabled during WOWL -- --Currently ARP and ND (IPv6 Neigbor Discovery) offload get disabled --on entering suspend. However when firmwares support the wowl_cap --iovar then these offload routines can be kept enabled as they --will work during WOWL as well. -- --Reviewed-by: Arend Van Spriel --Reviewed-by: Franky (Zhenhui) Lin --Reviewed-by: Pieter-Paul Giesberts --Signed-off-by: Hante Meuleman --Signed-off-by: Arend van Spriel --Signed-off-by: Kalle Valo ----- -- ----- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c --+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c --@@ -3556,7 +3556,8 @@ static s32 brcmf_cfg80211_resume(struct -- brcmf_report_wowl_wakeind(wiphy, ifp); -- brcmf_fil_iovar_int_set(ifp, "wowl_clear", 0); -- brcmf_config_wowl_pattern(ifp, "clr", NULL, 0, NULL, 0); --- brcmf_configure_arp_nd_offload(ifp, true); --+ if (!brcmf_feat_is_enabled(ifp, BRCMF_FEAT_WOWL_ARP_ND)) --+ brcmf_configure_arp_nd_offload(ifp, true); -- brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PM, -- cfg->wowl.pre_pmmode); -- cfg->wowl.active = false; --@@ -3580,7 +3581,8 @@ static void brcmf_configure_wowl(struct -- -- brcmf_dbg(TRACE, "Suspend, wowl config.\n"); -- --- brcmf_configure_arp_nd_offload(ifp, false); --+ if (!brcmf_feat_is_enabled(ifp, BRCMF_FEAT_WOWL_ARP_ND)) --+ brcmf_configure_arp_nd_offload(ifp, false); -- brcmf_fil_cmd_int_get(ifp, BRCMF_C_GET_PM, &cfg->wowl.pre_pmmode); -- brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PM, PM_MAX); -- ----- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c --+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c --@@ -147,6 +147,7 @@ void brcmf_feat_attach(struct brcmf_pub -- if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_WOWL)) { -- err = brcmf_fil_iovar_int_get(ifp, "wowl_cap", &wowl_cap); -- if (!err) { --+ ifp->drvr->feat_flags |= BIT(BRCMF_FEAT_WOWL_ARP_ND); -- if (wowl_cap & BRCMF_WOWL_PFN_FOUND) -- ifp->drvr->feat_flags |= -- BIT(BRCMF_FEAT_WOWL_ND); ----- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.h --+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.h --@@ -29,6 +29,7 @@ -- * SCAN_RANDOM_MAC: Random MAC during (net detect) scheduled scan. -- * WOWL_ND: WOWL net detect (PNO) -- * WOWL_GTK: (WOWL) GTK rekeying offload --+ * WOWL_ARP_ND: ARP and Neighbor Discovery offload support during WOWL. -- */ -- #define BRCMF_FEAT_LIST \ -- BRCMF_FEAT_DEF(MBSS) \ --@@ -40,7 +41,8 @@ -- BRCMF_FEAT_DEF(TDLS) \ -- BRCMF_FEAT_DEF(SCAN_RANDOM_MAC) \ -- BRCMF_FEAT_DEF(WOWL_ND) \ --- BRCMF_FEAT_DEF(WOWL_GTK) --+ BRCMF_FEAT_DEF(WOWL_GTK) \ --+ BRCMF_FEAT_DEF(WOWL_ARP_ND) -- -- /* -- * Quirks: -diff --git a/package/kernel/mac80211/patches/344-0017-brcmfmac-switch-to-new-platform-data.patch b/package/kernel/mac80211/patches/344-0017-brcmfmac-switch-to-new-platform-data.patch -deleted file mode 100644 -index 37b6855..0000000 ---- a/package/kernel/mac80211/patches/344-0017-brcmfmac-switch-to-new-platform-data.patch -+++ /dev/null -@@ -1,734 +0,0 @@ --From: Hante Meuleman --Date: Wed, 17 Feb 2016 11:27:07 +0100 --Subject: [PATCH] brcmfmac: switch to new platform data -- --Platform data is only available for sdio. With this patch a new --platform data structure is being used which allows for platform --data for any device and configurable per device. This patch only --switches to the new structure and adds support for SDIO devices. -- --Reviewed-by: Arend Van Spriel --Reviewed-by: Franky (Zhenhui) Lin --Reviewed-by: Pieter-Paul Giesberts --Signed-off-by: Hante Meuleman --Signed-off-by: Arend van Spriel --Signed-off-by: Kalle Valo ----- -- ----- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c --+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c --@@ -103,7 +103,7 @@ static void brcmf_sdiod_dummy_irqhandler -- -- int brcmf_sdiod_intr_register(struct brcmf_sdio_dev *sdiodev) -- { --- struct brcmfmac_sdio_platform_data *pdata; --+ struct brcmfmac_sdio_pd *pdata; -- int ret = 0; -- u8 data; -- u32 addr, gpiocontrol; --@@ -173,7 +173,7 @@ int brcmf_sdiod_intr_register(struct brc -- -- int brcmf_sdiod_intr_unregister(struct brcmf_sdio_dev *sdiodev) -- { --- struct brcmfmac_sdio_platform_data *pdata; --+ struct brcmfmac_sdio_pd *pdata; -- -- brcmf_dbg(SDIO, "Entering\n"); -- --@@ -1164,17 +1164,6 @@ static int brcmf_ops_sdio_probe(struct s -- dev_set_drvdata(&func->dev, bus_if); -- dev_set_drvdata(&sdiodev->func[1]->dev, bus_if); -- sdiodev->dev = &sdiodev->func[1]->dev; --- sdiodev->pdata = brcmf_get_module_param(sdiodev->dev); --- ---#ifdef CONFIG_PM_SLEEP --- /* wowl can be supported when KEEP_POWER is true and (WAKE_SDIO_IRQ --- * is true or when platform data OOB irq is true). --- */ --- if ((sdio_get_host_pm_caps(sdiodev->func[1]) & MMC_PM_KEEP_POWER) && --- ((sdio_get_host_pm_caps(sdiodev->func[1]) & MMC_PM_WAKE_SDIO_IRQ) || --- (sdiodev->pdata && sdiodev->pdata->oob_irq_supported))) --- bus_if->wowl_supported = true; ---#endif -- -- brcmf_sdiod_change_state(sdiodev, BRCMF_SDIOD_DOWN); -- ----- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c --+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c --@@ -6459,8 +6459,8 @@ int brcmf_cfg80211_wait_vif_event(struct -- static s32 brcmf_translate_country_code(struct brcmf_pub *drvr, char alpha2[2], -- struct brcmf_fil_country_le *ccreq) -- { --- struct cc_translate *country_codes; --- struct cc_entry *cc; --+ struct brcmfmac_pd_cc *country_codes; --+ struct brcmfmac_pd_cc_entry *cc; -- s32 found_index; -- int i; -- ----- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c --+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c --@@ -80,7 +80,7 @@ module_param_named(ignore_probe_fail, br -- MODULE_PARM_DESC(ignore_probe_fail, "always succeed probe for debugging"); -- #endif -- ---static struct brcmfmac_sdio_platform_data *brcmfmac_pdata; --+static struct brcmfmac_platform_data *brcmfmac_pdata; -- struct brcmf_mp_global_t brcmf_mp_global; -- -- int brcmf_c_preinit_dcmds(struct brcmf_if *ifp) --@@ -229,15 +229,46 @@ void __brcmf_dbg(u32 level, const char * -- -- static void brcmf_mp_attach(void) -- { --+ /* If module param firmware path is set then this will always be used, --+ * if not set then if available use the platform data version. To make --+ * sure it gets initialized at all, always copy the module param version --+ */ -- strlcpy(brcmf_mp_global.firmware_path, brcmf_firmware_path, -- BRCMF_FW_ALTPATH_LEN); --+ if ((brcmfmac_pdata) && (brcmfmac_pdata->fw_alternative_path) && --+ (brcmf_mp_global.firmware_path[0] == '\0')) { --+ strlcpy(brcmf_mp_global.firmware_path, --+ brcmfmac_pdata->fw_alternative_path, --+ BRCMF_FW_ALTPATH_LEN); --+ } -- } -- ---struct brcmfmac_sdio_platform_data *brcmf_get_module_param(struct device *dev) ---{ --- if (!brcmfmac_pdata) --- brcmf_of_probe(dev, &brcmfmac_pdata); --- return brcmfmac_pdata; --+struct brcmfmac_sdio_pd *brcmf_get_module_param(struct device *dev, --+ enum brcmf_bus_type bus_type, --+ u32 chip, u32 chiprev) --+{ --+ struct brcmfmac_sdio_pd *pdata; --+ struct brcmfmac_pd_device *device_pd; --+ int i; --+ --+ if (brcmfmac_pdata) { --+ for (i = 0; i < brcmfmac_pdata->device_count; i++) { --+ device_pd = &brcmfmac_pdata->devices[i]; --+ if ((device_pd->bus_type == bus_type) && --+ (device_pd->id == chip) && --+ ((device_pd->rev == chiprev) || --+ (device_pd->rev == -1))) { --+ brcmf_dbg(INFO, "Platform data for device found\n"); --+ if (device_pd->bus_type == BRCMF_BUSTYPE_SDIO) --+ return &device_pd->bus.sdio; --+ break; --+ } --+ } --+ } --+ pdata = NULL; --+ brcmf_of_probe(dev, &pdata); --+ --+ return pdata; -- } -- -- int brcmf_mp_device_attach(struct brcmf_pub *drvr) --@@ -287,7 +318,7 @@ static int brcmf_common_pd_remove(struct -- static struct platform_driver brcmf_pd = { -- .remove = brcmf_common_pd_remove, -- .driver = { --- .name = BRCMFMAC_SDIO_PDATA_NAME, --+ .name = BRCMFMAC_PDATA_NAME, -- } -- }; -- ----- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.h --+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.h --@@ -16,7 +16,7 @@ -- #define BRCMFMAC_COMMON_H -- -- #include ---#include --+#include -- #include "fwil_types.h" -- -- extern const u8 ALLFFMAC[ETH_ALEN]; --@@ -43,33 +43,6 @@ struct brcmf_mp_global_t { -- extern struct brcmf_mp_global_t brcmf_mp_global; -- -- /** --- * struct cc_entry - Struct for translating user space country code (iso3166) to --- * firmware country code and revision. --- * --- * @iso3166: iso3166 alpha 2 country code string. --- * @cc: firmware country code string. --- * @rev: firmware country code revision. --- */ ---struct cc_entry { --- char iso3166[BRCMF_COUNTRY_BUF_SZ]; --- char cc[BRCMF_COUNTRY_BUF_SZ]; --- s32 rev; ---}; --- ---/** --- * struct cc_translate - Struct for translating country codes as set by user --- * space to a country code and rev which can be used by --- * firmware. --- * --- * @table_size: number of entries in table (> 0) --- * @table: dynamic array of 1 or more elements with translation information. --- */ ---struct cc_translate { --- int table_size; --- struct cc_entry table[0]; ---}; --- ---/** -- * struct brcmf_mp_device - Device module paramaters. -- * -- * @sdiod_txglomsz: SDIO txglom size. --@@ -88,10 +61,12 @@ struct brcmf_mp_device { -- int fcmode; -- bool roamoff; -- bool ignore_probe_fail; --- struct cc_translate *country_codes; --+ struct brcmfmac_pd_cc *country_codes; -- }; -- ---struct brcmfmac_sdio_platform_data *brcmf_get_module_param(struct device *dev); --+struct brcmfmac_sdio_pd *brcmf_get_module_param(struct device *dev, --+ enum brcmf_bus_type bus_type, --+ u32 chip, u32 chiprev); -- int brcmf_mp_device_attach(struct brcmf_pub *drvr); -- void brcmf_mp_device_detach(struct brcmf_pub *drvr); -- #ifdef DEBUG ----- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.c --+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.c --@@ -23,8 +23,7 @@ -- #include "common.h" -- #include "of.h" -- ---void ---brcmf_of_probe(struct device *dev, struct brcmfmac_sdio_platform_data **sdio) --+void brcmf_of_probe(struct device *dev, struct brcmfmac_sdio_pd **sdio) -- { -- struct device_node *np = dev->of_node; -- int irq; ----- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.h --+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.h --@@ -15,10 +15,9 @@ -- */ -- #ifdef CONFIG_OF -- void ---brcmf_of_probe(struct device *dev, struct brcmfmac_sdio_platform_data **sdio); --+brcmf_of_probe(struct device *dev, struct brcmfmac_sdio_pd **sdio); -- #else ---static void brcmf_of_probe(struct device *dev, --- struct brcmfmac_sdio_platform_data **sdio) --+static void brcmf_of_probe(struct device *dev, struct brcmfmac_sdio_pd **sdio) -- { -- } -- #endif /* CONFIG_OF */ ----- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c --+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c --@@ -33,8 +33,6 @@ -- #include -- #include -- #include ---#include ---#include -- #include -- #include -- #include --@@ -44,6 +42,8 @@ -- #include "sdio.h" -- #include "chip.h" -- #include "firmware.h" --+#include "core.h" --+#include "common.h" -- -- #define DCMD_RESP_TIMEOUT msecs_to_jiffies(2500) -- #define CTL_DONE_TIMEOUT msecs_to_jiffies(2500) --@@ -3775,26 +3775,28 @@ static const struct brcmf_buscore_ops br -- static bool -- brcmf_sdio_probe_attach(struct brcmf_sdio *bus) -- { --+ struct brcmf_sdio_dev *sdiodev; -- u8 clkctl = 0; -- int err = 0; -- int reg_addr; -- u32 reg_val; -- u32 drivestrength; -- --- sdio_claim_host(bus->sdiodev->func[1]); --+ sdiodev = bus->sdiodev; --+ sdio_claim_host(sdiodev->func[1]); -- -- pr_debug("F1 signature read @0x18000000=0x%4x\n", --- brcmf_sdiod_regrl(bus->sdiodev, SI_ENUM_BASE, NULL)); --+ brcmf_sdiod_regrl(sdiodev, SI_ENUM_BASE, NULL)); -- -- /* -- * Force PLL off until brcmf_chip_attach() -- * programs PLL control regs -- */ -- --- brcmf_sdiod_regwb(bus->sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, --+ brcmf_sdiod_regwb(sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, -- BRCMF_INIT_CLKCTL1, &err); -- if (!err) --- clkctl = brcmf_sdiod_regrb(bus->sdiodev, --+ clkctl = brcmf_sdiod_regrb(sdiodev, -- SBSDIO_FUNC1_CHIPCLKCSR, &err); -- -- if (err || ((clkctl & ~SBSDIO_AVBITS) != BRCMF_INIT_CLKCTL1)) { --@@ -3803,50 +3805,77 @@ brcmf_sdio_probe_attach(struct brcmf_sdi -- goto fail; -- } -- --- bus->ci = brcmf_chip_attach(bus->sdiodev, &brcmf_sdio_buscore_ops); --+ bus->ci = brcmf_chip_attach(sdiodev, &brcmf_sdio_buscore_ops); -- if (IS_ERR(bus->ci)) { -- brcmf_err("brcmf_chip_attach failed!\n"); -- bus->ci = NULL; -- goto fail; -- } --+ sdiodev->pdata = brcmf_get_module_param(sdiodev->dev, --+ BRCMF_BUSTYPE_SDIO, --+ bus->ci->chip, --+ bus->ci->chiprev); --+ /* platform specific configuration: --+ * alignments must be at least 4 bytes for ADMA --+ */ --+ bus->head_align = ALIGNMENT; --+ bus->sgentry_align = ALIGNMENT; --+ if (sdiodev->pdata) { --+ if (sdiodev->pdata->sd_head_align > ALIGNMENT) --+ bus->head_align = sdiodev->pdata->sd_head_align; --+ if (sdiodev->pdata->sd_sgentry_align > ALIGNMENT) --+ bus->sgentry_align = sdiodev->pdata->sd_sgentry_align; --+ } --+ /* allocate scatter-gather table. sg support --+ * will be disabled upon allocation failure. --+ */ --+ brcmf_sdiod_sgtable_alloc(sdiodev); --+ --+#ifdef CONFIG_PM_SLEEP --+ /* wowl can be supported when KEEP_POWER is true and (WAKE_SDIO_IRQ --+ * is true or when platform data OOB irq is true). --+ */ --+ if ((sdio_get_host_pm_caps(sdiodev->func[1]) & MMC_PM_KEEP_POWER) && --+ ((sdio_get_host_pm_caps(sdiodev->func[1]) & MMC_PM_WAKE_SDIO_IRQ) || --+ (sdiodev->pdata && sdiodev->pdata->oob_irq_supported))) --+ sdiodev->bus_if->wowl_supported = true; --+#endif -- -- if (brcmf_sdio_kso_init(bus)) { -- brcmf_err("error enabling KSO\n"); -- goto fail; -- } -- --- if ((bus->sdiodev->pdata) && (bus->sdiodev->pdata->drive_strength)) --- drivestrength = bus->sdiodev->pdata->drive_strength; --+ if ((sdiodev->pdata) && (sdiodev->pdata->drive_strength)) --+ drivestrength = sdiodev->pdata->drive_strength; -- else -- drivestrength = DEFAULT_SDIO_DRIVE_STRENGTH; --- brcmf_sdio_drivestrengthinit(bus->sdiodev, bus->ci, drivestrength); --+ brcmf_sdio_drivestrengthinit(sdiodev, bus->ci, drivestrength); -- -- /* Set card control so an SDIO card reset does a WLAN backplane reset */ --- reg_val = brcmf_sdiod_regrb(bus->sdiodev, --- SDIO_CCCR_BRCM_CARDCTRL, &err); --+ reg_val = brcmf_sdiod_regrb(sdiodev, SDIO_CCCR_BRCM_CARDCTRL, &err); -- if (err) -- goto fail; -- -- reg_val |= SDIO_CCCR_BRCM_CARDCTRL_WLANRESET; -- --- brcmf_sdiod_regwb(bus->sdiodev, --- SDIO_CCCR_BRCM_CARDCTRL, reg_val, &err); --+ brcmf_sdiod_regwb(sdiodev, SDIO_CCCR_BRCM_CARDCTRL, reg_val, &err); -- if (err) -- goto fail; -- -- /* set PMUControl so a backplane reset does PMU state reload */ -- reg_addr = CORE_CC_REG(brcmf_chip_get_pmu(bus->ci)->base, pmucontrol); --- reg_val = brcmf_sdiod_regrl(bus->sdiodev, reg_addr, &err); --+ reg_val = brcmf_sdiod_regrl(sdiodev, reg_addr, &err); -- if (err) -- goto fail; -- -- reg_val |= (BCMA_CC_PMU_CTL_RES_RELOAD << BCMA_CC_PMU_CTL_RES_SHIFT); -- --- brcmf_sdiod_regwl(bus->sdiodev, reg_addr, reg_val, &err); --+ brcmf_sdiod_regwl(sdiodev, reg_addr, reg_val, &err); -- if (err) -- goto fail; -- --- sdio_release_host(bus->sdiodev->func[1]); --+ sdio_release_host(sdiodev->func[1]); -- -- brcmu_pktq_init(&bus->txq, (PRIOMASK + 1), TXQLEN); -- --@@ -3867,7 +3896,7 @@ brcmf_sdio_probe_attach(struct brcmf_sdi -- return true; -- -- fail: --- sdio_release_host(bus->sdiodev->func[1]); --+ sdio_release_host(sdiodev->func[1]); -- return false; -- } -- --@@ -4045,18 +4074,6 @@ struct brcmf_sdio *brcmf_sdio_probe(stru -- bus->txminmax = BRCMF_TXMINMAX; -- bus->tx_seq = SDPCM_SEQ_WRAP - 1; -- --- /* platform specific configuration: --- * alignments must be at least 4 bytes for ADMA --- */ --- bus->head_align = ALIGNMENT; --- bus->sgentry_align = ALIGNMENT; --- if (sdiodev->pdata) { --- if (sdiodev->pdata->sd_head_align > ALIGNMENT) --- bus->head_align = sdiodev->pdata->sd_head_align; --- if (sdiodev->pdata->sd_sgentry_align > ALIGNMENT) --- bus->sgentry_align = sdiodev->pdata->sd_sgentry_align; --- } --- -- /* single-threaded workqueue */ -- wq = alloc_ordered_workqueue("brcmf_wq/%s", WQ_MEM_RECLAIM, -- dev_name(&sdiodev->func[1]->dev)); ----- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h --+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h --@@ -184,7 +184,7 @@ struct brcmf_sdio_dev { -- struct brcmf_sdio *bus; -- struct device *dev; -- struct brcmf_bus *bus_if; --- struct brcmfmac_sdio_platform_data *pdata; --+ struct brcmfmac_sdio_pd *pdata; -- bool oob_irq_requested; -- bool irq_en; /* irq enable flags */ -- spinlock_t irq_en_lock; ----- a/include/linux/platform_data/brcmfmac-sdio.h --+++ /dev/null --@@ -1,135 +0,0 @@ ---/* --- * Copyright (c) 2013 Broadcom Corporation --- * --- * Permission to use, copy, modify, and/or distribute this software for any --- * purpose with or without fee is hereby granted, provided that the above --- * copyright notice and this permission notice appear in all copies. --- * --- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES --- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF --- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY --- * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES --- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION --- * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN --- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. --- */ --- ---#ifndef _LINUX_BRCMFMAC_PLATFORM_H ---#define _LINUX_BRCMFMAC_PLATFORM_H --- ---/* --- * Platform specific driver functions and data. Through the platform specific --- * device data functions can be provided to help the brcmfmac driver to --- * operate with the device in combination with the used platform. --- * --- * Use the platform data in the following (similar) way: --- * --- * ---#include --- --- ---static void brcmfmac_power_on(void) ---{ ---} --- ---static void brcmfmac_power_off(void) ---{ ---} --- ---static void brcmfmac_reset(void) ---{ ---} --- ---static struct brcmfmac_sdio_platform_data brcmfmac_sdio_pdata = { --- .power_on = brcmfmac_power_on, --- .power_off = brcmfmac_power_off, --- .reset = brcmfmac_reset ---}; --- ---static struct platform_device brcmfmac_device = { --- .name = BRCMFMAC_SDIO_PDATA_NAME, --- .id = PLATFORM_DEVID_NONE, --- .dev.platform_data = &brcmfmac_sdio_pdata ---}; --- ---void __init brcmfmac_init_pdata(void) ---{ --- brcmfmac_sdio_pdata.oob_irq_supported = true; --- brcmfmac_sdio_pdata.oob_irq_nr = gpio_to_irq(GPIO_BRCMF_SDIO_OOB); --- brcmfmac_sdio_pdata.oob_irq_flags = IORESOURCE_IRQ | --- IORESOURCE_IRQ_HIGHLEVEL; --- platform_device_register(&brcmfmac_device); ---} --- * --- * --- * Note: the brcmfmac can be loaded as module or be statically built-in into --- * the kernel. If built-in then do note that it uses module_init (and --- * module_exit) routines which equal device_initcall. So if you intend to --- * create a module with the platform specific data for the brcmfmac and have --- * it built-in to the kernel then use a higher initcall then device_initcall --- * (see init.h). If this is not done then brcmfmac will load without problems --- * but will not pickup the platform data. --- * --- * When the driver does not "detect" platform driver data then it will continue --- * without reporting anything and just assume there is no data needed. Which is --- * probably true for most platforms. --- * --- * Explanation of the platform_data fields: --- * --- * drive_strength: is the preferred drive_strength to be used for the SDIO --- * pins. If 0 then a default value will be used. This is the target drive --- * strength, the exact drive strength which will be used depends on the --- * capabilities of the device. --- * --- * oob_irq_supported: does the board have support for OOB interrupts. SDIO --- * in-band interrupts are relatively slow and for having less overhead on --- * interrupt processing an out of band interrupt can be used. If the HW --- * supports this then enable this by setting this field to true and configure --- * the oob related fields. --- * --- * oob_irq_nr, oob_irq_flags: the OOB interrupt information. The values are --- * used for registering the irq using request_irq function. --- * --- * broken_sg_support: flag for broken sg list support of SDIO host controller. --- * Set this to true if the SDIO host controller has higher align requirement --- * than 32 bytes for each scatterlist item. --- * --- * sd_head_align: alignment requirement for start of data buffer --- * --- * sd_sgentry_align: length alignment requirement for each sg entry --- * --- * power_on: This function is called by the brcmfmac when the module gets --- * loaded. This can be particularly useful for low power devices. The platform --- * spcific routine may for example decide to power up the complete device. --- * If there is no use-case for this function then provide NULL. --- * --- * power_off: This function is called by the brcmfmac when the module gets --- * unloaded. At this point the device can be powered down or otherwise be reset. --- * So if an actual power_off is not supported but reset is then reset the device --- * when this function gets called. This can be particularly useful for low power --- * devices. If there is no use-case for this function (either power-down or --- * reset) then provide NULL. --- * --- * reset: This function can get called if the device communication broke down. --- * This functionality is particularly useful in case of SDIO type devices. It is --- * possible to reset a dongle via sdio data interface, but it requires that --- * this is fully functional. This function is chip/module specific and this --- * function should return only after the complete reset has completed. --- */ --- ---#define BRCMFMAC_SDIO_PDATA_NAME "brcmfmac_sdio" --- ---struct brcmfmac_sdio_platform_data { --- unsigned int drive_strength; --- bool oob_irq_supported; --- unsigned int oob_irq_nr; --- unsigned long oob_irq_flags; --- bool broken_sg_support; --- unsigned short sd_head_align; --- unsigned short sd_sgentry_align; --- void (*power_on)(void); --- void (*power_off)(void); --- void (*reset)(void); ---}; --- ---#endif /* _LINUX_BRCMFMAC_PLATFORM_H */ ----- /dev/null --+++ b/include/linux/platform_data/brcmfmac.h --@@ -0,0 +1,185 @@ --+/* --+ * Copyright (c) 201 Broadcom Corporation --+ * --+ * Permission to use, copy, modify, and/or distribute this software for any --+ * purpose with or without fee is hereby granted, provided that the above --+ * copyright notice and this permission notice appear in all copies. --+ * --+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES --+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF --+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY --+ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES --+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION --+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN --+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. --+ */ --+ --+#ifndef _LINUX_BRCMFMAC_PLATFORM_H --+#define _LINUX_BRCMFMAC_PLATFORM_H --+ --+ --+#define BRCMFMAC_PDATA_NAME "brcmfmac" --+ --+#define BRCMFMAC_COUNTRY_BUF_SZ 4 --+ --+ --+/* --+ * Platform specific driver functions and data. Through the platform specific --+ * device data functions and data can be provided to help the brcmfmac driver to --+ * operate with the device in combination with the used platform. --+ */ --+ --+ --+/** --+ * Note: the brcmfmac can be loaded as module or be statically built-in into --+ * the kernel. If built-in then do note that it uses module_init (and --+ * module_exit) routines which equal device_initcall. So if you intend to --+ * create a module with the platform specific data for the brcmfmac and have --+ * it built-in to the kernel then use a higher initcall then device_initcall --+ * (see init.h). If this is not done then brcmfmac will load without problems --+ * but will not pickup the platform data. --+ * --+ * When the driver does not "detect" platform driver data then it will continue --+ * without reporting anything and just assume there is no data needed. Which is --+ * probably true for most platforms. --+ */ --+ --+/** --+ * enum brcmf_bus_type - Bus type identifier. Currently SDIO, USB and PCIE are --+ * supported. --+ */ --+enum brcmf_bus_type { --+ BRCMF_BUSTYPE_SDIO, --+ BRCMF_BUSTYPE_USB, --+ BRCMF_BUSTYPE_PCIE --+}; --+ --+ --+/** --+ * struct brcmfmac_sdio_pd - SDIO Device specific platform data. --+ * --+ * @txglomsz: SDIO txglom size. Use 0 if default of driver is to be --+ * used. --+ * @drive_strength: is the preferred drive_strength to be used for the SDIO --+ * pins. If 0 then a default value will be used. This is --+ * the target drive strength, the exact drive strength --+ * which will be used depends on the capabilities of the --+ * device. --+ * @oob_irq_supported: does the board have support for OOB interrupts. SDIO --+ * in-band interrupts are relatively slow and for having --+ * less overhead on interrupt processing an out of band --+ * interrupt can be used. If the HW supports this then --+ * enable this by setting this field to true and configure --+ * the oob related fields. --+ * @oob_irq_nr, --+ * @oob_irq_flags: the OOB interrupt information. The values are used for --+ * registering the irq using request_irq function. --+ * @broken_sg_support: flag for broken sg list support of SDIO host controller. --+ * Set this to true if the SDIO host controller has higher --+ * align requirement than 32 bytes for each scatterlist --+ * item. --+ * @sd_head_align: alignment requirement for start of data buffer. --+ * @sd_sgentry_align: length alignment requirement for each sg entry. --+ * @reset: This function can get called if the device communication --+ * broke down. This functionality is particularly useful in --+ * case of SDIO type devices. It is possible to reset a --+ * dongle via sdio data interface, but it requires that --+ * this is fully functional. This function is chip/module --+ * specific and this function should return only after the --+ * complete reset has completed. --+ */ --+struct brcmfmac_sdio_pd { --+ int txglomsz; --+ unsigned int drive_strength; --+ bool oob_irq_supported; --+ unsigned int oob_irq_nr; --+ unsigned long oob_irq_flags; --+ bool broken_sg_support; --+ unsigned short sd_head_align; --+ unsigned short sd_sgentry_align; --+ void (*reset)(void); --+}; --+ --+/** --+ * struct brcmfmac_pd_cc_entry - Struct for translating user space country code --+ * (iso3166) to firmware country code and --+ * revision. --+ * --+ * @iso3166: iso3166 alpha 2 country code string. --+ * @cc: firmware country code string. --+ * @rev: firmware country code revision. --+ */ --+struct brcmfmac_pd_cc_entry { --+ char iso3166[BRCMFMAC_COUNTRY_BUF_SZ]; --+ char cc[BRCMFMAC_COUNTRY_BUF_SZ]; --+ s32 rev; --+}; --+ --+/** --+ * struct brcmfmac_pd_cc - Struct for translating country codes as set by user --+ * space to a country code and rev which can be used by --+ * firmware. --+ * --+ * @table_size: number of entries in table (> 0) --+ * @table: array of 1 or more elements with translation information. --+ */ --+struct brcmfmac_pd_cc { --+ int table_size; --+ struct brcmfmac_pd_cc_entry table[0]; --+}; --+ --+/** --+ * struct brcmfmac_pd_device - Device specific platform data. (id/rev/bus_type) --+ * is the unique identifier of the device. --+ * --+ * @id: ID of the device for which this data is. In case of SDIO --+ * or PCIE this is the chipid as identified by chip.c In --+ * case of USB this is the chipid as identified by the --+ * device query. --+ * @rev: chip revision, see id. --+ * @bus_type: The type of bus. Some chipid/rev exist for different bus --+ * types. Each bus type has its own set of settings. --+ * @feature_disable: Bitmask of features to disable (override), See feature.c --+ * in brcmfmac for details. --+ * @country_codes: If available, pointer to struct for translating country --+ * codes. --+ * @bus: Bus specific (union) device settings. Currently only --+ * SDIO. --+ */ --+struct brcmfmac_pd_device { --+ unsigned int id; --+ unsigned int rev; --+ enum brcmf_bus_type bus_type; --+ unsigned int feature_disable; --+ struct brcmfmac_pd_cc *country_codes; --+ union { --+ struct brcmfmac_sdio_pd sdio; --+ } bus; --+}; --+ --+/** --+ * struct brcmfmac_platform_data - BRCMFMAC specific platform data. --+ * --+ * @power_on: This function is called by the brcmfmac driver when the module --+ * gets loaded. This can be particularly useful for low power --+ * devices. The platform spcific routine may for example decide to --+ * power up the complete device. If there is no use-case for this --+ * function then provide NULL. --+ * @power_off: This function is called by the brcmfmac when the module gets --+ * unloaded. At this point the devices can be powered down or --+ * otherwise be reset. So if an actual power_off is not supported --+ * but reset is supported by the devices then reset the devices --+ * when this function gets called. This can be particularly useful --+ * for low power devices. If there is no use-case for this --+ * function then provide NULL. --+ */ --+struct brcmfmac_platform_data { --+ void (*power_on)(void); --+ void (*power_off)(void); --+ char *fw_alternative_path; --+ int device_count; --+ struct brcmfmac_pd_device devices[0]; --+}; --+ --+ --+#endif /* _LINUX_BRCMFMAC_PLATFORM_H */ -diff --git a/package/kernel/mac80211/patches/344-0018-brcmfmac-merge-platform-data-and-module-paramaters.patch b/package/kernel/mac80211/patches/344-0018-brcmfmac-merge-platform-data-and-module-paramaters.patch -deleted file mode 100644 -index 34341d7..0000000 ---- a/package/kernel/mac80211/patches/344-0018-brcmfmac-merge-platform-data-and-module-paramaters.patch -+++ /dev/null -@@ -1,607 +0,0 @@ --From: Hante Meuleman --Date: Wed, 17 Feb 2016 11:27:08 +0100 --Subject: [PATCH] brcmfmac: merge platform data and module paramaters -- --Merge module parameters and platform data in one struct. This is the --last step to move to the new platform data per device. Now parameters --of platform data will be merged with module parameters per device. -- --Reviewed-by: Arend Van Spriel --Reviewed-by: Franky (Zhenhui) Lin --Reviewed-by: Pieter-Paul Giesberts --Signed-off-by: Hante Meuleman --Signed-off-by: Arend van Spriel --Signed-off-by: Kalle Valo ----- -- ----- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c --+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c --@@ -109,8 +109,8 @@ int brcmf_sdiod_intr_register(struct brc -- u32 addr, gpiocontrol; -- unsigned long flags; -- --- pdata = sdiodev->pdata; --- if ((pdata) && (pdata->oob_irq_supported)) { --+ pdata = &sdiodev->settings->bus.sdio; --+ if (pdata->oob_irq_supported) { -- brcmf_dbg(SDIO, "Enter, register OOB IRQ %d\n", -- pdata->oob_irq_nr); -- ret = request_irq(pdata->oob_irq_nr, brcmf_sdiod_oob_irqhandler, --@@ -177,8 +177,8 @@ int brcmf_sdiod_intr_unregister(struct b -- -- brcmf_dbg(SDIO, "Entering\n"); -- --- pdata = sdiodev->pdata; --- if ((pdata) && (pdata->oob_irq_supported)) { --+ pdata = &sdiodev->settings->bus.sdio; --+ if (pdata->oob_irq_supported) { -- sdio_claim_host(sdiodev->func[1]); -- brcmf_sdiod_regwb(sdiodev, SDIO_CCCR_BRCM_SEPINT, 0, NULL); -- brcmf_sdiod_regwb(sdiodev, SDIO_CCCR_IENx, 0, NULL); --@@ -522,7 +522,7 @@ static int brcmf_sdiod_sglist_rw(struct -- target_list = pktlist; -- /* for host with broken sg support, prepare a page aligned list */ -- __skb_queue_head_init(&local_list); --- if (sdiodev->pdata && sdiodev->pdata->broken_sg_support && !write) { --+ if (!write && sdiodev->settings->bus.sdio.broken_sg_support) { -- req_sz = 0; -- skb_queue_walk(pktlist, pkt_next) -- req_sz += pkt_next->len; --@@ -629,7 +629,7 @@ static int brcmf_sdiod_sglist_rw(struct -- } -- } -- --- if (sdiodev->pdata && sdiodev->pdata->broken_sg_support && !write) { --+ if (!write && sdiodev->settings->bus.sdio.broken_sg_support) { -- local_pkt_next = local_list.next; -- orig_offset = 0; -- skb_queue_walk(pktlist, pkt_next) { --@@ -900,7 +900,7 @@ void brcmf_sdiod_sgtable_alloc(struct br -- return; -- -- nents = max_t(uint, BRCMF_DEFAULT_RXGLOM_SIZE, --- sdiodev->bus_if->drvr->settings->sdiod_txglomsz); --+ sdiodev->settings->bus.sdio.txglomsz); -- nents += (nents >> 4) + 1; -- -- WARN_ON(nents > sdiodev->max_segment_count); --@@ -912,7 +912,7 @@ void brcmf_sdiod_sgtable_alloc(struct br -- sdiodev->sg_support = false; -- } -- --- sdiodev->txglomsz = sdiodev->bus_if->drvr->settings->sdiod_txglomsz; --+ sdiodev->txglomsz = sdiodev->settings->bus.sdio.txglomsz; -- } -- -- #ifdef CONFIG_PM_SLEEP --@@ -1246,8 +1246,8 @@ static int brcmf_ops_sdio_suspend(struct -- -- sdio_flags = MMC_PM_KEEP_POWER; -- if (sdiodev->wowl_enabled) { --- if (sdiodev->pdata->oob_irq_supported) --- enable_irq_wake(sdiodev->pdata->oob_irq_nr); --+ if (sdiodev->settings->bus.sdio.oob_irq_supported) --+ enable_irq_wake(sdiodev->settings->bus.sdio.oob_irq_nr); -- else -- sdio_flags |= MMC_PM_WAKE_SDIO_IRQ; -- } ----- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bus.h --+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bus.h --@@ -43,6 +43,8 @@ enum brcmf_bus_protocol_type { -- BRCMF_PROTO_MSGBUF -- }; -- --+struct brcmf_mp_device; --+ -- struct brcmf_bus_dcmd { -- char *name; -- char *param; --@@ -217,7 +219,7 @@ bool brcmf_c_prec_enq(struct device *dev -- void brcmf_rx_frame(struct device *dev, struct sk_buff *rxp); -- -- /* Indication from bus module regarding presence/insertion of dongle. */ ---int brcmf_attach(struct device *dev); --+int brcmf_attach(struct device *dev, struct brcmf_mp_device *settings); -- /* Indication from bus module regarding removal/absence of dongle */ -- void brcmf_detach(struct device *dev); -- /* Indication from bus module that dongle should be reset */ ----- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c --+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c --@@ -243,14 +243,35 @@ static void brcmf_mp_attach(void) -- } -- } -- ---struct brcmfmac_sdio_pd *brcmf_get_module_param(struct device *dev, --- enum brcmf_bus_type bus_type, --- u32 chip, u32 chiprev) --+struct brcmf_mp_device *brcmf_get_module_param(struct device *dev, --+ enum brcmf_bus_type bus_type, --+ u32 chip, u32 chiprev) -- { --- struct brcmfmac_sdio_pd *pdata; --+ struct brcmf_mp_device *settings; -- struct brcmfmac_pd_device *device_pd; --+ bool found; -- int i; -- --+ brcmf_dbg(INFO, "Enter, bus=%d, chip=%d, rev=%d\n", bus_type, chip, --+ chiprev); --+ settings = kzalloc(sizeof(*settings), GFP_ATOMIC); --+ if (!settings) --+ return NULL; --+ --+ /* start by using the module paramaters */ --+ settings->p2p_enable = !!brcmf_p2p_enable; --+ settings->feature_disable = brcmf_feature_disable; --+ settings->fcmode = brcmf_fcmode; --+ settings->roamoff = !!brcmf_roamoff; --+#ifdef DEBUG --+ settings->ignore_probe_fail = !!brcmf_ignore_probe_fail; --+#endif --+ --+ if (bus_type == BRCMF_BUSTYPE_SDIO) --+ settings->bus.sdio.txglomsz = brcmf_sdiod_txglomsz; --+ --+ /* See if there is any device specific platform data configured */ --+ found = false; -- if (brcmfmac_pdata) { -- for (i = 0; i < brcmfmac_pdata->device_count; i++) { -- device_pd = &brcmfmac_pdata->devices[i]; --@@ -259,38 +280,29 @@ struct brcmfmac_sdio_pd *brcmf_get_modul -- ((device_pd->rev == chiprev) || -- (device_pd->rev == -1))) { -- brcmf_dbg(INFO, "Platform data for device found\n"); --+ settings->country_codes = --+ device_pd->country_codes; -- if (device_pd->bus_type == BRCMF_BUSTYPE_SDIO) --- return &device_pd->bus.sdio; --+ memcpy(&settings->bus.sdio, --+ &device_pd->bus.sdio, --+ sizeof(settings->bus.sdio)); --+ found = true; -- break; -- } -- } -- } --- pdata = NULL; --- brcmf_of_probe(dev, &pdata); --- --- return pdata; ---} --- ---int brcmf_mp_device_attach(struct brcmf_pub *drvr) ---{ --- drvr->settings = kzalloc(sizeof(*drvr->settings), GFP_ATOMIC); --- if (!drvr->settings) --- return -ENOMEM; --- --- drvr->settings->sdiod_txglomsz = brcmf_sdiod_txglomsz; --- drvr->settings->p2p_enable = !!brcmf_p2p_enable; --- drvr->settings->feature_disable = brcmf_feature_disable; --- drvr->settings->fcmode = brcmf_fcmode; --- drvr->settings->roamoff = !!brcmf_roamoff; ---#ifdef DEBUG --- drvr->settings->ignore_probe_fail = !!brcmf_ignore_probe_fail; ---#endif --- return 0; --+ if ((bus_type == BRCMF_BUSTYPE_SDIO) && (!found)) { --+ /* No platform data for this device. In case of SDIO try OF --+ * (Open Firwmare) Device Tree. --+ */ --+ brcmf_of_probe(dev, &settings->bus.sdio); --+ } --+ return settings; -- } -- ---void brcmf_mp_device_detach(struct brcmf_pub *drvr) --+void brcmf_release_module_param(struct brcmf_mp_device *module_param) -- { --- kfree(drvr->settings); --+ kfree(module_param); -- } -- -- static int __init brcmf_common_pd_probe(struct platform_device *pdev) ----- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.h --+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.h --@@ -45,41 +45,30 @@ extern struct brcmf_mp_global_t brcmf_mp -- /** -- * struct brcmf_mp_device - Device module paramaters. -- * --- * @sdiod_txglomsz: SDIO txglom size. --- * @joinboost_5g_rssi: 5g rssi booost for preferred join selection. -- * @p2p_enable: Legacy P2P0 enable (old wpa_supplicant). -- * @feature_disable: Feature_disable bitmask. -- * @fcmode: FWS flow control. -- * @roamoff: Firmware roaming off? --+ * @ignore_probe_fail: Ignore probe failure. -- * @country_codes: If available, pointer to struct for translating country codes --+ * @bus: Bus specific platform data. Only SDIO at the mmoment. -- */ -- struct brcmf_mp_device { --- int sdiod_txglomsz; --- int joinboost_5g_rssi; --- bool p2p_enable; --- int feature_disable; --- int fcmode; --- bool roamoff; --- bool ignore_probe_fail; --+ bool p2p_enable; --+ unsigned int feature_disable; --+ int fcmode; --+ bool roamoff; --+ bool ignore_probe_fail; -- struct brcmfmac_pd_cc *country_codes; --+ union { --+ struct brcmfmac_sdio_pd sdio; --+ } bus; -- }; -- ---struct brcmfmac_sdio_pd *brcmf_get_module_param(struct device *dev, --- enum brcmf_bus_type bus_type, --- u32 chip, u32 chiprev); ---int brcmf_mp_device_attach(struct brcmf_pub *drvr); ---void brcmf_mp_device_detach(struct brcmf_pub *drvr); ---#ifdef DEBUG ---static inline bool brcmf_ignoring_probe_fail(struct brcmf_pub *drvr) ---{ --- return drvr->settings->ignore_probe_fail; ---} ---#else ---static inline bool brcmf_ignoring_probe_fail(struct brcmf_pub *drvr) ---{ --- return false; ---} ---#endif --+struct brcmf_mp_device *brcmf_get_module_param(struct device *dev, --+ enum brcmf_bus_type bus_type, --+ u32 chip, u32 chiprev); --+void brcmf_release_module_param(struct brcmf_mp_device *module_param); -- -- /* Sets dongle media info (drv_version, mac address). */ -- int brcmf_c_preinit_dcmds(struct brcmf_if *ifp); ----- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c --+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c --@@ -1104,7 +1104,7 @@ static int brcmf_inet6addr_changed(struc -- } -- #endif -- ---int brcmf_attach(struct device *dev) --+int brcmf_attach(struct device *dev, struct brcmf_mp_device *settings) -- { -- struct brcmf_pub *drvr = NULL; -- int ret = 0; --@@ -1126,10 +1126,7 @@ int brcmf_attach(struct device *dev) -- drvr->hdrlen = 0; -- drvr->bus_if = dev_get_drvdata(dev); -- drvr->bus_if->drvr = drvr; --- --- /* Initialize device specific settings */ --- if (brcmf_mp_device_attach(drvr)) --- goto fail; --+ drvr->settings = settings; -- -- /* attach debug facilities */ -- brcmf_debug_attach(drvr); --@@ -1274,7 +1271,7 @@ fail: -- brcmf_net_detach(p2p_ifp->ndev); -- drvr->iflist[0] = NULL; -- drvr->iflist[1] = NULL; --- if (brcmf_ignoring_probe_fail(drvr)) --+ if (drvr->settings->ignore_probe_fail) -- ret = 0; -- -- return ret; --@@ -1350,8 +1347,6 @@ void brcmf_detach(struct device *dev) -- -- brcmf_proto_detach(drvr); -- --- brcmf_mp_device_detach(drvr); --- -- brcmf_debug_detach(drvr); -- bus_if->drvr = NULL; -- kfree(drvr); ----- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.c --+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.c --@@ -23,7 +23,7 @@ -- #include "common.h" -- #include "of.h" -- ---void brcmf_of_probe(struct device *dev, struct brcmfmac_sdio_pd **sdio) --+void brcmf_of_probe(struct device *dev, struct brcmfmac_sdio_pd *sdio) -- { -- struct device_node *np = dev->of_node; -- int irq; --@@ -33,12 +33,8 @@ void brcmf_of_probe(struct device *dev, -- if (!np || !of_device_is_compatible(np, "brcm,bcm4329-fmac")) -- return; -- --- *sdio = devm_kzalloc(dev, sizeof(*sdio), GFP_KERNEL); --- if (!(*sdio)) --- return; --- -- if (of_property_read_u32(np, "brcm,drive-strength", &val) == 0) --- (*sdio)->drive_strength = val; --+ sdio->drive_strength = val; -- -- /* make sure there are interrupts defined in the node */ -- if (!of_find_property(np, "interrupts", NULL)) --@@ -51,7 +47,7 @@ void brcmf_of_probe(struct device *dev, -- } -- irqf = irqd_get_trigger_type(irq_get_irq_data(irq)); -- --- (*sdio)->oob_irq_supported = true; --- (*sdio)->oob_irq_nr = irq; --- (*sdio)->oob_irq_flags = irqf; --+ sdio->oob_irq_supported = true; --+ sdio->oob_irq_nr = irq; --+ sdio->oob_irq_flags = irqf; -- } ----- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.h --+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.h --@@ -14,10 +14,9 @@ -- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -- */ -- #ifdef CONFIG_OF ---void ---brcmf_of_probe(struct device *dev, struct brcmfmac_sdio_pd **sdio); --+void brcmf_of_probe(struct device *dev, struct brcmfmac_sdio_pd *sdio); -- #else ---static void brcmf_of_probe(struct device *dev, struct brcmfmac_sdio_pd **sdio) --+static void brcmf_of_probe(struct device *dev, struct brcmfmac_sdio_pd *sdio) -- { -- } -- #endif /* CONFIG_OF */ ----- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c --+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c --@@ -37,6 +37,8 @@ -- #include "pcie.h" -- #include "firmware.h" -- #include "chip.h" --+#include "core.h" --+#include "common.h" -- -- -- enum brcmf_pcie_state { --@@ -266,6 +268,7 @@ struct brcmf_pciedev_info { -- u16 (*read_ptr)(struct brcmf_pciedev_info *devinfo, u32 mem_offset); -- void (*write_ptr)(struct brcmf_pciedev_info *devinfo, u32 mem_offset, -- u16 value); --+ struct brcmf_mp_device *settings; -- }; -- -- struct brcmf_pcie_ringbuf { --@@ -1525,16 +1528,16 @@ static void brcmf_pcie_release_resource( -- } -- -- ---static int brcmf_pcie_attach_bus(struct device *dev) --+static int brcmf_pcie_attach_bus(struct brcmf_pciedev_info *devinfo) -- { -- int ret; -- -- /* Attach to the common driver interface */ --- ret = brcmf_attach(dev); --+ ret = brcmf_attach(&devinfo->pdev->dev, devinfo->settings); -- if (ret) { -- brcmf_err("brcmf_attach failed\n"); -- } else { --- ret = brcmf_bus_start(dev); --+ ret = brcmf_bus_start(&devinfo->pdev->dev); -- if (ret) -- brcmf_err("dongle is not responding\n"); -- } --@@ -1672,7 +1675,7 @@ static void brcmf_pcie_setup(struct devi -- init_waitqueue_head(&devinfo->mbdata_resp_wait); -- -- brcmf_pcie_intr_enable(devinfo); --- if (brcmf_pcie_attach_bus(bus->dev) == 0) --+ if (brcmf_pcie_attach_bus(devinfo) == 0) -- return; -- -- brcmf_pcie_bus_console_read(devinfo); --@@ -1716,6 +1719,15 @@ brcmf_pcie_probe(struct pci_dev *pdev, c -- goto fail; -- } -- --+ devinfo->settings = brcmf_get_module_param(&devinfo->pdev->dev, --+ BRCMF_BUSTYPE_PCIE, --+ devinfo->ci->chip, --+ devinfo->ci->chiprev); --+ if (!devinfo->settings) { --+ ret = -ENOMEM; --+ goto fail; --+ } --+ -- bus = kzalloc(sizeof(*bus), GFP_KERNEL); -- if (!bus) { -- ret = -ENOMEM; --@@ -1760,6 +1772,8 @@ fail: -- brcmf_pcie_release_resource(devinfo); -- if (devinfo->ci) -- brcmf_chip_detach(devinfo->ci); --+ if (devinfo->settings) --+ brcmf_release_module_param(devinfo->settings); -- kfree(pcie_bus_dev); -- kfree(devinfo); -- return ret; --@@ -1799,6 +1813,8 @@ brcmf_pcie_remove(struct pci_dev *pdev) -- -- if (devinfo->ci) -- brcmf_chip_detach(devinfo->ci); --+ if (devinfo->settings) --+ brcmf_release_module_param(devinfo->settings); -- -- kfree(devinfo); -- dev_set_drvdata(&pdev->dev, NULL); ----- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c --+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c --@@ -2442,15 +2442,17 @@ static void brcmf_sdio_bus_stop(struct d -- -- static inline void brcmf_sdio_clrintr(struct brcmf_sdio *bus) -- { --+ struct brcmf_sdio_dev *sdiodev; -- unsigned long flags; -- --- if (bus->sdiodev->oob_irq_requested) { --- spin_lock_irqsave(&bus->sdiodev->irq_en_lock, flags); --- if (!bus->sdiodev->irq_en && !atomic_read(&bus->ipend)) { --- enable_irq(bus->sdiodev->pdata->oob_irq_nr); --- bus->sdiodev->irq_en = true; --+ sdiodev = bus->sdiodev; --+ if (sdiodev->oob_irq_requested) { --+ spin_lock_irqsave(&sdiodev->irq_en_lock, flags); --+ if (!sdiodev->irq_en && !atomic_read(&bus->ipend)) { --+ enable_irq(sdiodev->settings->bus.sdio.oob_irq_nr); --+ sdiodev->irq_en = true; -- } --- spin_unlock_irqrestore(&bus->sdiodev->irq_en_lock, flags); --+ spin_unlock_irqrestore(&sdiodev->irq_en_lock, flags); -- } -- } -- --@@ -3394,9 +3396,7 @@ static int brcmf_sdio_bus_preinit(struct -- sizeof(u32)); -- } else { -- /* otherwise, set txglomalign */ --- value = 4; --- if (sdiodev->pdata) --- value = sdiodev->pdata->sd_sgentry_align; --+ value = sdiodev->settings->bus.sdio.sd_sgentry_align; -- /* SDIO ADMA requires at least 32 bit alignment */ -- value = max_t(u32, value, 4); -- err = brcmf_iovar_data_set(dev, "bus:txglomalign", &value, --@@ -3811,21 +3811,25 @@ brcmf_sdio_probe_attach(struct brcmf_sdi -- bus->ci = NULL; -- goto fail; -- } --- sdiodev->pdata = brcmf_get_module_param(sdiodev->dev, --+ sdiodev->settings = brcmf_get_module_param(sdiodev->dev, -- BRCMF_BUSTYPE_SDIO, -- bus->ci->chip, -- bus->ci->chiprev); --+ if (!sdiodev->settings) { --+ brcmf_err("Failed to get device parameters\n"); --+ goto fail; --+ } -- /* platform specific configuration: -- * alignments must be at least 4 bytes for ADMA -- */ -- bus->head_align = ALIGNMENT; -- bus->sgentry_align = ALIGNMENT; --- if (sdiodev->pdata) { --- if (sdiodev->pdata->sd_head_align > ALIGNMENT) --- bus->head_align = sdiodev->pdata->sd_head_align; --- if (sdiodev->pdata->sd_sgentry_align > ALIGNMENT) --- bus->sgentry_align = sdiodev->pdata->sd_sgentry_align; --- } --+ if (sdiodev->settings->bus.sdio.sd_head_align > ALIGNMENT) --+ bus->head_align = sdiodev->settings->bus.sdio.sd_head_align; --+ if (sdiodev->settings->bus.sdio.sd_sgentry_align > ALIGNMENT) --+ bus->sgentry_align = --+ sdiodev->settings->bus.sdio.sd_sgentry_align; --+ -- /* allocate scatter-gather table. sg support -- * will be disabled upon allocation failure. -- */ --@@ -3837,7 +3841,7 @@ brcmf_sdio_probe_attach(struct brcmf_sdi -- */ -- if ((sdio_get_host_pm_caps(sdiodev->func[1]) & MMC_PM_KEEP_POWER) && -- ((sdio_get_host_pm_caps(sdiodev->func[1]) & MMC_PM_WAKE_SDIO_IRQ) || --- (sdiodev->pdata && sdiodev->pdata->oob_irq_supported))) --+ (sdiodev->settings->bus.sdio.oob_irq_supported))) -- sdiodev->bus_if->wowl_supported = true; -- #endif -- --@@ -3846,8 +3850,8 @@ brcmf_sdio_probe_attach(struct brcmf_sdi -- goto fail; -- } -- --- if ((sdiodev->pdata) && (sdiodev->pdata->drive_strength)) --- drivestrength = sdiodev->pdata->drive_strength; --+ if (sdiodev->settings->bus.sdio.drive_strength) --+ drivestrength = sdiodev->settings->bus.sdio.drive_strength; -- else -- drivestrength = DEFAULT_SDIO_DRIVE_STRENGTH; -- brcmf_sdio_drivestrengthinit(sdiodev, bus->ci, drivestrength); --@@ -4124,7 +4128,7 @@ struct brcmf_sdio *brcmf_sdio_probe(stru -- bus->tx_hdrlen = SDPCM_HWHDR_LEN + SDPCM_SWHDR_LEN; -- -- /* Attach to the common layer, reserve hdr space */ --- ret = brcmf_attach(bus->sdiodev->dev); --+ ret = brcmf_attach(bus->sdiodev->dev, bus->sdiodev->settings); -- if (ret != 0) { -- brcmf_err("brcmf_attach failed\n"); -- goto fail; --@@ -4228,6 +4232,8 @@ void brcmf_sdio_remove(struct brcmf_sdio -- } -- brcmf_chip_detach(bus->ci); -- } --+ if (bus->sdiodev->settings) --+ brcmf_release_module_param(bus->sdiodev->settings); -- -- kfree(bus->rxbuf); -- kfree(bus->hdrbuf); ----- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h --+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h --@@ -184,7 +184,7 @@ struct brcmf_sdio_dev { -- struct brcmf_sdio *bus; -- struct device *dev; -- struct brcmf_bus *bus_if; --- struct brcmfmac_sdio_pd *pdata; --+ struct brcmf_mp_device *settings; -- bool oob_irq_requested; -- bool irq_en; /* irq enable flags */ -- spinlock_t irq_en_lock; ----- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c --+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c --@@ -27,6 +27,8 @@ -- #include "debug.h" -- #include "firmware.h" -- #include "usb.h" --+#include "core.h" --+#include "common.h" -- -- -- #define IOCTL_RESP_TIMEOUT msecs_to_jiffies(2000) --@@ -171,6 +173,7 @@ struct brcmf_usbdev_info { -- struct urb *bulk_urb; /* used for FW download */ -- -- bool wowl_enabled; --+ struct brcmf_mp_device *settings; -- }; -- -- static void brcmf_usb_rx_refill(struct brcmf_usbdev_info *devinfo, --@@ -1027,6 +1030,9 @@ static void brcmf_usb_detach(struct brcm -- -- kfree(devinfo->tx_reqs); -- kfree(devinfo->rx_reqs); --+ --+ if (devinfo->settings) --+ brcmf_release_module_param(devinfo->settings); -- } -- -- --@@ -1136,7 +1142,7 @@ static int brcmf_usb_bus_setup(struct br -- int ret; -- -- /* Attach to the common driver interface */ --- ret = brcmf_attach(devinfo->dev); --+ ret = brcmf_attach(devinfo->dev, devinfo->settings); -- if (ret) { -- brcmf_err("brcmf_attach failed\n"); -- return ret; --@@ -1223,6 +1229,14 @@ static int brcmf_usb_probe_cb(struct brc -- bus->wowl_supported = true; -- #endif -- --+ devinfo->settings = brcmf_get_module_param(bus->dev, BRCMF_BUSTYPE_USB, --+ bus_pub->devid, --+ bus_pub->chiprev); --+ if (!devinfo->settings) { --+ ret = -ENOMEM; --+ goto fail; --+ } --+ -- if (!brcmf_usb_dlneeded(devinfo)) { -- ret = brcmf_usb_bus_setup(devinfo); -- if (ret) -diff --git a/package/kernel/mac80211/patches/344-0019-brcmfmac-integrate-add_keyext-in-add_key.patch b/package/kernel/mac80211/patches/344-0019-brcmfmac-integrate-add_keyext-in-add_key.patch -deleted file mode 100644 -index eb680fc..0000000 ---- a/package/kernel/mac80211/patches/344-0019-brcmfmac-integrate-add_keyext-in-add_key.patch -+++ /dev/null -@@ -1,227 +0,0 @@ --From: Hante Meuleman --Date: Wed, 17 Feb 2016 11:27:09 +0100 --Subject: [PATCH] brcmfmac: integrate add_keyext in add_key -- --brcmf_add_keyext is called when a key is configured for a specific --mac address. This function is very similar to the calling function --brcmf_add_key. Integrate this function and also use existing del_key --function in case key is to be cleared. -- --Reviewed-by: Arend Van Spriel --Reviewed-by: Franky (Zhenhui) Lin --Reviewed-by: Pieter-Paul Giesberts --Signed-off-by: Hante Meuleman --Signed-off-by: Arend van Spriel --Signed-off-by: Kalle Valo ----- -- ----- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c --+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c --@@ -2073,84 +2073,34 @@ done: -- } -- -- static s32 ---brcmf_add_keyext(struct wiphy *wiphy, struct net_device *ndev, --- u8 key_idx, const u8 *mac_addr, struct key_params *params) --+brcmf_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev, --+ u8 key_idx, bool pairwise, const u8 *mac_addr) -- { -- struct brcmf_if *ifp = netdev_priv(ndev); -- struct brcmf_wsec_key key; -- s32 err = 0; --- u8 keybuf[8]; --+ --+ brcmf_dbg(TRACE, "Enter\n"); --+ if (!check_vif_up(ifp->vif)) --+ return -EIO; --+ --+ if (key_idx >= BRCMF_MAX_DEFAULT_KEYS) { --+ /* we ignore this key index in this case */ --+ return -EINVAL; --+ } -- -- memset(&key, 0, sizeof(key)); --- key.index = (u32) key_idx; --- /* Instead of bcast for ea address for default wep keys, --- driver needs it to be Null */ --- if (!is_multicast_ether_addr(mac_addr)) --- memcpy((char *)&key.ea, (void *)mac_addr, ETH_ALEN); --- key.len = (u32) params->key_len; --- /* check for key index change */ --- if (key.len == 0) { --- /* key delete */ --- err = send_key_to_dongle(ifp, &key); --- if (err) --- brcmf_err("key delete error (%d)\n", err); --- } else { --- if (key.len > sizeof(key.data)) { --- brcmf_err("Invalid key length (%d)\n", key.len); --- return -EINVAL; --- } -- --- brcmf_dbg(CONN, "Setting the key index %d\n", key.index); --- memcpy(key.data, params->key, key.len); --+ key.index = (u32)key_idx; --+ key.flags = BRCMF_PRIMARY_KEY; --+ key.algo = CRYPTO_ALGO_OFF; -- --- if (!brcmf_is_apmode(ifp->vif) && --- (params->cipher == WLAN_CIPHER_SUITE_TKIP)) { --- brcmf_dbg(CONN, "Swapping RX/TX MIC key\n"); --- memcpy(keybuf, &key.data[24], sizeof(keybuf)); --- memcpy(&key.data[24], &key.data[16], sizeof(keybuf)); --- memcpy(&key.data[16], keybuf, sizeof(keybuf)); --- } --+ brcmf_dbg(CONN, "key index (%d)\n", key_idx); -- --- /* if IW_ENCODE_EXT_RX_SEQ_VALID set */ --- if (params->seq && params->seq_len == 6) { --- /* rx iv */ --- u8 *ivptr; --- ivptr = (u8 *) params->seq; --- key.rxiv.hi = (ivptr[5] << 24) | (ivptr[4] << 16) | --- (ivptr[3] << 8) | ivptr[2]; --- key.rxiv.lo = (ivptr[1] << 8) | ivptr[0]; --- key.iv_initialized = true; --- } --+ /* Set the new key/index */ --+ err = send_key_to_dongle(ifp, &key); -- --- switch (params->cipher) { --- case WLAN_CIPHER_SUITE_WEP40: --- key.algo = CRYPTO_ALGO_WEP1; --- brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_WEP40\n"); --- break; --- case WLAN_CIPHER_SUITE_WEP104: --- key.algo = CRYPTO_ALGO_WEP128; --- brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_WEP104\n"); --- break; --- case WLAN_CIPHER_SUITE_TKIP: --- key.algo = CRYPTO_ALGO_TKIP; --- brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_TKIP\n"); --- break; --- case WLAN_CIPHER_SUITE_AES_CMAC: --- key.algo = CRYPTO_ALGO_AES_CCM; --- brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_AES_CMAC\n"); --- break; --- case WLAN_CIPHER_SUITE_CCMP: --- key.algo = CRYPTO_ALGO_AES_CCM; --- brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_CCMP\n"); --- break; --- default: --- brcmf_err("Invalid cipher (0x%x)\n", params->cipher); --- return -EINVAL; --- } --- err = send_key_to_dongle(ifp, &key); --- if (err) --- brcmf_err("wsec_key error (%d)\n", err); --- } --+ brcmf_dbg(TRACE, "Exit\n"); -- return err; -- } -- --@@ -2163,8 +2113,9 @@ brcmf_cfg80211_add_key(struct wiphy *wip -- struct brcmf_wsec_key *key; -- s32 val; -- s32 wsec; --- s32 err = 0; --+ s32 err; -- u8 keybuf[8]; --+ bool ext_key; -- -- brcmf_dbg(TRACE, "Enter\n"); -- brcmf_dbg(CONN, "key index (%d)\n", key_idx); --@@ -2177,27 +2128,32 @@ brcmf_cfg80211_add_key(struct wiphy *wip -- return -EINVAL; -- } -- --- if (mac_addr && --- (params->cipher != WLAN_CIPHER_SUITE_WEP40) && --- (params->cipher != WLAN_CIPHER_SUITE_WEP104)) { --- brcmf_dbg(TRACE, "Exit"); --- return brcmf_add_keyext(wiphy, ndev, key_idx, mac_addr, params); --- } --- --- key = &ifp->vif->profile.key[key_idx]; --- memset(key, 0, sizeof(*key)); --+ if (params->key_len == 0) --+ return brcmf_cfg80211_del_key(wiphy, ndev, key_idx, pairwise, --+ mac_addr); -- -- if (params->key_len > sizeof(key->data)) { -- brcmf_err("Too long key length (%u)\n", params->key_len); --- err = -EINVAL; --- goto done; --+ return -EINVAL; --+ } --+ --+ ext_key = false; --+ if (mac_addr && (params->cipher != WLAN_CIPHER_SUITE_WEP40) && --+ (params->cipher != WLAN_CIPHER_SUITE_WEP104)) { --+ brcmf_dbg(TRACE, "Ext key, mac %pM", mac_addr); --+ ext_key = true; -- } --+ --+ key = &ifp->vif->profile.key[key_idx]; --+ memset(key, 0, sizeof(*key)); --+ if ((ext_key) && (!is_multicast_ether_addr(mac_addr))) --+ memcpy((char *)&key->ea, (void *)mac_addr, ETH_ALEN); -- key->len = params->key_len; -- key->index = key_idx; --- -- memcpy(key->data, params->key, key->len); --+ if (!ext_key) --+ key->flags = BRCMF_PRIMARY_KEY; -- --- key->flags = BRCMF_PRIMARY_KEY; -- switch (params->cipher) { -- case WLAN_CIPHER_SUITE_WEP40: -- key->algo = CRYPTO_ALGO_WEP1; --@@ -2237,7 +2193,7 @@ brcmf_cfg80211_add_key(struct wiphy *wip -- } -- -- err = send_key_to_dongle(ifp, key); --- if (err) --+ if (ext_key || err) -- goto done; -- -- err = brcmf_fil_bsscfg_int_get(ifp, "wsec", &wsec); --@@ -2256,38 +2212,6 @@ done: -- brcmf_dbg(TRACE, "Exit\n"); -- return err; -- } --- ---static s32 ---brcmf_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev, --- u8 key_idx, bool pairwise, const u8 *mac_addr) ---{ --- struct brcmf_if *ifp = netdev_priv(ndev); --- struct brcmf_wsec_key key; --- s32 err = 0; --- --- brcmf_dbg(TRACE, "Enter\n"); --- if (!check_vif_up(ifp->vif)) --- return -EIO; --- --- if (key_idx >= BRCMF_MAX_DEFAULT_KEYS) { --- /* we ignore this key index in this case */ --- return -EINVAL; --- } --- --- memset(&key, 0, sizeof(key)); --- --- key.index = (u32) key_idx; --- key.flags = BRCMF_PRIMARY_KEY; --- key.algo = CRYPTO_ALGO_OFF; --- --- brcmf_dbg(CONN, "key index (%d)\n", key_idx); --- --- /* Set the new key/index */ --- err = send_key_to_dongle(ifp, &key); --- --- brcmf_dbg(TRACE, "Exit\n"); --- return err; ---} -- -- static s32 -- brcmf_cfg80211_get_key(struct wiphy *wiphy, struct net_device *ndev, -diff --git a/package/kernel/mac80211/patches/344-0020-brcmfmac-add-802.11w-management-frame-protection-sup.patch b/package/kernel/mac80211/patches/344-0020-brcmfmac-add-802.11w-management-frame-protection-sup.patch -deleted file mode 100644 -index c20d40c..0000000 ---- a/package/kernel/mac80211/patches/344-0020-brcmfmac-add-802.11w-management-frame-protection-sup.patch -+++ /dev/null -@@ -1,509 +0,0 @@ --From: Hante Meuleman --Date: Wed, 17 Feb 2016 11:27:10 +0100 --Subject: [PATCH] brcmfmac: add 802.11w management frame protection support -- --Add full support for both AP and STA for management frame protection. -- --Reviewed-by: Arend Van Spriel --Reviewed-by: Franky (Zhenhui) Lin --Reviewed-by: Pieter-Paul Giesberts --Signed-off-by: Hante Meuleman --Signed-off-by: Arend van Spriel --Signed-off-by: Kalle Valo ----- -- ----- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c --+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c --@@ -72,8 +72,13 @@ -- #define RSN_AKM_NONE 0 /* None (IBSS) */ -- #define RSN_AKM_UNSPECIFIED 1 /* Over 802.1x */ -- #define RSN_AKM_PSK 2 /* Pre-shared Key */ --+#define RSN_AKM_SHA256_1X 5 /* SHA256, 802.1X */ --+#define RSN_AKM_SHA256_PSK 6 /* SHA256, Pre-shared Key */ -- #define RSN_CAP_LEN 2 /* Length of RSN capabilities */ ---#define RSN_CAP_PTK_REPLAY_CNTR_MASK 0x000C --+#define RSN_CAP_PTK_REPLAY_CNTR_MASK (BIT(2) | BIT(3)) --+#define RSN_CAP_MFPR_MASK BIT(6) --+#define RSN_CAP_MFPC_MASK BIT(7) --+#define RSN_PMKID_COUNT_LEN 2 -- -- #define VNDR_IE_CMD_LEN 4 /* length of the set command -- * string :"add", "del" (+ NUL) --@@ -211,12 +216,19 @@ static const struct ieee80211_regdomain -- REG_RULE(5470-10, 5850+10, 80, 6, 20, 0), } -- }; -- ---static const u32 __wl_cipher_suites[] = { --+/* Note: brcmf_cipher_suites is an array of int defining which cipher suites --+ * are supported. A pointer to this array and the number of entries is passed --+ * on to upper layers. AES_CMAC defines whether or not the driver supports MFP. --+ * So the cipher suite AES_CMAC has to be the last one in the array, and when --+ * device does not support MFP then the number of suites will be decreased by 1 --+ */ --+static const u32 brcmf_cipher_suites[] = { -- WLAN_CIPHER_SUITE_WEP40, -- WLAN_CIPHER_SUITE_WEP104, -- WLAN_CIPHER_SUITE_TKIP, -- WLAN_CIPHER_SUITE_CCMP, --- WLAN_CIPHER_SUITE_AES_CMAC, --+ /* Keep as last entry: */ --+ WLAN_CIPHER_SUITE_AES_CMAC -- }; -- -- /* Vendor specific ie. id = 221, oui and type defines exact ie */ --@@ -1533,7 +1545,7 @@ static s32 brcmf_set_auth_type(struct ne -- -- static s32 -- brcmf_set_wsec_mode(struct net_device *ndev, --- struct cfg80211_connect_params *sme, bool mfp) --+ struct cfg80211_connect_params *sme) -- { -- struct brcmf_cfg80211_profile *profile = ndev_to_prof(ndev); -- struct brcmf_cfg80211_security *sec; --@@ -1592,10 +1604,7 @@ brcmf_set_wsec_mode(struct net_device *n -- sme->privacy) -- pval = AES_ENABLED; -- --- if (mfp) --- wsec = pval | gval | MFP_CAPABLE; --- else --- wsec = pval | gval; --+ wsec = pval | gval; -- err = brcmf_fil_bsscfg_int_set(netdev_priv(ndev), "wsec", wsec); -- if (err) { -- brcmf_err("error (%d)\n", err); --@@ -1612,56 +1621,100 @@ brcmf_set_wsec_mode(struct net_device *n -- static s32 -- brcmf_set_key_mgmt(struct net_device *ndev, struct cfg80211_connect_params *sme) -- { --- struct brcmf_cfg80211_profile *profile = ndev_to_prof(ndev); --- struct brcmf_cfg80211_security *sec; --- s32 val = 0; --- s32 err = 0; --+ struct brcmf_if *ifp = netdev_priv(ndev); --+ s32 val; --+ s32 err; --+ const struct brcmf_tlv *rsn_ie; --+ const u8 *ie; --+ u32 ie_len; --+ u32 offset; --+ u16 rsn_cap; --+ u32 mfp; --+ u16 count; -- --- if (sme->crypto.n_akm_suites) { --- err = brcmf_fil_bsscfg_int_get(netdev_priv(ndev), --- "wpa_auth", &val); --- if (err) { --- brcmf_err("could not get wpa_auth (%d)\n", err); --- return err; --+ if (!sme->crypto.n_akm_suites) --+ return 0; --+ --+ err = brcmf_fil_bsscfg_int_get(netdev_priv(ndev), "wpa_auth", &val); --+ if (err) { --+ brcmf_err("could not get wpa_auth (%d)\n", err); --+ return err; --+ } --+ if (val & (WPA_AUTH_PSK | WPA_AUTH_UNSPECIFIED)) { --+ switch (sme->crypto.akm_suites[0]) { --+ case WLAN_AKM_SUITE_8021X: --+ val = WPA_AUTH_UNSPECIFIED; --+ break; --+ case WLAN_AKM_SUITE_PSK: --+ val = WPA_AUTH_PSK; --+ break; --+ default: --+ brcmf_err("invalid cipher group (%d)\n", --+ sme->crypto.cipher_group); --+ return -EINVAL; -- } --- if (val & (WPA_AUTH_PSK | WPA_AUTH_UNSPECIFIED)) { --- switch (sme->crypto.akm_suites[0]) { --- case WLAN_AKM_SUITE_8021X: --- val = WPA_AUTH_UNSPECIFIED; --- break; --- case WLAN_AKM_SUITE_PSK: --- val = WPA_AUTH_PSK; --- break; --- default: --- brcmf_err("invalid cipher group (%d)\n", --- sme->crypto.cipher_group); --- return -EINVAL; --- } --- } else if (val & (WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED)) { --- switch (sme->crypto.akm_suites[0]) { --- case WLAN_AKM_SUITE_8021X: --- val = WPA2_AUTH_UNSPECIFIED; --- break; --- case WLAN_AKM_SUITE_PSK: --- val = WPA2_AUTH_PSK; --- break; --- default: --- brcmf_err("invalid cipher group (%d)\n", --- sme->crypto.cipher_group); --- return -EINVAL; --- } --+ } else if (val & (WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED)) { --+ switch (sme->crypto.akm_suites[0]) { --+ case WLAN_AKM_SUITE_8021X: --+ val = WPA2_AUTH_UNSPECIFIED; --+ break; --+ case WLAN_AKM_SUITE_8021X_SHA256: --+ val = WPA2_AUTH_1X_SHA256; --+ break; --+ case WLAN_AKM_SUITE_PSK_SHA256: --+ val = WPA2_AUTH_PSK_SHA256; --+ break; --+ case WLAN_AKM_SUITE_PSK: --+ val = WPA2_AUTH_PSK; --+ break; --+ default: --+ brcmf_err("invalid cipher group (%d)\n", --+ sme->crypto.cipher_group); --+ return -EINVAL; -- } --+ } -- --- 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); --- return err; --- } --+ if (!brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MFP)) --+ goto skip_mfp_config; --+ /* The MFP mode (1 or 2) needs to be determined, parse IEs. The --+ * IE will not be verified, just a quick search for MFP config --+ */ --+ rsn_ie = brcmf_parse_tlvs((const u8 *)sme->ie, sme->ie_len, --+ WLAN_EID_RSN); --+ if (!rsn_ie) --+ goto skip_mfp_config; --+ ie = (const u8 *)rsn_ie; --+ ie_len = rsn_ie->len + TLV_HDR_LEN; --+ /* Skip unicast suite */ --+ offset = TLV_HDR_LEN + WPA_IE_VERSION_LEN + WPA_IE_MIN_OUI_LEN; --+ if (offset + WPA_IE_SUITE_COUNT_LEN >= ie_len) --+ goto skip_mfp_config; --+ /* Skip multicast suite */ --+ count = ie[offset] + (ie[offset + 1] << 8); --+ offset += WPA_IE_SUITE_COUNT_LEN + (count * WPA_IE_MIN_OUI_LEN); --+ if (offset + WPA_IE_SUITE_COUNT_LEN >= ie_len) --+ goto skip_mfp_config; --+ /* Skip auth key management suite(s) */ --+ count = ie[offset] + (ie[offset + 1] << 8); --+ offset += WPA_IE_SUITE_COUNT_LEN + (count * WPA_IE_MIN_OUI_LEN); --+ if (offset + WPA_IE_SUITE_COUNT_LEN > ie_len) --+ goto skip_mfp_config; --+ /* Ready to read capabilities */ --+ mfp = BRCMF_MFP_NONE; --+ rsn_cap = ie[offset] + (ie[offset + 1] << 8); --+ if (rsn_cap & RSN_CAP_MFPR_MASK) --+ mfp = BRCMF_MFP_REQUIRED; --+ else if (rsn_cap & RSN_CAP_MFPC_MASK) --+ mfp = BRCMF_MFP_CAPABLE; --+ brcmf_fil_bsscfg_int_set(netdev_priv(ndev), "mfp", mfp); --+ --+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); --+ return err; -- } --- sec = &profile->sec; --- sec->wpa_auth = sme->crypto.akm_suites[0]; -- -- return err; -- } --@@ -1827,7 +1880,7 @@ brcmf_cfg80211_connect(struct wiphy *wip -- goto done; -- } -- --- err = brcmf_set_wsec_mode(ndev, sme, sme->mfp == NL80211_MFP_REQUIRED); --+ err = brcmf_set_wsec_mode(ndev, sme); -- if (err) { -- brcmf_err("wl_set_set_cipher failed (%d)\n", err); -- goto done; --@@ -2077,10 +2130,12 @@ brcmf_cfg80211_del_key(struct wiphy *wip -- u8 key_idx, bool pairwise, const u8 *mac_addr) -- { -- struct brcmf_if *ifp = netdev_priv(ndev); --- struct brcmf_wsec_key key; --- s32 err = 0; --+ struct brcmf_wsec_key *key; --+ s32 err; -- -- brcmf_dbg(TRACE, "Enter\n"); --+ brcmf_dbg(CONN, "key index (%d)\n", key_idx); --+ -- if (!check_vif_up(ifp->vif)) -- return -EIO; -- --@@ -2089,16 +2144,19 @@ brcmf_cfg80211_del_key(struct wiphy *wip -- return -EINVAL; -- } -- --- memset(&key, 0, sizeof(key)); --+ key = &ifp->vif->profile.key[key_idx]; -- --- key.index = (u32)key_idx; --- key.flags = BRCMF_PRIMARY_KEY; --- key.algo = CRYPTO_ALGO_OFF; --+ if (key->algo == CRYPTO_ALGO_OFF) { --+ brcmf_dbg(CONN, "Ignore clearing of (never configured) key\n"); --+ return -EINVAL; --+ } -- --- brcmf_dbg(CONN, "key index (%d)\n", key_idx); --+ memset(key, 0, sizeof(*key)); --+ key->index = (u32)key_idx; --+ key->flags = BRCMF_PRIMARY_KEY; -- --- /* Set the new key/index */ --- err = send_key_to_dongle(ifp, &key); --+ /* Clear the key/index */ --+ err = send_key_to_dongle(ifp, key); -- -- brcmf_dbg(TRACE, "Exit\n"); -- return err; --@@ -2106,8 +2164,8 @@ brcmf_cfg80211_del_key(struct wiphy *wip -- -- static s32 -- brcmf_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev, --- u8 key_idx, bool pairwise, const u8 *mac_addr, --- struct key_params *params) --+ u8 key_idx, bool pairwise, const u8 *mac_addr, --+ struct key_params *params) -- { -- struct brcmf_if *ifp = netdev_priv(ndev); -- struct brcmf_wsec_key *key; --@@ -2214,9 +2272,10 @@ done: -- } -- -- static s32 ---brcmf_cfg80211_get_key(struct wiphy *wiphy, struct net_device *ndev, --- u8 key_idx, bool pairwise, const u8 *mac_addr, void *cookie, --- void (*callback) (void *cookie, struct key_params * params)) --+brcmf_cfg80211_get_key(struct wiphy *wiphy, struct net_device *ndev, u8 key_idx, --+ bool pairwise, const u8 *mac_addr, void *cookie, --+ void (*callback)(void *cookie, --+ struct key_params *params)) -- { -- struct key_params params; -- struct brcmf_if *ifp = netdev_priv(ndev); --@@ -2268,8 +2327,15 @@ done: -- -- static s32 -- brcmf_cfg80211_config_default_mgmt_key(struct wiphy *wiphy, --- struct net_device *ndev, u8 key_idx) --+ struct net_device *ndev, u8 key_idx) -- { --+ struct brcmf_if *ifp = netdev_priv(ndev); --+ --+ brcmf_dbg(TRACE, "Enter key_idx %d\n", key_idx); --+ --+ if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MFP)) --+ return 0; --+ -- brcmf_dbg(INFO, "Not supported\n"); -- -- return -EOPNOTSUPP; --@@ -3769,7 +3835,7 @@ brcmf_configure_wpaie(struct brcmf_if *i -- u32 auth = 0; /* d11 open authentication */ -- u16 count; -- s32 err = 0; --- s32 len = 0; --+ s32 len; -- u32 i; -- u32 wsec; -- u32 pval = 0; --@@ -3779,6 +3845,7 @@ brcmf_configure_wpaie(struct brcmf_if *i -- u8 *data; -- u16 rsn_cap; -- u32 wme_bss_disable; --+ u32 mfp; -- -- brcmf_dbg(TRACE, "Enter\n"); -- if (wpa_ie == NULL) --@@ -3893,19 +3960,53 @@ brcmf_configure_wpaie(struct brcmf_if *i -- is_rsn_ie ? (wpa_auth |= WPA2_AUTH_PSK) : -- (wpa_auth |= WPA_AUTH_PSK); -- break; --+ case RSN_AKM_SHA256_PSK: --+ brcmf_dbg(TRACE, "RSN_AKM_MFP_PSK\n"); --+ wpa_auth |= WPA2_AUTH_PSK_SHA256; --+ break; --+ case RSN_AKM_SHA256_1X: --+ brcmf_dbg(TRACE, "RSN_AKM_MFP_1X\n"); --+ wpa_auth |= WPA2_AUTH_1X_SHA256; --+ break; -- default: -- brcmf_err("Ivalid key mgmt info\n"); -- } -- offset++; -- } -- --+ mfp = BRCMF_MFP_NONE; -- if (is_rsn_ie) { -- wme_bss_disable = 1; -- if ((offset + RSN_CAP_LEN) <= len) { -- rsn_cap = data[offset] + (data[offset + 1] << 8); -- if (rsn_cap & RSN_CAP_PTK_REPLAY_CNTR_MASK) -- wme_bss_disable = 0; --+ if (rsn_cap & RSN_CAP_MFPR_MASK) { --+ brcmf_dbg(TRACE, "MFP Required\n"); --+ mfp = BRCMF_MFP_REQUIRED; --+ /* Firmware only supports mfp required in --+ * combination with WPA2_AUTH_PSK_SHA256 or --+ * WPA2_AUTH_1X_SHA256. --+ */ --+ if (!(wpa_auth & (WPA2_AUTH_PSK_SHA256 | --+ WPA2_AUTH_1X_SHA256))) { --+ err = -EINVAL; --+ goto exit; --+ } --+ /* Firmware has requirement that WPA2_AUTH_PSK/ --+ * WPA2_AUTH_UNSPECIFIED be set, if SHA256 OUI --+ * is to be included in the rsn ie. --+ */ --+ if (wpa_auth & WPA2_AUTH_PSK_SHA256) --+ wpa_auth |= WPA2_AUTH_PSK; --+ else if (wpa_auth & WPA2_AUTH_1X_SHA256) --+ wpa_auth |= WPA2_AUTH_UNSPECIFIED; --+ } else if (rsn_cap & RSN_CAP_MFPC_MASK) { --+ brcmf_dbg(TRACE, "MFP Capable\n"); --+ mfp = BRCMF_MFP_CAPABLE; --+ } -- } --+ offset += RSN_CAP_LEN; -- /* set wme_bss_disable to sync RSN Capabilities */ -- err = brcmf_fil_bsscfg_int_set(ifp, "wme_bss_disable", -- wme_bss_disable); --@@ -3913,6 +4014,21 @@ brcmf_configure_wpaie(struct brcmf_if *i -- brcmf_err("wme_bss_disable error %d\n", err); -- goto exit; -- } --+ --+ /* Skip PMKID cnt as it is know to be 0 for AP. */ --+ offset += RSN_PMKID_COUNT_LEN; --+ --+ /* See if there is BIP wpa suite left for MFP */ --+ if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MFP) && --+ ((offset + WPA_IE_MIN_OUI_LEN) <= len)) { --+ err = brcmf_fil_bsscfg_data_set(ifp, "bip", --+ &data[offset], --+ WPA_IE_MIN_OUI_LEN); --+ if (err < 0) { --+ brcmf_err("bip error %d\n", err); --+ goto exit; --+ } --+ } -- } -- /* FOR WPS , set SES_OW_ENABLED */ -- wsec = (pval | gval | SES_OW_ENABLED); --@@ -3929,6 +4045,16 @@ brcmf_configure_wpaie(struct brcmf_if *i -- brcmf_err("wsec error %d\n", err); -- goto exit; -- } --+ /* Configure MFP, this needs to go after wsec otherwise the wsec command --+ * will overwrite the values set by MFP --+ */ --+ 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); --+ goto exit; --+ } --+ } -- /* set upper-layer auth */ -- err = brcmf_fil_bsscfg_int_set(ifp, "wpa_auth", wpa_auth); -- if (err < 0) { --@@ -6149,8 +6275,10 @@ static int brcmf_setup_wiphy(struct wiph -- wiphy->n_addresses = i; -- -- wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM; --- wiphy->cipher_suites = __wl_cipher_suites; --- wiphy->n_cipher_suites = ARRAY_SIZE(__wl_cipher_suites); --+ wiphy->cipher_suites = brcmf_cipher_suites; --+ wiphy->n_cipher_suites = ARRAY_SIZE(brcmf_cipher_suites); --+ if (!brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MFP)) --+ wiphy->n_cipher_suites--; -- wiphy->flags |= WIPHY_FLAG_PS_ON_BY_DEFAULT | -- WIPHY_FLAG_OFFCHAN_TX | -- WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL; ----- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h --+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h --@@ -72,7 +72,7 @@ -- -- #define BRCMF_VNDR_IE_P2PAF_SHIFT 12 -- ---#define BRCMF_MAX_DEFAULT_KEYS 4 --+#define BRCMF_MAX_DEFAULT_KEYS 6 -- -- /* beacon loss timeout defaults */ -- #define BRCMF_DEFAULT_BCN_TIMEOUT_ROAM_ON 2 --@@ -107,7 +107,6 @@ struct brcmf_cfg80211_security { -- u32 auth_type; -- u32 cipher_pairwise; -- u32 cipher_group; --- u32 wpa_auth; -- }; -- -- /** ----- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c --+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c --@@ -161,6 +161,7 @@ void brcmf_feat_attach(struct brcmf_pub -- ifp->drvr->feat_flags &= ~BIT(BRCMF_FEAT_MBSS); -- 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"); -- -- pfn_mac.version = BRCMF_PFN_MACADDR_CFG_VER; -- err = brcmf_fil_iovar_data_get(ifp, "pfn_macaddr", &pfn_mac, ----- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.h --+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.h --@@ -30,6 +30,7 @@ -- * WOWL_ND: WOWL net detect (PNO) -- * WOWL_GTK: (WOWL) GTK rekeying offload -- * WOWL_ARP_ND: ARP and Neighbor Discovery offload support during WOWL. --+ * MFP: 802.11w Management Frame Protection. -- */ -- #define BRCMF_FEAT_LIST \ -- BRCMF_FEAT_DEF(MBSS) \ --@@ -42,7 +43,8 @@ -- BRCMF_FEAT_DEF(SCAN_RANDOM_MAC) \ -- BRCMF_FEAT_DEF(WOWL_ND) \ -- BRCMF_FEAT_DEF(WOWL_GTK) \ --- BRCMF_FEAT_DEF(WOWL_ARP_ND) --+ BRCMF_FEAT_DEF(WOWL_ARP_ND) \ --+ BRCMF_FEAT_DEF(MFP) -- -- /* -- * Quirks: ----- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil_types.h --+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil_types.h --@@ -142,6 +142,10 @@ -- #define BRCMF_RSN_KEK_LENGTH 16 -- #define BRCMF_RSN_REPLAY_LEN 8 -- --+#define BRCMF_MFP_NONE 0 --+#define BRCMF_MFP_CAPABLE 1 --+#define BRCMF_MFP_REQUIRED 2 --+ -- /* join preference types for join_pref iovar */ -- enum brcmf_join_pref_types { -- BRCMF_JOIN_PREF_RSSI = 1, ----- a/drivers/net/wireless/broadcom/brcm80211/include/brcmu_wifi.h --+++ b/drivers/net/wireless/broadcom/brcm80211/include/brcmu_wifi.h --@@ -236,6 +236,8 @@ static inline bool ac_bitmap_tst(u8 bitm -- #define WPA2_AUTH_RESERVED3 0x0200 -- #define WPA2_AUTH_RESERVED4 0x0400 -- #define WPA2_AUTH_RESERVED5 0x0800 --+#define WPA2_AUTH_1X_SHA256 0x1000 /* 1X with SHA256 key derivation */ --+#define WPA2_AUTH_PSK_SHA256 0x8000 /* PSK with SHA256 key derivation */ -- -- #define DOT11_DEFAULT_RTS_LEN 2347 -- #define DOT11_DEFAULT_FRAG_LEN 2346 -diff --git a/package/kernel/mac80211/patches/345-brcmfmac-Remove-waitqueue_active-check.patch b/package/kernel/mac80211/patches/345-brcmfmac-Remove-waitqueue_active-check.patch -deleted file mode 100644 -index 39f4383..0000000 ---- a/package/kernel/mac80211/patches/345-brcmfmac-Remove-waitqueue_active-check.patch -+++ /dev/null -@@ -1,54 +0,0 @@ --From: Hui Wang --Date: Wed, 9 Mar 2016 15:25:26 +0800 --Subject: [PATCH] brcmfmac: Remove waitqueue_active check -- --We met a problem of pm_suspend when repeated closing/opening the lid --on a Lenovo laptop (1/20 reproduce rate), below is the log: -- --[ 199.735876] PM: Entering mem sleep --[ 199.750516] e1000e: EEE TX LPI TIMER: 00000011 --[ 199.856638] Trying to free nonexistent resource <000000000000d000-000000000000d0ff> --[ 201.753566] brcmfmac: brcmf_pcie_suspend: Timeout on response for entering D3 substate --[ 201.753581] pci_legacy_suspend(): brcmf_pcie_suspend+0x0/0x1f0 [brcmfmac] returns -5 --[ 201.753585] dpm_run_callback(): pci_pm_suspend+0x0/0x160 returns -5 --[ 201.753589] PM: Device 0000:04:00.0 failed to suspend async: error -5 -- --Through debugging, we found when problem happens, it is not the device --fails to enter D3, but the signal D3_ACK comes too early to pass the --waitqueue_active() check. -- --Just like this: --brcmf_pcie_send_mb_data(devinfo, BRCMF_H2D_HOST_D3_INFORM); --// signal is triggered here --wait_event_timeout(devinfo->mbdata_resp_wait, devinfo->mbdata_completed, -- BRCMF_PCIE_MBDATA_TIMEOUT); -- --So far I think it is safe to remove waitqueue_active check since there --is only one place to trigger this signal (sending --BRCMF_H2D_HOST_D3_INFORM). And it is not a problem calling wake_up --event earlier than calling wait_event. -- --Cc: Brett Rudley --Cc: Hante Meuleman --Cc: Franky (Zhenhui) Lin --Cc: Pieter-Paul Giesberts --Cc: Arend van Spriel --Signed-off-by: Hui Wang --Signed-off-by: Kalle Valo ----- -- ----- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c --+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c --@@ -677,10 +677,8 @@ static void brcmf_pcie_handle_mb_data(st -- brcmf_dbg(PCIE, "D2H_MB_DATA: DEEP SLEEP EXIT\n"); -- if (dtoh_mb_data & BRCMF_D2H_DEV_D3_ACK) { -- brcmf_dbg(PCIE, "D2H_MB_DATA: D3 ACK\n"); --- if (waitqueue_active(&devinfo->mbdata_resp_wait)) { --- devinfo->mbdata_completed = true; --- wake_up(&devinfo->mbdata_resp_wait); --- } --+ devinfo->mbdata_completed = true; --+ wake_up(&devinfo->mbdata_resp_wait); -- } -- } -- -diff --git a/package/kernel/mac80211/patches/346-brcmfmac-uninitialized-ret-variable.patch b/package/kernel/mac80211/patches/346-brcmfmac-uninitialized-ret-variable.patch -deleted file mode 100644 -index 3c9ed42..0000000 ---- a/package/kernel/mac80211/patches/346-brcmfmac-uninitialized-ret-variable.patch -+++ /dev/null -@@ -1,21 +0,0 @@ --From: Dan Carpenter --Date: Tue, 15 Mar 2016 10:06:10 +0300 --Subject: [PATCH] brcmfmac: uninitialized "ret" variable -- --There is an error path where "ret" isn't initialized. -- --Signed-off-by: Dan Carpenter --Signed-off-by: Kalle Valo ----- -- ----- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c --+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c --@@ -250,7 +250,7 @@ static int brcmf_sdiod_request_data(stru -- u32 addr, u8 regsz, void *data, bool write) -- { -- struct sdio_func *func; --- int ret; --+ int ret = -EINVAL; -- -- brcmf_dbg(SDIO, "rw=%d, func=%d, addr=0x%05x, nbytes=%d\n", -- write, fn, addr, regsz); -diff --git a/package/kernel/mac80211/patches/347-brcmfmac-sdio-remove-unused-variable-retry_limit.patch b/package/kernel/mac80211/patches/347-brcmfmac-sdio-remove-unused-variable-retry_limit.patch -deleted file mode 100644 -index d1deb6e..0000000 ---- a/package/kernel/mac80211/patches/347-brcmfmac-sdio-remove-unused-variable-retry_limit.patch -+++ /dev/null -@@ -1,24 +0,0 @@ --From: Colin Ian King --Date: Sun, 20 Mar 2016 17:34:52 +0000 --Subject: [PATCH] brcmfmac: sdio: remove unused variable retry_limit -- --retry_limit has never been used during the life of this driver, so --we may as well remove it as it is redundant. -- --Signed-off-by: Colin Ian King --Reviewed-by: Julian Calaby --Signed-off-by: Kalle Valo ----- -- ----- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c --+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c --@@ -535,9 +535,6 @@ static int qcount[NUMPRIO]; -- -- #define RETRYCHAN(chan) ((chan) == SDPCM_EVENT_CHANNEL) -- ---/* Retry count for register access failures */ ---static const uint retry_limit = 2; --- -- /* Limit on rounding up frames */ -- static const uint max_roundup = 512; -- -diff --git a/package/kernel/mac80211/patches/348-brcmfmac-Delete-unnecessary-variable-initialisation.patch b/package/kernel/mac80211/patches/348-brcmfmac-Delete-unnecessary-variable-initialisation.patch -deleted file mode 100644 -index d399b26..0000000 ---- a/package/kernel/mac80211/patches/348-brcmfmac-Delete-unnecessary-variable-initialisation.patch -+++ /dev/null -@@ -1,26 +0,0 @@ --From: Markus Elfring --Date: Fri, 18 Mar 2016 13:23:24 +1100 --Subject: [PATCH] brcmfmac: Delete unnecessary variable initialisation -- --In brcmf_sdio_download_firmware(), bcmerror is set by the call to --brcmf_sdio_download_code_file(), before it's checked in the following --line. -- --Signed-off-by: Markus Elfring --Acked-by: Arend van Spriel --[Rewrote commit message] --Signed-off-by: Julian Calaby --Signed-off-by: Kalle Valo ----- -- ----- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c --+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c --@@ -3258,7 +3258,7 @@ static int brcmf_sdio_download_firmware( -- const struct firmware *fw, -- void *nvram, u32 nvlen) -- { --- int bcmerror = -EFAULT; --+ int bcmerror; -- u32 rstvec; -- -- sdio_claim_host(bus->sdiodev->func[1]); -diff --git a/package/kernel/mac80211/patches/349-0001-brcmfmac-clear-eventmask-array-before-using-it.patch b/package/kernel/mac80211/patches/349-0001-brcmfmac-clear-eventmask-array-before-using-it.patch -deleted file mode 100644 -index 0acb4fa..0000000 ---- a/package/kernel/mac80211/patches/349-0001-brcmfmac-clear-eventmask-array-before-using-it.patch -+++ /dev/null -@@ -1,27 +0,0 @@ --From: Hante Meuleman --Date: Mon, 11 Apr 2016 11:35:21 +0200 --Subject: [PATCH] brcmfmac: clear eventmask array before using it -- --When the event_msgs iovar is set an array is used to configure the --enabled events. This arrays needs to nulled before configuring --otherwise unhandled events will be enabled. This solves a problem --where in case of wowl the host got woken by an incorrectly enabled --event. -- --Reviewed-by: Pieter-Paul Giesberts --Reviewed-by: Arend Van Spriel --Signed-off-by: Hante Meuleman --Signed-off-by: Arend van Spriel --Signed-off-by: Kalle Valo ----- -- ----- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.c --+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.c --@@ -371,6 +371,7 @@ int brcmf_fweh_activate_events(struct br -- int i, err; -- s8 eventmask[BRCMF_EVENTING_MASK_LEN]; -- --+ memset(eventmask, 0, sizeof(eventmask)); -- for (i = 0; i < BRCMF_E_LAST; i++) { -- if (ifp->drvr->fweh.evt_handler[i]) { -- brcmf_dbg(EVENT, "enable event %s\n", -diff --git a/package/kernel/mac80211/patches/349-0002-brcmfmac-fix-clearing-wowl-wake-indicators.patch b/package/kernel/mac80211/patches/349-0002-brcmfmac-fix-clearing-wowl-wake-indicators.patch -deleted file mode 100644 -index 8d30678..0000000 ---- a/package/kernel/mac80211/patches/349-0002-brcmfmac-fix-clearing-wowl-wake-indicators.patch -+++ /dev/null -@@ -1,27 +0,0 @@ --From: Hante Meuleman --Date: Mon, 11 Apr 2016 11:35:22 +0200 --Subject: [PATCH] brcmfmac: fix clearing wowl wake indicators -- --Newer firmwares require the usage of the wowl wakeind struct as size --for the iovar to clear the wake indicators. Older firmwares do not --care, so change the used size. -- --Reviewed-by: Arend Van Spriel --Reviewed-by: Pieter-Paul Giesberts --Signed-off-by: Hante Meuleman --Signed-off-by: Arend van Spriel --Signed-off-by: Kalle Valo ----- -- ----- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c --+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c --@@ -3608,7 +3608,8 @@ static void brcmf_configure_wowl(struct -- if (!test_bit(BRCMF_VIF_STATUS_CONNECTED, &ifp->vif->sme_state)) -- wowl_config |= BRCMF_WOWL_UNASSOC; -- --- brcmf_fil_iovar_data_set(ifp, "wowl_wakeind", "clear", strlen("clear")); --+ brcmf_fil_iovar_data_set(ifp, "wowl_wakeind", "clear", --+ sizeof(struct brcmf_wowl_wakeind_le)); -- brcmf_fil_iovar_int_set(ifp, "wowl", wowl_config); -- brcmf_fil_iovar_int_set(ifp, "wowl_activate", 1); -- brcmf_bus_wowl_config(cfg->pub->bus_if, true); -diff --git a/package/kernel/mac80211/patches/349-0003-brcmfmac-insert-default-boardrev-in-nvram-data-if-mi.patch b/package/kernel/mac80211/patches/349-0003-brcmfmac-insert-default-boardrev-in-nvram-data-if-mi.patch -deleted file mode 100644 -index f293401..0000000 ---- a/package/kernel/mac80211/patches/349-0003-brcmfmac-insert-default-boardrev-in-nvram-data-if-mi.patch -+++ /dev/null -@@ -1,114 +0,0 @@ --From: Hante Meuleman --Date: Mon, 11 Apr 2016 11:35:23 +0200 --Subject: [PATCH] brcmfmac: insert default boardrev in nvram data if -- missing -- --Some nvram files/stores come without the boardrev information, --but firmware requires this to be set. When not found in nvram then --add a default boardrev string to the nvram data. -- --Reported-by: Rafal Milecki --Reviewed-by: Arend Van Spriel --Reviewed-by: Franky (Zhenhui) Lin --Reviewed-by: Pieter-Paul Giesberts --Signed-off-by: Hante Meuleman --Signed-off-by: Arend van Spriel --Signed-off-by: Kalle Valo ----- -- ----- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c --+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c --@@ -29,6 +29,7 @@ -- #define BRCMF_FW_MAX_NVRAM_SIZE 64000 -- #define BRCMF_FW_NVRAM_DEVPATH_LEN 19 /* devpath0=pcie/1/4/ */ -- #define BRCMF_FW_NVRAM_PCIEDEV_LEN 10 /* pcie/1/4/ + \0 */ --+#define BRCMF_FW_DEFAULT_BOARDREV "boardrev=0xff" -- -- enum nvram_parser_state { -- IDLE, --@@ -51,6 +52,7 @@ enum nvram_parser_state { -- * @entry: start position of key,value entry. -- * @multi_dev_v1: detect pcie multi device v1 (compressed). -- * @multi_dev_v2: detect pcie multi device v2. --+ * @boardrev_found: nvram contains boardrev information. -- */ -- struct nvram_parser { -- enum nvram_parser_state state; --@@ -63,6 +65,7 @@ struct nvram_parser { -- u32 entry; -- bool multi_dev_v1; -- bool multi_dev_v2; --+ bool boardrev_found; -- }; -- -- /** --@@ -125,6 +128,8 @@ static enum nvram_parser_state brcmf_nvr -- nvp->multi_dev_v1 = true; -- if (strncmp(&nvp->data[nvp->entry], "pcie/", 5) == 0) -- nvp->multi_dev_v2 = true; --+ if (strncmp(&nvp->data[nvp->entry], "boardrev", 8) == 0) --+ nvp->boardrev_found = true; -- } else if (!is_nvram_char(c) || c == ' ') { -- brcmf_dbg(INFO, "warning: ln=%d:col=%d: '=' expected, skip invalid key entry\n", -- nvp->line, nvp->column); --@@ -284,6 +289,8 @@ static void brcmf_fw_strip_multi_v1(stru -- while (i < nvp->nvram_len) { -- if ((nvp->nvram[i] - '0' == id) && (nvp->nvram[i + 1] == ':')) { -- i += 2; --+ if (strncmp(&nvp->nvram[i], "boardrev", 8) == 0) --+ nvp->boardrev_found = true; -- while (nvp->nvram[i] != 0) { -- nvram[j] = nvp->nvram[i]; -- i++; --@@ -335,6 +342,8 @@ static void brcmf_fw_strip_multi_v2(stru -- while (i < nvp->nvram_len - len) { -- if (strncmp(&nvp->nvram[i], prefix, len) == 0) { -- i += len; --+ if (strncmp(&nvp->nvram[i], "boardrev", 8) == 0) --+ nvp->boardrev_found = true; -- while (nvp->nvram[i] != 0) { -- nvram[j] = nvp->nvram[i]; -- i++; --@@ -356,6 +365,18 @@ fail: -- nvp->nvram_len = 0; -- } -- --+static void brcmf_fw_add_defaults(struct nvram_parser *nvp) --+{ --+ if (nvp->boardrev_found) --+ return; --+ --+ memcpy(&nvp->nvram[nvp->nvram_len], &BRCMF_FW_DEFAULT_BOARDREV, --+ strlen(BRCMF_FW_DEFAULT_BOARDREV)); --+ nvp->nvram_len += strlen(BRCMF_FW_DEFAULT_BOARDREV); --+ nvp->nvram[nvp->nvram_len] = '\0'; --+ nvp->nvram_len++; --+} --+ -- /* brcmf_nvram_strip :Takes a buffer of "=\n" lines read from a fil -- * and ending in a NUL. Removes carriage returns, empty lines, comment lines, -- * and converts newlines to NULs. Shortens buffer as needed and pads with NULs. --@@ -377,16 +398,21 @@ static void *brcmf_fw_nvram_strip(const -- if (nvp.state == END) -- break; -- } --- if (nvp.multi_dev_v1) --+ if (nvp.multi_dev_v1) { --+ nvp.boardrev_found = false; -- brcmf_fw_strip_multi_v1(&nvp, domain_nr, bus_nr); --- else if (nvp.multi_dev_v2) --+ } else if (nvp.multi_dev_v2) { --+ nvp.boardrev_found = false; -- brcmf_fw_strip_multi_v2(&nvp, domain_nr, bus_nr); --+ } -- -- if (nvp.nvram_len == 0) { -- kfree(nvp.nvram); -- return NULL; -- } -- --+ brcmf_fw_add_defaults(&nvp); --+ -- pad = nvp.nvram_len; -- *new_length = roundup(nvp.nvram_len + 1, 4); -- while (pad != *new_length) { -diff --git a/package/kernel/mac80211/patches/349-0004-brcmfmac-fix-p2p-scan-abort-null-pointer-exception.patch b/package/kernel/mac80211/patches/349-0004-brcmfmac-fix-p2p-scan-abort-null-pointer-exception.patch -deleted file mode 100644 -index ed0c83f..0000000 ---- a/package/kernel/mac80211/patches/349-0004-brcmfmac-fix-p2p-scan-abort-null-pointer-exception.patch -+++ /dev/null -@@ -1,29 +0,0 @@ --From: Hante Meuleman --Date: Mon, 11 Apr 2016 11:35:24 +0200 --Subject: [PATCH] brcmfmac: fix p2p scan abort null pointer exception -- --When p2p connection setup is performed without having ever done an --escan a null pointer exception can occur. This is because the ifp --to abort scanning is taken from escan struct while it was never --initialized. Fix this by using the primary ifp for scan abort. The --abort should still be performed and all scan related commands are --performed on primary ifp. -- --Reviewed-by: Arend Van Spriel --Reviewed-by: Pieter-Paul Giesberts --Signed-off-by: Hante Meuleman --Signed-off-by: Arend van Spriel --Signed-off-by: Kalle Valo ----- -- ----- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c --+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c --@@ -1266,7 +1266,7 @@ static void -- brcmf_p2p_stop_wait_next_action_frame(struct brcmf_cfg80211_info *cfg) -- { -- struct brcmf_p2p_info *p2p = &cfg->p2p; --- struct brcmf_if *ifp = cfg->escan_info.ifp; --+ struct brcmf_if *ifp = p2p->bss_idx[P2PAPI_BSSCFG_PRIMARY].vif->ifp; -- -- if (test_bit(BRCMF_P2P_STATUS_SENDING_ACT_FRAME, &p2p->status) && -- (test_bit(BRCMF_P2P_STATUS_ACTION_TX_COMPLETED, &p2p->status) || -diff --git a/package/kernel/mac80211/patches/349-0005-brcmfmac-screening-firmware-event-packet.patch b/package/kernel/mac80211/patches/349-0005-brcmfmac-screening-firmware-event-packet.patch -deleted file mode 100644 -index 4d26404..0000000 ---- a/package/kernel/mac80211/patches/349-0005-brcmfmac-screening-firmware-event-packet.patch -+++ /dev/null -@@ -1,297 +0,0 @@ --From: Franky Lin --Date: Mon, 11 Apr 2016 11:35:25 +0200 --Subject: [PATCH] brcmfmac: screening firmware event packet -- --Firmware uses asynchronized events as a communication method to the --host. The event packets are marked as ETH_P_LINK_CTL protocol type. For --SDIO and PCIe bus, this kind of packets are delivered through virtual --event channel not data channel. This patch adds a screening logic to --make sure the event handler only processes the events coming from the --correct channel. -- --Reviewed-by: Pieter-Paul Giesberts --Signed-off-by: Franky Lin --Signed-off-by: Arend van Spriel --Signed-off-by: Kalle Valo ----- -- ----- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bus.h --+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bus.h --@@ -216,7 +216,9 @@ bool brcmf_c_prec_enq(struct device *dev -- int prec); -- -- /* Receive frame for delivery to OS. Callee disposes of rxp. */ ---void brcmf_rx_frame(struct device *dev, struct sk_buff *rxp); --+void brcmf_rx_frame(struct device *dev, struct sk_buff *rxp, bool handle_evnt); --+/* Receive async event packet from firmware. Callee disposes of rxp. */ --+void brcmf_rx_event(struct device *dev, struct sk_buff *rxp); -- -- /* Indication from bus module regarding presence/insertion of dongle. */ -- int brcmf_attach(struct device *dev, struct brcmf_mp_device *settings); ----- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c --+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c --@@ -311,16 +311,17 @@ void brcmf_txflowblock(struct device *de -- brcmf_fws_bus_blocked(drvr, state); -- } -- ---void brcmf_netif_rx(struct brcmf_if *ifp, struct sk_buff *skb) --+void brcmf_netif_rx(struct brcmf_if *ifp, struct sk_buff *skb, --+ bool handle_event) -- { --- skb->dev = ifp->ndev; --- skb->protocol = eth_type_trans(skb, skb->dev); --+ skb->protocol = eth_type_trans(skb, ifp->ndev); -- -- if (skb->pkt_type == PACKET_MULTICAST) -- ifp->stats.multicast++; -- -- /* Process special event packets */ --- brcmf_fweh_process_skb(ifp->drvr, skb); --+ if (handle_event) --+ brcmf_fweh_process_skb(ifp->drvr, skb); -- -- if (!(ifp->ndev->flags & IFF_UP)) { -- brcmu_pkt_buf_free_skb(skb); --@@ -381,7 +382,7 @@ static void brcmf_rxreorder_process_info -- /* validate flags and flow id */ -- if (flags == 0xFF) { -- brcmf_err("invalid flags...so ignore this packet\n"); --- brcmf_netif_rx(ifp, pkt); --+ brcmf_netif_rx(ifp, pkt, false); -- return; -- } -- --@@ -393,7 +394,7 @@ static void brcmf_rxreorder_process_info -- if (rfi == NULL) { -- brcmf_dbg(INFO, "received flags to cleanup, but no flow (%d) yet\n", -- flow_id); --- brcmf_netif_rx(ifp, pkt); --+ brcmf_netif_rx(ifp, pkt, false); -- return; -- } -- --@@ -418,7 +419,7 @@ static void brcmf_rxreorder_process_info -- rfi = kzalloc(buf_size, GFP_ATOMIC); -- if (rfi == NULL) { -- brcmf_err("failed to alloc buffer\n"); --- brcmf_netif_rx(ifp, pkt); --+ brcmf_netif_rx(ifp, pkt, false); -- return; -- } -- --@@ -532,11 +533,11 @@ static void brcmf_rxreorder_process_info -- netif_rx: -- skb_queue_walk_safe(&reorder_list, pkt, pnext) { -- __skb_unlink(pkt, &reorder_list); --- brcmf_netif_rx(ifp, pkt); --+ brcmf_netif_rx(ifp, pkt, false); -- } -- } -- ---void brcmf_rx_frame(struct device *dev, struct sk_buff *skb) --+void brcmf_rx_frame(struct device *dev, struct sk_buff *skb, bool handle_evnt) -- { -- struct brcmf_if *ifp; -- struct brcmf_bus *bus_if = dev_get_drvdata(dev); --@@ -560,7 +561,32 @@ void brcmf_rx_frame(struct device *dev, -- if (rd->reorder) -- brcmf_rxreorder_process_info(ifp, rd->reorder, skb); -- else --- brcmf_netif_rx(ifp, skb); --+ brcmf_netif_rx(ifp, skb, handle_evnt); --+} --+ --+void brcmf_rx_event(struct device *dev, struct sk_buff *skb) --+{ --+ struct brcmf_if *ifp; --+ struct brcmf_bus *bus_if = dev_get_drvdata(dev); --+ struct brcmf_pub *drvr = bus_if->drvr; --+ int ret; --+ --+ brcmf_dbg(EVENT, "Enter: %s: rxp=%p\n", dev_name(dev), skb); --+ --+ /* process and remove protocol-specific header */ --+ ret = brcmf_proto_hdrpull(drvr, true, skb, &ifp); --+ --+ if (ret || !ifp || !ifp->ndev) { --+ if (ret != -ENODATA && ifp) --+ ifp->stats.rx_errors++; --+ brcmu_pkt_buf_free_skb(skb); --+ return; --+ } --+ --+ skb->protocol = eth_type_trans(skb, ifp->ndev); --+ --+ brcmf_fweh_process_skb(ifp->drvr, skb); --+ brcmu_pkt_buf_free_skb(skb); -- } -- -- void brcmf_txfinalize(struct brcmf_if *ifp, struct sk_buff *txp, bool success) ----- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h --+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h --@@ -225,7 +225,8 @@ int brcmf_get_next_free_bsscfgidx(struct -- void brcmf_txflowblock_if(struct brcmf_if *ifp, -- enum brcmf_netif_stop_reason reason, bool state); -- void brcmf_txfinalize(struct brcmf_if *ifp, struct sk_buff *txp, bool success); ---void brcmf_netif_rx(struct brcmf_if *ifp, struct sk_buff *skb); --+void brcmf_netif_rx(struct brcmf_if *ifp, struct sk_buff *skb, --+ bool handle_event); -- void brcmf_net_setcarrier(struct brcmf_if *ifp, bool on); -- int __init brcmf_core_init(void); -- void __exit brcmf_core_exit(void); ----- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c --+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c --@@ -20,6 +20,7 @@ -- -- #include -- #include --+#include -- -- #include -- #include --@@ -1075,28 +1076,13 @@ static void brcmf_msgbuf_rxbuf_event_pos -- } -- -- ---static void ---brcmf_msgbuf_rx_skb(struct brcmf_msgbuf *msgbuf, struct sk_buff *skb, --- u8 ifidx) ---{ --- struct brcmf_if *ifp; --- --- ifp = brcmf_get_ifp(msgbuf->drvr, ifidx); --- if (!ifp || !ifp->ndev) { --- brcmf_err("Received pkt for invalid ifidx %d\n", ifidx); --- brcmu_pkt_buf_free_skb(skb); --- return; --- } --- brcmf_netif_rx(ifp, skb); ---} --- --- -- static void brcmf_msgbuf_process_event(struct brcmf_msgbuf *msgbuf, void *buf) -- { -- struct msgbuf_rx_event *event; -- u32 idx; -- u16 buflen; -- struct sk_buff *skb; --+ struct brcmf_if *ifp; -- -- event = (struct msgbuf_rx_event *)buf; -- idx = le32_to_cpu(event->msg.request_id); --@@ -1116,7 +1102,19 @@ static void brcmf_msgbuf_process_event(s -- -- skb_trim(skb, buflen); -- --- brcmf_msgbuf_rx_skb(msgbuf, skb, event->msg.ifidx); --+ 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); --+ goto exit; --+ } --+ --+ skb->protocol = eth_type_trans(skb, ifp->ndev); --+ --+ brcmf_fweh_process_skb(ifp->drvr, skb); --+ --+exit: --+ brcmu_pkt_buf_free_skb(skb); -- } -- -- --@@ -1128,6 +1126,7 @@ brcmf_msgbuf_process_rx_complete(struct -- u16 data_offset; -- u16 buflen; -- u32 idx; --+ struct brcmf_if *ifp; -- -- brcmf_msgbuf_update_rxbufpost_count(msgbuf, 1); -- --@@ -1148,7 +1147,14 @@ brcmf_msgbuf_process_rx_complete(struct -- -- skb_trim(skb, buflen); -- --- brcmf_msgbuf_rx_skb(msgbuf, skb, rx_complete->msg.ifidx); --+ 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); --+ brcmu_pkt_buf_free_skb(skb); --+ return; --+ } --+ brcmf_netif_rx(ifp, skb, false); -- } -- -- ----- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c --+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c --@@ -1294,6 +1294,17 @@ static inline u8 brcmf_sdio_getdatoffset -- return (u8)((hdrvalue & SDPCM_DOFFSET_MASK) >> SDPCM_DOFFSET_SHIFT); -- } -- --+static inline bool brcmf_sdio_fromevntchan(u8 *swheader) --+{ --+ u32 hdrvalue; --+ u8 ret; --+ --+ hdrvalue = *(u32 *)swheader; --+ ret = (u8)((hdrvalue & SDPCM_CHANNEL_MASK) >> SDPCM_CHANNEL_SHIFT); --+ --+ return (ret == SDPCM_EVENT_CHANNEL); --+} --+ -- static int brcmf_sdio_hdparse(struct brcmf_sdio *bus, u8 *header, -- struct brcmf_sdio_hdrinfo *rd, -- enum brcmf_sdio_frmtype type) --@@ -1641,7 +1652,11 @@ static u8 brcmf_sdio_rxglom(struct brcmf -- pfirst->len, pfirst->next, -- pfirst->prev); -- skb_unlink(pfirst, &bus->glom); --- brcmf_rx_frame(bus->sdiodev->dev, pfirst); --+ if (brcmf_sdio_fromevntchan(pfirst->data)) --+ brcmf_rx_event(bus->sdiodev->dev, pfirst); --+ else --+ brcmf_rx_frame(bus->sdiodev->dev, pfirst, --+ false); -- bus->sdcnt.rxglompkts++; -- } -- --@@ -1967,18 +1982,19 @@ static uint brcmf_sdio_readframes(struct -- __skb_trim(pkt, rd->len); -- skb_pull(pkt, rd->dat_offset); -- --+ if (pkt->len == 0) --+ brcmu_pkt_buf_free_skb(pkt); --+ else if (rd->channel == SDPCM_EVENT_CHANNEL) --+ brcmf_rx_event(bus->sdiodev->dev, pkt); --+ else --+ brcmf_rx_frame(bus->sdiodev->dev, pkt, --+ false); --+ -- /* prepare the descriptor for the next read */ -- rd->len = rd->len_nxtfrm << 4; -- rd->len_nxtfrm = 0; -- /* treat all packet as event if we don't know */ -- rd->channel = SDPCM_EVENT_CHANNEL; --- --- if (pkt->len == 0) { --- brcmu_pkt_buf_free_skb(pkt); --- continue; --- } --- --- brcmf_rx_frame(bus->sdiodev->dev, pkt); -- } -- -- rxcount = maxframes - rxleft; ----- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c --+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c --@@ -514,7 +514,7 @@ static void brcmf_usb_rx_complete(struct -- -- if (devinfo->bus_pub.state == BRCMFMAC_USB_STATE_UP) { -- skb_put(skb, urb->actual_length); --- brcmf_rx_frame(devinfo->dev, skb); --+ brcmf_rx_frame(devinfo->dev, skb, true); -- brcmf_usb_rx_refill(devinfo, req); -- } else { -- brcmu_pkt_buf_free_skb(skb); -diff --git a/package/kernel/mac80211/patches/349-0006-brcmfmac-cleanup-ampdu-rx-host-reorder-code.patch b/package/kernel/mac80211/patches/349-0006-brcmfmac-cleanup-ampdu-rx-host-reorder-code.patch -deleted file mode 100644 -index 33b263d..0000000 ---- a/package/kernel/mac80211/patches/349-0006-brcmfmac-cleanup-ampdu-rx-host-reorder-code.patch -+++ /dev/null -@@ -1,585 +0,0 @@ --From: Arend van Spriel --Date: Mon, 11 Apr 2016 11:35:26 +0200 --Subject: [PATCH] brcmfmac: cleanup ampdu-rx host reorder code -- --The code for ampdu-rx host reorder is related to the firmware signalling --supported in BCDC protocol. This change moves the code to fwsignal module. -- --Reviewed-by: Hante Meuleman --Reviewed-by: Pieter-Paul Giesberts --Reviewed-by: Franky Lin --Signed-off-by: Arend van Spriel --Signed-off-by: Kalle Valo ----- -- ----- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcdc.c --+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcdc.c --@@ -351,6 +351,12 @@ brcmf_proto_bcdc_add_tdls_peer(struct br -- { -- } -- --+static void brcmf_proto_bcdc_rxreorder(struct brcmf_if *ifp, --+ struct sk_buff *skb) --+{ --+ brcmf_fws_rxreorder(ifp, skb); --+} --+ -- int brcmf_proto_bcdc_attach(struct brcmf_pub *drvr) -- { -- struct brcmf_bcdc *bcdc; --@@ -372,6 +378,7 @@ int brcmf_proto_bcdc_attach(struct brcmf -- drvr->proto->configure_addr_mode = brcmf_proto_bcdc_configure_addr_mode; -- drvr->proto->delete_peer = brcmf_proto_bcdc_delete_peer; -- drvr->proto->add_tdls_peer = brcmf_proto_bcdc_add_tdls_peer; --+ drvr->proto->rxreorder = brcmf_proto_bcdc_rxreorder; -- drvr->proto->pd = bcdc; -- -- drvr->hdrlen += BCDC_HEADER_LEN + BRCMF_PROT_FW_SIGNAL_MAX_TXBYTES; ----- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c --+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c --@@ -40,19 +40,6 @@ -- -- #define MAX_WAIT_FOR_8021X_TX msecs_to_jiffies(950) -- ---/* AMPDU rx reordering definitions */ ---#define BRCMF_RXREORDER_FLOWID_OFFSET 0 ---#define BRCMF_RXREORDER_MAXIDX_OFFSET 2 ---#define BRCMF_RXREORDER_FLAGS_OFFSET 4 ---#define BRCMF_RXREORDER_CURIDX_OFFSET 6 ---#define BRCMF_RXREORDER_EXPIDX_OFFSET 8 --- ---#define BRCMF_RXREORDER_DEL_FLOW 0x01 ---#define BRCMF_RXREORDER_FLUSH_ALL 0x02 ---#define BRCMF_RXREORDER_CURIDX_VALID 0x04 ---#define BRCMF_RXREORDER_EXPIDX_VALID 0x08 ---#define BRCMF_RXREORDER_NEW_HOLE 0x10 --- -- #define BRCMF_BSSIDX_INVALID -1 -- -- char *brcmf_ifname(struct brcmf_if *ifp) --@@ -342,207 +329,11 @@ void brcmf_netif_rx(struct brcmf_if *ifp -- netif_rx_ni(skb); -- } -- ---static void brcmf_rxreorder_get_skb_list(struct brcmf_ampdu_rx_reorder *rfi, --- u8 start, u8 end, --- struct sk_buff_head *skb_list) ---{ --- /* initialize return list */ --- __skb_queue_head_init(skb_list); --- --- if (rfi->pend_pkts == 0) { --- brcmf_dbg(INFO, "no packets in reorder queue\n"); --- return; --- } --- --- do { --- if (rfi->pktslots[start]) { --- __skb_queue_tail(skb_list, rfi->pktslots[start]); --- rfi->pktslots[start] = NULL; --- } --- start++; --- if (start > rfi->max_idx) --- start = 0; --- } while (start != end); --- rfi->pend_pkts -= skb_queue_len(skb_list); ---} --- ---static void brcmf_rxreorder_process_info(struct brcmf_if *ifp, u8 *reorder_data, --- struct sk_buff *pkt) ---{ --- u8 flow_id, max_idx, cur_idx, exp_idx, end_idx; --- struct brcmf_ampdu_rx_reorder *rfi; --- struct sk_buff_head reorder_list; --- struct sk_buff *pnext; --- u8 flags; --- u32 buf_size; --- --- flow_id = reorder_data[BRCMF_RXREORDER_FLOWID_OFFSET]; --- flags = reorder_data[BRCMF_RXREORDER_FLAGS_OFFSET]; --- --- /* validate flags and flow id */ --- if (flags == 0xFF) { --- brcmf_err("invalid flags...so ignore this packet\n"); --- brcmf_netif_rx(ifp, pkt, false); --- return; --- } --- --- rfi = ifp->drvr->reorder_flows[flow_id]; --- if (flags & BRCMF_RXREORDER_DEL_FLOW) { --- brcmf_dbg(INFO, "flow-%d: delete\n", --- flow_id); --- --- if (rfi == NULL) { --- brcmf_dbg(INFO, "received flags to cleanup, but no flow (%d) yet\n", --- flow_id); --- brcmf_netif_rx(ifp, pkt, false); --- return; --- } --- --- brcmf_rxreorder_get_skb_list(rfi, rfi->exp_idx, rfi->exp_idx, --- &reorder_list); --- /* add the last packet */ --- __skb_queue_tail(&reorder_list, pkt); --- kfree(rfi); --- ifp->drvr->reorder_flows[flow_id] = NULL; --- goto netif_rx; --- } --- /* from here on we need a flow reorder instance */ --- if (rfi == NULL) { --- buf_size = sizeof(*rfi); --- max_idx = reorder_data[BRCMF_RXREORDER_MAXIDX_OFFSET]; --- --- buf_size += (max_idx + 1) * sizeof(pkt); --- --- /* allocate space for flow reorder info */ --- brcmf_dbg(INFO, "flow-%d: start, maxidx %d\n", --- flow_id, max_idx); --- rfi = kzalloc(buf_size, GFP_ATOMIC); --- if (rfi == NULL) { --- brcmf_err("failed to alloc buffer\n"); --- brcmf_netif_rx(ifp, pkt, false); --- return; --- } --- --- ifp->drvr->reorder_flows[flow_id] = rfi; --- rfi->pktslots = (struct sk_buff **)(rfi+1); --- rfi->max_idx = max_idx; --- } --- if (flags & BRCMF_RXREORDER_NEW_HOLE) { --- if (rfi->pend_pkts) { --- brcmf_rxreorder_get_skb_list(rfi, rfi->exp_idx, --- rfi->exp_idx, --- &reorder_list); --- WARN_ON(rfi->pend_pkts); --- } else { --- __skb_queue_head_init(&reorder_list); --- } --- rfi->cur_idx = reorder_data[BRCMF_RXREORDER_CURIDX_OFFSET]; --- rfi->exp_idx = reorder_data[BRCMF_RXREORDER_EXPIDX_OFFSET]; --- rfi->max_idx = reorder_data[BRCMF_RXREORDER_MAXIDX_OFFSET]; --- rfi->pktslots[rfi->cur_idx] = pkt; --- rfi->pend_pkts++; --- brcmf_dbg(DATA, "flow-%d: new hole %d (%d), pending %d\n", --- flow_id, rfi->cur_idx, rfi->exp_idx, rfi->pend_pkts); --- } else if (flags & BRCMF_RXREORDER_CURIDX_VALID) { --- cur_idx = reorder_data[BRCMF_RXREORDER_CURIDX_OFFSET]; --- exp_idx = reorder_data[BRCMF_RXREORDER_EXPIDX_OFFSET]; --- --- if ((exp_idx == rfi->exp_idx) && (cur_idx != rfi->exp_idx)) { --- /* still in the current hole */ --- /* enqueue the current on the buffer chain */ --- if (rfi->pktslots[cur_idx] != NULL) { --- brcmf_dbg(INFO, "HOLE: ERROR buffer pending..free it\n"); --- brcmu_pkt_buf_free_skb(rfi->pktslots[cur_idx]); --- rfi->pktslots[cur_idx] = NULL; --- } --- rfi->pktslots[cur_idx] = pkt; --- rfi->pend_pkts++; --- rfi->cur_idx = cur_idx; --- brcmf_dbg(DATA, "flow-%d: store pkt %d (%d), pending %d\n", --- flow_id, cur_idx, exp_idx, rfi->pend_pkts); --- --- /* can return now as there is no reorder --- * list to process. --- */ --- return; --- } --- if (rfi->exp_idx == cur_idx) { --- if (rfi->pktslots[cur_idx] != NULL) { --- brcmf_dbg(INFO, "error buffer pending..free it\n"); --- brcmu_pkt_buf_free_skb(rfi->pktslots[cur_idx]); --- rfi->pktslots[cur_idx] = NULL; --- } --- rfi->pktslots[cur_idx] = pkt; --- rfi->pend_pkts++; --- --- /* got the expected one. flush from current to expected --- * and update expected --- */ --- brcmf_dbg(DATA, "flow-%d: expected %d (%d), pending %d\n", --- flow_id, cur_idx, exp_idx, rfi->pend_pkts); --- --- rfi->cur_idx = cur_idx; --- rfi->exp_idx = exp_idx; --- --- brcmf_rxreorder_get_skb_list(rfi, cur_idx, exp_idx, --- &reorder_list); --- brcmf_dbg(DATA, "flow-%d: freeing buffers %d, pending %d\n", --- flow_id, skb_queue_len(&reorder_list), --- rfi->pend_pkts); --- } else { --- u8 end_idx; --- --- brcmf_dbg(DATA, "flow-%d (0x%x): both moved, old %d/%d, new %d/%d\n", --- flow_id, flags, rfi->cur_idx, rfi->exp_idx, --- cur_idx, exp_idx); --- if (flags & BRCMF_RXREORDER_FLUSH_ALL) --- end_idx = rfi->exp_idx; --- else --- end_idx = exp_idx; --- --- /* flush pkts first */ --- brcmf_rxreorder_get_skb_list(rfi, rfi->exp_idx, end_idx, --- &reorder_list); --- --- if (exp_idx == ((cur_idx + 1) % (rfi->max_idx + 1))) { --- __skb_queue_tail(&reorder_list, pkt); --- } else { --- rfi->pktslots[cur_idx] = pkt; --- rfi->pend_pkts++; --- } --- rfi->exp_idx = exp_idx; --- rfi->cur_idx = cur_idx; --- } --- } else { --- /* explicity window move updating the expected index */ --- exp_idx = reorder_data[BRCMF_RXREORDER_EXPIDX_OFFSET]; --- --- brcmf_dbg(DATA, "flow-%d (0x%x): change expected: %d -> %d\n", --- flow_id, flags, rfi->exp_idx, exp_idx); --- if (flags & BRCMF_RXREORDER_FLUSH_ALL) --- end_idx = rfi->exp_idx; --- else --- end_idx = exp_idx; --- --- brcmf_rxreorder_get_skb_list(rfi, rfi->exp_idx, end_idx, --- &reorder_list); --- __skb_queue_tail(&reorder_list, pkt); --- /* set the new expected idx */ --- rfi->exp_idx = exp_idx; --- } ---netif_rx: --- skb_queue_walk_safe(&reorder_list, pkt, pnext) { --- __skb_unlink(pkt, &reorder_list); --- brcmf_netif_rx(ifp, pkt, false); --- } ---} --- -- void brcmf_rx_frame(struct device *dev, struct sk_buff *skb, bool handle_evnt) -- { -- struct brcmf_if *ifp; -- struct brcmf_bus *bus_if = dev_get_drvdata(dev); -- struct brcmf_pub *drvr = bus_if->drvr; --- struct brcmf_skb_reorder_data *rd; -- int ret; -- -- brcmf_dbg(DATA, "Enter: %s: rxp=%p\n", dev_name(dev), skb); --@@ -557,9 +348,8 @@ void brcmf_rx_frame(struct device *dev, -- return; -- } -- --- rd = (struct brcmf_skb_reorder_data *)skb->cb; --- if (rd->reorder) --- brcmf_rxreorder_process_info(ifp, rd->reorder, skb); --+ if (brcmf_proto_is_reorder_skb(skb)) --+ brcmf_proto_rxreorder(ifp, skb); -- else -- brcmf_netif_rx(ifp, skb, handle_evnt); -- } ----- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h --+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h --@@ -208,10 +208,6 @@ struct brcmf_if { -- u8 ipv6addr_idx; -- }; -- ---struct brcmf_skb_reorder_data { --- u8 *reorder; ---}; --- -- int brcmf_netdev_wait_pend8021x(struct brcmf_if *ifp); -- -- /* Return pointer to interface name */ ----- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.c --+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.c --@@ -92,6 +92,19 @@ enum brcmf_fws_tlv_len { -- }; -- #undef BRCMF_FWS_TLV_DEF -- --+/* AMPDU rx reordering definitions */ --+#define BRCMF_RXREORDER_FLOWID_OFFSET 0 --+#define BRCMF_RXREORDER_MAXIDX_OFFSET 2 --+#define BRCMF_RXREORDER_FLAGS_OFFSET 4 --+#define BRCMF_RXREORDER_CURIDX_OFFSET 6 --+#define BRCMF_RXREORDER_EXPIDX_OFFSET 8 --+ --+#define BRCMF_RXREORDER_DEL_FLOW 0x01 --+#define BRCMF_RXREORDER_FLUSH_ALL 0x02 --+#define BRCMF_RXREORDER_CURIDX_VALID 0x04 --+#define BRCMF_RXREORDER_EXPIDX_VALID 0x08 --+#define BRCMF_RXREORDER_NEW_HOLE 0x10 --+ -- #ifdef DEBUG -- /* -- * brcmf_fws_tlv_names - array of tlv names. --@@ -1614,6 +1627,202 @@ static int brcmf_fws_notify_bcmc_credit_ -- return 0; -- } -- --+static void brcmf_rxreorder_get_skb_list(struct brcmf_ampdu_rx_reorder *rfi, --+ u8 start, u8 end, --+ struct sk_buff_head *skb_list) --+{ --+ /* initialize return list */ --+ __skb_queue_head_init(skb_list); --+ --+ if (rfi->pend_pkts == 0) { --+ brcmf_dbg(INFO, "no packets in reorder queue\n"); --+ return; --+ } --+ --+ do { --+ if (rfi->pktslots[start]) { --+ __skb_queue_tail(skb_list, rfi->pktslots[start]); --+ rfi->pktslots[start] = NULL; --+ } --+ start++; --+ if (start > rfi->max_idx) --+ start = 0; --+ } while (start != end); --+ rfi->pend_pkts -= skb_queue_len(skb_list); --+} --+ --+void brcmf_fws_rxreorder(struct brcmf_if *ifp, struct sk_buff *pkt) --+{ --+ u8 *reorder_data; --+ u8 flow_id, max_idx, cur_idx, exp_idx, end_idx; --+ struct brcmf_ampdu_rx_reorder *rfi; --+ struct sk_buff_head reorder_list; --+ struct sk_buff *pnext; --+ u8 flags; --+ u32 buf_size; --+ --+ reorder_data = ((struct brcmf_skb_reorder_data *)pkt->cb)->reorder; --+ flow_id = reorder_data[BRCMF_RXREORDER_FLOWID_OFFSET]; --+ flags = reorder_data[BRCMF_RXREORDER_FLAGS_OFFSET]; --+ --+ /* validate flags and flow id */ --+ if (flags == 0xFF) { --+ brcmf_err("invalid flags...so ignore this packet\n"); --+ brcmf_netif_rx(ifp, pkt, false); --+ return; --+ } --+ --+ rfi = ifp->drvr->reorder_flows[flow_id]; --+ if (flags & BRCMF_RXREORDER_DEL_FLOW) { --+ brcmf_dbg(INFO, "flow-%d: delete\n", --+ flow_id); --+ --+ if (rfi == NULL) { --+ brcmf_dbg(INFO, "received flags to cleanup, but no flow (%d) yet\n", --+ flow_id); --+ brcmf_netif_rx(ifp, pkt, false); --+ return; --+ } --+ --+ brcmf_rxreorder_get_skb_list(rfi, rfi->exp_idx, rfi->exp_idx, --+ &reorder_list); --+ /* add the last packet */ --+ __skb_queue_tail(&reorder_list, pkt); --+ kfree(rfi); --+ ifp->drvr->reorder_flows[flow_id] = NULL; --+ goto netif_rx; --+ } --+ /* from here on we need a flow reorder instance */ --+ if (rfi == NULL) { --+ buf_size = sizeof(*rfi); --+ max_idx = reorder_data[BRCMF_RXREORDER_MAXIDX_OFFSET]; --+ --+ buf_size += (max_idx + 1) * sizeof(pkt); --+ --+ /* allocate space for flow reorder info */ --+ brcmf_dbg(INFO, "flow-%d: start, maxidx %d\n", --+ flow_id, max_idx); --+ rfi = kzalloc(buf_size, GFP_ATOMIC); --+ if (rfi == NULL) { --+ brcmf_err("failed to alloc buffer\n"); --+ brcmf_netif_rx(ifp, pkt, false); --+ return; --+ } --+ --+ ifp->drvr->reorder_flows[flow_id] = rfi; --+ rfi->pktslots = (struct sk_buff **)(rfi + 1); --+ rfi->max_idx = max_idx; --+ } --+ if (flags & BRCMF_RXREORDER_NEW_HOLE) { --+ if (rfi->pend_pkts) { --+ brcmf_rxreorder_get_skb_list(rfi, rfi->exp_idx, --+ rfi->exp_idx, --+ &reorder_list); --+ WARN_ON(rfi->pend_pkts); --+ } else { --+ __skb_queue_head_init(&reorder_list); --+ } --+ rfi->cur_idx = reorder_data[BRCMF_RXREORDER_CURIDX_OFFSET]; --+ rfi->exp_idx = reorder_data[BRCMF_RXREORDER_EXPIDX_OFFSET]; --+ rfi->max_idx = reorder_data[BRCMF_RXREORDER_MAXIDX_OFFSET]; --+ rfi->pktslots[rfi->cur_idx] = pkt; --+ rfi->pend_pkts++; --+ brcmf_dbg(DATA, "flow-%d: new hole %d (%d), pending %d\n", --+ flow_id, rfi->cur_idx, rfi->exp_idx, rfi->pend_pkts); --+ } else if (flags & BRCMF_RXREORDER_CURIDX_VALID) { --+ cur_idx = reorder_data[BRCMF_RXREORDER_CURIDX_OFFSET]; --+ exp_idx = reorder_data[BRCMF_RXREORDER_EXPIDX_OFFSET]; --+ --+ if ((exp_idx == rfi->exp_idx) && (cur_idx != rfi->exp_idx)) { --+ /* still in the current hole */ --+ /* enqueue the current on the buffer chain */ --+ if (rfi->pktslots[cur_idx] != NULL) { --+ brcmf_dbg(INFO, "HOLE: ERROR buffer pending..free it\n"); --+ brcmu_pkt_buf_free_skb(rfi->pktslots[cur_idx]); --+ rfi->pktslots[cur_idx] = NULL; --+ } --+ rfi->pktslots[cur_idx] = pkt; --+ rfi->pend_pkts++; --+ rfi->cur_idx = cur_idx; --+ brcmf_dbg(DATA, "flow-%d: store pkt %d (%d), pending %d\n", --+ flow_id, cur_idx, exp_idx, rfi->pend_pkts); --+ --+ /* can return now as there is no reorder --+ * list to process. --+ */ --+ return; --+ } --+ if (rfi->exp_idx == cur_idx) { --+ if (rfi->pktslots[cur_idx] != NULL) { --+ brcmf_dbg(INFO, "error buffer pending..free it\n"); --+ brcmu_pkt_buf_free_skb(rfi->pktslots[cur_idx]); --+ rfi->pktslots[cur_idx] = NULL; --+ } --+ rfi->pktslots[cur_idx] = pkt; --+ rfi->pend_pkts++; --+ --+ /* got the expected one. flush from current to expected --+ * and update expected --+ */ --+ brcmf_dbg(DATA, "flow-%d: expected %d (%d), pending %d\n", --+ flow_id, cur_idx, exp_idx, rfi->pend_pkts); --+ --+ rfi->cur_idx = cur_idx; --+ rfi->exp_idx = exp_idx; --+ --+ brcmf_rxreorder_get_skb_list(rfi, cur_idx, exp_idx, --+ &reorder_list); --+ brcmf_dbg(DATA, "flow-%d: freeing buffers %d, pending %d\n", --+ flow_id, skb_queue_len(&reorder_list), --+ rfi->pend_pkts); --+ } else { --+ u8 end_idx; --+ --+ brcmf_dbg(DATA, "flow-%d (0x%x): both moved, old %d/%d, new %d/%d\n", --+ flow_id, flags, rfi->cur_idx, rfi->exp_idx, --+ cur_idx, exp_idx); --+ if (flags & BRCMF_RXREORDER_FLUSH_ALL) --+ end_idx = rfi->exp_idx; --+ else --+ end_idx = exp_idx; --+ --+ /* flush pkts first */ --+ brcmf_rxreorder_get_skb_list(rfi, rfi->exp_idx, end_idx, --+ &reorder_list); --+ --+ if (exp_idx == ((cur_idx + 1) % (rfi->max_idx + 1))) { --+ __skb_queue_tail(&reorder_list, pkt); --+ } else { --+ rfi->pktslots[cur_idx] = pkt; --+ rfi->pend_pkts++; --+ } --+ rfi->exp_idx = exp_idx; --+ rfi->cur_idx = cur_idx; --+ } --+ } else { --+ /* explicity window move updating the expected index */ --+ exp_idx = reorder_data[BRCMF_RXREORDER_EXPIDX_OFFSET]; --+ --+ brcmf_dbg(DATA, "flow-%d (0x%x): change expected: %d -> %d\n", --+ flow_id, flags, rfi->exp_idx, exp_idx); --+ if (flags & BRCMF_RXREORDER_FLUSH_ALL) --+ end_idx = rfi->exp_idx; --+ else --+ end_idx = exp_idx; --+ --+ brcmf_rxreorder_get_skb_list(rfi, rfi->exp_idx, end_idx, --+ &reorder_list); --+ __skb_queue_tail(&reorder_list, pkt); --+ /* set the new expected idx */ --+ rfi->exp_idx = exp_idx; --+ } --+netif_rx: --+ skb_queue_walk_safe(&reorder_list, pkt, pnext) { --+ __skb_unlink(pkt, &reorder_list); --+ brcmf_netif_rx(ifp, pkt, false); --+ } --+} --+ -- void brcmf_fws_hdrpull(struct brcmf_if *ifp, s16 siglen, struct sk_buff *skb) -- { -- struct brcmf_skb_reorder_data *rd; ----- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.h --+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.h --@@ -29,5 +29,6 @@ void brcmf_fws_add_interface(struct brcm -- void brcmf_fws_del_interface(struct brcmf_if *ifp); -- void brcmf_fws_bustxfail(struct brcmf_fws_info *fws, struct sk_buff *skb); -- void brcmf_fws_bus_blocked(struct brcmf_pub *drvr, bool flow_blocked); --+void brcmf_fws_rxreorder(struct brcmf_if *ifp, struct sk_buff *skb); -- -- #endif /* FWSIGNAL_H_ */ ----- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c --+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c --@@ -527,6 +527,9 @@ static int brcmf_msgbuf_hdrpull(struct b -- return -ENODEV; -- } -- --+static void brcmf_msgbuf_rxreorder(struct brcmf_if *ifp, struct sk_buff *skb) --+{ --+} -- -- static void -- brcmf_msgbuf_remove_flowring(struct brcmf_msgbuf *msgbuf, u16 flowid) --@@ -1466,6 +1469,7 @@ int brcmf_proto_msgbuf_attach(struct brc -- drvr->proto->configure_addr_mode = brcmf_msgbuf_configure_addr_mode; -- drvr->proto->delete_peer = brcmf_msgbuf_delete_peer; -- drvr->proto->add_tdls_peer = brcmf_msgbuf_add_tdls_peer; --+ drvr->proto->rxreorder = brcmf_msgbuf_rxreorder; -- drvr->proto->pd = msgbuf; -- -- init_waitqueue_head(&msgbuf->ioctl_resp_wait); ----- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/proto.h --+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/proto.h --@@ -22,6 +22,9 @@ enum proto_addr_mode { -- ADDR_DIRECT -- }; -- --+struct brcmf_skb_reorder_data { --+ u8 *reorder; --+}; -- -- struct brcmf_proto { -- int (*hdrpull)(struct brcmf_pub *drvr, bool do_fws, --@@ -38,6 +41,7 @@ struct brcmf_proto { -- u8 peer[ETH_ALEN]); -- void (*add_tdls_peer)(struct brcmf_pub *drvr, int ifidx, -- u8 peer[ETH_ALEN]); --+ void (*rxreorder)(struct brcmf_if *ifp, struct sk_buff *skb); -- void *pd; -- }; -- --@@ -91,6 +95,18 @@ brcmf_proto_add_tdls_peer(struct brcmf_p -- { -- drvr->proto->add_tdls_peer(drvr, ifidx, peer); -- } --+static inline bool brcmf_proto_is_reorder_skb(struct sk_buff *skb) --+{ --+ struct brcmf_skb_reorder_data *rd; --+ --+ rd = (struct brcmf_skb_reorder_data *)skb->cb; --+ return !!rd->reorder; --+} -- --+static inline void --+brcmf_proto_rxreorder(struct brcmf_if *ifp, struct sk_buff *skb) --+{ --+ ifp->drvr->proto->rxreorder(ifp, skb); --+} -- -- #endif /* BRCMFMAC_PROTO_H */ -diff --git a/package/kernel/mac80211/patches/349-0007-brcmfmac-revise-handling-events-in-receive-path.patch b/package/kernel/mac80211/patches/349-0007-brcmfmac-revise-handling-events-in-receive-path.patch -deleted file mode 100644 -index a43feff..0000000 ---- a/package/kernel/mac80211/patches/349-0007-brcmfmac-revise-handling-events-in-receive-path.patch -+++ /dev/null -@@ -1,139 +0,0 @@ --From: Arend van Spriel --Date: Mon, 11 Apr 2016 11:35:27 +0200 --Subject: [PATCH] brcmfmac: revise handling events in receive path -- --Move event handling out of brcmf_netif_rx() avoiding the need --to pass a flag. This flag is only ever true for USB hosts as --other interface use separate brcmf_rx_event() function. -- --Reviewed-by: Hante Meuleman --Reviewed-by: Pieter-Paul Giesberts --Reviewed-by: Franky Lin --Signed-off-by: Arend van Spriel --Signed-off-by: Kalle Valo ----- -- ----- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bus.h --+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bus.h --@@ -216,7 +216,7 @@ bool brcmf_c_prec_enq(struct device *dev -- int prec); -- -- /* Receive frame for delivery to OS. Callee disposes of rxp. */ ---void brcmf_rx_frame(struct device *dev, struct sk_buff *rxp, bool handle_evnt); --+void brcmf_rx_frame(struct device *dev, struct sk_buff *rxp, bool handle_event); -- /* Receive async event packet from firmware. Callee disposes of rxp. */ -- void brcmf_rx_event(struct device *dev, struct sk_buff *rxp); -- ----- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c --+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c --@@ -298,18 +298,11 @@ void brcmf_txflowblock(struct device *de -- brcmf_fws_bus_blocked(drvr, state); -- } -- ---void brcmf_netif_rx(struct brcmf_if *ifp, struct sk_buff *skb, --- bool handle_event) --+void brcmf_netif_rx(struct brcmf_if *ifp, struct sk_buff *skb) -- { --- skb->protocol = eth_type_trans(skb, ifp->ndev); --- -- if (skb->pkt_type == PACKET_MULTICAST) -- ifp->stats.multicast++; -- --- /* Process special event packets */ --- if (handle_event) --- brcmf_fweh_process_skb(ifp->drvr, skb); --- -- if (!(ifp->ndev->flags & IFF_UP)) { -- brcmu_pkt_buf_free_skb(skb); -- return; --@@ -329,7 +322,7 @@ void brcmf_netif_rx(struct brcmf_if *ifp -- netif_rx_ni(skb); -- } -- ---void brcmf_rx_frame(struct device *dev, struct sk_buff *skb, bool handle_evnt) --+void brcmf_rx_frame(struct device *dev, struct sk_buff *skb, bool handle_event) -- { -- struct brcmf_if *ifp; -- struct brcmf_bus *bus_if = dev_get_drvdata(dev); --@@ -348,10 +341,17 @@ void brcmf_rx_frame(struct device *dev, -- return; -- } -- --- if (brcmf_proto_is_reorder_skb(skb)) --+ skb->protocol = eth_type_trans(skb, ifp->ndev); --+ --+ if (brcmf_proto_is_reorder_skb(skb)) { -- brcmf_proto_rxreorder(ifp, skb); --- else --- brcmf_netif_rx(ifp, skb, handle_evnt); --+ } else { --+ /* Process special event packets */ --+ if (handle_event) --+ brcmf_fweh_process_skb(ifp->drvr, skb); --+ --+ brcmf_netif_rx(ifp, skb); --+ } -- } -- -- void brcmf_rx_event(struct device *dev, struct sk_buff *skb) ----- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h --+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h --@@ -221,8 +221,7 @@ int brcmf_get_next_free_bsscfgidx(struct -- void brcmf_txflowblock_if(struct brcmf_if *ifp, -- enum brcmf_netif_stop_reason reason, bool state); -- void brcmf_txfinalize(struct brcmf_if *ifp, struct sk_buff *txp, bool success); ---void brcmf_netif_rx(struct brcmf_if *ifp, struct sk_buff *skb, --- bool handle_event); --+void brcmf_netif_rx(struct brcmf_if *ifp, struct sk_buff *skb); -- void brcmf_net_setcarrier(struct brcmf_if *ifp, bool on); -- int __init brcmf_core_init(void); -- void __exit brcmf_core_exit(void); ----- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.c --+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.c --@@ -1668,7 +1668,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"); --- brcmf_netif_rx(ifp, pkt, false); --+ brcmf_netif_rx(ifp, pkt); -- return; -- } -- --@@ -1680,7 +1680,7 @@ void brcmf_fws_rxreorder(struct brcmf_if -- if (rfi == NULL) { -- brcmf_dbg(INFO, "received flags to cleanup, but no flow (%d) yet\n", -- flow_id); --- brcmf_netif_rx(ifp, pkt, false); --+ brcmf_netif_rx(ifp, pkt); -- return; -- } -- --@@ -1705,7 +1705,7 @@ void brcmf_fws_rxreorder(struct brcmf_if -- rfi = kzalloc(buf_size, GFP_ATOMIC); -- if (rfi == NULL) { -- brcmf_err("failed to alloc buffer\n"); --- brcmf_netif_rx(ifp, pkt, false); --+ brcmf_netif_rx(ifp, pkt); -- return; -- } -- --@@ -1819,7 +1819,7 @@ void brcmf_fws_rxreorder(struct brcmf_if -- netif_rx: -- skb_queue_walk_safe(&reorder_list, pkt, pnext) { -- __skb_unlink(pkt, &reorder_list); --- brcmf_netif_rx(ifp, pkt, false); --+ brcmf_netif_rx(ifp, pkt); -- } -- } -- ----- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c --+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c --@@ -1157,7 +1157,7 @@ brcmf_msgbuf_process_rx_complete(struct -- brcmu_pkt_buf_free_skb(skb); -- return; -- } --- brcmf_netif_rx(ifp, skb, false); --+ brcmf_netif_rx(ifp, skb); -- } -- -- -diff --git a/package/kernel/mac80211/patches/349-0008-brcmfmac-create-common-function-for-handling-brcmf_p.patch b/package/kernel/mac80211/patches/349-0008-brcmfmac-create-common-function-for-handling-brcmf_p.patch -deleted file mode 100644 -index 08ea235..0000000 ---- a/package/kernel/mac80211/patches/349-0008-brcmfmac-create-common-function-for-handling-brcmf_p.patch -+++ /dev/null -@@ -1,88 +0,0 @@ --From: Arend van Spriel --Date: Mon, 11 Apr 2016 11:35:28 +0200 --Subject: [PATCH] brcmfmac: create common function for handling -- brcmf_proto_hdrpull() -- --In receive path brcmf_proto_hdrpull() needs to be called and handled --similar in brcmf_rx_frame() and brcmf_rx_event(). Move that duplicated --code in separate function. -- --Reviewed-by: Hante Meuleman --Reviewed-by: Pieter-Paul Giesberts --Reviewed-by: Franky Lin --Signed-off-by: Arend van Spriel --Signed-off-by: Kalle Valo ----- -- ----- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c --+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c --@@ -322,26 +322,35 @@ void brcmf_netif_rx(struct brcmf_if *ifp -- netif_rx_ni(skb); -- } -- ---void brcmf_rx_frame(struct device *dev, struct sk_buff *skb, bool handle_event) --+static int brcmf_rx_hdrpull(struct brcmf_pub *drvr, struct sk_buff *skb, --+ struct brcmf_if **ifp) -- { --- struct brcmf_if *ifp; --- struct brcmf_bus *bus_if = dev_get_drvdata(dev); --- struct brcmf_pub *drvr = bus_if->drvr; -- int ret; -- --- brcmf_dbg(DATA, "Enter: %s: rxp=%p\n", dev_name(dev), skb); --- -- /* process and remove protocol-specific header */ --- ret = brcmf_proto_hdrpull(drvr, true, skb, &ifp); --+ ret = brcmf_proto_hdrpull(drvr, true, skb, ifp); -- --- if (ret || !ifp || !ifp->ndev) { --+ if (ret || !(*ifp) || !(*ifp)->ndev) { -- if (ret != -ENODATA && ifp) --- ifp->stats.rx_errors++; --+ (*ifp)->stats.rx_errors++; -- brcmu_pkt_buf_free_skb(skb); --- return; --+ return -ENODATA; -- } -- --- skb->protocol = eth_type_trans(skb, ifp->ndev); --+ skb->protocol = eth_type_trans(skb, (*ifp)->ndev); --+ return 0; --+} --+ --+void brcmf_rx_frame(struct device *dev, struct sk_buff *skb, bool handle_event) --+{ --+ struct brcmf_if *ifp; --+ struct brcmf_bus *bus_if = dev_get_drvdata(dev); --+ struct brcmf_pub *drvr = bus_if->drvr; --+ --+ brcmf_dbg(DATA, "Enter: %s: rxp=%p\n", dev_name(dev), skb); --+ --+ if (brcmf_rx_hdrpull(drvr, skb, &ifp)) --+ return; -- -- if (brcmf_proto_is_reorder_skb(skb)) { -- brcmf_proto_rxreorder(ifp, skb); --@@ -359,21 +368,11 @@ void brcmf_rx_event(struct device *dev, -- struct brcmf_if *ifp; -- struct brcmf_bus *bus_if = dev_get_drvdata(dev); -- struct brcmf_pub *drvr = bus_if->drvr; --- int ret; -- -- brcmf_dbg(EVENT, "Enter: %s: rxp=%p\n", dev_name(dev), skb); -- --- /* process and remove protocol-specific header */ --- ret = brcmf_proto_hdrpull(drvr, true, skb, &ifp); --- --- if (ret || !ifp || !ifp->ndev) { --- if (ret != -ENODATA && ifp) --- ifp->stats.rx_errors++; --- brcmu_pkt_buf_free_skb(skb); --+ if (brcmf_rx_hdrpull(drvr, skb, &ifp)) -- return; --- } --- --- skb->protocol = eth_type_trans(skb, ifp->ndev); -- -- brcmf_fweh_process_skb(ifp->drvr, skb); -- brcmu_pkt_buf_free_skb(skb); -diff --git a/package/kernel/mac80211/patches/351-0005-brcmfmac-rework-function-picking-free-BSS-index.patch b/package/kernel/mac80211/patches/351-0005-brcmfmac-rework-function-picking-free-BSS-index.patch -deleted file mode 100644 -index c602f22..0000000 ---- a/package/kernel/mac80211/patches/351-0005-brcmfmac-rework-function-picking-free-BSS-index.patch -+++ /dev/null -@@ -1,119 +0,0 @@ --From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= --Date: Thu, 26 May 2016 01:44:27 +0200 --Subject: [PATCH] brcmfmac: rework function picking free BSS index --MIME-Version: 1.0 --Content-Type: text/plain; charset=UTF-8 --Content-Transfer-Encoding: 8bit -- --The old implementation was overcomplicated and slightly bugged in some --corner cases. -- --Consider following state of BSS-es (limited to 6 for simplification): --drvr->iflist[0]: { bsscfgidx:0, ndev->name:wlan1, } --drvr->iflist[1]: (null) --drvr->iflist[2]: { bsscfgidx:2, ndev->name:wlan1-1, } --drvr->iflist[3]: { bsscfgidx:3, ndev->name:wlan1-2, } --drvr->iflist[4]: (null) --drvr->iflist[5]: (null) --In such case the next AP interface should bsscfgidx 4 (we don't use 1 as --it's reserved for P2P). -- --With old code the loop iterations were following: --[ifidx = 0] [bsscfgidx = 2] [highest = 2] --[ifidx = 1] [bsscfgidx = 2] [highest = 2] available = true --[ifidx = 2] [bsscfgidx = 2] [highest = 2] bsscfgidx = highest + 1 --[ifidx = 3] [bsscfgidx = 3] [highest = 2] bsscfgidx = highest + 1 --[ifidx = 4] [bsscfgidx = 3] [highest = 2] available = true --[ifidx = 5] [bsscfgidx = 3] [highest = 2] available = true --There were 2 obvious problems: --1) Having empty BSS at index 1 was resulting in available being always -- set to true, even if we would run out of BSS-es. --2) Calculated bsscfgidx was invalid (3 instead of 4) resulting in driver -- not being able to create the 4th AP interface. -- --New code is simpler, placed in file where it's really used, handles --running out of free BSS-es and allows using 4 interfaces at the same --time. It also looks for the first free BSS instead of one after the last --in use. It works well with current driver (which doesn't allow deleting --interfaces) and should be future proof (if we ever allow deleting). -- --Signed-off-by: RafaÅ‚ MiÅ‚ecki --Signed-off-by: Kalle Valo ----- -- ----- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c --+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c --@@ -527,6 +527,21 @@ brcmf_cfg80211_update_proto_addr_mode(st -- ADDR_INDIRECT); -- } -- --+static int brcmf_get_first_free_bsscfgidx(struct brcmf_pub *drvr) --+{ --+ int bsscfgidx; --+ --+ for (bsscfgidx = 0; bsscfgidx < BRCMF_MAX_IFS; bsscfgidx++) { --+ /* bsscfgidx 1 is reserved for legacy P2P */ --+ if (bsscfgidx == 1) --+ continue; --+ if (!drvr->iflist[bsscfgidx]) --+ return bsscfgidx; --+ } --+ --+ return -ENOMEM; --+} --+ -- static int brcmf_cfg80211_request_ap_if(struct brcmf_if *ifp) -- { -- struct brcmf_mbss_ssid_le mbss_ssid_le; --@@ -534,7 +549,7 @@ static int brcmf_cfg80211_request_ap_if( -- int err; -- -- memset(&mbss_ssid_le, 0, sizeof(mbss_ssid_le)); --- bsscfgidx = brcmf_get_next_free_bsscfgidx(ifp->drvr); --+ bsscfgidx = brcmf_get_first_free_bsscfgidx(ifp->drvr); -- if (bsscfgidx < 0) -- return bsscfgidx; -- ----- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c --+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c --@@ -753,30 +753,6 @@ void brcmf_remove_interface(struct brcmf -- brcmf_del_if(ifp->drvr, ifp->bsscfgidx); -- } -- ---int brcmf_get_next_free_bsscfgidx(struct brcmf_pub *drvr) ---{ --- int ifidx; --- int bsscfgidx; --- bool available; --- int highest; --- --- available = false; --- bsscfgidx = 2; --- highest = 2; --- for (ifidx = 0; ifidx < BRCMF_MAX_IFS; ifidx++) { --- if (drvr->iflist[ifidx]) { --- if (drvr->iflist[ifidx]->bsscfgidx == bsscfgidx) --- bsscfgidx = highest + 1; --- else if (drvr->iflist[ifidx]->bsscfgidx > highest) --- highest = drvr->iflist[ifidx]->bsscfgidx; --- } else { --- available = true; --- } --- } --- --- return available ? bsscfgidx : -ENOMEM; ---} --- -- #ifdef CONFIG_INET -- #define ARPOL_MAX_ENTRIES 8 -- static int brcmf_inetaddr_changed(struct notifier_block *nb, ----- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h --+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h --@@ -217,7 +217,6 @@ int brcmf_net_attach(struct brcmf_if *if -- struct brcmf_if *brcmf_add_if(struct brcmf_pub *drvr, s32 bsscfgidx, s32 ifidx, -- bool is_p2pdev, char *name, u8 *mac_addr); -- void brcmf_remove_interface(struct brcmf_if *ifp); ---int brcmf_get_next_free_bsscfgidx(struct brcmf_pub *drvr); -- void brcmf_txflowblock_if(struct brcmf_if *ifp, -- enum brcmf_netif_stop_reason reason, bool state); -- void brcmf_txfinalize(struct brcmf_if *ifp, struct sk_buff *txp, bool success); -diff --git a/package/kernel/mac80211/patches/351-0007-brcmutil-add-field-storing-control-channel-to-the-st.patch b/package/kernel/mac80211/patches/351-0007-brcmutil-add-field-storing-control-channel-to-the-st.patch -deleted file mode 100644 -index a79c9a2..0000000 ---- a/package/kernel/mac80211/patches/351-0007-brcmutil-add-field-storing-control-channel-to-the-st.patch -+++ /dev/null -@@ -1,244 +0,0 @@ --From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= --Date: Fri, 20 May 2016 13:38:57 +0200 --Subject: [PATCH] brcmutil: add field storing control channel to the struct -- brcmu_chan --MIME-Version: 1.0 --Content-Type: text/plain; charset=UTF-8 --Content-Transfer-Encoding: 8bit -- --Our d11 code supports encoding/decoding channel info into/from chanspec --format used by firmware. Current implementation is quite misleading --because of the way "chnum" field is used. --When encoding channel info, "chnum" has to be filled by a caller with --*center* channel number. However when decoding chanspec the same field --is filled with a *control* channel number. -- --1) This can be confusing. It's expected for information to be the same -- after encoding and decoding. --2) It doesn't allow accessing all info when decoding. Some functions may -- need to know both channel numbers, e.g. cfg80211 callback getting -- current channel. --Solve this by adding a separated field for control channel. -- --Signed-off-by: RafaÅ‚ MiÅ‚ecki --Reviewed-by: Arend van Spriel --Signed-off-by: Kalle Valo ----- -- ----- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c --+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c --@@ -2689,7 +2689,7 @@ static s32 brcmf_inform_single_bss(struc -- if (!bi->ctl_ch) { -- ch.chspec = le16_to_cpu(bi->chanspec); -- cfg->d11inf.decchspec(&ch); --- bi->ctl_ch = ch.chnum; --+ bi->ctl_ch = ch.control_ch_num; -- } -- channel = bi->ctl_ch; -- --@@ -2807,7 +2807,7 @@ static s32 brcmf_inform_ibss(struct brcm -- else -- band = wiphy->bands[IEEE80211_BAND_5GHZ]; -- --- freq = ieee80211_channel_to_frequency(ch.chnum, band->band); --+ freq = ieee80211_channel_to_frequency(ch.control_ch_num, band->band); -- cfg->channel = freq; -- notify_channel = ieee80211_get_channel(wiphy, freq); -- --@@ -2817,7 +2817,7 @@ static s32 brcmf_inform_ibss(struct brcm -- notify_ielen = le32_to_cpu(bi->ie_length); -- notify_signal = (s16)le16_to_cpu(bi->RSSI) * 100; -- --- brcmf_dbg(CONN, "channel: %d(%d)\n", ch.chnum, freq); --+ brcmf_dbg(CONN, "channel: %d(%d)\n", ch.control_ch_num, freq); -- brcmf_dbg(CONN, "capability: %X\n", notify_capability); -- brcmf_dbg(CONN, "beacon interval: %d\n", notify_interval); -- brcmf_dbg(CONN, "signal: %d\n", notify_signal); --@@ -5235,7 +5235,7 @@ brcmf_bss_roaming_done(struct brcmf_cfg8 -- else -- band = wiphy->bands[IEEE80211_BAND_5GHZ]; -- --- freq = ieee80211_channel_to_frequency(ch.chnum, band->band); --+ freq = ieee80211_channel_to_frequency(ch.control_ch_num, band->band); -- notify_channel = ieee80211_get_channel(wiphy, freq); -- -- done: --@@ -5757,14 +5757,15 @@ static int brcmf_construct_chaninfo(stru -- channel = band->channels; -- index = band->n_channels; -- for (j = 0; j < band->n_channels; j++) { --- if (channel[j].hw_value == ch.chnum) { --+ if (channel[j].hw_value == ch.control_ch_num) { -- index = j; -- break; -- } -- } -- channel[index].center_freq = --- ieee80211_channel_to_frequency(ch.chnum, band->band); --- channel[index].hw_value = ch.chnum; --+ ieee80211_channel_to_frequency(ch.control_ch_num, --+ band->band); --+ channel[index].hw_value = ch.control_ch_num; -- -- /* assuming the chanspecs order is HT20, -- * HT40 upper, HT40 lower, and VHT80. --@@ -5866,7 +5867,7 @@ static int brcmf_enable_bw40_2g(struct b -- if (WARN_ON(ch.bw != BRCMU_CHAN_BW_40)) -- continue; -- for (j = 0; j < band->n_channels; j++) { --- if (band->channels[j].hw_value == ch.chnum) --+ if (band->channels[j].hw_value == ch.control_ch_num) -- break; -- } -- if (WARN_ON(j == band->n_channels)) ----- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c --+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c --@@ -1246,7 +1246,7 @@ bool brcmf_p2p_scan_finding_common_chann -- if (!bi->ctl_ch) { -- ch.chspec = le16_to_cpu(bi->chanspec); -- cfg->d11inf.decchspec(&ch); --- bi->ctl_ch = ch.chnum; --+ bi->ctl_ch = ch.control_ch_num; -- } -- afx_hdl->peer_chan = bi->ctl_ch; -- brcmf_dbg(TRACE, "ACTION FRAME SCAN : Peer %pM found, channel : %d\n", --@@ -1385,7 +1385,7 @@ int brcmf_p2p_notify_action_frame_rx(str -- if (test_bit(BRCMF_P2P_STATUS_FINDING_COMMON_CHANNEL, -- &p2p->status) && -- (ether_addr_equal(afx_hdl->tx_dst_addr, e->addr))) { --- afx_hdl->peer_chan = ch.chnum; --+ afx_hdl->peer_chan = ch.control_ch_num; -- brcmf_dbg(INFO, "GON request: Peer found, channel=%d\n", -- afx_hdl->peer_chan); -- complete(&afx_hdl->act_frm_scan); --@@ -1428,7 +1428,7 @@ int brcmf_p2p_notify_action_frame_rx(str -- memcpy(&mgmt_frame->u, frame, mgmt_frame_len); -- mgmt_frame_len += offsetof(struct ieee80211_mgmt, u); -- --- freq = ieee80211_channel_to_frequency(ch.chnum, --+ freq = ieee80211_channel_to_frequency(ch.control_ch_num, -- ch.band == BRCMU_CHAN_BAND_2G ? -- IEEE80211_BAND_2GHZ : -- IEEE80211_BAND_5GHZ); --@@ -1873,7 +1873,7 @@ s32 brcmf_p2p_notify_rx_mgmt_p2p_probere -- -- if (test_bit(BRCMF_P2P_STATUS_FINDING_COMMON_CHANNEL, &p2p->status) && -- (ether_addr_equal(afx_hdl->tx_dst_addr, e->addr))) { --- afx_hdl->peer_chan = ch.chnum; --+ afx_hdl->peer_chan = ch.control_ch_num; -- brcmf_dbg(INFO, "PROBE REQUEST: Peer found, channel=%d\n", -- afx_hdl->peer_chan); -- complete(&afx_hdl->act_frm_scan); --@@ -1898,7 +1898,7 @@ s32 brcmf_p2p_notify_rx_mgmt_p2p_probere -- -- mgmt_frame = (u8 *)(rxframe + 1); -- mgmt_frame_len = e->datalen - sizeof(*rxframe); --- freq = ieee80211_channel_to_frequency(ch.chnum, --+ freq = ieee80211_channel_to_frequency(ch.control_ch_num, -- ch.band == BRCMU_CHAN_BAND_2G ? -- IEEE80211_BAND_2GHZ : -- IEEE80211_BAND_5GHZ); ----- a/drivers/net/wireless/broadcom/brcm80211/brcmutil/d11.c --+++ b/drivers/net/wireless/broadcom/brcm80211/brcmutil/d11.c --@@ -107,6 +107,7 @@ static void brcmu_d11n_decchspec(struct -- u16 val; -- -- ch->chnum = (u8)(ch->chspec & BRCMU_CHSPEC_CH_MASK); --+ ch->control_ch_num = ch->chnum; -- -- switch (ch->chspec & BRCMU_CHSPEC_D11N_BW_MASK) { -- case BRCMU_CHSPEC_D11N_BW_20: --@@ -118,10 +119,10 @@ static void brcmu_d11n_decchspec(struct -- val = ch->chspec & BRCMU_CHSPEC_D11N_SB_MASK; -- if (val == BRCMU_CHSPEC_D11N_SB_L) { -- ch->sb = BRCMU_CHAN_SB_L; --- ch->chnum -= CH_10MHZ_APART; --+ ch->control_ch_num -= CH_10MHZ_APART; -- } else { -- ch->sb = BRCMU_CHAN_SB_U; --- ch->chnum += CH_10MHZ_APART; --+ ch->control_ch_num += CH_10MHZ_APART; -- } -- break; -- default: --@@ -147,6 +148,7 @@ static void brcmu_d11ac_decchspec(struct -- u16 val; -- -- ch->chnum = (u8)(ch->chspec & BRCMU_CHSPEC_CH_MASK); --+ ch->control_ch_num = ch->chnum; -- -- switch (ch->chspec & BRCMU_CHSPEC_D11AC_BW_MASK) { -- case BRCMU_CHSPEC_D11AC_BW_20: --@@ -158,10 +160,10 @@ static void brcmu_d11ac_decchspec(struct -- val = ch->chspec & BRCMU_CHSPEC_D11AC_SB_MASK; -- if (val == BRCMU_CHSPEC_D11AC_SB_L) { -- ch->sb = BRCMU_CHAN_SB_L; --- ch->chnum -= CH_10MHZ_APART; --+ ch->control_ch_num -= CH_10MHZ_APART; -- } else if (val == BRCMU_CHSPEC_D11AC_SB_U) { -- ch->sb = BRCMU_CHAN_SB_U; --- ch->chnum += CH_10MHZ_APART; --+ ch->control_ch_num += CH_10MHZ_APART; -- } else { -- WARN_ON_ONCE(1); -- } --@@ -172,16 +174,16 @@ static void brcmu_d11ac_decchspec(struct -- BRCMU_CHSPEC_D11AC_SB_SHIFT); -- switch (ch->sb) { -- case BRCMU_CHAN_SB_LL: --- ch->chnum -= CH_30MHZ_APART; --+ ch->control_ch_num -= CH_30MHZ_APART; -- break; -- case BRCMU_CHAN_SB_LU: --- ch->chnum -= CH_10MHZ_APART; --+ ch->control_ch_num -= CH_10MHZ_APART; -- break; -- case BRCMU_CHAN_SB_UL: --- ch->chnum += CH_10MHZ_APART; --+ ch->control_ch_num += CH_10MHZ_APART; -- break; -- case BRCMU_CHAN_SB_UU: --- ch->chnum += CH_30MHZ_APART; --+ ch->control_ch_num += CH_30MHZ_APART; -- break; -- default: -- WARN_ON_ONCE(1); ----- a/drivers/net/wireless/broadcom/brcm80211/include/brcmu_d11.h --+++ b/drivers/net/wireless/broadcom/brcm80211/include/brcmu_d11.h --@@ -125,14 +125,36 @@ enum brcmu_chan_sb { -- BRCMU_CHAN_SB_UU = BRCMU_CHAN_SB_LUU, -- }; -- --+/** --+ * struct brcmu_chan - stores channel formats --+ * --+ * This structure can be used with functions translating chanspec into generic --+ * channel info and the other way. --+ * --+ * @chspec: firmware specific format --+ * @chnum: center channel number --+ * @control_ch_num: control channel number --+ * @band: frequency band --+ * @bw: channel width --+ * @sb: control sideband (location of control channel against the center one) --+ */ -- struct brcmu_chan { -- u16 chspec; -- u8 chnum; --+ u8 control_ch_num; -- u8 band; -- enum brcmu_chan_bw bw; -- enum brcmu_chan_sb sb; -- }; -- --+/** --+ * struct brcmu_d11inf - provides functions translating channel format --+ * --+ * @io_type: determines version of channel format used by firmware --+ * @encchspec: encodes channel info into a chanspec, requires center channel --+ * number, ignores control one --+ * @decchspec: decodes chanspec into generic info --+ */ -- struct brcmu_d11inf { -- u8 io_type; -- -diff --git a/package/kernel/mac80211/patches/351-0008-brcmfmac-support-get_channel-cfg80211-callback.patch b/package/kernel/mac80211/patches/351-0008-brcmfmac-support-get_channel-cfg80211-callback.patch -deleted file mode 100644 -index 2c536d1..0000000 ---- a/package/kernel/mac80211/patches/351-0008-brcmfmac-support-get_channel-cfg80211-callback.patch -+++ /dev/null -@@ -1,94 +0,0 @@ --From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= --Date: Fri, 20 May 2016 13:38:58 +0200 --Subject: [PATCH] brcmfmac: support get_channel cfg80211 callback --MIME-Version: 1.0 --Content-Type: text/plain; charset=UTF-8 --Content-Transfer-Encoding: 8bit -- --This is important for brcmfmac as some of released firmwares (e.g. --brcmfmac4366b-pcie.bin) may pick different channel than requested. This --has been tested with BCM4366B1 in D-Link DIR-885L. -- --Signed-off-by: RafaÅ‚ MiÅ‚ecki --Signed-off-by: Kalle Valo ----- -- ----- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c --+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c --@@ -4847,6 +4847,68 @@ exit: -- return err; -- } -- --+static int brcmf_cfg80211_get_channel(struct wiphy *wiphy, --+ struct wireless_dev *wdev, --+ struct cfg80211_chan_def *chandef) --+{ --+ struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); --+ struct net_device *ndev = wdev->netdev; --+ 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) --+ return -ENODEV; --+ ifp = netdev_priv(ndev); --+ --+ err = brcmf_fil_iovar_int_get(ifp, "chanspec", &chanspec); --+ if (err) { --+ brcmf_err("chanspec failed (%d)\n", err); --+ return err; --+ } --+ --+ ch.chspec = chanspec; --+ cfg->d11inf.decchspec(&ch); --+ --+ switch (ch.band) { --+ case BRCMU_CHAN_BAND_2G: --+ band = NL80211_BAND_2GHZ; --+ break; --+ case BRCMU_CHAN_BAND_5G: --+ band = NL80211_BAND_5GHZ; --+ break; --+ } --+ --+ switch (ch.bw) { --+ case BRCMU_CHAN_BW_80: --+ width = NL80211_CHAN_WIDTH_80; --+ break; --+ case BRCMU_CHAN_BW_40: --+ width = NL80211_CHAN_WIDTH_40; --+ break; --+ case BRCMU_CHAN_BW_20: --+ width = NL80211_CHAN_WIDTH_20; --+ break; --+ case BRCMU_CHAN_BW_80P80: --+ width = NL80211_CHAN_WIDTH_80P80; --+ break; --+ case BRCMU_CHAN_BW_160: --+ width = NL80211_CHAN_WIDTH_160; --+ break; --+ } --+ --+ freq = ieee80211_channel_to_frequency(ch.control_ch_num, band); --+ chandef->chan = ieee80211_get_channel(wiphy, freq); --+ chandef->width = width; --+ chandef->center_freq1 = ieee80211_channel_to_frequency(ch.chnum, band); --+ chandef->center_freq2 = 0; --+ --+ return 0; --+} --+ -- static int brcmf_cfg80211_crit_proto_start(struct wiphy *wiphy, -- struct wireless_dev *wdev, -- enum nl80211_crit_proto_id proto, --@@ -5009,6 +5071,7 @@ static struct cfg80211_ops brcmf_cfg8021 -- .mgmt_tx = brcmf_cfg80211_mgmt_tx, -- .remain_on_channel = brcmf_p2p_remain_on_channel, -- .cancel_remain_on_channel = brcmf_cfg80211_cancel_remain_on_channel, --+ .get_channel = brcmf_cfg80211_get_channel, -- .start_p2p_device = brcmf_p2p_start_device, -- .stop_p2p_device = brcmf_p2p_stop_device, -- .crit_proto_start = brcmf_cfg80211_crit_proto_start, -diff --git a/package/kernel/mac80211/patches/351-0009-brcmfmac-print-errors-if-creating-interface-fails.patch b/package/kernel/mac80211/patches/351-0009-brcmfmac-print-errors-if-creating-interface-fails.patch -deleted file mode 100644 -index 1b119b2..0000000 ---- a/package/kernel/mac80211/patches/351-0009-brcmfmac-print-errors-if-creating-interface-fails.patch -+++ /dev/null -@@ -1,59 +0,0 @@ --From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= --Date: Fri, 27 May 2016 10:54:28 +0200 --Subject: [PATCH] brcmfmac: print errors if creating interface fails -- --This is helpful for debugging. Without this all I was getting from "iw" --command on failed creating of P2P interface was: --> command failed: Too many open files in system (-23) -- --Signed-off-by: Rafal Milecki --[arend@broadcom.com: reduce error prints upon iface creation] --Signed-off-by: Arend van Spriel --Reviewed-by: Julian Calaby --Signed-off-by: Kalle Valo ----- -- ----- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c --+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c --@@ -670,20 +670,24 @@ static struct wireless_dev *brcmf_cfg802 -- return ERR_PTR(-EOPNOTSUPP); -- case NL80211_IFTYPE_AP: -- wdev = brcmf_ap_add_vif(wiphy, name, flags, params); --- if (!IS_ERR(wdev)) --- brcmf_cfg80211_update_proto_addr_mode(wdev); --- return wdev; --+ break; -- case NL80211_IFTYPE_P2P_CLIENT: -- case NL80211_IFTYPE_P2P_GO: -- case NL80211_IFTYPE_P2P_DEVICE: -- wdev = brcmf_p2p_add_vif(wiphy, name, name_assign_type, type, flags, params); --- if (!IS_ERR(wdev)) --- brcmf_cfg80211_update_proto_addr_mode(wdev); --- return wdev; --+ break; -- case NL80211_IFTYPE_UNSPECIFIED: -- default: -- return ERR_PTR(-EINVAL); -- } --+ --+ if (IS_ERR(wdev)) --+ brcmf_err("add iface %s type %d failed: err=%d\n", --+ name, type, (int)PTR_ERR(wdev)); --+ else --+ brcmf_cfg80211_update_proto_addr_mode(wdev); --+ --+ return wdev; -- } -- -- static void brcmf_scan_config_mpc(struct brcmf_if *ifp, int mpc) ----- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c --+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c --@@ -2030,8 +2030,6 @@ static int brcmf_p2p_request_p2p_if(stru -- -- err = brcmf_fil_iovar_data_set(ifp, "p2p_ifadd", &if_request, -- sizeof(if_request)); --- if (err) --- return err; -- -- return err; -- } -diff --git a/package/kernel/mac80211/patches/351-0010-brcmfmac-fix-setting-AP-channel-with-new-firmwares.patch b/package/kernel/mac80211/patches/351-0010-brcmfmac-fix-setting-AP-channel-with-new-firmwares.patch -deleted file mode 100644 -index a2e18a5..0000000 ---- a/package/kernel/mac80211/patches/351-0010-brcmfmac-fix-setting-AP-channel-with-new-firmwares.patch -+++ /dev/null -@@ -1,114 +0,0 @@ --From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= --Date: Fri, 27 May 2016 21:07:19 +0200 --Subject: [PATCH] brcmfmac: fix setting AP channel with new firmwares --MIME-Version: 1.0 --Content-Type: text/plain; charset=UTF-8 --Content-Transfer-Encoding: 8bit -- --Firmware for new chipsets is based on a new major version of code --internally maintained at Broadcom. E.g. brcmfmac4366b-pcie.bin (used for --BCM4366B1) is based on 10.10.69.3309 while brcmfmac43602-pcie.ap.bin was --based on 7.35.177.56. -- --Currently setting AP 5 GHz channel doesn't work reliably with BCM4366B1. --When setting e.g. 36 control channel with VHT80 (center channel 42) --firmware may randomly pick one of: --1) 52 control channel with 58 as center one --2) 100 control channel with 106 as center one --3) 116 control channel with 122 as center one --4) 149 control channel with 155 as center one -- --It seems new firmwares require setting AP mode (BRCMF_C_SET_AP) before --specifying a channel. Changing an order of firmware calls fixes the --problem. This requirement resulted in two separated "chanspec" calls, --one in AP code path and one in P2P path. -- --This fix was verified with BCM4366B1 and tested for regressions on --BCM43602. -- --Signed-off-by: RafaÅ‚ MiÅ‚ecki --Signed-off-by: Kalle Valo ----- -- ----- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c --+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c --@@ -4382,7 +4382,7 @@ brcmf_cfg80211_start_ap(struct wiphy *wi -- struct brcmf_join_params join_params; -- enum nl80211_iftype dev_role; -- struct brcmf_fil_bss_enable_le bss_enable; --- u16 chanspec; --+ u16 chanspec = chandef_to_chanspec(&cfg->d11inf, &settings->chandef); -- bool mbss; -- int is_11d; -- --@@ -4458,16 +4458,8 @@ brcmf_cfg80211_start_ap(struct wiphy *wi -- -- brcmf_config_ap_mgmt_ie(ifp->vif, &settings->beacon); -- --+ /* Parameters shared by all radio interfaces */ -- if (!mbss) { --- chanspec = chandef_to_chanspec(&cfg->d11inf, --- &settings->chandef); --- err = brcmf_fil_iovar_int_set(ifp, "chanspec", chanspec); --- if (err < 0) { --- brcmf_err("Set Channel failed: chspec=%d, %d\n", --- chanspec, err); --- goto exit; --- } --- -- if (is_11d != ifp->vif->is_11d) { -- err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_REGULATORY, -- is_11d); --@@ -4515,6 +4507,8 @@ brcmf_cfg80211_start_ap(struct wiphy *wi -- err = -EINVAL; -- goto exit; -- } --+ --+ /* Interface specific setup */ -- if (dev_role == NL80211_IFTYPE_AP) { -- if ((brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MBSS)) && (!mbss)) -- brcmf_fil_iovar_int_set(ifp, "mbss", 1); --@@ -4524,6 +4518,17 @@ brcmf_cfg80211_start_ap(struct wiphy *wi -- brcmf_err("setting AP mode failed %d\n", err); -- goto exit; -- } --+ if (!mbss) { --+ /* Firmware 10.x requires setting channel after enabling --+ * AP and before bringing interface up. --+ */ --+ err = brcmf_fil_iovar_int_set(ifp, "chanspec", chanspec); --+ if (err < 0) { --+ brcmf_err("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); --@@ -4545,7 +4550,13 @@ brcmf_cfg80211_start_ap(struct wiphy *wi -- goto exit; -- } -- brcmf_dbg(TRACE, "AP mode configuration complete\n"); --- } else { --+ } 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); --+ goto exit; --+ } -- err = brcmf_fil_bsscfg_data_set(ifp, "ssid", &ssid_le, -- sizeof(ssid_le)); -- if (err < 0) { --@@ -4562,7 +4573,10 @@ brcmf_cfg80211_start_ap(struct wiphy *wi -- } -- -- brcmf_dbg(TRACE, "GO mode configuration complete\n"); --+ } else { --+ WARN_ON(1); -- } --+ -- set_bit(BRCMF_VIF_STATUS_AP_CREATED, &ifp->vif->sme_state); -- brcmf_net_setcarrier(ifp, true); -- -diff --git a/package/kernel/mac80211/patches/351-0011-brcmfmac-don-t-remove-interface-on-link-down-firmwar.patch b/package/kernel/mac80211/patches/351-0011-brcmfmac-don-t-remove-interface-on-link-down-firmwar.patch -deleted file mode 100644 -index 167e434..0000000 ---- a/package/kernel/mac80211/patches/351-0011-brcmfmac-don-t-remove-interface-on-link-down-firmwar.patch -+++ /dev/null -@@ -1,60 +0,0 @@ --From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= --Date: Mon, 30 May 2016 06:40:54 +0200 --Subject: [PATCH] brcmfmac: don't remove interface on link down firmware event --MIME-Version: 1.0 --Content-Type: text/plain; charset=UTF-8 --Content-Transfer-Encoding: 8bit -- --There are two firmware events we handle similarly in brcmfmac: --BRCMF_E_LINK and BRCMF_E_IF. The difference from firmware point of view --is that the first one means BSS remains present in the firmware. Trying --to (re)create it (e.g. when adding new virtual interface) will result in --an error. -- --Current code treats both events in a similar way. It removes Linux --interface for each of them. It works OK with e.g. BCM43602. Its firmware --generates both events for each interface. It means we get BRCMF_E_LINK --and remove interface. That is soon followed by BRCMF_E_IF which means --BSS was also removed in a firmware. The only downside of this is a --harmless error like: --[ 208.643180] brcmfmac: brcmf_fweh_call_event_handler: no interface object -- --Unfortunately BCM4366 firmware doesn't automatically remove BSS and so --it doesn't generate BRCMF_E_IF. In such case we incorrectly remove Linux --interface on BRCMF_E_LINK as BSS is still present in the firmware. It --results in an error when trying to re-create virtual interface, e.g.: --> iw phy phy1 interface add wlan1-1 type __ap --[ 3602.929199] brcmfmac: brcmf_ap_add_vif: timeout occurred --command failed: I/O error (-5) -- --With this patch we don't remove Linux interface while firmware keeps --BSS. Thanks to this we keep a consistent states of host driver and --device firmware. -- --Further improvement should be to mark BSS as disabled and remove --interface on BRCMF_E_LINK. Then we should add support for reusing --BSS-es. -- --Signed-off-by: RafaÅ‚ MiÅ‚ecki --Signed-off-by: Kalle Valo ----- -- ----- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c --+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c --@@ -5372,7 +5372,6 @@ brcmf_notify_connect_status_ap(struct br -- struct net_device *ndev, -- const struct brcmf_event_msg *e, void *data) -- { --- struct brcmf_if *ifp = netdev_priv(ndev); -- static int generation; -- u32 event = e->event_code; -- u32 reason = e->reason; --@@ -5383,8 +5382,6 @@ brcmf_notify_connect_status_ap(struct br -- ndev != cfg_to_ndev(cfg)) { -- brcmf_dbg(CONN, "AP mode link down\n"); -- complete(&cfg->vif_disabled); --- if (ifp->vif->mbss) --- brcmf_remove_interface(ifp); -- return 0; -- } -- -diff --git a/package/kernel/mac80211/patches/351-0017-brcmfmac-drop-unused-pm_block-vif-attribute.patch b/package/kernel/mac80211/patches/351-0017-brcmfmac-drop-unused-pm_block-vif-attribute.patch -deleted file mode 100644 -index 28ef3a6..0000000 ---- a/package/kernel/mac80211/patches/351-0017-brcmfmac-drop-unused-pm_block-vif-attribute.patch -+++ /dev/null -@@ -1,103 +0,0 @@ --From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= --Date: Mon, 6 Jun 2016 23:03:55 +0200 --Subject: [PATCH] brcmfmac: drop unused pm_block vif attribute --MIME-Version: 1.0 --Content-Type: text/plain; charset=UTF-8 --Content-Transfer-Encoding: 8bit -- --This attribute was added 3 years ago by --commit 3eacf866559c ("brcmfmac: introduce brcmf_cfg80211_vif structure") --but it remains unused since then. It seems we can safely drop it. -- --Signed-off-by: Rafał Miłecki --Signed-off-by: Kalle Valo ----- -- ----- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c --+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c --@@ -587,7 +587,7 @@ struct wireless_dev *brcmf_ap_add_vif(st -- -- brcmf_dbg(INFO, "Adding vif \"%s\"\n", name); -- --- vif = brcmf_alloc_vif(cfg, NL80211_IFTYPE_AP, false); --+ vif = brcmf_alloc_vif(cfg, NL80211_IFTYPE_AP); -- if (IS_ERR(vif)) -- return (struct wireless_dev *)vif; -- --@@ -5098,8 +5098,7 @@ static struct cfg80211_ops brcmf_cfg8021 -- }; -- -- struct brcmf_cfg80211_vif *brcmf_alloc_vif(struct brcmf_cfg80211_info *cfg, --- enum nl80211_iftype type, --- bool pm_block) --+ enum nl80211_iftype type) -- { -- struct brcmf_cfg80211_vif *vif_walk; -- struct brcmf_cfg80211_vif *vif; --@@ -5114,8 +5113,6 @@ struct brcmf_cfg80211_vif *brcmf_alloc_v -- vif->wdev.wiphy = cfg->wiphy; -- vif->wdev.iftype = type; -- --- vif->pm_block = pm_block; --- -- brcmf_init_prof(&vif->profile); -- -- if (type == NL80211_IFTYPE_AP) { --@@ -6754,7 +6751,7 @@ struct brcmf_cfg80211_info *brcmf_cfg802 -- init_vif_event(&cfg->vif_event); -- INIT_LIST_HEAD(&cfg->vif_list); -- --- vif = brcmf_alloc_vif(cfg, NL80211_IFTYPE_STATION, false); --+ vif = brcmf_alloc_vif(cfg, NL80211_IFTYPE_STATION); -- if (IS_ERR(vif)) -- goto wiphy_out; -- ----- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h --+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h --@@ -167,7 +167,6 @@ struct vif_saved_ie { -- * @wdev: wireless device. -- * @profile: profile information. -- * @sme_state: SME state using enum brcmf_vif_status bits. --- * @pm_block: power-management blocked. -- * @list: linked list. -- * @mgmt_rx_reg: registered rx mgmt frame types. -- * @mbss: Multiple BSS type, set if not first AP (not relevant for P2P). --@@ -177,7 +176,6 @@ struct brcmf_cfg80211_vif { -- struct wireless_dev wdev; -- struct brcmf_cfg80211_profile profile; -- unsigned long sme_state; --- bool pm_block; -- struct vif_saved_ie saved_ie; -- struct list_head list; -- u16 mgmt_rx_reg; --@@ -388,8 +386,7 @@ s32 brcmf_cfg80211_down(struct net_devic -- enum nl80211_iftype brcmf_cfg80211_get_iftype(struct brcmf_if *ifp); -- -- struct brcmf_cfg80211_vif *brcmf_alloc_vif(struct brcmf_cfg80211_info *cfg, --- enum nl80211_iftype type, --- bool pm_block); --+ enum nl80211_iftype type); -- void brcmf_free_vif(struct brcmf_cfg80211_vif *vif); -- -- s32 brcmf_vif_set_mgmt_ie(struct brcmf_cfg80211_vif *vif, s32 pktflag, ----- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c --+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c --@@ -2074,8 +2074,7 @@ static struct wireless_dev *brcmf_p2p_cr -- if (p2p->bss_idx[P2PAPI_BSSCFG_DEVICE].vif) -- return ERR_PTR(-ENOSPC); -- --- p2p_vif = brcmf_alloc_vif(p2p->cfg, NL80211_IFTYPE_P2P_DEVICE, --- false); --+ p2p_vif = brcmf_alloc_vif(p2p->cfg, NL80211_IFTYPE_P2P_DEVICE); -- if (IS_ERR(p2p_vif)) { -- brcmf_err("could not create discovery vif\n"); -- return (struct wireless_dev *)p2p_vif; --@@ -2175,7 +2174,7 @@ struct wireless_dev *brcmf_p2p_add_vif(s -- return ERR_PTR(-EOPNOTSUPP); -- } -- --- vif = brcmf_alloc_vif(cfg, type, false); --+ vif = brcmf_alloc_vif(cfg, type); -- if (IS_ERR(vif)) -- return (struct wireless_dev *)vif; -- brcmf_cfg80211_arm_vif_event(cfg, vif); -diff --git a/package/kernel/mac80211/patches/351-0018-brcmfmac-include-required-headers-in-cfg80211.h.patch b/package/kernel/mac80211/patches/351-0018-brcmfmac-include-required-headers-in-cfg80211.h.patch -deleted file mode 100644 -index 09547d8..0000000 ---- a/package/kernel/mac80211/patches/351-0018-brcmfmac-include-required-headers-in-cfg80211.h.patch -+++ /dev/null -@@ -1,37 +0,0 @@ --From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= --Date: Tue, 7 Jun 2016 08:20:21 +0200 --Subject: [PATCH] brcmfmac: include required headers in cfg80211.h --MIME-Version: 1.0 --Content-Type: text/plain; charset=UTF-8 --Content-Transfer-Encoding: 8bit -- --Without this including cfg80211.h in a wrong order could result in: -- --drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h:122:24: error: array type has incomplete element type -- struct brcmf_wsec_key key[BRCMF_MAX_DEFAULT_KEYS]; -- ^ --drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h:291:24: error: field ‘p2p’ has incomplete type -- struct brcmf_p2p_info p2p; -- ^ --drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h:297:27: error: field ‘pmk_list’ has incomplete type -- struct brcmf_pmk_list_le pmk_list; -- ^ --drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h:317:28: error: field ‘assoclist’ has incomplete type -- struct brcmf_assoclist_le assoclist; -- --Signed-off-by: Rafał Miłecki --Signed-off-by: Kalle Valo ----- -- ----- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h --+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h --@@ -20,6 +20,9 @@ -- /* for brcmu_d11inf */ -- #include -- --+#include "fwil_types.h" --+#include "p2p.h" --+ -- #define WL_NUM_SCAN_MAX 10 -- #define WL_TLV_INFO_MAX 1024 -- #define WL_BSS_INFO_MAX 2048 -diff --git a/package/kernel/mac80211/patches/351-0019-brcmfmac-slightly-simplify-building-interface-combin.patch b/package/kernel/mac80211/patches/351-0019-brcmfmac-slightly-simplify-building-interface-combin.patch -deleted file mode 100644 -index 461e3db..0000000 ---- a/package/kernel/mac80211/patches/351-0019-brcmfmac-slightly-simplify-building-interface-combin.patch -+++ /dev/null -@@ -1,108 +0,0 @@ --From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= --Date: Tue, 7 Jun 2016 21:10:18 +0200 --Subject: [PATCH] brcmfmac: slightly simplify building interface combinations --MIME-Version: 1.0 --Content-Type: text/plain; charset=UTF-8 --Content-Transfer-Encoding: 8bit -- --This change reorders some operations in brcmf_setup_ifmodes in hope to --make it simpler: --1) It allocates arrays right before filling them. This way it's easier -- to follow requested array length as it's immediately followed by -- code filling it. It's easier to check e.g. why we need 4 entries for -- P2P. Other than that it deduplicates some checks (e.g. for P2P). --2) It reorders code to first prepare limits and then define a new combo. -- Previously this was mixed (e.g. we were setting num of channels -- before preparing limits). --3) It modifies mbss code to use i variable just like other combos do. -- --Signed-off-by: Rafał Miłecki --Acked-by: Arend van Spriel --Signed-off-by: Kalle Valo ----- -- ----- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c --+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c --@@ -6208,29 +6208,15 @@ static int brcmf_setup_ifmodes(struct wi -- if (!combo) -- goto err; -- --- c0_limits = kcalloc(p2p ? 3 : 2, sizeof(*c0_limits), GFP_KERNEL); --- if (!c0_limits) --- goto err; --- --- if (p2p) { --- p2p_limits = kcalloc(4, sizeof(*p2p_limits), GFP_KERNEL); --- if (!p2p_limits) --- goto err; --- } --- --- if (mbss) { --- mbss_limits = kcalloc(1, sizeof(*mbss_limits), GFP_KERNEL); --- if (!mbss_limits) --- goto err; --- } --- -- wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | -- BIT(NL80211_IFTYPE_ADHOC) | -- BIT(NL80211_IFTYPE_AP); -- -- c = 0; -- i = 0; --- combo[c].num_different_channels = 1; --+ c0_limits = kcalloc(p2p ? 3 : 2, sizeof(*c0_limits), GFP_KERNEL); --+ if (!c0_limits) --+ goto err; -- c0_limits[i].max = 1; -- c0_limits[i++].types = BIT(NL80211_IFTYPE_STATION); -- if (p2p) { --@@ -6248,6 +6234,7 @@ static int brcmf_setup_ifmodes(struct wi -- c0_limits[i].max = 1; -- c0_limits[i++].types = BIT(NL80211_IFTYPE_AP); -- } --+ combo[c].num_different_channels = 1; -- combo[c].max_interfaces = i; -- combo[c].n_limits = i; -- combo[c].limits = c0_limits; --@@ -6255,7 +6242,9 @@ static int brcmf_setup_ifmodes(struct wi -- if (p2p) { -- c++; -- i = 0; --- combo[c].num_different_channels = 1; --+ p2p_limits = kcalloc(4, sizeof(*p2p_limits), GFP_KERNEL); --+ if (!p2p_limits) --+ goto err; -- p2p_limits[i].max = 1; -- p2p_limits[i++].types = BIT(NL80211_IFTYPE_STATION); -- p2p_limits[i].max = 1; --@@ -6264,6 +6253,7 @@ static int brcmf_setup_ifmodes(struct wi -- p2p_limits[i++].types = BIT(NL80211_IFTYPE_P2P_CLIENT); -- p2p_limits[i].max = 1; -- p2p_limits[i++].types = BIT(NL80211_IFTYPE_P2P_DEVICE); --+ combo[c].num_different_channels = 1; -- combo[c].max_interfaces = i; -- combo[c].n_limits = i; -- combo[c].limits = p2p_limits; --@@ -6271,14 +6261,19 @@ static int brcmf_setup_ifmodes(struct wi -- -- if (mbss) { -- c++; --+ i = 0; --+ mbss_limits = kcalloc(1, sizeof(*mbss_limits), GFP_KERNEL); --+ if (!mbss_limits) --+ goto err; --+ mbss_limits[i].max = 4; --+ mbss_limits[i++].types = BIT(NL80211_IFTYPE_AP); -- combo[c].beacon_int_infra_match = true; -- combo[c].num_different_channels = 1; --- mbss_limits[0].max = 4; --- mbss_limits[0].types = BIT(NL80211_IFTYPE_AP); -- combo[c].max_interfaces = 4; --- combo[c].n_limits = 1; --+ combo[c].n_limits = i; -- combo[c].limits = mbss_limits; -- } --+ -- wiphy->n_iface_combinations = n_combos; -- wiphy->iface_combinations = combo; -- return 0; -diff --git a/package/kernel/mac80211/patches/351-0020-brcmfmac-fix-lockup-when-removing-P2P-interface-afte.patch b/package/kernel/mac80211/patches/351-0020-brcmfmac-fix-lockup-when-removing-P2P-interface-afte.patch -deleted file mode 100644 -index e991f32..0000000 ---- a/package/kernel/mac80211/patches/351-0020-brcmfmac-fix-lockup-when-removing-P2P-interface-afte.patch -+++ /dev/null -@@ -1,160 +0,0 @@ --From b50ddfa8530e9b5f52e873fdd6ff04f327a88799 Mon Sep 17 00:00:00 2001 --From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= --Date: Fri, 17 Jun 2016 12:29:21 +0200 --Subject: [PATCH] brcmfmac: fix lockup when removing P2P interface after event -- timeout --MIME-Version: 1.0 --Content-Type: text/plain; charset=UTF-8 --Content-Transfer-Encoding: 8bit -- --Removing P2P interface is handled by sending a proper request to the --firmware. On success firmware triggers an event and driver's handler --removes a matching interface. -- --However on event timeout we remove interface directly from the cfg80211 --callback. Current code doesn't handle this case correctly as it always --assumes rtnl to be unlocked. -- --Fix it by adding an extra rtnl_locked parameter to functions and calling --unregister_netdevice when needed. -- --Signed-off-by: Rafał Miłecki --Signed-off-by: Kalle Valo ----- -- .../wireless/broadcom/brcm80211/brcmfmac/core.c | 29 +++++++++++++--------- -- .../wireless/broadcom/brcm80211/brcmfmac/core.h | 2 +- -- .../wireless/broadcom/brcm80211/brcmfmac/fweh.c | 2 +- -- .../net/wireless/broadcom/brcm80211/brcmfmac/p2p.c | 4 +-- -- 4 files changed, 21 insertions(+), 16 deletions(-) -- ----- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c --+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c --@@ -548,12 +548,16 @@ fail: -- return -EBADE; -- } -- ---static void brcmf_net_detach(struct net_device *ndev) --+static void brcmf_net_detach(struct net_device *ndev, bool rtnl_locked) -- { --- if (ndev->reg_state == NETREG_REGISTERED) --- unregister_netdev(ndev); --- else --+ if (ndev->reg_state == NETREG_REGISTERED) { --+ if (rtnl_locked) --+ unregister_netdevice(ndev); --+ else --+ unregister_netdev(ndev); --+ } else { -- brcmf_cfg80211_free_netdev(ndev); --+ } -- } -- -- void brcmf_net_setcarrier(struct brcmf_if *ifp, bool on) --@@ -651,7 +655,7 @@ struct brcmf_if *brcmf_add_if(struct brc -- brcmf_err("ERROR: netdev:%s already exists\n", -- ifp->ndev->name); -- netif_stop_queue(ifp->ndev); --- brcmf_net_detach(ifp->ndev); --+ brcmf_net_detach(ifp->ndev, false); -- drvr->iflist[bsscfgidx] = NULL; -- } else { -- brcmf_dbg(INFO, "netdev:%s ignore IF event\n", --@@ -699,7 +703,8 @@ struct brcmf_if *brcmf_add_if(struct brc -- return ifp; -- } -- ---static void brcmf_del_if(struct brcmf_pub *drvr, s32 bsscfgidx) --+static void brcmf_del_if(struct brcmf_pub *drvr, s32 bsscfgidx, --+ bool rtnl_locked) -- { -- struct brcmf_if *ifp; -- --@@ -729,7 +734,7 @@ static void brcmf_del_if(struct brcmf_pu -- cancel_work_sync(&ifp->multicast_work); -- cancel_work_sync(&ifp->ndoffload_work); -- } --- brcmf_net_detach(ifp->ndev); --+ brcmf_net_detach(ifp->ndev, rtnl_locked); -- } else { -- /* Only p2p device interfaces which get dynamically created -- * end up here. In this case the p2p module should be informed --@@ -743,14 +748,14 @@ static void brcmf_del_if(struct brcmf_pu -- } -- } -- ---void brcmf_remove_interface(struct brcmf_if *ifp) --+void brcmf_remove_interface(struct brcmf_if *ifp, bool rtnl_locked) -- { -- if (!ifp || WARN_ON(ifp->drvr->iflist[ifp->bsscfgidx] != ifp)) -- return; -- brcmf_dbg(TRACE, "Enter, bsscfgidx=%d, ifidx=%d\n", ifp->bsscfgidx, -- ifp->ifidx); -- brcmf_fws_del_interface(ifp); --- brcmf_del_if(ifp->drvr, ifp->bsscfgidx); --+ brcmf_del_if(ifp->drvr, ifp->bsscfgidx, rtnl_locked); -- } -- -- #ifdef CONFIG_INET --@@ -1057,9 +1062,9 @@ fail: -- brcmf_fws_deinit(drvr); -- } -- if (ifp) --- brcmf_net_detach(ifp->ndev); --+ brcmf_net_detach(ifp->ndev, false); -- if (p2p_ifp) --- brcmf_net_detach(p2p_ifp->ndev); --+ brcmf_net_detach(p2p_ifp->ndev, false); -- drvr->iflist[0] = NULL; -- drvr->iflist[1] = NULL; -- if (drvr->settings->ignore_probe_fail) --@@ -1128,7 +1133,7 @@ void brcmf_detach(struct device *dev) -- -- /* make sure primary interface removed last */ -- for (i = BRCMF_MAX_IFS-1; i > -1; i--) --- brcmf_remove_interface(drvr->iflist[i]); --+ brcmf_remove_interface(drvr->iflist[i], false); -- -- brcmf_cfg80211_detach(drvr->config); -- ----- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h --+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h --@@ -216,7 +216,7 @@ struct brcmf_if *brcmf_get_ifp(struct br -- int brcmf_net_attach(struct brcmf_if *ifp, bool rtnl_locked); -- struct brcmf_if *brcmf_add_if(struct brcmf_pub *drvr, s32 bsscfgidx, s32 ifidx, -- bool is_p2pdev, char *name, u8 *mac_addr); ---void brcmf_remove_interface(struct brcmf_if *ifp); --+void brcmf_remove_interface(struct brcmf_if *ifp, bool rtnl_locked); -- void brcmf_txflowblock_if(struct brcmf_if *ifp, -- enum brcmf_netif_stop_reason reason, bool state); -- void brcmf_txfinalize(struct brcmf_if *ifp, struct sk_buff *txp, bool success); ----- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.c --+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.c --@@ -183,7 +183,7 @@ static void brcmf_fweh_handle_if_event(s -- err = brcmf_fweh_call_event_handler(ifp, emsg->event_code, emsg, data); -- -- if (ifp && ifevent->action == BRCMF_E_IF_DEL) --- brcmf_remove_interface(ifp); --+ brcmf_remove_interface(ifp, false); -- } -- -- /** ----- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c --+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c --@@ -2289,7 +2289,7 @@ int brcmf_p2p_del_vif(struct wiphy *wiph -- err = 0; -- } -- if (err) --- brcmf_remove_interface(vif->ifp); --+ brcmf_remove_interface(vif->ifp, true); -- -- brcmf_cfg80211_arm_vif_event(cfg, NULL); -- if (vif->wdev.iftype != NL80211_IFTYPE_P2P_DEVICE) --@@ -2395,7 +2395,7 @@ void brcmf_p2p_detach(struct brcmf_p2p_i -- if (vif != NULL) { -- brcmf_p2p_cancel_remain_on_channel(vif->ifp); -- brcmf_p2p_deinit_discovery(p2p); --- brcmf_remove_interface(vif->ifp); --+ brcmf_remove_interface(vif->ifp, false); -- } -- /* just set it all to zero */ -- memset(p2p, 0, sizeof(*p2p)); -diff --git a/package/kernel/mac80211/patches/351-0021-brcmfmac-use-const-char-for-interface-name-in-brcmf_.patch b/package/kernel/mac80211/patches/351-0021-brcmfmac-use-const-char-for-interface-name-in-brcmf_.patch -deleted file mode 100644 -index ed65f4d..0000000 ---- a/package/kernel/mac80211/patches/351-0021-brcmfmac-use-const-char-for-interface-name-in-brcmf_.patch -+++ /dev/null -@@ -1,39 +0,0 @@ --From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= --Date: Fri, 17 Jun 2016 12:48:44 +0200 --Subject: [PATCH] brcmfmac: use const char * for interface name in brcmf_add_if --MIME-Version: 1.0 --Content-Type: text/plain; charset=UTF-8 --Content-Transfer-Encoding: 8bit -- --This function can work just fine with const pointer, it only calls --alloc_netdev which take const as well. Moreover it makes this function --more flexible as some cfg80211 callback may provide const char * as --well, e.g. add_virtual_intf. This will be needed for more advanced --interface management. -- --Signed-off-by: Rafał Miłecki --Signed-off-by: Kalle Valo ----- -- ----- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c --+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c --@@ -638,7 +638,7 @@ fail: -- } -- -- struct brcmf_if *brcmf_add_if(struct brcmf_pub *drvr, s32 bsscfgidx, s32 ifidx, --- bool is_p2pdev, char *name, u8 *mac_addr) --+ bool is_p2pdev, const char *name, u8 *mac_addr) -- { -- struct brcmf_if *ifp; -- struct net_device *ndev; ----- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h --+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h --@@ -215,7 +215,7 @@ char *brcmf_ifname(struct brcmf_if *ifp) -- struct brcmf_if *brcmf_get_ifp(struct brcmf_pub *drvr, int ifidx); -- int brcmf_net_attach(struct brcmf_if *ifp, bool rtnl_locked); -- struct brcmf_if *brcmf_add_if(struct brcmf_pub *drvr, s32 bsscfgidx, s32 ifidx, --- bool is_p2pdev, char *name, u8 *mac_addr); --+ bool is_p2pdev, const char *name, u8 *mac_addr); -- void brcmf_remove_interface(struct brcmf_if *ifp, bool rtnl_locked); -- void brcmf_txflowblock_if(struct brcmf_if *ifp, -- enum brcmf_netif_stop_reason reason, bool state); -diff --git a/package/kernel/mac80211/patches/351-0022-brcmfmac-include-also-core.h-header-in-cfg80211.h.patch b/package/kernel/mac80211/patches/351-0022-brcmfmac-include-also-core.h-header-in-cfg80211.h.patch -deleted file mode 100644 -index ef35fab..0000000 ---- a/package/kernel/mac80211/patches/351-0022-brcmfmac-include-also-core.h-header-in-cfg80211.h.patch -+++ /dev/null -@@ -1,33 +0,0 @@ --From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= --Date: Sat, 18 Jun 2016 18:49:38 +0200 --Subject: [PATCH] brcmfmac: include also core.h header in cfg80211.h --MIME-Version: 1.0 --Content-Type: text/plain; charset=UTF-8 --Content-Transfer-Encoding: 8bit -- --This header provides two inline functions using struct brcmf_if so we --need core.h to avoid: -- --drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h: In function ‘ndev_to_prof’: --drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h:368:13: error: dereferencing pointer to incomplete type -- return &ifp->vif->profile; -- ^ --drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h: In function ‘ndev_to_vif’: --drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h:374:12: error: dereferencing pointer to incomplete type -- return ifp->vif; -- ^ -- --Signed-off-by: Rafał Miłecki --Signed-off-by: Kalle Valo ----- -- ----- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h --+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h --@@ -20,6 +20,7 @@ -- /* for brcmu_d11inf */ -- #include -- --+#include "core.h" -- #include "fwil_types.h" -- #include "p2p.h" -- -diff --git a/package/kernel/mac80211/patches/351-0023-brcmfmac-add-missing-break-when-deleting-P2P_DEVICE.patch b/package/kernel/mac80211/patches/351-0023-brcmfmac-add-missing-break-when-deleting-P2P_DEVICE.patch -deleted file mode 100644 -index ab9a634..0000000 ---- a/package/kernel/mac80211/patches/351-0023-brcmfmac-add-missing-break-when-deleting-P2P_DEVICE.patch -+++ /dev/null -@@ -1,27 +0,0 @@ --From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= --Date: Sun, 19 Jun 2016 01:55:57 +0200 --Subject: [PATCH] brcmfmac: add missing break when deleting P2P_DEVICE --MIME-Version: 1.0 --Content-Type: text/plain; charset=UTF-8 --Content-Transfer-Encoding: 8bit -- --We obviously don't want to fall through in that switch. With this change --1) We wait for event (triggered by p2p_disc) as expected --2) We remove interface manually on timeout --3) We return 0 on success instead of -ENOTSUPP -- --Signed-off-by: Rafał Miłecki --Signed-off-by: Kalle Valo ----- -- ----- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c --+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c --@@ -2263,6 +2263,8 @@ int brcmf_p2p_del_vif(struct wiphy *wiph -- return 0; -- brcmf_p2p_cancel_remain_on_channel(vif->ifp); -- brcmf_p2p_deinit_discovery(p2p); --+ break; --+ -- default: -- return -ENOTSUPP; -- } -diff --git a/package/kernel/mac80211/patches/351-0024-brcmfmac-delete-interface-directly-in-code-that-sent.patch b/package/kernel/mac80211/patches/351-0024-brcmfmac-delete-interface-directly-in-code-that-sent.patch -deleted file mode 100644 -index 6dd0c03..0000000 ---- a/package/kernel/mac80211/patches/351-0024-brcmfmac-delete-interface-directly-in-code-that-sent.patch -+++ /dev/null -@@ -1,75 +0,0 @@ --From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= --Date: Wed, 29 Jun 2016 21:54:26 +0200 --Subject: [PATCH] brcmfmac: delete interface directly in code that sent fw -- request --MIME-Version: 1.0 --Content-Type: text/plain; charset=UTF-8 --Content-Transfer-Encoding: 8bit -- --So far when receiving event about in-firmware-interface removal our --event worker was notifying listener and afterwards it was removing Linux --interface. -- --First of all it was resulting in slightly unexpected order. The listener --(del_virtual_intf callback) was (usually) returning with success before --we even called unregister_netdev(ice). -- --Please note this couldn't be simply fixed by changing order of calls in --brcmf_fweh_handle_if_event as unregistering interface earlier could free --struct brcmf_if. -- --Another problem of current implementation are possible lockups. Focus on --the time slot between calling event handler and removing Linux --interface. During that time original caller may leave (unlocking rtnl --semaphore) *and* another call to the same code may be done (locking it --again). If that happens our event handler will stuck at removing Linux --interface, it won't handle another event and will block process holding --rtnl lock. -- --This can be simply solved by unregistering interface in a proper --callback, right after receiving confirmation event from firmware. This --only required modifying worker to don't unregister on its own if there --is someone waiting for the event. -- --Signed-off-by: Rafał Miłecki --Signed-off-by: Kalle Valo ----- -- ----- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.c --+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.c --@@ -18,6 +18,7 @@ -- #include "brcmu_wifi.h" -- #include "brcmu_utils.h" -- --+#include "cfg80211.h" -- #include "core.h" -- #include "debug.h" -- #include "tracepoint.h" --@@ -182,8 +183,13 @@ static void brcmf_fweh_handle_if_event(s -- -- err = brcmf_fweh_call_event_handler(ifp, emsg->event_code, emsg, data); -- --- if (ifp && ifevent->action == BRCMF_E_IF_DEL) --- brcmf_remove_interface(ifp, false); --+ if (ifp && ifevent->action == BRCMF_E_IF_DEL) { --+ bool armed = brcmf_cfg80211_vif_event_armed(drvr->config); --+ --+ /* Default handling in case no-one waits for this event */ --+ if (!armed) --+ brcmf_remove_interface(ifp, false); --+ } -- } -- -- /** ----- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c --+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c --@@ -2290,8 +2290,7 @@ int brcmf_p2p_del_vif(struct wiphy *wiph -- else -- err = 0; -- } --- if (err) --- brcmf_remove_interface(vif->ifp, true); --+ brcmf_remove_interface(vif->ifp, true); -- -- brcmf_cfg80211_arm_vif_event(cfg, NULL); -- if (vif->wdev.iftype != NL80211_IFTYPE_P2P_DEVICE) -diff --git a/package/kernel/mac80211/patches/351-0025-brcmfmac-support-removing-AP-interfaces-with-interfa.patch b/package/kernel/mac80211/patches/351-0025-brcmfmac-support-removing-AP-interfaces-with-interfa.patch -deleted file mode 100644 -index 1929f0b..0000000 ---- a/package/kernel/mac80211/patches/351-0025-brcmfmac-support-removing-AP-interfaces-with-interfa.patch -+++ /dev/null -@@ -1,84 +0,0 @@ --From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= --Date: Wed, 29 Jun 2016 21:54:27 +0200 --Subject: [PATCH] brcmfmac: support removing AP interfaces with -- "interface_remove" --MIME-Version: 1.0 --Content-Type: text/plain; charset=UTF-8 --Content-Transfer-Encoding: 8bit -- --New firmwares (e.g. 10.10.69.36 for BCM4366) support "interface_remove" --for removing interfaces. Try to use this method on cfg80211 request. In --case of older firmwares (e.g. 7.35.177.56 for BCM43602 as I tested) this --will just result in firmware rejecting command and this won't change any --behavior. -- --Signed-off-by: Rafał Miłecki --Signed-off-by: Kalle Valo ----- -- ----- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c --+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c --@@ -771,12 +771,48 @@ s32 brcmf_notify_escan_complete(struct b -- return err; -- } -- --+static int brcmf_cfg80211_del_ap_iface(struct wiphy *wiphy, --+ struct wireless_dev *wdev) --+{ --+ struct brcmf_cfg80211_info *cfg = wiphy_priv(wiphy); --+ struct net_device *ndev = wdev->netdev; --+ struct brcmf_if *ifp = netdev_priv(ndev); --+ int ret; --+ int err; --+ --+ brcmf_cfg80211_arm_vif_event(cfg, ifp->vif); --+ --+ err = brcmf_fil_bsscfg_data_set(ifp, "interface_remove", NULL, 0); --+ if (err) { --+ brcmf_err("interface_remove failed %d\n", err); --+ goto err_unarm; --+ } --+ --+ /* wait for firmware event */ --+ ret = brcmf_cfg80211_wait_vif_event(cfg, BRCMF_E_IF_DEL, --+ BRCMF_VIF_EVENT_TIMEOUT); --+ if (!ret) { --+ brcmf_err("timeout occurred\n"); --+ err = -EIO; --+ goto err_unarm; --+ } --+ --+ brcmf_remove_interface(ifp, true); --+ --+err_unarm: --+ brcmf_cfg80211_arm_vif_event(cfg, NULL); --+ return err; --+} --+ -- static -- int brcmf_cfg80211_del_iface(struct wiphy *wiphy, struct wireless_dev *wdev) -- { -- struct brcmf_cfg80211_info *cfg = wiphy_priv(wiphy); -- struct net_device *ndev = wdev->netdev; -- --+ if (ndev && ndev == cfg_to_ndev(cfg)) --+ return -ENOTSUPP; --+ -- /* vif event pending in firmware */ -- if (brcmf_cfg80211_vif_event_armed(cfg)) -- return -EBUSY; --@@ -793,12 +829,13 @@ int brcmf_cfg80211_del_iface(struct wiph -- switch (wdev->iftype) { -- case NL80211_IFTYPE_ADHOC: -- case NL80211_IFTYPE_STATION: --- case NL80211_IFTYPE_AP: -- case NL80211_IFTYPE_AP_VLAN: -- case NL80211_IFTYPE_WDS: -- case NL80211_IFTYPE_MONITOR: -- case NL80211_IFTYPE_MESH_POINT: -- return -EOPNOTSUPP; --+ case NL80211_IFTYPE_AP: --+ return brcmf_cfg80211_del_ap_iface(wiphy, wdev); -- case NL80211_IFTYPE_P2P_CLIENT: -- case NL80211_IFTYPE_P2P_GO: -- case NL80211_IFTYPE_P2P_DEVICE: -diff --git a/package/kernel/mac80211/patches/351-0026-brcmfmac-respect-hidden_ssid-for-AP-interfaces.patch b/package/kernel/mac80211/patches/351-0026-brcmfmac-respect-hidden_ssid-for-AP-interfaces.patch -deleted file mode 100644 -index ae458e7..0000000 ---- a/package/kernel/mac80211/patches/351-0026-brcmfmac-respect-hidden_ssid-for-AP-interfaces.patch -+++ /dev/null -@@ -1,43 +0,0 @@ --From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= --Date: Wed, 6 Jul 2016 12:22:54 +0200 --Subject: [PATCH] brcmfmac: respect hidden_ssid for AP interfaces --MIME-Version: 1.0 --Content-Type: text/plain; charset=UTF-8 --Content-Transfer-Encoding: 8bit -- --This was succesfully tested with 4366B1. A small workaround is needed --for the main interface otherwise it would stuck at the hidden state. -- --Signed-off-by: Rafał Miłecki --Signed-off-by: Kalle Valo ----- -- ----- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c --+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c --@@ -4586,6 +4586,15 @@ brcmf_cfg80211_start_ap(struct wiphy *wi -- brcmf_err("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); --+ goto exit; --+ } --+ } --+ -- brcmf_dbg(TRACE, "AP mode configuration complete\n"); -- } else if (dev_role == NL80211_IFTYPE_P2P_GO) { -- err = brcmf_fil_iovar_int_set(ifp, "chanspec", chanspec); --@@ -4644,6 +4653,10 @@ static int brcmf_cfg80211_stop_ap(struct -- return err; -- } -- --+ /* First BSS doesn't get a full reset */ --+ if (ifp->bsscfgidx == 0) --+ brcmf_fil_iovar_int_set(ifp, "closednet", 0); --+ -- memset(&join_params, 0, sizeof(join_params)); -- err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_SSID, -- &join_params, sizeof(join_params)); -diff --git a/package/kernel/mac80211/patches/351-0027-brcmfmac-restore-stopping-netdev-queue-when-bus-clog.patch b/package/kernel/mac80211/patches/351-0027-brcmfmac-restore-stopping-netdev-queue-when-bus-clog.patch -deleted file mode 100644 -index fcafa79..0000000 ---- a/package/kernel/mac80211/patches/351-0027-brcmfmac-restore-stopping-netdev-queue-when-bus-clog.patch -+++ /dev/null -@@ -1,53 +0,0 @@ --From: Arend Van Spriel --Date: Fri, 15 Jul 2016 12:16:12 +0200 --Subject: [PATCH] brcmfmac: restore stopping netdev queue when bus clogs up --MIME-Version: 1.0 --Content-Type: text/plain; charset=UTF-8 --Content-Transfer-Encoding: 8bit -- --When the host-interface bus has hard time handling transmit packets --it informs higher layer about this and it would stop the netdev --queue when needed. However, since commit 9cd18359d31e ("brcmfmac: --Make FWS queueing configurable.") this was broken. With this patch --the behaviour is restored. -- --Cc: stable@vger.kernel.org # v4.5, v4.6, v4.7 --Fixes: 9cd18359d31e ("brcmfmac: Make FWS queueing configurable.") --Tested-by: Per Förlin --Reviewed-by: Hante Meuleman --Reviewed-by: Pieter-Paul Giesberts --Reviewed-by: Franky Lin --Signed-off-by: Arend van Spriel --Signed-off-by: Kalle Valo ----- -- ----- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.c --+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.c --@@ -2469,10 +2469,22 @@ void brcmf_fws_bustxfail(struct brcmf_fw -- void brcmf_fws_bus_blocked(struct brcmf_pub *drvr, bool flow_blocked) -- { -- struct brcmf_fws_info *fws = drvr->fws; --+ struct brcmf_if *ifp; --+ int i; -- --- fws->bus_flow_blocked = flow_blocked; --- if (!flow_blocked) --- brcmf_fws_schedule_deq(fws); --- else --- fws->stats.bus_flow_block++; --+ if (fws->avoid_queueing) { --+ for (i = 0; i < BRCMF_MAX_IFS; i++) { --+ ifp = drvr->iflist[i]; --+ if (!ifp || !ifp->ndev) --+ continue; --+ brcmf_txflowblock_if(ifp, BRCMF_NETIF_STOP_REASON_FLOW, --+ flow_blocked); --+ } --+ } else { --+ fws->bus_flow_blocked = flow_blocked; --+ if (!flow_blocked) --+ brcmf_fws_schedule_deq(fws); --+ else --+ fws->stats.bus_flow_block++; --+ } -- } -diff --git a/package/kernel/mac80211/patches/351-0028-brcmfmac-defer-DPC-processing-during-probe.patch b/package/kernel/mac80211/patches/351-0028-brcmfmac-defer-DPC-processing-during-probe.patch -deleted file mode 100644 -index a24c07f..0000000 ---- a/package/kernel/mac80211/patches/351-0028-brcmfmac-defer-DPC-processing-during-probe.patch -+++ /dev/null -@@ -1,42 +0,0 @@ --From fd3ed33f51c2a586412d35b4f64803f019ab589f Mon Sep 17 00:00:00 2001 --From: Arend Van Spriel --Date: Fri, 15 Jul 2016 12:39:13 +0200 --Subject: [PATCH] brcmfmac: defer DPC processing during probe -- --The sdio dpc starts processing when in SDIOD_STATE_DATA. This state was --entered right after firmware download. This patch moves that transition --just before enabling sdio interrupt handling thus avoiding watchdog --expiry which would put the bus to sleep while probing. -- --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/sdio.c | 7 +++---- -- 1 file changed, 3 insertions(+), 4 deletions(-) -- ----- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c --+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c --@@ -3304,10 +3304,6 @@ static int brcmf_sdio_download_firmware( -- goto err; -- } -- --- /* Allow full data communication using DPC from now on. */ --- brcmf_sdiod_change_state(bus->sdiodev, BRCMF_SDIOD_DATA); --- bcmerror = 0; --- -- err: -- brcmf_sdio_clkctl(bus, CLK_SDONLY, false); -- sdio_release_host(bus->sdiodev->func[1]); --@@ -4045,6 +4041,9 @@ static void brcmf_sdio_firmware_callback -- } -- -- if (err == 0) { --+ /* Allow full data communication using DPC from now on. */ --+ brcmf_sdiod_change_state(bus->sdiodev, BRCMF_SDIOD_DATA); --+ -- err = brcmf_sdiod_intr_register(sdiodev); -- if (err != 0) -- brcmf_err("intr register failed:%d\n", err); -diff --git a/package/kernel/mac80211/patches/351-0029-brcmfmac-Fix-glob_skb-leak-in-brcmf_sdiod_recv_chain.patch b/package/kernel/mac80211/patches/351-0029-brcmfmac-Fix-glob_skb-leak-in-brcmf_sdiod_recv_chain.patch -deleted file mode 100644 -index ba9a349..0000000 ---- a/package/kernel/mac80211/patches/351-0029-brcmfmac-Fix-glob_skb-leak-in-brcmf_sdiod_recv_chain.patch -+++ /dev/null -@@ -1,32 +0,0 @@ --From 3bdae810721b33061d2e541bd78a70f86ca42af3 Mon Sep 17 00:00:00 2001 --From: Florian Fainelli --Date: Mon, 18 Jul 2016 16:24:34 -0700 --Subject: [PATCH] brcmfmac: Fix glob_skb leak in brcmf_sdiod_recv_chain -- --In case brcmf_sdiod_recv_chain() cannot complete a succeful call to --brcmf_sdiod_buffrw, we would be leaking glom_skb and not free it as we --should, fix this. -- --Reported-by: coverity (CID 1164856) --Fixes: a413e39a38573 ("brcmfmac: fix brcmf_sdcard_recv_chain() for host without sg support") --Signed-off-by: Florian Fainelli --Acked-by: Arend van Spriel --Signed-off-by: Kalle Valo ----- -- drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c | 4 +++- -- 1 file changed, 3 insertions(+), 1 deletion(-) -- ----- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c --+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c --@@ -722,8 +722,10 @@ int brcmf_sdiod_recv_chain(struct brcmf_ -- return -ENOMEM; -- err = brcmf_sdiod_buffrw(sdiodev, SDIO_FUNC_2, false, addr, -- glom_skb); --- if (err) --+ if (err) { --+ brcmu_pkt_buf_free_skb(glom_skb); -- goto done; --+ } -- -- skb_queue_walk(pktq, skb) { -- memcpy(skb->data, glom_skb->data, skb->len); -diff --git a/package/kernel/mac80211/patches/351-0030-net-wireless-broadcom-brcm80211-brcmfmac-usb-don-t-p.patch b/package/kernel/mac80211/patches/351-0030-net-wireless-broadcom-brcm80211-brcmfmac-usb-don-t-p.patch -deleted file mode 100644 -index 540b7f0..0000000 ---- a/package/kernel/mac80211/patches/351-0030-net-wireless-broadcom-brcm80211-brcmfmac-usb-don-t-p.patch -+++ /dev/null -@@ -1,34 +0,0 @@ --From 938f89e50a41c2d56710805fb019ad7618cef84b Mon Sep 17 00:00:00 2001 --From: Wolfram Sang --Date: Thu, 11 Aug 2016 23:05:31 +0200 --Subject: [PATCH] net: wireless: broadcom: brcm80211: brcmfmac: usb: don't -- print error when allocating urb fails -- --kmalloc will print enough information in case of failure. -- --Signed-off-by: Wolfram Sang --Signed-off-by: David S. Miller ----- -- drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c | 8 ++------ -- 1 file changed, 2 insertions(+), 6 deletions(-) -- ----- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c --+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c --@@ -1099,15 +1099,11 @@ struct brcmf_usbdev *brcmf_usb_attach(st -- devinfo->tx_freecount = ntxq; -- -- devinfo->ctl_urb = usb_alloc_urb(0, GFP_ATOMIC); --- if (!devinfo->ctl_urb) { --- brcmf_err("usb_alloc_urb (ctl) failed\n"); --+ if (!devinfo->ctl_urb) -- goto error; --- } -- devinfo->bulk_urb = usb_alloc_urb(0, GFP_ATOMIC); --- if (!devinfo->bulk_urb) { --- brcmf_err("usb_alloc_urb (bulk) failed\n"); --+ if (!devinfo->bulk_urb) -- goto error; --- } -- -- return &devinfo->bus_pub; -- -diff --git a/package/kernel/mac80211/patches/351-0031-brcmfmac-Check-rtnl_lock-is-locked-when-removing-int.patch b/package/kernel/mac80211/patches/351-0031-brcmfmac-Check-rtnl_lock-is-locked-when-removing-int.patch -deleted file mode 100644 -index b98b68a..0000000 ---- a/package/kernel/mac80211/patches/351-0031-brcmfmac-Check-rtnl_lock-is-locked-when-removing-int.patch -+++ /dev/null -@@ -1,111 +0,0 @@ --From 15dacf880e49ce3ecee05eb1a0c6b8e363dbacdc Mon Sep 17 00:00:00 2001 --From: "mhiramat@kernel.org" --Date: Mon, 15 Aug 2016 18:40:57 +0900 --Subject: [PATCH] brcmfmac: Check rtnl_lock is locked when removing interface --MIME-Version: 1.0 --Content-Type: text/plain; charset=UTF-8 --Content-Transfer-Encoding: 8bit -- --Check rtnl_lock is locked in brcmf_p2p_ifp_removed() by passing --rtnl_locked flag. Actually the caller brcmf_del_if() checks whether --the rtnl_lock is locked, but doesn't pass it to brcmf_p2p_ifp_removed(). -- --Without this fix, wpa_supplicant goes softlockup with rtnl_lock --holding (this means all other process using netlink are locked up too) -- --e.g. --[ 4495.876627] INFO: task wpa_supplicant:7307 blocked for more than 10 seconds. --[ 4495.876632] Tainted: G W 4.8.0-rc1+ #8 --[ 4495.876635] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message. --[ 4495.876638] wpa_supplicant D ffff974c647b39a0 0 7307 1 0x00000000 --[ 4495.876644] ffff974c647b39a0 0000000000000000 ffff974c00000000 ffff974c7dc59c58 --[ 4495.876651] ffff974c6b7417c0 ffff974c645017c0 ffff974c647b4000 ffffffff86f16c08 --[ 4495.876657] ffff974c645017c0 0000000000000246 00000000ffffffff ffff974c647b39b8 --[ 4495.876664] Call Trace: --[ 4495.876671] [] schedule+0x3c/0x90 --[ 4495.876676] [] schedule_preempt_disabled+0x15/0x20 --[ 4495.876682] [] mutex_lock_nested+0x176/0x3b0 --[ 4495.876686] [] ? rtnl_lock+0x17/0x20 --[ 4495.876690] [] rtnl_lock+0x17/0x20 --[ 4495.876720] [] brcmf_p2p_ifp_removed+0x4d/0x70 [brcmfmac] --[ 4495.876741] [] brcmf_remove_interface+0x196/0x1b0 [brcmfmac] --[ 4495.876760] [] brcmf_p2p_del_vif+0x111/0x220 [brcmfmac] --[ 4495.876777] [] brcmf_cfg80211_del_iface+0x21b/0x270 [brcmfmac] --[ 4495.876820] [] nl80211_del_interface+0xfe/0x3a0 [cfg80211] --[ 4495.876825] [] genl_family_rcv_msg+0x1b5/0x370 --[ 4495.876832] [] ? trace_hardirqs_on+0xd/0x10 --[ 4495.876836] [] genl_rcv_msg+0x7d/0xb0 --[ 4495.876839] [] ? genl_family_rcv_msg+0x370/0x370 --[ 4495.876846] [] netlink_rcv_skb+0x97/0xb0 --[ 4495.876849] [] genl_rcv+0x28/0x40 --[ 4495.876854] [] netlink_unicast+0x1d3/0x2f0 --[ 4495.876860] [] ? netlink_unicast+0x14b/0x2f0 --[ 4495.876866] [] netlink_sendmsg+0x2eb/0x3a0 --[ 4495.876870] [] sock_sendmsg+0x38/0x50 --[ 4495.876874] [] ___sys_sendmsg+0x27f/0x290 --[ 4495.876882] [] ? mntput_no_expire+0x5/0x3f0 --[ 4495.876888] [] ? mntput_no_expire+0x8e/0x3f0 --[ 4495.876894] [] ? mntput_no_expire+0x5/0x3f0 --[ 4495.876899] [] ? mntput+0x24/0x40 --[ 4495.876904] [] ? __fput+0x190/0x200 --[ 4495.876909] [] __sys_sendmsg+0x45/0x80 --[ 4495.876914] [] SyS_sendmsg+0x12/0x20 --[ 4495.876918] [] entry_SYSCALL_64_fastpath+0x23/0xc1 --[ 4495.876924] [] ? trace_hardirqs_off_caller+0x1f/0xc0 -- --Signed-off-by: Masami Hiramatsu --Acked-by: Rafał Miłecki --Signed-off-by: Kalle Valo ----- -- drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c | 2 +- -- drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c | 8 +++++--- -- drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.h | 2 +- -- 3 files changed, 7 insertions(+), 5 deletions(-) -- ----- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c --+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c --@@ -743,7 +743,7 @@ static void brcmf_del_if(struct brcmf_pu -- * serious troublesome side effects. The p2p module will clean -- * up the ifp if needed. -- */ --- brcmf_p2p_ifp_removed(ifp); --+ brcmf_p2p_ifp_removed(ifp, rtnl_locked); -- kfree(ifp); -- } -- } ----- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c --+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c --@@ -2299,7 +2299,7 @@ int brcmf_p2p_del_vif(struct wiphy *wiph -- return err; -- } -- ---void brcmf_p2p_ifp_removed(struct brcmf_if *ifp) --+void brcmf_p2p_ifp_removed(struct brcmf_if *ifp, bool rtnl_locked) -- { -- struct brcmf_cfg80211_info *cfg; -- struct brcmf_cfg80211_vif *vif; --@@ -2308,9 +2308,11 @@ void brcmf_p2p_ifp_removed(struct brcmf_ -- vif = ifp->vif; -- cfg = wdev_to_cfg(&vif->wdev); -- cfg->p2p.bss_idx[P2PAPI_BSSCFG_DEVICE].vif = NULL; --- rtnl_lock(); --+ if (!rtnl_locked) --+ rtnl_lock(); -- cfg80211_unregister_wdev(&vif->wdev); --- rtnl_unlock(); --+ if (!rtnl_locked) --+ rtnl_unlock(); -- brcmf_free_vif(vif); -- } -- ----- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.h --+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.h --@@ -155,7 +155,7 @@ struct wireless_dev *brcmf_p2p_add_vif(s -- int brcmf_p2p_del_vif(struct wiphy *wiphy, struct wireless_dev *wdev); -- int brcmf_p2p_ifchange(struct brcmf_cfg80211_info *cfg, -- enum brcmf_fil_p2p_if_types if_type); ---void brcmf_p2p_ifp_removed(struct brcmf_if *ifp); --+void brcmf_p2p_ifp_removed(struct brcmf_if *ifp, bool rtnl_locked); -- int brcmf_p2p_start_device(struct wiphy *wiphy, struct wireless_dev *wdev); -- void brcmf_p2p_stop_device(struct wiphy *wiphy, struct wireless_dev *wdev); -- int brcmf_p2p_scan_prep(struct wiphy *wiphy, -diff --git a/package/kernel/mac80211/patches/351-0032-brcmfmac-Change-vif_event_lock-to-spinlock.patch b/package/kernel/mac80211/patches/351-0032-brcmfmac-Change-vif_event_lock-to-spinlock.patch -deleted file mode 100644 -index 30ca258..0000000 ---- a/package/kernel/mac80211/patches/351-0032-brcmfmac-Change-vif_event_lock-to-spinlock.patch -+++ /dev/null -@@ -1,175 +0,0 @@ --From b64abcb7dae6060c67ab0e548da3ef923c49641d Mon Sep 17 00:00:00 2001 --From: "mhiramat@kernel.org" --Date: Mon, 15 Aug 2016 18:41:12 +0900 --Subject: [PATCH] brcmfmac: Change vif_event_lock to spinlock -- --Change vif_event_lock to spinlock from mutex, since this lock is --used in wait_event_timeout() via vif_event_equals(). This caused --a warning report as below. -- --As far as I can see, this lock protects regions where updating --structure members, not function calls. Also, since those --regions are not called from interrupt handlers (of course, it --was a mutex), spin_lock is used instead of spin_lock_irqsave. -- --[ 186.678550] ------------[ cut here ]------------ --[ 186.678556] WARNING: CPU: 2 PID: 7140 at /home/mhiramat/ksrc/linux/kernel/sched/core.c:7545 __might_sleep+0x7c/0x80 --[ 186.678560] do not call blocking ops when !TASK_RUNNING; state=2 set at [] prepare_to_wait_event+0x60/0x100 --[ 186.678560] Modules linked in: brcmfmac xt_CHECKSUM rfcomm ipt_MASQUERADE nf_nat_masquerade_ipv4 xt_addrtype br_netfilter xt_tcpudp ip6t_rpfilter ip6t_REJECT nf_reject_ipv6 ipt_REJECT nf_reject_ipv4 xt_conntrack ip_set nfnetlink ebtable_nat ebtable_broute bridge stp llc ebtable_filter ebtables ip6table_raw ip6table_security ip6table_nat nf_conntrack_ipv6 nf_defrag_ipv6 nf_nat_ipv6 ip6table_mangle ip6table_filter ip6_tables iptable_raw iptable_security iptable_nat nf_conntrack_ipv4 nf_defrag_ipv4 nf_nat_ipv4 nf_nat nf_conntrack iptable_mangle iptable_filter ip_tables x_tables bnep nls_iso8859_1 i2c_designware_platform i2c_designware_core snd_hda_codec_hdmi snd_hda_codec_realtek dcdbas snd_hda_codec_generic snd_hda_intel snd_hda_codec intel_rapl snd_hda_core x86_pkg_temp_thermal intel_powerclamp coretemp --[ 186.678594] snd_pcm crct10dif_pclmul crc32_pclmul aesni_intel aes_x86_64 joydev glue_helper snd_hwdep lrw gf128mul uvcvideo ablk_helper snd_seq_midi cryptd snd_seq_midi_event snd_rawmidi videobuf2_vmalloc videobuf2_memops snd_seq input_leds videobuf2_v4l2 cfg80211 videobuf2_core snd_timer videodev serio_raw btusb snd_seq_device media btrtl rtsx_pci_ms snd mei_me memstick hid_multitouch mei soundcore brcmutil idma64 virt_dma intel_lpss_pci processor_thermal_device intel_soc_dts_iosf hci_uart btbcm btqca btintel bluetooth int3403_thermal dell_smo8800 intel_lpss_acpi intel_lpss int3402_thermal int340x_thermal_zone intel_hid mac_hid int3400_thermal shpchp sparse_keymap acpi_pad acpi_thermal_rel acpi_als kfifo_buf industrialio kvm_intel kvm irqbypass parport_pc ppdev lp parport autofs4 btrfs xor raid6_pq --[ 186.678631] usbhid nouveau ttm i915 rtsx_pci_sdmmc mxm_wmi i2c_algo_bit drm_kms_helper syscopyarea sysfillrect sysimgblt fb_sys_fops psmouse drm ahci rtsx_pci nvme nvme_core libahci i2c_hid hid pinctrl_sunrisepoint video wmi pinctrl_intel fjes [last unloaded: brcmfmac] --[ 186.678646] CPU: 2 PID: 7140 Comm: wpa_supplicant Not tainted 4.8.0-rc1+ #8 --[ 186.678647] Hardware name: Dell Inc. XPS 15 9550/0N7TVV, BIOS 01.02.00 04/07/2016 --[ 186.678648] 0000000000000000 ffff9d8c64b5b900 ffffffff98442f23 ffff9d8c64b5b950 --[ 186.678651] 0000000000000000 ffff9d8c64b5b940 ffffffff9808b22b 00001d790000000d --[ 186.678653] ffffffff98c75e78 000000000000026c 0000000000000000 ffff9d8c2706d058 --[ 186.678655] Call Trace: --[ 186.678659] [] dump_stack+0x85/0xc2 --[ 186.678666] [] __warn+0xcb/0xf0 --[ 186.678668] [] warn_slowpath_fmt+0x4f/0x60 --[ 186.678671] [] ? prepare_to_wait_event+0x60/0x100 --[ 186.678672] [] ? prepare_to_wait_event+0x60/0x100 --[ 186.678674] [] __might_sleep+0x7c/0x80 --[ 186.678680] [] mutex_lock_nested+0x33/0x3b0 --[ 186.678682] [] ? trace_hardirqs_on+0xd/0x10 --[ 186.678689] [] brcmf_cfg80211_wait_vif_event+0xcd/0x130 [brcmfmac] --[ 186.678691] [] ? wake_atomic_t_function+0x60/0x60 --[ 186.678697] [] brcmf_p2p_del_vif+0xf9/0x220 [brcmfmac] --[ 186.678702] [] brcmf_cfg80211_del_iface+0x21b/0x270 [brcmfmac] --[ 186.678716] [] nl80211_del_interface+0xfe/0x3a0 [cfg80211] --[ 186.678718] [] genl_family_rcv_msg+0x1b5/0x370 --[ 186.678720] [] ? trace_hardirqs_on+0xd/0x10 --[ 186.678721] [] genl_rcv_msg+0x7d/0xb0 --[ 186.678722] [] ? genl_family_rcv_msg+0x370/0x370 --[ 186.678724] [] netlink_rcv_skb+0x97/0xb0 --[ 186.678726] [] genl_rcv+0x28/0x40 --[ 186.678727] [] netlink_unicast+0x1d3/0x2f0 --[ 186.678729] [] ? netlink_unicast+0x14b/0x2f0 --[ 186.678731] [] netlink_sendmsg+0x2eb/0x3a0 --[ 186.678733] [] sock_sendmsg+0x38/0x50 --[ 186.678734] [] ___sys_sendmsg+0x27f/0x290 --[ 186.678737] [] ? mntput_no_expire+0x5/0x3f0 --[ 186.678739] [] ? mntput_no_expire+0x8e/0x3f0 --[ 186.678741] [] ? mntput_no_expire+0x5/0x3f0 --[ 186.678743] [] ? mntput+0x24/0x40 --[ 186.678744] [] ? __fput+0x190/0x200 --[ 186.678746] [] __sys_sendmsg+0x45/0x80 --[ 186.678748] [] SyS_sendmsg+0x12/0x20 --[ 186.678749] [] entry_SYSCALL_64_fastpath+0x23/0xc1 --[ 186.678751] [] ? trace_hardirqs_off_caller+0x1f/0xc0 --[ 186.678752] ---[ end trace e224d66c5d8408b5 ]--- -- --Signed-off-by: Masami Hiramatsu --Acked-by: Arend van Spriel --Signed-off-by: Kalle Valo ----- -- .../broadcom/brcm80211/brcmfmac/cfg80211.c | 26 +++++++++++----------- -- .../broadcom/brcm80211/brcmfmac/cfg80211.h | 2 +- -- 2 files changed, 14 insertions(+), 14 deletions(-) -- ----- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c --+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c --@@ -5555,7 +5555,7 @@ static s32 brcmf_notify_vif_event(struct -- ifevent->action, ifevent->flags, ifevent->ifidx, -- ifevent->bsscfgidx); -- --- mutex_lock(&event->vif_event_lock); --+ spin_lock(&event->vif_event_lock); -- event->action = ifevent->action; -- vif = event->vif; -- --@@ -5563,7 +5563,7 @@ static s32 brcmf_notify_vif_event(struct -- case BRCMF_E_IF_ADD: -- /* waiting process may have timed out */ -- if (!cfg->vif_event.vif) { --- mutex_unlock(&event->vif_event_lock); --+ spin_unlock(&event->vif_event_lock); -- return -EBADF; -- } -- --@@ -5574,24 +5574,24 @@ static s32 brcmf_notify_vif_event(struct -- ifp->ndev->ieee80211_ptr = &vif->wdev; -- SET_NETDEV_DEV(ifp->ndev, wiphy_dev(cfg->wiphy)); -- } --- mutex_unlock(&event->vif_event_lock); --+ spin_unlock(&event->vif_event_lock); -- wake_up(&event->vif_wq); -- return 0; -- -- case BRCMF_E_IF_DEL: --- mutex_unlock(&event->vif_event_lock); --+ spin_unlock(&event->vif_event_lock); -- /* event may not be upon user request */ -- if (brcmf_cfg80211_vif_event_armed(cfg)) -- wake_up(&event->vif_wq); -- return 0; -- -- case BRCMF_E_IF_CHANGE: --- mutex_unlock(&event->vif_event_lock); --+ spin_unlock(&event->vif_event_lock); -- wake_up(&event->vif_wq); -- return 0; -- -- default: --- mutex_unlock(&event->vif_event_lock); --+ spin_unlock(&event->vif_event_lock); -- break; -- } -- return -EINVAL; --@@ -5712,7 +5712,7 @@ static void wl_deinit_priv(struct brcmf_ -- static void init_vif_event(struct brcmf_cfg80211_vif_event *event) -- { -- init_waitqueue_head(&event->vif_wq); --- mutex_init(&event->vif_event_lock); --+ spin_lock_init(&event->vif_event_lock); -- } -- -- static s32 brcmf_dongle_roam(struct brcmf_if *ifp) --@@ -6607,9 +6607,9 @@ static inline bool vif_event_equals(stru -- { -- u8 evt_action; -- --- mutex_lock(&event->vif_event_lock); --+ spin_lock(&event->vif_event_lock); -- evt_action = event->action; --- mutex_unlock(&event->vif_event_lock); --+ spin_unlock(&event->vif_event_lock); -- return evt_action == action; -- } -- --@@ -6618,10 +6618,10 @@ void brcmf_cfg80211_arm_vif_event(struct -- { -- struct brcmf_cfg80211_vif_event *event = &cfg->vif_event; -- --- mutex_lock(&event->vif_event_lock); --+ spin_lock(&event->vif_event_lock); -- event->vif = vif; -- event->action = 0; --- mutex_unlock(&event->vif_event_lock); --+ spin_unlock(&event->vif_event_lock); -- } -- -- bool brcmf_cfg80211_vif_event_armed(struct brcmf_cfg80211_info *cfg) --@@ -6629,9 +6629,9 @@ bool brcmf_cfg80211_vif_event_armed(stru -- struct brcmf_cfg80211_vif_event *event = &cfg->vif_event; -- bool armed; -- --- mutex_lock(&event->vif_event_lock); --+ spin_lock(&event->vif_event_lock); -- armed = event->vif != NULL; --- mutex_unlock(&event->vif_event_lock); --+ spin_unlock(&event->vif_event_lock); -- -- return armed; -- } ----- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h --+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h --@@ -227,7 +227,7 @@ struct escan_info { -- */ -- struct brcmf_cfg80211_vif_event { -- wait_queue_head_t vif_wq; --- struct mutex vif_event_lock; --+ spinlock_t vif_event_lock; -- u8 action; -- struct brcmf_cfg80211_vif *vif; -- }; -diff --git a/package/kernel/mac80211/patches/351-0033-brcmfmac-add-missing-header-dependencies.patch b/package/kernel/mac80211/patches/351-0033-brcmfmac-add-missing-header-dependencies.patch -deleted file mode 100644 -index 1a7947b..0000000 ---- a/package/kernel/mac80211/patches/351-0033-brcmfmac-add-missing-header-dependencies.patch -+++ /dev/null -@@ -1,29 +0,0 @@ --From 8af92af3f2d55db143417a5d401696f4b642009a Mon Sep 17 00:00:00 2001 --From: Baoyou Xie --Date: Mon, 29 Aug 2016 20:39:35 +0800 --Subject: [PATCH] brcmfmac: add missing header dependencies -- --We get 1 warning when building kernel with W=1: -- --drivers/net/wireless/broadcom/brcm80211/brcmfmac/tracepoint.c:23:6: warning: no previous prototype for '__brcmf_err' [-Wmissing-prototypes] -- --In fact, this function is declared in brcmfmac/debug.h, so this patch --adds missing header dependencies. -- --Signed-off-by: Baoyou Xie --Acked-by: Arnd Bergmann --Signed-off-by: Kalle Valo ----- -- drivers/net/wireless/broadcom/brcm80211/brcmfmac/tracepoint.c | 1 + -- 1 file changed, 1 insertion(+) -- ----- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/tracepoint.c --+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/tracepoint.c --@@ -19,6 +19,7 @@ -- #ifndef __CHECKER__ -- #define CREATE_TRACE_POINTS -- #include "tracepoint.h" --+#include "debug.h" -- -- void __brcmf_err(const char *func, const char *fmt, ...) -- { -diff --git a/package/kernel/mac80211/patches/351-0034-brcmfmac-Add-USB-ID-for-Cisco-Linksys-AE1200.patch b/package/kernel/mac80211/patches/351-0034-brcmfmac-Add-USB-ID-for-Cisco-Linksys-AE1200.patch -deleted file mode 100644 -index 24cd92a..0000000 ---- a/package/kernel/mac80211/patches/351-0034-brcmfmac-Add-USB-ID-for-Cisco-Linksys-AE1200.patch -+++ /dev/null -@@ -1,51 +0,0 @@ --From bccf3ffc8c6d8e0251a15541bb4d12b423c4f729 Mon Sep 17 00:00:00 2001 --From: Ismael Luceno --Date: Mon, 22 Aug 2016 19:40:07 -0300 --Subject: [PATCH] brcmfmac: Add USB ID for Cisco Linksys AE1200 -- --The AE1200 comes with different revisions of the BCM43235 chipset, --but all have the same USB ID. Only revision 3 can be supported. -- --Signed-off-by: Ismael Luceno --Signed-off-by: Kalle Valo ----- -- drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c | 4 ++++ -- drivers/net/wireless/broadcom/brcm80211/include/brcm_hw_ids.h | 2 ++ -- 2 files changed, 6 insertions(+) -- ----- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c --+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c --@@ -1456,11 +1456,15 @@ static int brcmf_usb_reset_resume(struct -- #define BRCMF_USB_DEVICE(dev_id) \ -- { USB_DEVICE(BRCM_USB_VENDOR_ID_BROADCOM, dev_id) } -- --+#define LINKSYS_USB_DEVICE(dev_id) \ --+ { USB_DEVICE(BRCM_USB_VENDOR_ID_LINKSYS, dev_id) } --+ -- static struct usb_device_id brcmf_usb_devid_table[] = { -- BRCMF_USB_DEVICE(BRCM_USB_43143_DEVICE_ID), -- BRCMF_USB_DEVICE(BRCM_USB_43236_DEVICE_ID), -- BRCMF_USB_DEVICE(BRCM_USB_43242_DEVICE_ID), -- BRCMF_USB_DEVICE(BRCM_USB_43569_DEVICE_ID), --+ LINKSYS_USB_DEVICE(BRCM_USB_43235_LINKSYS_DEVICE_ID), -- { USB_DEVICE(BRCM_USB_VENDOR_ID_LG, BRCM_USB_43242_LG_DEVICE_ID) }, -- /* special entry for device with firmware loaded and running */ -- BRCMF_USB_DEVICE(BRCM_USB_BCMFW_DEVICE_ID), ----- a/drivers/net/wireless/broadcom/brcm80211/include/brcm_hw_ids.h --+++ b/drivers/net/wireless/broadcom/brcm80211/include/brcm_hw_ids.h --@@ -22,6 +22,7 @@ -- -- #define BRCM_USB_VENDOR_ID_BROADCOM 0x0a5c -- #define BRCM_USB_VENDOR_ID_LG 0x043e --+#define BRCM_USB_VENDOR_ID_LINKSYS 0x13b1 -- #define BRCM_PCIE_VENDOR_ID_BROADCOM PCI_VENDOR_ID_BROADCOM -- -- /* Chipcommon Core Chip IDs */ --@@ -56,6 +57,7 @@ -- -- /* USB Device IDs */ -- #define BRCM_USB_43143_DEVICE_ID 0xbd1e --+#define BRCM_USB_43235_LINKSYS_DEVICE_ID 0x0039 -- #define BRCM_USB_43236_DEVICE_ID 0xbd17 -- #define BRCM_USB_43242_DEVICE_ID 0xbd1f -- #define BRCM_USB_43242_LG_DEVICE_ID 0x3101 -diff --git a/package/kernel/mac80211/patches/351-0035-brcmfmac-fix-pmksa-bssid-usage.patch b/package/kernel/mac80211/patches/351-0035-brcmfmac-fix-pmksa-bssid-usage.patch -deleted file mode 100644 -index b58a266..0000000 ---- a/package/kernel/mac80211/patches/351-0035-brcmfmac-fix-pmksa-bssid-usage.patch -+++ /dev/null -@@ -1,51 +0,0 @@ --From 7703773ef1d85b40433902a8da20167331597e4a Mon Sep 17 00:00:00 2001 --From: Nicolas Iooss --Date: Tue, 23 Aug 2016 11:37:17 +0200 --Subject: [PATCH] brcmfmac: fix pmksa->bssid usage -- --The struct cfg80211_pmksa defines its bssid field as: -- -- const u8 *bssid; -- --contrary to struct brcmf_pmksa, which uses: -- -- u8 bssid[ETH_ALEN]; -- --Therefore in brcmf_cfg80211_del_pmksa(), &pmksa->bssid takes the address --of this field (of type u8**), not the one of its content (which would be --u8*). Remove the & operator to make brcmf_dbg("%pM") and memcmp() --behave as expected. -- --This bug have been found using a custom static checker (which checks the --usage of %p... attributes at build time). It has been introduced in --commit 6c404f34f2bd ("brcmfmac: Cleanup pmksa cache handling code"), --which replaced pmksa->bssid by &pmksa->bssid while refactoring the code, --without modifying struct cfg80211_pmksa definition. -- --Replace &pmk[i].bssid with pmk[i].bssid too to make the code clearer, --this change does not affect the semantic. -- --Fixes: 6c404f34f2bd ("brcmfmac: Cleanup pmksa cache handling code") --Cc: stable@vger.kernel.org --Signed-off-by: Nicolas Iooss --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 --@@ -3804,11 +3804,11 @@ brcmf_cfg80211_del_pmksa(struct wiphy *w -- if (!check_vif_up(ifp->vif)) -- return -EIO; -- --- brcmf_dbg(CONN, "del_pmksa - PMK bssid = %pM\n", &pmksa->bssid); --+ brcmf_dbg(CONN, "del_pmksa - PMK bssid = %pM\n", pmksa->bssid); -- -- npmk = le32_to_cpu(cfg->pmk_list.npmk); -- for (i = 0; i < npmk; i++) --- if (!memcmp(&pmksa->bssid, &pmk[i].bssid, ETH_ALEN)) --+ if (!memcmp(pmksa->bssid, pmk[i].bssid, ETH_ALEN)) -- break; -- -- if ((npmk > 0) && (i < npmk)) { -diff --git a/package/kernel/mac80211/patches/351-0036-brcmfmac-avoid-potential-stack-overflow-in-brcmf_cfg.patch b/package/kernel/mac80211/patches/351-0036-brcmfmac-avoid-potential-stack-overflow-in-brcmf_cfg.patch -deleted file mode 100644 -index 760b6da..0000000 ---- a/package/kernel/mac80211/patches/351-0036-brcmfmac-avoid-potential-stack-overflow-in-brcmf_cfg.patch -+++ /dev/null -@@ -1,34 +0,0 @@ --From ded89912156b1a47d940a0c954c43afbabd0c42c Mon Sep 17 00:00:00 2001 --From: Arend Van Spriel --Date: Mon, 5 Sep 2016 10:45:47 +0100 --Subject: [PATCH] brcmfmac: avoid potential stack overflow in -- brcmf_cfg80211_start_ap() -- --User-space can choose to omit NL80211_ATTR_SSID and only provide raw --IE TLV data. When doing so it can provide SSID IE with length exceeding --the allowed size. The driver further processes this IE copying it --into a local variable without checking the length. Hence stack can be --corrupted and used as exploit. -- --Cc: stable@vger.kernel.org # v4.7 --Reported-by: Daxing Guo --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, 1 insertion(+), 1 deletion(-) -- ----- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c --+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c --@@ -4447,7 +4447,7 @@ brcmf_cfg80211_start_ap(struct wiphy *wi -- (u8 *)&settings->beacon.head[ie_offset], -- settings->beacon.head_len - ie_offset, -- WLAN_EID_SSID); --- if (!ssid_ie) --+ if (!ssid_ie || ssid_ie->len > IEEE80211_MAX_SSID_LEN) -- return -EINVAL; -- -- memcpy(ssid_le.SSID, ssid_ie->data, ssid_ie->len); -diff --git a/package/kernel/mac80211/patches/351-0037-brcmfmac-add-support-for-bcm4339-chip-with-modalias-.patch b/package/kernel/mac80211/patches/351-0037-brcmfmac-add-support-for-bcm4339-chip-with-modalias-.patch -deleted file mode 100644 -index 1285b30..0000000 ---- a/package/kernel/mac80211/patches/351-0037-brcmfmac-add-support-for-bcm4339-chip-with-modalias-.patch -+++ /dev/null -@@ -1,55 +0,0 @@ --From 634faf3686900ccdee87b77e2c56df8b2159912b Mon Sep 17 00:00:00 2001 --From: Arend Van Spriel --Date: Mon, 5 Sep 2016 11:42:12 +0100 --Subject: [PATCH] brcmfmac: add support for bcm4339 chip with modalias -- sdio:c00v02D0d4339 -- --The driver already supports the bcm4339 chipset but only for the variant --that shares the same modalias as the bcm4335, ie. sdio:c00v02D0d4335. --It turns out that there are also bcm4339 devices out there that have a --more distiguishable modalias sdio:c00v02D0d4339. -- --Reported-by: Steve deRosier --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/bcmsdh.c | 1 + -- drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c | 3 ++- -- include/linux/mmc/sdio_ids.h | 1 + -- 3 files changed, 4 insertions(+), 1 deletion(-) -- ----- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c --+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c --@@ -1097,6 +1097,7 @@ static const struct sdio_device_id brcmf -- BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_43341), -- BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_43362), -- BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_4335_4339), --+ BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_4339), -- BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_43430), -- BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_4345), -- BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_4354), ----- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c --+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c --@@ -3756,7 +3756,8 @@ static u32 brcmf_sdio_buscore_read32(voi -- u32 val, rev; -- -- val = brcmf_sdiod_regrl(sdiodev, addr, NULL); --- if (sdiodev->func[0]->device == SDIO_DEVICE_ID_BROADCOM_4335_4339 && --+ if ((sdiodev->func[0]->device == SDIO_DEVICE_ID_BROADCOM_4335_4339 || --+ sdiodev->func[0]->device == SDIO_DEVICE_ID_BROADCOM_4339) && -- addr == CORE_CC_REG(SI_ENUM_BASE, chipid)) { -- rev = (val & CID_REV_MASK) >> CID_REV_SHIFT; -- if (rev >= 2) { ----- a/include/linux/mmc/sdio_ids.h --+++ b/include/linux/mmc/sdio_ids.h --@@ -32,6 +32,7 @@ -- #define SDIO_DEVICE_ID_BROADCOM_43340 0xa94c -- #define SDIO_DEVICE_ID_BROADCOM_43341 0xa94d -- #define SDIO_DEVICE_ID_BROADCOM_4335_4339 0x4335 --+#define SDIO_DEVICE_ID_BROADCOM_4339 0x4339 -- #define SDIO_DEVICE_ID_BROADCOM_43362 0xa962 -- #define SDIO_DEVICE_ID_BROADCOM_43430 0xa9a6 -- #define SDIO_DEVICE_ID_BROADCOM_4345 0x4345 -diff --git a/package/kernel/mac80211/patches/351-0038-brcmfmac-sdio-shorten-retry-loop-in-brcmf_sdio_kso_c.patch b/package/kernel/mac80211/patches/351-0038-brcmfmac-sdio-shorten-retry-loop-in-brcmf_sdio_kso_c.patch -deleted file mode 100644 -index 1d5667e..0000000 ---- a/package/kernel/mac80211/patches/351-0038-brcmfmac-sdio-shorten-retry-loop-in-brcmf_sdio_kso_c.patch -+++ /dev/null -@@ -1,56 +0,0 @@ --From 5251b6be8bb5c5675bdf12347c7b83937a5c91e5 Mon Sep 17 00:00:00 2001 --From: Arend Van Spriel --Date: Mon, 5 Sep 2016 11:42:13 +0100 --Subject: [PATCH] brcmfmac: sdio: shorten retry loop in -- brcmf_sdio_kso_control() -- --In brcmf_sdio_kso_control() there is a retry loop as hardware may take --time to settle. However, when the call to brcmf_sdiod_regrb() returns --an error it is due to SDIO access failure and it makes no sense to wait --for hardware to settle. This patch aborts the loop after a number of --subsequent access errors. -- --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/sdio.c | 11 +++++++++-- -- 1 file changed, 9 insertions(+), 2 deletions(-) -- ----- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c --+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c --@@ -313,6 +313,7 @@ struct rte_console { -- -- #define KSO_WAIT_US 50 -- #define MAX_KSO_ATTEMPTS (PMU_MAX_TRANSITION_DLY/KSO_WAIT_US) --+#define BRCMF_SDIO_MAX_ACCESS_ERRORS 5 -- -- /* -- * Conversion of 802.1D priority to precedence level --@@ -675,6 +676,7 @@ brcmf_sdio_kso_control(struct brcmf_sdio -- { -- u8 wr_val = 0, rd_val, cmp_val, bmask; -- int err = 0; --+ int err_cnt = 0; -- int try_cnt = 0; -- -- brcmf_dbg(TRACE, "Enter: on=%d\n", on); --@@ -710,9 +712,14 @@ brcmf_sdio_kso_control(struct brcmf_sdio -- */ -- rd_val = brcmf_sdiod_regrb(bus->sdiodev, SBSDIO_FUNC1_SLEEPCSR, -- &err); --- if (((rd_val & bmask) == cmp_val) && !err) --+ if (!err) { --+ if ((rd_val & bmask) == cmp_val) --+ break; --+ err_cnt = 0; --+ } --+ /* bail out upon subsequent access errors */ --+ if (err && (err_cnt++ > BRCMF_SDIO_MAX_ACCESS_ERRORS)) -- break; --- -- udelay(KSO_WAIT_US); -- brcmf_sdiod_regwb(bus->sdiodev, SBSDIO_FUNC1_SLEEPCSR, -- wr_val, &err); -diff --git a/package/kernel/mac80211/patches/351-0039-brcmfmac-ignore-11d-configuration-errors.patch b/package/kernel/mac80211/patches/351-0039-brcmfmac-ignore-11d-configuration-errors.patch -deleted file mode 100644 -index 1620e00..0000000 ---- a/package/kernel/mac80211/patches/351-0039-brcmfmac-ignore-11d-configuration-errors.patch -+++ /dev/null -@@ -1,84 +0,0 @@ --From b3589dfe02123a0d0ea82076a9f8ef84a46852c0 Mon Sep 17 00:00:00 2001 --From: Hante Meuleman --Date: Mon, 19 Sep 2016 12:09:51 +0100 --Subject: [PATCH] brcmfmac: ignore 11d configuration errors -- --802.11d is not always supported by firmware anymore. Currently the --AP configuration of 11d will cause an abort if the ioctl set is --failing. This behavior is not correct and the error should be --ignored. -- --Reviewed-by: Arend Van Spriel --Reviewed-by: Franky Lin --Reviewed-by: Pieter-Paul Giesberts --Signed-off-by: Hante Meuleman --Signed-off-by: Arend van Spriel --Signed-off-by: Kalle Valo ----- -- .../broadcom/brcm80211/brcmfmac/cfg80211.c | 27 ++++++++++++---------- -- 1 file changed, 15 insertions(+), 12 deletions(-) -- ----- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c --+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c --@@ -4422,6 +4422,7 @@ brcmf_cfg80211_start_ap(struct wiphy *wi -- u16 chanspec = chandef_to_chanspec(&cfg->d11inf, &settings->chandef); -- bool mbss; -- int is_11d; --+ bool supports_11d; -- -- brcmf_dbg(TRACE, "ctrlchn=%d, center=%d, bw=%d, beacon_interval=%d, dtim_period=%d,\n", -- settings->chandef.chan->hw_value, --@@ -4434,11 +4435,16 @@ brcmf_cfg80211_start_ap(struct wiphy *wi -- mbss = ifp->vif->mbss; -- -- /* store current 11d setting */ --- brcmf_fil_cmd_int_get(ifp, BRCMF_C_GET_REGULATORY, &ifp->vif->is_11d); --- country_ie = brcmf_parse_tlvs((u8 *)settings->beacon.tail, --- settings->beacon.tail_len, --- WLAN_EID_COUNTRY); --- is_11d = country_ie ? 1 : 0; --+ if (brcmf_fil_cmd_int_get(ifp, BRCMF_C_GET_REGULATORY, --+ &ifp->vif->is_11d)) { --+ supports_11d = false; --+ } else { --+ country_ie = brcmf_parse_tlvs((u8 *)settings->beacon.tail, --+ settings->beacon.tail_len, --+ WLAN_EID_COUNTRY); --+ is_11d = country_ie ? 1 : 0; --+ supports_11d = true; --+ } -- -- memset(&ssid_le, 0, sizeof(ssid_le)); -- if (settings->ssid == NULL || settings->ssid_len == 0) { --@@ -4497,7 +4503,7 @@ brcmf_cfg80211_start_ap(struct wiphy *wi -- -- /* Parameters shared by all radio interfaces */ -- if (!mbss) { --- if (is_11d != ifp->vif->is_11d) { --+ if ((supports_11d) && (is_11d != ifp->vif->is_11d)) { -- err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_REGULATORY, -- is_11d); -- if (err < 0) { --@@ -4539,7 +4545,7 @@ brcmf_cfg80211_start_ap(struct wiphy *wi -- brcmf_err("SET INFRA error %d\n", err); -- goto exit; -- } --- } else if (WARN_ON(is_11d != ifp->vif->is_11d)) { --+ } else if (WARN_ON(supports_11d && (is_11d != ifp->vif->is_11d))) { -- /* Multiple-BSS should use same 11d configuration */ -- err = -EINVAL; -- goto exit; --@@ -4673,11 +4679,8 @@ static int brcmf_cfg80211_stop_ap(struct -- brcmf_err("setting INFRA mode failed %d\n", err); -- if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MBSS)) -- brcmf_fil_iovar_int_set(ifp, "mbss", 0); --- err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_REGULATORY, --- ifp->vif->is_11d); --- if (err < 0) --- brcmf_err("restoring REGULATORY setting failed %d\n", --- err); --+ brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_REGULATORY, --+ ifp->vif->is_11d); -- /* Bring device back up so it can be used again */ -- err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_UP, 1); -- if (err < 0) -diff --git a/package/kernel/mac80211/patches/351-0040-brcmfmac-rework-pointer-trickery-in-brcmf_proto_bcdc.patch b/package/kernel/mac80211/patches/351-0040-brcmfmac-rework-pointer-trickery-in-brcmf_proto_bcdc.patch -deleted file mode 100644 -index 9461164..0000000 ---- a/package/kernel/mac80211/patches/351-0040-brcmfmac-rework-pointer-trickery-in-brcmf_proto_bcdc.patch -+++ /dev/null -@@ -1,32 +0,0 @@ --From 704d1c6b56f4ee2ad6a5f012a72a278d17c1a223 Mon Sep 17 00:00:00 2001 --From: Arend Van Spriel --Date: Mon, 19 Sep 2016 12:09:52 +0100 --Subject: [PATCH] brcmfmac: rework pointer trickery in -- brcmf_proto_bcdc_query_dcmd() -- --The variable info is assigned to point to bcdc->msg[1], which is the --same as pointing to bcdc->buf. As that is what we want to access --make it clear by fixing the assignment. This also avoid out-of-bounds --errors from static analyzers are bcdc->msg[1] is not in the structure --definition. -- --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/bcdc.c | 2 +- -- 1 file changed, 1 insertion(+), 1 deletion(-) -- ----- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcdc.c --+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcdc.c --@@ -194,7 +194,7 @@ retry: -- } -- -- /* Check info buffer */ --- info = (void *)&msg[1]; --+ info = (void *)&bcdc->buf[0]; -- -- /* Copy info buffer */ -- if (buf) { -diff --git a/package/kernel/mac80211/patches/351-0041-brcmfmac-fix-memory-leak-in-brcmf_flowring_add_tdls_.patch b/package/kernel/mac80211/patches/351-0041-brcmfmac-fix-memory-leak-in-brcmf_flowring_add_tdls_.patch -deleted file mode 100644 -index 2ececdf..0000000 ---- a/package/kernel/mac80211/patches/351-0041-brcmfmac-fix-memory-leak-in-brcmf_flowring_add_tdls_.patch -+++ /dev/null -@@ -1,39 +0,0 @@ --From bc981641360183990de59da17f9f560f9150b801 Mon Sep 17 00:00:00 2001 --From: Arend Van Spriel --Date: Mon, 19 Sep 2016 12:09:53 +0100 --Subject: [PATCH] brcmfmac: fix memory leak in brcmf_flowring_add_tdls_peer() -- --In the error paths in brcmf_flowring_add_tdls_peer() the allocated --resource should be freed. -- --Reviewed-by: Hante Meuleman --Reviewed-by: Pieter-Paul Giesberts --Signed-off-by: Arend van Spriel --Signed-off-by: Kalle Valo ----- -- drivers/net/wireless/broadcom/brcm80211/brcmfmac/flowring.c | 8 ++++++-- -- 1 file changed, 6 insertions(+), 2 deletions(-) -- ----- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/flowring.c --+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/flowring.c --@@ -495,14 +495,18 @@ void brcmf_flowring_add_tdls_peer(struct -- } else { -- search = flow->tdls_entry; -- if (memcmp(search->mac, peer, ETH_ALEN) == 0) --- return; --+ goto free_entry; -- while (search->next) { -- search = search->next; -- if (memcmp(search->mac, peer, ETH_ALEN) == 0) --- return; --+ goto free_entry; -- } -- search->next = tdls_entry; -- } -- -- flow->tdls_active = true; --+ return; --+ --+free_entry: --+ kfree(tdls_entry); -- } -diff --git a/package/kernel/mac80211/patches/351-0042-brcmfmac-initialize-variable-in-brcmf_sdiod_regrl.patch b/package/kernel/mac80211/patches/351-0042-brcmfmac-initialize-variable-in-brcmf_sdiod_regrl.patch -deleted file mode 100644 -index 529cc8d..0000000 ---- a/package/kernel/mac80211/patches/351-0042-brcmfmac-initialize-variable-in-brcmf_sdiod_regrl.patch -+++ /dev/null -@@ -1,28 +0,0 @@ --From 26305d3d7298d1ddf8fd4ce95a382aa90534f0a3 Mon Sep 17 00:00:00 2001 --From: Arend Van Spriel --Date: Mon, 19 Sep 2016 12:09:54 +0100 --Subject: [PATCH] brcmfmac: initialize variable in brcmf_sdiod_regrl() -- --In case of an error the variable returned is uninitialized. The caller --will probably check the error code before using it, but better assure --it is set to zero. -- --Reviewed-by: Hante Meuleman --Reviewed-by: Pieter-Paul Giesberts --Signed-off-by: Arend van Spriel --Signed-off-by: Kalle Valo ----- -- drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c | 2 +- -- 1 file changed, 1 insertion(+), 1 deletion(-) -- ----- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c --+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c --@@ -416,7 +416,7 @@ u8 brcmf_sdiod_regrb(struct brcmf_sdio_d -- -- u32 brcmf_sdiod_regrl(struct brcmf_sdio_dev *sdiodev, u32 addr, int *ret) -- { --- u32 data; --+ u32 data = 0; -- int retval; -- -- brcmf_dbg(SDIO, "addr:0x%08x\n", addr); -diff --git a/package/kernel/mac80211/patches/351-0043-brcmfmac-remove-worker-from-.ndo_set_mac_address-cal.patch b/package/kernel/mac80211/patches/351-0043-brcmfmac-remove-worker-from-.ndo_set_mac_address-cal.patch -deleted file mode 100644 -index 67af30e..0000000 ---- a/package/kernel/mac80211/patches/351-0043-brcmfmac-remove-worker-from-.ndo_set_mac_address-cal.patch -+++ /dev/null -@@ -1,107 +0,0 @@ --From 8fa5fdec09cd379c9ecb8972f344f8f308e0ccf3 Mon Sep 17 00:00:00 2001 --From: Arend Van Spriel --Date: Mon, 19 Sep 2016 12:09:55 +0100 --Subject: [PATCH] brcmfmac: remove worker from .ndo_set_mac_address() callback -- --As it turns out there is no need to use a worker for the callback --because it is not called from atomic context. -- --Reported-by: Dan Williams --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 | 39 ++++++++-------------- -- .../wireless/broadcom/brcm80211/brcmfmac/core.h | 2 -- -- 2 files changed, 13 insertions(+), 28 deletions(-) -- ----- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c --+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c --@@ -136,27 +136,6 @@ static void _brcmf_set_multicast_list(st -- err); -- } -- ---static void ---_brcmf_set_mac_address(struct work_struct *work) ---{ --- struct brcmf_if *ifp; --- s32 err; --- --- ifp = container_of(work, struct brcmf_if, setmacaddr_work); --- --- brcmf_dbg(TRACE, "Enter, bsscfgidx=%d\n", ifp->bsscfgidx); --- --- err = brcmf_fil_iovar_data_set(ifp, "cur_etheraddr", ifp->mac_addr, --- ETH_ALEN); --- if (err < 0) { --- brcmf_err("Setting cur_etheraddr failed, %d\n", err); --- } else { --- brcmf_dbg(TRACE, "MAC address updated to %pM\n", --- ifp->mac_addr); --- memcpy(ifp->ndev->dev_addr, ifp->mac_addr, ETH_ALEN); --- } ---} --- -- #if IS_ENABLED(CONFIG_IPV6) -- static void _brcmf_update_ndtable(struct work_struct *work) -- { --@@ -190,10 +169,20 @@ static int brcmf_netdev_set_mac_address( -- { -- struct brcmf_if *ifp = netdev_priv(ndev); -- struct sockaddr *sa = (struct sockaddr *)addr; --+ int err; -- --- memcpy(&ifp->mac_addr, sa->sa_data, ETH_ALEN); --- schedule_work(&ifp->setmacaddr_work); --- return 0; --+ brcmf_dbg(TRACE, "Enter, bsscfgidx=%d\n", ifp->bsscfgidx); --+ --+ 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); --+ } else { --+ brcmf_dbg(TRACE, "updated to %pM\n", sa->sa_data); --+ memcpy(ifp->mac_addr, sa->sa_data, ETH_ALEN); --+ memcpy(ifp->ndev->dev_addr, ifp->mac_addr, ETH_ALEN); --+ } --+ return err; -- } -- -- static void brcmf_netdev_set_multicast_list(struct net_device *ndev) --@@ -525,7 +514,6 @@ int brcmf_net_attach(struct brcmf_if *if -- /* set the mac address */ -- memcpy(ndev->dev_addr, ifp->mac_addr, ETH_ALEN); -- --- INIT_WORK(&ifp->setmacaddr_work, _brcmf_set_mac_address); -- INIT_WORK(&ifp->multicast_work, _brcmf_set_multicast_list); -- INIT_WORK(&ifp->ndoffload_work, _brcmf_update_ndtable); -- --@@ -730,7 +718,6 @@ static void brcmf_del_if(struct brcmf_pu -- } -- -- if (ifp->ndev->netdev_ops == &brcmf_netdev_ops_pri) { --- cancel_work_sync(&ifp->setmacaddr_work); -- cancel_work_sync(&ifp->multicast_work); -- cancel_work_sync(&ifp->ndoffload_work); -- } ----- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h --+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h --@@ -176,7 +176,6 @@ enum brcmf_netif_stop_reason { -- * @vif: points to cfg80211 specific interface information. -- * @ndev: associated network device. -- * @stats: interface specific network statistics. --- * @setmacaddr_work: worker object for setting mac address. -- * @multicast_work: worker object for multicast provisioning. -- * @ndoffload_work: worker object for neighbor discovery offload configuration. -- * @fws_desc: interface specific firmware-signalling descriptor. --@@ -193,7 +192,6 @@ struct brcmf_if { -- struct brcmf_cfg80211_vif *vif; -- struct net_device *ndev; -- struct net_device_stats stats; --- struct work_struct setmacaddr_work; -- struct work_struct multicast_work; -- struct work_struct ndoffload_work; -- struct brcmf_fws_mac_descriptor *fws_desc; -diff --git a/package/kernel/mac80211/patches/351-0044-brcmfmac-remove-unnecessary-null-pointer-check.patch b/package/kernel/mac80211/patches/351-0044-brcmfmac-remove-unnecessary-null-pointer-check.patch -deleted file mode 100644 -index 5a08479..0000000 ---- a/package/kernel/mac80211/patches/351-0044-brcmfmac-remove-unnecessary-null-pointer-check.patch -+++ /dev/null -@@ -1,31 +0,0 @@ --From 835680b82f029818c813324aed3073cdcf63241f Mon Sep 17 00:00:00 2001 --From: Hante Meuleman --Date: Mon, 19 Sep 2016 12:09:56 +0100 --Subject: [PATCH] brcmfmac: remove unnecessary null pointer check -- --in the function brcmf_bus_start() in the exception handling a --check is made to dermine whether ifp is null, though this is not --possible. Removing the unnessary check. -- --Reviewed-by: Arend Van Spriel --Reviewed-by: Franky Lin --Reviewed-by: Pieter-Paul Giesberts --Signed-off-by: Hante Meuleman --Signed-off-by: Arend van Spriel --Signed-off-by: Kalle Valo ----- -- drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c | 3 +-- -- 1 file changed, 1 insertion(+), 2 deletions(-) -- ----- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c --+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c --@@ -1048,8 +1048,7 @@ fail: -- brcmf_fws_del_interface(ifp); -- brcmf_fws_deinit(drvr); -- } --- if (ifp) --- brcmf_net_detach(ifp->ndev, false); --+ brcmf_net_detach(ifp->ndev, false); -- if (p2p_ifp) -- brcmf_net_detach(p2p_ifp->ndev, false); -- drvr->iflist[0] = NULL; -diff --git a/package/kernel/mac80211/patches/351-0045-brcmfmac-fix-clearing-entry-IPv6-address.patch b/package/kernel/mac80211/patches/351-0045-brcmfmac-fix-clearing-entry-IPv6-address.patch -deleted file mode 100644 -index 0b3a23e..0000000 ---- a/package/kernel/mac80211/patches/351-0045-brcmfmac-fix-clearing-entry-IPv6-address.patch -+++ /dev/null -@@ -1,37 +0,0 @@ --From 2b7425f3629b38c438f890c20c5faeca64b144ff Mon Sep 17 00:00:00 2001 --From: Hante Meuleman --Date: Mon, 19 Sep 2016 12:09:57 +0100 --Subject: [PATCH] brcmfmac: fix clearing entry IPv6 address -- --When IPv6 address is to be cleared there is a possible out of --bound access. But also the clearing of the last entry and the --adjustment of total number of stored IPv6 addresses is not --updated. This patch fixes that bug. Bug was found using coverity. -- --Reviewed-by: Arend Van Spriel --Reviewed-by: Franky Lin --Reviewed-by: Pieter-Paul Giesberts --Signed-off-by: Hante Meuleman --Signed-off-by: Arend van Spriel --Signed-off-by: Kalle Valo ----- -- drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c | 7 +++++-- -- 1 file changed, 5 insertions(+), 2 deletions(-) -- ----- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c --+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c --@@ -873,9 +873,12 @@ static int brcmf_inet6addr_changed(struc -- } -- break; -- case NETDEV_DOWN: --- if (i < NDOL_MAX_ENTRIES) --- for (; i < ifp->ipv6addr_idx; i++) --+ if (i < NDOL_MAX_ENTRIES) { --+ for (; i < ifp->ipv6addr_idx - 1; i++) -- table[i] = table[i + 1]; --+ memset(&table[i], 0, sizeof(table[i])); --+ ifp->ipv6addr_idx--; --+ } -- break; -- default: -- break; -diff --git a/package/kernel/mac80211/patches/351-0046-brcmfmac-fix-out-of-bound-access-on-clearing-wowl-wa.patch b/package/kernel/mac80211/patches/351-0046-brcmfmac-fix-out-of-bound-access-on-clearing-wowl-wa.patch -deleted file mode 100644 -index a47cb32..0000000 ---- a/package/kernel/mac80211/patches/351-0046-brcmfmac-fix-out-of-bound-access-on-clearing-wowl-wa.patch -+++ /dev/null -@@ -1,44 +0,0 @@ --From a7ed7828ecda0c2b5e0d7f55dedd4230afd4b583 Mon Sep 17 00:00:00 2001 --From: Hante Meuleman --Date: Mon, 19 Sep 2016 12:09:58 +0100 --Subject: [PATCH] brcmfmac: fix out of bound access on clearing wowl wake -- indicator -- --Clearing the wowl wakeindicator happens with a rather odd --construction where the string "clear" is used to set the iovar --wowl_wakeind. This was implemented incorrectly as it caused an --out of bound access. Use an intermediate variable of correct --length and copy string in that. Problem was found using coverity. -- --Reviewed-by: Arend Van Spriel --Reviewed-by: Franky Lin --Reviewed-by: Pieter-Paul Giesberts --Signed-off-by: Hante Meuleman --Signed-off-by: Arend van Spriel --Signed-off-by: Kalle Valo ----- -- drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | 6 ++++-- -- 1 file changed, 4 insertions(+), 2 deletions(-) -- ----- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c --+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c --@@ -3623,6 +3623,7 @@ static void brcmf_configure_wowl(struct -- struct cfg80211_wowlan *wowl) -- { -- u32 wowl_config; --+ struct brcmf_wowl_wakeind_le wowl_wakeind; -- u32 i; -- -- brcmf_dbg(TRACE, "Suspend, wowl config.\n"); --@@ -3664,8 +3665,9 @@ static void brcmf_configure_wowl(struct -- if (!test_bit(BRCMF_VIF_STATUS_CONNECTED, &ifp->vif->sme_state)) -- wowl_config |= BRCMF_WOWL_UNASSOC; -- --- brcmf_fil_iovar_data_set(ifp, "wowl_wakeind", "clear", --- sizeof(struct brcmf_wowl_wakeind_le)); --+ memcpy(&wowl_wakeind, "clear", 6); --+ brcmf_fil_iovar_data_set(ifp, "wowl_wakeind", &wowl_wakeind, --+ sizeof(wowl_wakeind)); -- brcmf_fil_iovar_int_set(ifp, "wowl", wowl_config); -- brcmf_fil_iovar_int_set(ifp, "wowl_activate", 1); -- brcmf_bus_wowl_config(cfg->pub->bus_if, true); -diff --git a/package/kernel/mac80211/patches/351-0047-brcmfmac-simplify-mapping-of-auth-type.patch b/package/kernel/mac80211/patches/351-0047-brcmfmac-simplify-mapping-of-auth-type.patch -deleted file mode 100644 -index a652ae6..0000000 ---- a/package/kernel/mac80211/patches/351-0047-brcmfmac-simplify-mapping-of-auth-type.patch -+++ /dev/null -@@ -1,39 +0,0 @@ --From 92c313604711a0976def79dabb9e8da3cc2cc780 Mon Sep 17 00:00:00 2001 --From: Hante Meuleman --Date: Mon, 19 Sep 2016 12:09:59 +0100 --Subject: [PATCH] brcmfmac: simplify mapping of auth type -- --The 802.11 standard only has four valid auth type configurations of which --our firmware only supports two, ie. Open System and Shared Key. Simplify --the mapping falling back to automatic for other types specified by --user-space. -- --Reviewed-by: Arend Van Spriel --Reviewed-by: Franky Lin --Reviewed-by: Pieter-Paul Giesberts --Signed-off-by: Hante Meuleman --Signed-off-by: Arend van Spriel --Signed-off-by: Kalle Valo ----- -- drivers/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 --@@ -1577,15 +1577,9 @@ static s32 brcmf_set_auth_type(struct ne -- val = 1; -- brcmf_dbg(CONN, "shared key\n"); -- break; --- case NL80211_AUTHTYPE_AUTOMATIC: --- val = 2; --- brcmf_dbg(CONN, "automatic\n"); --- break; --- case NL80211_AUTHTYPE_NETWORK_EAP: --- brcmf_dbg(CONN, "network eap\n"); -- default: -- val = 2; --- brcmf_err("invalid auth type (%d)\n", sme->auth_type); --+ brcmf_dbg(CONN, "automatic, auth type (%d)\n", sme->auth_type); -- break; -- } -- -diff --git a/package/kernel/mac80211/patches/351-0048-brcmfmac-fix-memory-leak-in-brcmf_fill_bss_param.patch b/package/kernel/mac80211/patches/351-0048-brcmfmac-fix-memory-leak-in-brcmf_fill_bss_param.patch -deleted file mode 100644 -index a6fae37..0000000 ---- a/package/kernel/mac80211/patches/351-0048-brcmfmac-fix-memory-leak-in-brcmf_fill_bss_param.patch -+++ /dev/null -@@ -1,41 +0,0 @@ --From 23e9c128adb2038c27a424a5f91136e7fa3e0dc6 Mon Sep 17 00:00:00 2001 --From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= --Date: Wed, 21 Sep 2016 08:23:24 +0200 --Subject: [PATCH] brcmfmac: fix memory leak in brcmf_fill_bss_param --MIME-Version: 1.0 --Content-Type: text/plain; charset=UTF-8 --Content-Transfer-Encoding: 8bit -- --This function is called from get_station callback which means that every --time user space was getting/dumping station(s) we were leaking 2 KiB. -- --Signed-off-by: Rafał Miłecki --Fixes: 1f0dc59a6de ("brcmfmac: rework .get_station() callback") --Cc: stable@vger.kernel.org # 4.2+ --Acked-by: Arend van Spriel --Signed-off-by: Kalle Valo ----- -- drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | 5 ++++- -- 1 file changed, 4 insertions(+), 1 deletion(-) -- ----- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c --+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c --@@ -2463,7 +2463,7 @@ static void brcmf_fill_bss_param(struct -- WL_BSS_INFO_MAX); -- if (err) { -- brcmf_err("Failed to get bss info (%d)\n", err); --- return; --+ goto out_kfree; -- } -- si->filled |= BIT(NL80211_STA_INFO_BSS_PARAM); -- si->bss_param.beacon_interval = le16_to_cpu(buf->bss_le.beacon_period); --@@ -2475,6 +2475,9 @@ static void brcmf_fill_bss_param(struct -- si->bss_param.flags |= BSS_PARAM_FLAGS_SHORT_PREAMBLE; -- if (capability & WLAN_CAPABILITY_SHORT_SLOT_TIME) -- si->bss_param.flags |= BSS_PARAM_FLAGS_SHORT_SLOT_TIME; --+ --+out_kfree: --+ kfree(buf); -- } -- -- static s32 -diff --git a/package/kernel/mac80211/patches/351-0049-brcmfmac-drop-unused-fields-from-struct-brcmf_pub.patch b/package/kernel/mac80211/patches/351-0049-brcmfmac-drop-unused-fields-from-struct-brcmf_pub.patch -deleted file mode 100644 -index 47af73a..0000000 ---- a/package/kernel/mac80211/patches/351-0049-brcmfmac-drop-unused-fields-from-struct-brcmf_pub.patch -+++ /dev/null -@@ -1,60 +0,0 @@ --From 2df86ad959c9d1cdbeb2f23a0801857731156692 Mon Sep 17 00:00:00 2001 --From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= --Date: Fri, 23 Sep 2016 15:27:46 +0200 --Subject: [PATCH] brcmfmac: drop unused fields from struct brcmf_pub --MIME-Version: 1.0 --Content-Type: text/plain; charset=UTF-8 --Content-Transfer-Encoding: 8bit -- --They seem to be there from the first day. We calculate these values but --never use them. -- --Signed-off-by: Rafał Miłecki --Signed-off-by: Kalle Valo ----- -- drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c | 3 --- -- drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h | 4 ---- -- drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.c | 2 -- -- 3 files changed, 9 deletions(-) -- ----- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c --+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c --@@ -508,9 +508,6 @@ int brcmf_net_attach(struct brcmf_if *if -- ndev->hard_header_len += drvr->hdrlen; -- ndev->ethtool_ops = &brcmf_ethtool_ops; -- --- drvr->rxsz = ndev->mtu + ndev->hard_header_len + --- drvr->hdrlen; --- -- /* set the mac address */ -- memcpy(ndev->dev_addr, ifp->mac_addr, ETH_ALEN); -- ----- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h --+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h --@@ -112,15 +112,11 @@ struct brcmf_pub { -- -- /* Internal brcmf items */ -- uint hdrlen; /* Total BRCMF header length (proto + bus) */ --- uint rxsz; /* Rx buffer size bus module should use */ -- -- /* Dongle media info */ -- char fwver[BRCMF_DRIVER_FIRMWARE_VERSION_LEN]; -- u8 mac[ETH_ALEN]; /* MAC address obtained from dongle */ -- --- /* Multicast data packets sent to dongle */ --- unsigned long tx_multicast; --- -- struct mac_address addresses[BRCMF_MAX_IFS]; -- -- struct brcmf_if *iflist[BRCMF_MAX_IFS]; ----- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.c --+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.c --@@ -2104,8 +2104,6 @@ int brcmf_fws_process_skb(struct brcmf_i -- if (!skb->priority) -- skb->priority = cfg80211_classify8021d(skb, NULL); -- --- drvr->tx_multicast += !!multicast; --- -- if (fws->avoid_queueing) { -- rc = brcmf_proto_txdata(drvr, ifp->ifidx, 0, skb); -- if (rc < 0) -diff --git a/package/kernel/mac80211/patches/351-0050-brcmfmac-replace-WARNING-on-timeout-with-a-simple-er.patch b/package/kernel/mac80211/patches/351-0050-brcmfmac-replace-WARNING-on-timeout-with-a-simple-er.patch -deleted file mode 100644 -index ca4863a..0000000 ---- a/package/kernel/mac80211/patches/351-0050-brcmfmac-replace-WARNING-on-timeout-with-a-simple-er.patch -+++ /dev/null -@@ -1,38 +0,0 @@ --From 2f0e56fa37cce60a5ac5d451bcadec51cd711436 Mon Sep 17 00:00:00 2001 --From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= --Date: Tue, 27 Sep 2016 12:12:24 +0200 --Subject: [PATCH] brcmfmac: replace WARNING on timeout with a simple error -- message --MIME-Version: 1.0 --Content-Type: text/plain; charset=UTF-8 --Content-Transfer-Encoding: 8bit -- --Even with timeout increased to 950 ms we get WARNINGs from time to time. --It mostly happens on A-MPDU stalls (e.g. when station goes out of --range). It may take up to 5-10 secods for the firmware to recover and --for that time it doesn't process packets. -- --It's still useful to have a message on time out as it may indicate some --firmware problem and incorrect key update. Raising a WARNING however --wasn't really that necessary, it doesn't point to any driver bug anymore --and backtrace wasn't much useful. -- --Signed-off-by: Rafał Miłecki --Acked-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 --@@ -1155,7 +1155,8 @@ int brcmf_netdev_wait_pend8021x(struct b -- !brcmf_get_pend_8021x_cnt(ifp), -- MAX_WAIT_FOR_8021X_TX); -- --- WARN_ON(!err); --+ if (!err) --+ brcmf_err("Timed out waiting for no pending 802.1x packets\n"); -- -- return !err; -- } -diff --git a/package/kernel/mac80211/patches/351-0051-brcmfmac-use-correct-skb-freeing-helper-when-deletin.patch b/package/kernel/mac80211/patches/351-0051-brcmfmac-use-correct-skb-freeing-helper-when-deletin.patch -deleted file mode 100644 -index 6976359..0000000 ---- a/package/kernel/mac80211/patches/351-0051-brcmfmac-use-correct-skb-freeing-helper-when-deletin.patch -+++ /dev/null -@@ -1,58 +0,0 @@ --From 7f00ee2bbc630900ba16fc2690473f3e2db0e264 Mon Sep 17 00:00:00 2001 --From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= --Date: Tue, 27 Sep 2016 14:11:04 +0200 --Subject: [PATCH] brcmfmac: use correct skb freeing helper when deleting -- flowring --MIME-Version: 1.0 --Content-Type: text/plain; charset=UTF-8 --Content-Transfer-Encoding: 8bit -- --Flowrings contain skbs waiting for transmission that were passed to us --by netif. It means we checked every one of them looking for 802.1x --Ethernet type. When deleting flowring we have to use freeing function --that will check for 802.1x type as well. -- --Freeing skbs without a proper check was leading to counter not being --properly decreased. This was triggering a WARNING every time --brcmf_netdev_wait_pend8021x was called. -- --Signed-off-by: Rafał Miłecki --Acked-by: Arend van Spriel --Cc: stable@vger.kernel.org # 4.5+ --Signed-off-by: Kalle Valo ----- -- drivers/net/wireless/broadcom/brcm80211/brcmfmac/flowring.c | 9 ++++++++- -- 1 file changed, 8 insertions(+), 1 deletion(-) -- ----- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/flowring.c --+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/flowring.c --@@ -234,13 +234,20 @@ static void brcmf_flowring_block(struct -- -- void brcmf_flowring_delete(struct brcmf_flowring *flow, u16 flowid) -- { --+ struct brcmf_bus *bus_if = dev_get_drvdata(flow->dev); -- struct brcmf_flowring_ring *ring; --+ struct brcmf_if *ifp; -- u16 hash_idx; --+ u8 ifidx; -- struct sk_buff *skb; -- -- ring = flow->rings[flowid]; -- if (!ring) -- return; --+ --+ ifidx = brcmf_flowring_ifidx_get(flow, flowid); --+ ifp = brcmf_get_ifp(bus_if->drvr, ifidx); --+ -- brcmf_flowring_block(flow, flowid, false); -- hash_idx = ring->hash_id; -- flow->hash[hash_idx].ifidx = BRCMF_FLOWRING_INVALID_IFIDX; --@@ -249,7 +256,7 @@ void brcmf_flowring_delete(struct brcmf_ -- -- skb = skb_dequeue(&ring->skblist); -- while (skb) { --- brcmu_pkt_buf_free_skb(skb); --+ brcmf_txfinalize(ifp, skb, false); -- skb = skb_dequeue(&ring->skblist); -- } -- -diff --git a/package/kernel/mac80211/patches/402-ath_regd_optional.patch b/package/kernel/mac80211/patches/402-ath_regd_optional.patch -index 7351353..4634283 100644 ---- a/package/kernel/mac80211/patches/402-ath_regd_optional.patch -+++ b/package/kernel/mac80211/patches/402-ath_regd_optional.patch -@@ -8,7 +8,7 @@ - + return; - +#endif - + -- for (band = 0; band < IEEE80211_NUM_BANDS; band++) { -+ for (band = 0; band < NUM_NL80211_BANDS; band++) { - if (!wiphy->bands[band]) - continue; - @@ -374,6 +378,10 @@ ath_reg_apply_ir_flags(struct wiphy *wip -@@ -19,7 +19,7 @@ - + return; - +#endif - + -- sband = wiphy->bands[IEEE80211_BAND_2GHZ]; -+ sband = wiphy->bands[NL80211_BAND_2GHZ]; - if (!sband) - return; - @@ -402,6 +410,10 @@ static void ath_reg_apply_radar_flags(st -@@ -30,7 +30,7 @@ - + return; - +#endif - + -- if (!wiphy->bands[IEEE80211_BAND_5GHZ]) -+ if (!wiphy->bands[NL80211_BAND_5GHZ]) - return; - - @@ -633,6 +645,11 @@ ath_regd_init_wiphy(struct ath_regulator -@@ -59,7 +59,7 @@ - ---help--- - --- a/.local-symbols - +++ b/.local-symbols --@@ -125,6 +125,7 @@ ADM8211= -+@@ -127,6 +127,7 @@ ADM8211= - ATH_COMMON= - WLAN_VENDOR_ATH= - ATH_DEBUG= -diff --git a/package/kernel/mac80211/patches/410-ath9k_allow_adhoc_and_ap.patch b/package/kernel/mac80211/patches/410-ath9k_allow_adhoc_and_ap.patch -index 1a62484..f2f52f9 100644 ---- a/package/kernel/mac80211/patches/410-ath9k_allow_adhoc_and_ap.patch -+++ b/package/kernel/mac80211/patches/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 --@@ -722,6 +722,7 @@ static const struct ieee80211_iface_limi -+@@ -727,6 +727,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/500-ath9k_eeprom_debugfs.patch b/package/kernel/mac80211/patches/500-ath9k_eeprom_debugfs.patch -index a7f9d9f..f21eed1 100644 ---- a/package/kernel/mac80211/patches/500-ath9k_eeprom_debugfs.patch -+++ b/package/kernel/mac80211/patches/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 --@@ -1301,6 +1301,53 @@ void ath9k_deinit_debug(struct ath_softc -+@@ -1315,6 +1315,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); --@@ -1320,6 +1367,8 @@ int ath9k_init_debug(struct ath_hw *ah) -+@@ -1334,6 +1381,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/501-ath9k_ahb_init.patch b/package/kernel/mac80211/patches/501-ath9k_ahb_init.patch -index 5892c3e..1825d77 100644 ---- a/package/kernel/mac80211/patches/501-ath9k_ahb_init.patch -+++ b/package/kernel/mac80211/patches/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 --@@ -1024,23 +1024,23 @@ static int __init ath9k_init(void) -+@@ -1030,23 +1030,23 @@ static int __init ath9k_init(void) - { - int error; - -diff --git a/package/kernel/mac80211/patches/511-ath9k_reduce_rxbuf.patch b/package/kernel/mac80211/patches/511-ath9k_reduce_rxbuf.patch -index 6766111..15b8d7b 100644 ---- a/package/kernel/mac80211/patches/511-ath9k_reduce_rxbuf.patch -+++ b/package/kernel/mac80211/patches/511-ath9k_reduce_rxbuf.patch -@@ -8,4 +8,4 @@ - +#define ATH_RXBUF 256 - #define ATH_TXBUF 512 - #define ATH_TXBUF_RESERVE 5 -- #define ATH_MAX_QDEPTH (ATH_TXBUF / 4 - ATH_TXBUF_RESERVE) -+ #define ATH_TXMAXTRY 13 -diff --git a/package/kernel/mac80211/patches/512-ath9k_channelbw_debugfs.patch b/package/kernel/mac80211/patches/512-ath9k_channelbw_debugfs.patch -index 5ecf528..c98072b 100644 ---- a/package/kernel/mac80211/patches/512-ath9k_channelbw_debugfs.patch -+++ b/package/kernel/mac80211/patches/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 --@@ -1348,6 +1348,52 @@ static const struct file_operations fops -+@@ -1362,6 +1362,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); --@@ -1369,6 +1415,8 @@ int ath9k_init_debug(struct ath_hw *ah) -+@@ -1383,6 +1429,8 @@ int ath9k_init_debug(struct ath_hw *ah) - - debugfs_create_file("eeprom", S_IRUSR, sc->debug.debugfs_phy, sc, - &fops_eeprom); -@@ -90,7 +90,7 @@ - ichan->channel = chan->center_freq; - ichan->chan = chan; - @@ -308,7 +310,19 @@ static void ath9k_cmn_update_ichannel(st -- if (chan->band == IEEE80211_BAND_5GHZ) -+ if (chan->band == NL80211_BAND_5GHZ) - flags |= CHANNEL_5GHZ; - - - switch (chandef->width) { -diff --git a/package/kernel/mac80211/patches/513-ath9k_add_pci_ids.patch b/package/kernel/mac80211/patches/513-ath9k_add_pci_ids.patch -index c84d1bc..167eeff 100644 ---- a/package/kernel/mac80211/patches/513-ath9k_add_pci_ids.patch -+++ b/package/kernel/mac80211/patches/513-ath9k_add_pci_ids.patch -@@ -20,7 +20,7 @@ - #define AR9160_DEVID_PCI 0x0027 - --- a/drivers/net/wireless/ath/ath9k/pci.c - +++ b/drivers/net/wireless/ath/ath9k/pci.c --@@ -751,6 +751,7 @@ static const struct pci_device_id ath_pc -+@@ -761,6 +761,7 @@ static const struct pci_device_id ath_pc - .driver_data = ATH9K_PCI_BT_ANT_DIV }, - #endif - -diff --git a/package/kernel/mac80211/patches/522-mac80211_configure_antenna_gain.patch b/package/kernel/mac80211/patches/522-mac80211_configure_antenna_gain.patch -index e151a12..c40598d 100644 ---- a/package/kernel/mac80211/patches/522-mac80211_configure_antenna_gain.patch -+++ b/package/kernel/mac80211/patches/522-mac80211_configure_antenna_gain.patch -@@ -1,6 +1,6 @@ - --- a/include/net/cfg80211.h - +++ b/include/net/cfg80211.h --@@ -2363,6 +2363,7 @@ struct cfg80211_qos_map { -+@@ -2410,6 +2410,7 @@ struct cfg80211_qos_map { - * (as advertised by the nl80211 feature flag.) - * @get_tx_power: store the current TX power into the dbm variable; - * return 0 if successful -@@ -8,7 +8,7 @@ - * - * @set_wds_peer: set the WDS peer for a WDS interface - * --@@ -2624,6 +2625,7 @@ struct cfg80211_ops { -+@@ -2671,6 +2672,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 --@@ -1286,6 +1286,7 @@ enum ieee80211_smps_mode { -+@@ -1317,6 +1317,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 --@@ -1306,6 +1307,7 @@ enum ieee80211_smps_mode { -+@@ -1337,6 +1338,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 --@@ -1790,6 +1790,9 @@ enum nl80211_commands { -- * between scans. The scan plans are executed sequentially. -- * Each scan plan is a nested attribute of &enum nl80211_sched_scan_plan. -+@@ -1829,6 +1829,9 @@ enum nl80211_commands { -+ * %NL80211_ATTR_EXT_CAPA_MASK, to specify the extended capabilities per -+ * interface type. - * - + * @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 --@@ -2164,6 +2167,8 @@ enum nl80211_attrs { -- NL80211_ATTR_MAX_SCAN_PLAN_ITERATIONS, -- NL80211_ATTR_SCHED_SCAN_PLANS, -+@@ -2213,6 +2216,8 @@ enum nl80211_attrs { -+ -+ NL80211_ATTR_IFTYPE_EXT_CAPA, - - + NL80211_ATTR_WIPHY_ANTENNA_GAIN, - + -@@ -57,7 +57,7 @@ - __NL80211_ATTR_AFTER_LAST, - --- a/net/mac80211/cfg.c - +++ b/net/mac80211/cfg.c --@@ -2229,6 +2229,19 @@ static int ieee80211_get_tx_power(struct -+@@ -2238,6 +2238,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) - { --@@ -3403,6 +3416,7 @@ const struct cfg80211_ops mac80211_confi -+@@ -3412,6 +3425,7 @@ const struct cfg80211_ops mac80211_confi - .set_wiphy_params = ieee80211_set_wiphy_params, - .set_tx_power = ieee80211_set_tx_power, - .get_tx_power = ieee80211_get_tx_power, -@@ -87,7 +87,7 @@ - CFG80211_TESTMODE_CMD(ieee80211_testmode_cmd) - --- a/net/mac80211/ieee80211_i.h - +++ b/net/mac80211/ieee80211_i.h --@@ -1318,6 +1318,7 @@ struct ieee80211_local { -+@@ -1338,6 +1338,7 @@ struct ieee80211_local { - int dynamic_ps_forced_timeout; - - int user_power_level; /* in dBm, for all interfaces */ -@@ -119,7 +119,7 @@ - if (local->hw.conf.power_level != power) { - changed |= IEEE80211_CONF_CHANGE_POWER; - local->hw.conf.power_level = power; --@@ -586,6 +592,7 @@ struct ieee80211_hw *ieee80211_alloc_hw_ -+@@ -588,6 +594,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 --@@ -403,6 +403,7 @@ static const struct nla_policy nl80211_p -- [NL80211_ATTR_NETNS_FD] = { .type = NLA_U32 }, -- [NL80211_ATTR_SCHED_SCAN_DELAY] = { .type = NLA_U32 }, -- [NL80211_ATTR_REG_INDOOR] = { .type = NLA_FLAG }, -+@@ -407,6 +407,7 @@ static const struct nla_policy nl80211_p -+ [NL80211_ATTR_PBSS] = { .type = NLA_FLAG }, -+ [NL80211_ATTR_BSS_SELECT] = { .type = NLA_NESTED }, -+ [NL80211_ATTR_STA_SUPPORT_P2P_PS] = { .type = NLA_U8 }, - + [NL80211_ATTR_WIPHY_ANTENNA_GAIN] = { .type = NLA_U32 }, - }; - - /* policy for the key attributes */ --@@ -2220,6 +2221,20 @@ static int nl80211_set_wiphy(struct sk_b -+@@ -2294,6 +2295,20 @@ static int nl80211_set_wiphy(struct sk_b - if (result) - return result; - } -diff --git a/package/kernel/mac80211/patches/530-ath9k_extra_leds.patch b/package/kernel/mac80211/patches/530-ath9k_extra_leds.patch -index 5a5e464..0b25749 100644 ---- a/package/kernel/mac80211/patches/530-ath9k_extra_leds.patch -+++ b/package/kernel/mac80211/patches/530-ath9k_extra_leds.patch -@@ -1,16 +1,16 @@ - --- a/drivers/net/wireless/ath/ath9k/ath9k.h - +++ b/drivers/net/wireless/ath/ath9k/ath9k.h - @@ -814,6 +814,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); -- void ath_fill_led_pin(struct ath_softc *sc); - +int ath_create_gpio_led(struct ath_softc *sc, int gpio, const char *name, --+ const char *trigger, bool active_low); -++ const char *trigger, bool active_low); - + - #else - static inline void ath_init_leds(struct ath_softc *sc) - { --@@ -953,6 +956,13 @@ void ath_ant_comb_scan(struct ath_softc -+@@ -950,6 +953,13 @@ void ath_ant_comb_scan(struct ath_softc - - #define ATH9K_NUM_CHANCTX 2 /* supports 2 operating channels */ - -@@ -24,7 +24,7 @@ - struct ath_softc { - struct ieee80211_hw *hw; - struct device *dev; --@@ -1005,9 +1015,8 @@ struct ath_softc { -+@@ -1002,9 +1012,8 @@ struct ath_softc { - spinlock_t chan_lock; - - #ifdef CPTCFG_MAC80211_LEDS -@@ -38,24 +38,33 @@ - #ifdef CPTCFG_ATH9K_DEBUGFS - --- a/drivers/net/wireless/ath/ath9k/gpio.c - +++ b/drivers/net/wireless/ath/ath9k/gpio.c --@@ -24,45 +24,102 @@ -- static void ath_led_brightness(struct led_classdev *led_cdev, -- enum led_brightness brightness) -+@@ -22,7 +22,7 @@ -+ -+ #ifdef CPTCFG_MAC80211_LEDS -+ -+-void ath_fill_led_pin(struct ath_softc *sc) -++static void ath_fill_led_pin(struct ath_softc *sc) - { --- struct ath_softc *sc = container_of(led_cdev, struct ath_softc, led_cdev); --- u32 val = (brightness == LED_OFF); -+ struct ath_hw *ah = sc->sc_ah; -+ -+@@ -39,61 +39,111 @@ void ath_fill_led_pin(struct ath_softc * -+ else -+ ah->led_pin = ATH_LED_PIN_DEF; -+ } -++} -++ -++static void ath_led_brightness(struct led_classdev *led_cdev, -++ enum led_brightness brightness) -++{ - + struct ath_led *led = container_of(led_cdev, struct ath_led, cdev); - + struct ath_softc *sc = led->sc; -- --- if (sc->sc_ah->config.led_active_high) --- val = !val; -++ - + ath9k_ps_wakeup(sc); - + ath9k_hw_set_gpio(sc->sc_ah, led->gpio->gpio, - + (brightness != LED_OFF) ^ led->gpio->active_low); - + ath9k_ps_restore(sc); - +} -- --- ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin, val); -++ - +static int ath_add_led(struct ath_softc *sc, struct ath_led *led) - +{ - + const struct gpio_led *gpio = led->gpio; -@@ -71,30 +80,40 @@ - + - + led->sc = sc; - + list_add(&led->list, &sc->leds); --+ --+ /* Configure gpio for output */ --+ ath9k_hw_cfg_output(sc->sc_ah, gpio->gpio, --+ AR_GPIO_OUTPUT_MUX_AS_OUTPUT); --+ -+ -+ /* Configure gpio for output */ -+- ath9k_hw_gpio_request_out(ah, ah->led_pin, "ath9k-led", -++ ath9k_hw_gpio_request_out(sc->sc_ah, gpio->gpio, gpio->name, -+ AR_GPIO_OUTPUT_MUX_AS_OUTPUT); -+ -+- /* LED off, active low */ -+- ath9k_hw_set_gpio(ah, ah->led_pin, ah->config.led_active_high ? 0 : 1); - + /* LED off */ - + ath9k_hw_set_gpio(sc->sc_ah, gpio->gpio, gpio->active_low); - + - + return 0; --+} --+ -+ } -+ -+-static void ath_led_brightness(struct led_classdev *led_cdev, -+- enum led_brightness brightness) - +int ath_create_gpio_led(struct ath_softc *sc, int gpio_num, const char *name, - + const char *trigger, bool active_low) --+{ -+ { -+- struct ath_softc *sc = container_of(led_cdev, struct ath_softc, led_cdev); -+- u32 val = (brightness == LED_OFF); - + struct ath_led *led; - + struct gpio_led *gpio; - + char *_name; - + int ret; --+ -+ -+- if (sc->sc_ah->config.led_active_high) -+- val = !val; - + led = kzalloc(sizeof(*led) + sizeof(*gpio) + strlen(name) + 1, - + GFP_KERNEL); - + if (!led) - + return -ENOMEM; --+ -+ -+- ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin, val); - + led->gpio = gpio = (struct gpio_led *) (led + 1); - + _name = (char *) (led->gpio + 1); - + -@@ -115,15 +134,18 @@ - { - - if (!sc->led_registered) - - return; --+ struct ath_led *led; -- -+- - - ath_led_brightness(&sc->led_cdev, LED_OFF); - - led_classdev_unregister(&sc->led_cdev); -++ struct ath_led *led; -+ -+- ath9k_hw_gpio_free(sc->sc_ah, sc->sc_ah->led_pin); - + while (!list_empty(&sc->leds)) { - + led = list_first_entry(&sc->leds, struct ath_led, list); - + list_del(&led->list); - + ath_led_brightness(&led->cdev, LED_OFF); - + led_classdev_unregister(&led->cdev); -++ ath9k_hw_gpio_free(sc->sc_ah, led->gpio->gpio); - + kfree(led); - + } - } -@@ -139,6 +161,8 @@ - if (AR_SREV_9100(sc->sc_ah)) - return; - -+ ath_fill_led_pin(sc); -+ - - if (!ath9k_led_blink) - - sc->led_cdev.default_trigger = - - ieee80211_get_radio_led_name(sc->hw); -@@ -159,13 +183,14 @@ - + trigger = ieee80211_get_radio_led_name(sc->hw); - - - sc->led_registered = true; --+ ath_create_gpio_led(sc, sc->sc_ah->led_pin, led_name, trigger, !sc->sc_ah->config.led_active_high); -++ ath_create_gpio_led(sc, sc->sc_ah->led_pin, led_name, trigger, -++ !sc->sc_ah->config.led_active_high); - } -+ #endif - -- void ath_fill_led_pin(struct ath_softc *sc) - --- a/drivers/net/wireless/ath/ath9k/init.c - +++ b/drivers/net/wireless/ath/ath9k/init.c --@@ -936,7 +936,7 @@ int ath9k_init_device(u16 devid, struct -+@@ -942,7 +942,7 @@ int ath9k_init_device(u16 devid, struct - - #ifdef CPTCFG_MAC80211_LEDS - /* must be initialized before ieee80211_register_hw */ -@@ -176,7 +201,7 @@ - #endif - --- a/drivers/net/wireless/ath/ath9k/debug.c - +++ b/drivers/net/wireless/ath/ath9k/debug.c --@@ -1393,6 +1393,61 @@ static const struct file_operations fops -+@@ -1407,6 +1407,61 @@ static const struct file_operations fops - .llseek = default_llseek, - }; - -@@ -238,7 +263,7 @@ - - int ath9k_init_debug(struct ath_hw *ah) - { --@@ -1417,6 +1472,10 @@ int ath9k_init_debug(struct ath_hw *ah) -+@@ -1431,6 +1486,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/531-ath9k_extra_platform_leds.patch b/package/kernel/mac80211/patches/531-ath9k_extra_platform_leds.patch -index 7c10ea6..f656697 100644 ---- a/package/kernel/mac80211/patches/531-ath9k_extra_platform_leds.patch -+++ b/package/kernel/mac80211/patches/531-ath9k_extra_platform_leds.patch -@@ -1,6 +1,6 @@ - --- a/include/linux/ath9k_platform.h - +++ b/include/linux/ath9k_platform.h --@@ -41,6 +41,9 @@ struct ath9k_platform_data { -+@@ -45,6 +45,9 @@ struct ath9k_platform_data { - int (*external_reset)(void); - - bool use_eeprom; -@@ -20,7 +20,7 @@ - - /********************************/ - /* LED functions */ --@@ -88,6 +89,24 @@ int ath_create_gpio_led(struct ath_softc -+@@ -108,6 +109,24 @@ int ath_create_gpio_led(struct ath_softc - return ret; - } - -@@ -45,7 +45,7 @@ - void ath_deinit_leds(struct ath_softc *sc) - { - struct ath_led *led; --@@ -103,8 +122,10 @@ void ath_deinit_leds(struct ath_softc *s -+@@ -124,8 +143,10 @@ void ath_deinit_leds(struct ath_softc *s - - void ath_init_leds(struct ath_softc *sc) - { -@@ -56,10 +56,10 @@ - - INIT_LIST_HEAD(&sc->leds); - --@@ -120,6 +141,12 @@ void ath_init_leds(struct ath_softc *sc) -- trigger = ieee80211_get_radio_led_name(sc->hw); -+@@ -144,6 +165,12 @@ void ath_init_leds(struct ath_softc *sc) - -- ath_create_gpio_led(sc, sc->sc_ah->led_pin, led_name, trigger, !sc->sc_ah->config.led_active_high); -+ ath_create_gpio_led(sc, sc->sc_ah->led_pin, led_name, trigger, -+ !sc->sc_ah->config.led_active_high); - + - + if (!pdata) - + return; -@@ -67,5 +67,5 @@ - + for (i = 0; i < pdata->num_leds; i++) - + ath_create_platform_led(sc, &pdata->leds[i]); - } -+ #endif - -- void ath_fill_led_pin(struct ath_softc *sc) -diff --git a/package/kernel/mac80211/patches/532-ath9k_get_led_polarity_from_platform_data.patch b/package/kernel/mac80211/patches/532-ath9k_get_led_polarity_from_platform_data.patch -index 6d62a2b..50d8a7a 100644 ---- a/package/kernel/mac80211/patches/532-ath9k_get_led_polarity_from_platform_data.patch -+++ b/package/kernel/mac80211/patches/532-ath9k_get_led_polarity_from_platform_data.patch -@@ -1,6 +1,6 @@ - --- a/include/linux/ath9k_platform.h - +++ b/include/linux/ath9k_platform.h --@@ -36,6 +36,7 @@ struct ath9k_platform_data { -+@@ -40,6 +40,7 @@ struct ath9k_platform_data { - bool tx_gain_buffalo; - bool disable_2ghz; - bool disable_5ghz; -@@ -10,7 +10,7 @@ - int (*external_reset)(void); - --- a/drivers/net/wireless/ath/ath9k/init.c - +++ b/drivers/net/wireless/ath/ath9k/init.c --@@ -577,6 +577,7 @@ static int ath9k_init_softc(u16 devid, s -+@@ -580,6 +580,7 @@ static int ath9k_init_softc(u16 devid, s - ah->external_reset = pdata->external_reset; - ah->disable_2ghz = pdata->disable_2ghz; - ah->disable_5ghz = pdata->disable_5ghz; -diff --git a/package/kernel/mac80211/patches/541-ath9k_rx_dma_stop_check.patch b/package/kernel/mac80211/patches/541-ath9k_rx_dma_stop_check.patch -index 3c5e9f5..c2d2781 100644 ---- a/package/kernel/mac80211/patches/541-ath9k_rx_dma_stop_check.patch -+++ b/package/kernel/mac80211/patches/541-ath9k_rx_dma_stop_check.patch -@@ -1,6 +1,6 @@ - --- a/drivers/net/wireless/ath/ath9k/mac.c - +++ b/drivers/net/wireless/ath/ath9k/mac.c --@@ -695,7 +695,7 @@ bool ath9k_hw_stopdmarecv(struct ath_hw -+@@ -698,7 +698,7 @@ bool ath9k_hw_stopdmarecv(struct ath_hw - { - #define AH_RX_STOP_DMA_TIMEOUT 10000 /* usec */ - struct ath_common *common = ath9k_hw_common(ah); -@@ -9,7 +9,7 @@ - int i; - - /* Enable access to the DMA observation bus */ --@@ -725,6 +725,16 @@ bool ath9k_hw_stopdmarecv(struct ath_hw -+@@ -728,6 +728,16 @@ bool ath9k_hw_stopdmarecv(struct ath_hw - } - - if (i == 0) { -diff --git a/package/kernel/mac80211/patches/542-ath9k_debugfs_diag.patch b/package/kernel/mac80211/patches/542-ath9k_debugfs_diag.patch -index e83c6bf..4615643 100644 ---- a/package/kernel/mac80211/patches/542-ath9k_debugfs_diag.patch -+++ b/package/kernel/mac80211/patches/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 --@@ -1449,6 +1449,50 @@ static const struct file_operations fops -+@@ -1463,6 +1463,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); --@@ -1476,6 +1520,8 @@ int ath9k_init_debug(struct ath_hw *ah) -+@@ -1490,6 +1534,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 --@@ -519,6 +519,12 @@ enum { -+@@ -520,6 +520,12 @@ enum { - ATH9K_RESET_COLD, - }; - -@@ -75,7 +75,7 @@ - struct ath9k_hw_version { - u32 magic; - u16 devid; --@@ -804,6 +810,8 @@ struct ath_hw { -+@@ -805,6 +811,8 @@ struct ath_hw { - u32 rfkill_polarity; - u32 ah_flags; - -@@ -84,7 +84,7 @@ - bool reset_power_on; - bool htc_reset_init; - --@@ -1066,6 +1074,7 @@ void ath9k_hw_check_nav(struct ath_hw *a -+@@ -1068,6 +1076,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 --@@ -1819,6 +1819,20 @@ u32 ath9k_hw_get_tsf_offset(struct times -+@@ -1841,6 +1841,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) - { --@@ -2027,6 +2041,7 @@ int ath9k_hw_reset(struct ath_hw *ah, st -+@@ -2049,6 +2063,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/543-ath9k_entropy_from_adc.patch b/package/kernel/mac80211/patches/543-ath9k_entropy_from_adc.patch -index d7bb5a1..656ed43 100644 ---- a/package/kernel/mac80211/patches/543-ath9k_entropy_from_adc.patch -+++ b/package/kernel/mac80211/patches/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 --@@ -720,6 +720,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 --@@ -742,6 +743,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 --@@ -1998,6 +1998,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); --@@ -2034,6 +2054,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,9 +55,9 @@ - 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 --@@ -711,7 +711,8 @@ static void ath9k_init_txpower_limits(st -+@@ -716,7 +716,8 @@ static void ath9k_init_txpower_limits(st - if (ah->caps.hw_caps & ATH9K_HW_CAP_5GHZ) -- ath9k_init_band_txpower(sc, IEEE80211_BAND_5GHZ); -+ ath9k_init_band_txpower(sc, NL80211_BAND_5GHZ); - - - ah->curchan = curchan; - + if (curchan) -@@ -65,7 +65,7 @@ - } - - static const struct ieee80211_iface_limit if_limits[] = { --@@ -897,6 +898,18 @@ static void ath9k_set_hw_capab(struct at -+@@ -903,6 +904,18 @@ static void ath9k_set_hw_capab(struct at - SET_IEEE80211_PERM_ADDR(hw, common->macaddr); - } - -@@ -84,7 +84,7 @@ - int ath9k_init_device(u16 devid, struct ath_softc *sc, - const struct ath_bus_ops *bus_ops) - { --@@ -942,6 +955,8 @@ int ath9k_init_device(u16 devid, struct -+@@ -948,6 +961,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 --@@ -1327,9 +1327,30 @@ void ar5008_hw_init_rate_txpower(struct -+@@ -1325,9 +1325,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, --@@ -1344,6 +1365,8 @@ int ar5008_hw_attach_phy_ops(struct ath_ -+@@ -1342,6 +1363,8 @@ int ar5008_hw_attach_phy_ops(struct ath_ - if (ret) - return ret; - -@@ -175,7 +175,7 @@ - #define AR_PHY_TIMING2 0x9810 - #define AR_PHY_TIMING3 0x9814 - #define AR_PHY_TIMING3_DSC_MAN 0xFFFE0000 --@@ -390,6 +399,8 @@ -+@@ -393,6 +402,8 @@ - #define AR_PHY_RFBUS_GRANT 0x9C20 - #define AR_PHY_RFBUS_GRANT_EN 0x00000001 - -diff --git a/package/kernel/mac80211/patches/544-ath9k-ar933x-usb-hang-workaround.patch b/package/kernel/mac80211/patches/544-ath9k-ar933x-usb-hang-workaround.patch -index 8768c5d..b9c962e 100644 ---- a/package/kernel/mac80211/patches/544-ath9k-ar933x-usb-hang-workaround.patch -+++ b/package/kernel/mac80211/patches/544-ath9k-ar933x-usb-hang-workaround.patch -@@ -20,9 +20,9 @@ - /******************/ - /* Chip Revisions */ - /******************/ --@@ -1397,6 +1410,9 @@ static bool ath9k_hw_set_reset(struct at -- if (AR_SREV_9100(ah)) -+@@ -1417,6 +1430,9 @@ static bool ath9k_hw_set_reset(struct at - udelay(50); -+ } - - + if (AR_SREV_9330(ah) || AR_SREV_9340(ah)) - + ath9k_hw_disable_pll_lock_detect(ah); -@@ -30,7 +30,7 @@ - return true; - } - --@@ -1496,6 +1512,9 @@ static bool ath9k_hw_chip_reset(struct a -+@@ -1516,6 +1532,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; - } - --@@ -1797,8 +1816,14 @@ static int ath9k_hw_do_fastcc(struct ath -+@@ -1819,8 +1838,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; - } - --@@ -2052,6 +2077,9 @@ int ath9k_hw_reset(struct ath_hw *ah, st -+@@ -2074,6 +2099,9 @@ int ath9k_hw_reset(struct ath_hw *ah, st - ath9k_hw_set_radar_params(ah); - } - -diff --git a/package/kernel/mac80211/patches/545-ath9k_ani_ws_detect.patch b/package/kernel/mac80211/patches/545-ath9k_ani_ws_detect.patch -index 3d24ccd..b639f97 100644 ---- a/package/kernel/mac80211/patches/545-ath9k_ani_ws_detect.patch -+++ b/package/kernel/mac80211/patches/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 --@@ -956,55 +956,6 @@ static bool ar5008_hw_ani_control_new(st -+@@ -954,55 +954,6 @@ static bool ar5008_hw_ani_control_new(st - * on == 0 means more noise imm - */ - u32 on = param ? 1 : 0; -@@ -58,7 +58,7 @@ - REG_SET_BIT(ah, AR_PHY_SFCORR_LOW, - --- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c - +++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c --@@ -41,20 +41,6 @@ static const int cycpwrThr1_table[] = -+@@ -42,20 +42,6 @@ static const int cycpwrThr1_table[] = - /* level: 0 1 2 3 4 5 6 7 8 */ - { -6, -4, -2, 0, 2, 4, 6, 8 }; /* lvl 0-7, default 3 */ - -@@ -79,7 +79,7 @@ - static const u8 ofdm2pwr[] = { - ALL_TARGET_LEGACY_6_24, - ALL_TARGET_LEGACY_6_24, --@@ -1089,11 +1075,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) { --@@ -1107,61 +1088,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/546-ath9k_platform_led_name.patch b/package/kernel/mac80211/patches/546-ath9k_platform_led_name.patch -new file mode 100644 -index 0000000..ced72c6 ---- /dev/null -+++ b/package/kernel/mac80211/patches/546-ath9k_platform_led_name.patch -@@ -0,0 +1,39 @@ -+From: Michal Cieslakiewicz -+Date: Sun, 31 Jan 2016 20:45:57 +0100 -+Subject: [PATCH v4 1/8] mac80211: ath9k: enable platform WLAN LED name -+ -+Enable platform-supplied WLAN LED name for ath9k device. It replaces generic -+'ath9k-phy*' label with string set during platform initialization. -+ -+Signed-off-by: Michal Cieslakiewicz -+--- -+ drivers/net/wireless/ath/ath9k/gpio.c | 10 +++++++--- -+ include/linux/ath9k_platform.h | 1 + -+ 2 files changed, 8 insertions(+), 3 deletions(-) -+ -+--- a/drivers/net/wireless/ath/ath9k/gpio.c -++++ b/drivers/net/wireless/ath/ath9k/gpio.c -+@@ -155,8 +155,11 @@ void ath_init_leds(struct ath_softc *sc) -+ -+ ath_fill_led_pin(sc); -+ -+- snprintf(led_name, sizeof(led_name), "ath9k-%s", -+- wiphy_name(sc->hw->wiphy)); -++ if (pdata && pdata->led_name) -++ strncpy(led_name, pdata->led_name, sizeof(led_name)); -++ else -++ snprintf(led_name, sizeof(led_name), "ath9k-%s", -++ wiphy_name(sc->hw->wiphy)); -+ -+ if (ath9k_led_blink) -+ trigger = sc->led_default_trigger; -+--- a/include/linux/ath9k_platform.h -++++ b/include/linux/ath9k_platform.h -+@@ -49,6 +49,7 @@ struct ath9k_platform_data { -+ -+ int num_leds; -+ const struct gpio_led *leds; -++ const char *led_name; -+ }; -+ -+ #endif /* _LINUX_ATH9K_PLATFORM_H */ -diff --git a/package/kernel/mac80211/patches/547-ath9k_led_defstate_fix.patch b/package/kernel/mac80211/patches/547-ath9k_led_defstate_fix.patch -new file mode 100644 -index 0000000..5d84cf0 ---- /dev/null -+++ b/package/kernel/mac80211/patches/547-ath9k_led_defstate_fix.patch -@@ -0,0 +1,29 @@ -+From: Michal Cieslakiewicz -+Date: Sun, 31 Jan 2016 20:48:49 +0100 -+Subject: [PATCH v4 2/8] mac80211: ath9k: set default state for platform LEDs -+ -+Support default state for platform LEDs connected to ath9k device. -+Now LEDs are correctly set on or off at ath9k module initialization. -+Very useful if power LED is connected to wireless chip. -+ -+Signed-off-by: Michal Cieslakiewicz -+--- -+ gpio.c | 7 +++++-- -+ 1 file changed, 5 insertions(+), 2 deletions(-) -+ -+--- a/drivers/net/wireless/ath/ath9k/gpio.c -++++ b/drivers/net/wireless/ath/ath9k/gpio.c -+@@ -74,8 +74,11 @@ static int ath_add_led(struct ath_softc -+ ath9k_hw_gpio_request_out(sc->sc_ah, gpio->gpio, gpio->name, -+ AR_GPIO_OUTPUT_MUX_AS_OUTPUT); -+ -+- /* LED off */ -+- ath9k_hw_set_gpio(sc->sc_ah, gpio->gpio, gpio->active_low); -++ /* Set default LED state */ -++ if (gpio->default_state == LEDS_GPIO_DEFSTATE_ON) -++ ath9k_hw_set_gpio(sc->sc_ah, gpio->gpio, !gpio->active_low); -++ else -++ ath9k_hw_set_gpio(sc->sc_ah, gpio->gpio, gpio->active_low); -+ -+ return 0; -+ } -diff --git a/package/kernel/mac80211/patches/548-ath9k_enable_gpio_chip.patch b/package/kernel/mac80211/patches/548-ath9k_enable_gpio_chip.patch -new file mode 100644 -index 0000000..de7c0ac ---- /dev/null -+++ b/package/kernel/mac80211/patches/548-ath9k_enable_gpio_chip.patch -@@ -0,0 +1,234 @@ -+From: Michal Cieslakiewicz -+Date: Sun, 31 Jan 2016 21:01:31 +0100 -+Subject: [PATCH v4 4/8] mac80211: ath9k: enable access to GPIO -+ -+Enable access to GPIO chip and its pins for Atheros AR92xx -+wireless devices. For now AR9285 and AR9287 are supported. -+ -+Signed-off-by: Michal Cieslakiewicz -+Signed-off-by: Felix Fietkau -+--- -+--- a/drivers/net/wireless/ath/ath9k/ath9k.h -++++ b/drivers/net/wireless/ath/ath9k/ath9k.h -+@@ -24,6 +24,7 @@ -+ #include -+ #include -+ #include -++#include -+ -+ #include "common.h" -+ #include "debug.h" -+@@ -960,6 +961,14 @@ struct ath_led { -+ struct led_classdev cdev; -+ }; -+ -++#ifdef CONFIG_GPIOLIB -++struct ath9k_gpio_chip { -++ struct ath_softc *sc; -++ char label[32]; -++ struct gpio_chip gchip; -++}; -++#endif -++ -+ struct ath_softc { -+ struct ieee80211_hw *hw; -+ struct device *dev; -+@@ -1014,6 +1023,9 @@ struct ath_softc { -+ #ifdef CPTCFG_MAC80211_LEDS -+ const char *led_default_trigger; -+ struct list_head leds; -++#ifdef CONFIG_GPIOLIB -++ struct ath9k_gpio_chip *gpiochip; -++#endif -+ #endif -+ -+ #ifdef CPTCFG_ATH9K_DEBUGFS -+--- a/drivers/net/wireless/ath/ath9k/gpio.c -++++ b/drivers/net/wireless/ath/ath9k/gpio.c -+@@ -16,13 +16,135 @@ -+ -+ #include "ath9k.h" -+ #include -++#include -++ -++#ifdef CPTCFG_MAC80211_LEDS -++ -++#ifdef CONFIG_GPIOLIB -++ -++/***************/ -++/* GPIO Chip */ -++/***************/ -++ -++/* gpio_chip handler : set GPIO to input */ -++static int ath9k_gpio_pin_cfg_input(struct gpio_chip *chip, unsigned offset) -++{ -++ struct ath9k_gpio_chip *gc = container_of(chip, struct ath9k_gpio_chip, -++ gchip); -++ -++ ath9k_hw_gpio_request_in(gc->sc->sc_ah, offset, "ath9k-gpio"); -++ -++ return 0; -++} -++ -++/* gpio_chip handler : set GPIO to output */ -++static int ath9k_gpio_pin_cfg_output(struct gpio_chip *chip, unsigned offset, -++ int value) -++{ -++ struct ath9k_gpio_chip *gc = container_of(chip, struct ath9k_gpio_chip, -++ gchip); -++ -++ ath9k_hw_gpio_request_out(gc->sc->sc_ah, offset, "ath9k-gpio", -++ AR_GPIO_OUTPUT_MUX_AS_OUTPUT); -++ ath9k_hw_set_gpio(gc->sc->sc_ah, offset, value); -++ -++ return 0; -++} -++ -++/* gpio_chip handler : query GPIO direction (0=out, 1=in) */ -++static int ath9k_gpio_pin_get_dir(struct gpio_chip *chip, unsigned offset) -++{ -++ struct ath9k_gpio_chip *gc = container_of(chip, struct ath9k_gpio_chip, -++ gchip); -++ struct ath_hw *ah = gc->sc->sc_ah; -++ -++ return !((REG_READ(ah, AR_GPIO_OE_OUT) >> (offset * 2)) & 3); -++} -++ -++/* gpio_chip handler : get GPIO pin value */ -++static int ath9k_gpio_pin_get(struct gpio_chip *chip, unsigned offset) -++{ -++ struct ath9k_gpio_chip *gc = container_of(chip, struct ath9k_gpio_chip, -++ gchip); -++ -++ return ath9k_hw_gpio_get(gc->sc->sc_ah, offset); -++} -++ -++/* gpio_chip handler : set GPIO pin to value */ -++static void ath9k_gpio_pin_set(struct gpio_chip *chip, unsigned offset, -++ int value) -++{ -++ struct ath9k_gpio_chip *gc = container_of(chip, struct ath9k_gpio_chip, -++ gchip); -++ -++ ath9k_hw_set_gpio(gc->sc->sc_ah, offset, value); -++} -++ -++/* register GPIO chip */ -++static void ath9k_register_gpio_chip(struct ath_softc *sc) -++{ -++ struct ath9k_gpio_chip *gc; -++ struct ath_hw *ah = sc->sc_ah; -++ -++ gc = kzalloc(sizeof(struct ath9k_gpio_chip), GFP_KERNEL); -++ if (!gc) -++ return; -++ -++ snprintf(gc->label, sizeof(gc->label), "ath9k-%s", -++ wiphy_name(sc->hw->wiphy)); -++#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,5,0) -++ gc->gchip.parent = sc->dev; -++#else -++ gc->gchip.dev = sc->dev; -++#endif -++ gc->gchip.label = gc->label; -++ gc->gchip.base = -1; /* determine base automatically */ -++ gc->gchip.ngpio = ah->caps.num_gpio_pins; -++ gc->gchip.direction_input = ath9k_gpio_pin_cfg_input; -++ gc->gchip.direction_output = ath9k_gpio_pin_cfg_output; -++ gc->gchip.get_direction = ath9k_gpio_pin_get_dir; -++ gc->gchip.get = ath9k_gpio_pin_get; -++ gc->gchip.set = ath9k_gpio_pin_set; -++ -++ if (gpiochip_add(&gc->gchip)) { -++ kfree(gc); -++ return; -++ } -++ -++ gc->gchip.owner = NULL; -++ sc->gpiochip = gc; -++ gc->sc = sc; -++} -++ -++/* remove GPIO chip */ -++static void ath9k_unregister_gpio_chip(struct ath_softc *sc) -++{ -++ struct ath9k_gpio_chip *gc = sc->gpiochip; -++ -++ if (!gc) -++ return; -++ -++ gpiochip_remove(&gc->gchip); -++ kfree(gc); -++ sc->gpiochip = NULL; -++} -++ -++#else /* CONFIG_GPIOLIB */ -++ -++static inline void ath9k_register_gpio_chip(struct ath_softc *sc) -++{ -++} -++ -++static inline void ath9k_unregister_gpio_chip(struct ath_softc *sc) -++{ -++} -++ -++#endif /* CONFIG_GPIOLIB */ -+ -+ /********************************/ -+ /* LED functions */ -+ /********************************/ -+ -+-#ifdef CPTCFG_MAC80211_LEDS -+- -+ static void ath_fill_led_pin(struct ath_softc *sc) -+ { -+ struct ath_hw *ah = sc->sc_ah; -+@@ -80,6 +202,12 @@ static int ath_add_led(struct ath_softc -+ else -+ ath9k_hw_set_gpio(sc->sc_ah, gpio->gpio, gpio->active_low); -+ -++#ifdef CONFIG_GPIOLIB -++ /* If there is GPIO chip configured, reserve LED pin */ -++ if (sc->gpiochip) -++ gpio_request(sc->gpiochip->gchip.base + gpio->gpio, gpio->name); -++#endif -++ -+ return 0; -+ } -+ -+@@ -136,12 +264,18 @@ void ath_deinit_leds(struct ath_softc *s -+ -+ while (!list_empty(&sc->leds)) { -+ led = list_first_entry(&sc->leds, struct ath_led, list); -++#ifdef CONFIG_GPIOLIB -++ /* If there is GPIO chip configured, free LED pin */ -++ if (sc->gpiochip) -++ gpio_free(sc->gpiochip->gchip.base + led->gpio->gpio); -++#endif -+ list_del(&led->list); -+ ath_led_brightness(&led->cdev, LED_OFF); -+ led_classdev_unregister(&led->cdev); -+ ath9k_hw_gpio_free(sc->sc_ah, led->gpio->gpio); -+ kfree(led); -+ } -++ ath9k_unregister_gpio_chip(sc); -+ } -+ -+ void ath_init_leds(struct ath_softc *sc) -+@@ -158,6 +292,8 @@ void ath_init_leds(struct ath_softc *sc) -+ -+ ath_fill_led_pin(sc); -+ -++ ath9k_register_gpio_chip(sc); -++ -+ if (pdata && pdata->led_name) -+ strncpy(led_name, pdata->led_name, sizeof(led_name)); -+ else -+@@ -178,6 +314,7 @@ void ath_init_leds(struct ath_softc *sc) -+ for (i = 0; i < pdata->num_leds; i++) -+ ath_create_platform_led(sc, &pdata->leds[i]); -+ } -++ -+ #endif -+ -+ /*******************/ -diff --git a/package/kernel/mac80211/patches/549-ath9k_enable_gpio_buttons.patch b/package/kernel/mac80211/patches/549-ath9k_enable_gpio_buttons.patch -new file mode 100644 -index 0000000..b9d1883 ---- /dev/null -+++ b/package/kernel/mac80211/patches/549-ath9k_enable_gpio_buttons.patch -@@ -0,0 +1,149 @@ -+From: Michal Cieslakiewicz -+Subject: [PATCH v5 5/8] mac80211: ath9k: enable GPIO buttons -+ -+Enable platform-defined GPIO button support for ath9k device. -+Key poller is activated for attached platform buttons. -+Requires ath9k GPIO chip access. -+ -+Signed-off-by: Michal Cieslakiewicz -+Signed-off-by: Felix Fietkau -+--- -+--- a/drivers/net/wireless/ath/ath9k/ath9k.h -++++ b/drivers/net/wireless/ath/ath9k/ath9k.h -+@@ -1025,6 +1025,7 @@ struct ath_softc { -+ struct list_head leds; -+ #ifdef CONFIG_GPIOLIB -+ struct ath9k_gpio_chip *gpiochip; -++ struct platform_device *btnpdev; /* gpio-keys-polled */ -+ #endif -+ #endif -+ -+--- a/drivers/net/wireless/ath/ath9k/gpio.c -++++ b/drivers/net/wireless/ath/ath9k/gpio.c -+@@ -17,6 +17,8 @@ -+ #include "ath9k.h" -+ #include -+ #include -++#include -++#include -+ -+ #ifdef CPTCFG_MAC80211_LEDS -+ -+@@ -129,6 +131,64 @@ static void ath9k_unregister_gpio_chip(s -+ sc->gpiochip = NULL; -+ } -+ -++/******************/ -++/* GPIO Buttons */ -++/******************/ -++ -++/* add GPIO buttons */ -++static void ath9k_init_buttons(struct ath_softc *sc) -++{ -++ struct ath9k_platform_data *pdata = sc->dev->platform_data; -++ struct platform_device *pdev; -++ struct gpio_keys_platform_data gkpdata; -++ struct gpio_keys_button *bt; -++ int i; -++ -++ if (!sc->gpiochip) -++ return; -++ -++ if (!pdata || !pdata->btns || !pdata->num_btns) -++ return; -++ -++ bt = devm_kmemdup(sc->dev, pdata->btns, -++ pdata->num_btns * sizeof(struct gpio_keys_button), -++ GFP_KERNEL); -++ if (!bt) -++ return; -++ -++ for (i = 0; i < pdata->num_btns; i++) { -++ ath9k_hw_gpio_request_in(sc->sc_ah, pdata->btns[i].gpio, -++ "ath9k-gpio"); -++ bt[i].gpio = sc->gpiochip->gchip.base + pdata->btns[i].gpio; -++ } -++ -++ memset(&gkpdata, 0, sizeof(struct gpio_keys_platform_data)); -++ gkpdata.buttons = bt; -++ gkpdata.nbuttons = pdata->num_btns; -++ gkpdata.poll_interval = pdata->btn_poll_interval; -++ -++ pdev = platform_device_register_data(sc->dev, "gpio-keys-polled", -++ PLATFORM_DEVID_AUTO, &gkpdata, -++ sizeof(gkpdata)); -++ if (!IS_ERR_OR_NULL(pdev)) -++ sc->btnpdev = pdev; -++ else { -++ sc->btnpdev = NULL; -++ devm_kfree(sc->dev, bt); -++ } -++} -++ -++/* remove GPIO buttons */ -++static void ath9k_deinit_buttons(struct ath_softc *sc) -++{ -++ if (!sc->gpiochip || !sc->btnpdev) -++ return; -++ -++ platform_device_unregister(sc->btnpdev); -++ -++ sc->btnpdev = NULL; -++} -++ -+ #else /* CONFIG_GPIOLIB */ -+ -+ static inline void ath9k_register_gpio_chip(struct ath_softc *sc) -+@@ -139,6 +199,14 @@ static inline void ath9k_unregister_gpio -+ { -+ } -+ -++static inline void ath9k_init_buttons(struct ath_softc *sc) -++{ -++} -++ -++static inline void ath9k_deinit_buttons(struct ath_softc *sc) -++{ -++} -++ -+ #endif /* CONFIG_GPIOLIB */ -+ -+ /********************************/ -+@@ -262,6 +330,7 @@ void ath_deinit_leds(struct ath_softc *s -+ { -+ struct ath_led *led; -+ -++ ath9k_deinit_buttons(sc); -+ while (!list_empty(&sc->leds)) { -+ led = list_first_entry(&sc->leds, struct ath_led, list); -+ #ifdef CONFIG_GPIOLIB -+@@ -293,6 +362,7 @@ void ath_init_leds(struct ath_softc *sc) -+ ath_fill_led_pin(sc); -+ -+ ath9k_register_gpio_chip(sc); -++ ath9k_init_buttons(sc); -+ -+ if (pdata && pdata->led_name) -+ strncpy(led_name, pdata->led_name, sizeof(led_name)); -+@@ -308,7 +378,7 @@ void ath_init_leds(struct ath_softc *sc) -+ ath_create_gpio_led(sc, sc->sc_ah->led_pin, led_name, trigger, -+ !sc->sc_ah->config.led_active_high); -+ -+- if (!pdata) -++ if (!pdata || !pdata->leds || !pdata->num_leds) -+ return; -+ -+ for (i = 0; i < pdata->num_leds; i++) -+--- a/include/linux/ath9k_platform.h -++++ b/include/linux/ath9k_platform.h -+@@ -50,6 +50,10 @@ struct ath9k_platform_data { -+ int num_leds; -+ const struct gpio_led *leds; -+ const char *led_name; -++ -++ unsigned num_btns; -++ const struct gpio_keys_button *btns; -++ unsigned btn_poll_interval; -+ }; -+ -+ #endif /* _LINUX_ATH9K_PLATFORM_H */ -diff --git a/package/kernel/mac80211/patches/600-0002-rt2x00-rt2800lib-introduce-RT2800_HAS_HIGH_SHARED_ME.patch b/package/kernel/mac80211/patches/600-0002-rt2x00-rt2800lib-introduce-RT2800_HAS_HIGH_SHARED_ME.patch -index 8245909..db70a33 100644 ---- a/package/kernel/mac80211/patches/600-0002-rt2x00-rt2800lib-introduce-RT2800_HAS_HIGH_SHARED_ME.patch -+++ b/package/kernel/mac80211/patches/600-0002-rt2x00-rt2800lib-introduce-RT2800_HAS_HIGH_SHARED_ME.patch -@@ -24,7 +24,7 @@ Changes since v1: - - --- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c - +++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c --@@ -7722,6 +7722,7 @@ static int rt2800_probe_rt(struct rt2x00 -+@@ -7726,6 +7726,7 @@ static int rt2800_probe_rt(struct rt2x00 - - int rt2800_probe_hw(struct rt2x00_dev *rt2x00dev) - { -@@ -32,7 +32,7 @@ Changes since v1: - int retval; - u32 reg; - --@@ -7729,6 +7730,9 @@ int rt2800_probe_hw(struct rt2x00_dev *r -+@@ -7733,6 +7734,9 @@ int rt2800_probe_hw(struct rt2x00_dev *r - if (retval) - return retval; - -diff --git a/package/kernel/mac80211/patches/600-0003-rt2x00-rt2800-serialize-shared-memory-access.patch b/package/kernel/mac80211/patches/600-0003-rt2x00-rt2800-serialize-shared-memory-access.patch -index 7abfcd1..a3b62bc 100644 ---- a/package/kernel/mac80211/patches/600-0003-rt2x00-rt2800-serialize-shared-memory-access.patch -+++ b/package/kernel/mac80211/patches/600-0003-rt2x00-rt2800-serialize-shared-memory-access.patch -@@ -239,7 +239,7 @@ Changes since v1: --- - msleep(1); - - /* --@@ -7726,6 +7774,8 @@ int rt2800_probe_hw(struct rt2x00_dev *r -+@@ -7730,6 +7778,8 @@ int rt2800_probe_hw(struct rt2x00_dev *r - int retval; - u32 reg; - -@@ -248,7 +248,7 @@ Changes since v1: --- - retval = rt2800_probe_rt(rt2x00dev); - if (retval) - return retval; --@@ -7809,8 +7859,11 @@ void rt2800_get_key_seq(struct ieee80211 -+@@ -7813,8 +7863,11 @@ void rt2800_get_key_seq(struct ieee80211 - return; - - offset = MAC_IVEIV_ENTRY(key->hw_key_idx); -diff --git a/package/kernel/mac80211/patches/600-0005-rt2x00-rt2800lib-add-hw_beacon_count-field-to-struct.patch b/package/kernel/mac80211/patches/600-0005-rt2x00-rt2800lib-add-hw_beacon_count-field-to-struct.patch -index 02b2acf..f41a160 100644 ---- a/package/kernel/mac80211/patches/600-0005-rt2x00-rt2800lib-add-hw_beacon_count-field-to-struct.patch -+++ b/package/kernel/mac80211/patches/600-0005-rt2x00-rt2800lib-add-hw_beacon_count-field-to-struct.patch -@@ -41,7 +41,7 @@ Signed-off-by: Gabor Juhos - rt2800_clear_beacon_register(rt2x00dev, i); - - if (rt2x00_is_usb(rt2x00dev)) { --@@ -7827,6 +7828,8 @@ int rt2800_probe_hw(struct rt2x00_dev *r -+@@ -7831,6 +7832,8 @@ int rt2800_probe_hw(struct rt2x00_dev *r - if (rt2x00_rt(rt2x00dev, RT3593)) - __set_bit(RT2800_HAS_HIGH_SHARED_MEM, &drv_data->rt2800_flags); - -diff --git a/package/kernel/mac80211/patches/600-0007-rt2x00-rt2800lib-fix-max-supported-beacon-count-for-.patch b/package/kernel/mac80211/patches/600-0007-rt2x00-rt2800lib-fix-max-supported-beacon-count-for-.patch -index e909272..5099c64 100644 ---- a/package/kernel/mac80211/patches/600-0007-rt2x00-rt2800lib-fix-max-supported-beacon-count-for-.patch -+++ b/package/kernel/mac80211/patches/600-0007-rt2x00-rt2800lib-fix-max-supported-beacon-count-for-.patch -@@ -10,7 +10,7 @@ Signed-off-by: Gabor Juhos - - --- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c - +++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c --@@ -7852,7 +7852,10 @@ int rt2800_probe_hw(struct rt2x00_dev *r -+@@ -7856,7 +7856,10 @@ int rt2800_probe_hw(struct rt2x00_dev *r - if (rt2x00_rt(rt2x00dev, RT3593)) - __set_bit(RT2800_HAS_HIGH_SHARED_MEM, &drv_data->rt2800_flags); - -diff --git a/package/kernel/mac80211/patches/600-0009-rt2x00-rt2800lib-enable-support-for-RT3883.patch b/package/kernel/mac80211/patches/600-0009-rt2x00-rt2800lib-enable-support-for-RT3883.patch -index 7fe38e0..a2e7015 100644 ---- a/package/kernel/mac80211/patches/600-0009-rt2x00-rt2800lib-enable-support-for-RT3883.patch -+++ b/package/kernel/mac80211/patches/600-0009-rt2x00-rt2800lib-enable-support-for-RT3883.patch -@@ -10,7 +10,7 @@ Signed-off-by: Gabor Juhos - - --- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c - +++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c --@@ -7822,6 +7822,7 @@ static int rt2800_probe_rt(struct rt2x00 -+@@ -7826,6 +7826,7 @@ static int rt2800_probe_rt(struct rt2x00 - case RT3390: - case RT3572: - case RT3593: -diff --git a/package/kernel/mac80211/patches/600-0010-rt2x00-rt2800lib-add-rf_vals-for-RF3853.patch b/package/kernel/mac80211/patches/600-0010-rt2x00-rt2800lib-add-rf_vals-for-RF3853.patch -index 253a0c0..89bd0ac 100644 ---- a/package/kernel/mac80211/patches/600-0010-rt2x00-rt2800lib-add-rf_vals-for-RF3853.patch -+++ b/package/kernel/mac80211/patches/600-0010-rt2x00-rt2800lib-add-rf_vals-for-RF3853.patch -@@ -98,7 +98,7 @@ Signed-off-by: Gabor Juhos - static const struct rf_channel rf_vals_5592_xtal20[] = { - /* Channel, N, K, mod, R */ - {1, 482, 4, 10, 3}, --@@ -7669,6 +7729,11 @@ static int rt2800_probe_hw_mode(struct r -+@@ -7673,6 +7733,11 @@ static int rt2800_probe_hw_mode(struct r - spec->channels = rf_vals_3x; - break; - -diff --git a/package/kernel/mac80211/patches/600-0011-rt2x00-rt2800lib-enable-VCO-calibration-for-RF3853.patch b/package/kernel/mac80211/patches/600-0011-rt2x00-rt2800lib-enable-VCO-calibration-for-RF3853.patch -index f15c22b..b7efc9f 100644 ---- a/package/kernel/mac80211/patches/600-0011-rt2x00-rt2800lib-enable-VCO-calibration-for-RF3853.patch -+++ b/package/kernel/mac80211/patches/600-0011-rt2x00-rt2800lib-enable-VCO-calibration-for-RF3853.patch -@@ -18,7 +18,7 @@ Signed-off-by: Gabor Juhos - case RF5360: - case RF5362: - case RF5370: --@@ -7848,6 +7849,7 @@ static int rt2800_probe_hw_mode(struct r -+@@ -7852,6 +7853,7 @@ static int rt2800_probe_hw_mode(struct r - case RF3053: - case RF3070: - case RF3290: -diff --git a/package/kernel/mac80211/patches/600-0026-rt2x00-rt2800lib-use-correct-beacon-count-for-RT3883.patch b/package/kernel/mac80211/patches/600-0026-rt2x00-rt2800lib-use-correct-beacon-count-for-RT3883.patch -index 6ce224a..220e35f 100644 ---- a/package/kernel/mac80211/patches/600-0026-rt2x00-rt2800lib-use-correct-beacon-count-for-RT3883.patch -+++ b/package/kernel/mac80211/patches/600-0026-rt2x00-rt2800lib-use-correct-beacon-count-for-RT3883.patch -@@ -10,7 +10,7 @@ Signed-off-by: Gabor Juhos - - --- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c - +++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c --@@ -8403,7 +8403,8 @@ int rt2800_probe_hw(struct rt2x00_dev *r -+@@ -8407,7 +8407,8 @@ int rt2800_probe_hw(struct rt2x00_dev *r - if (rt2x00_rt(rt2x00dev, RT3593)) - __set_bit(RT2800_HAS_HIGH_SHARED_MEM, &drv_data->rt2800_flags); - -diff --git a/package/kernel/mac80211/patches/600-0032-rt2x00-rt2800lib-enable-RT2800_HAS_HIGH_SHARED_MEM-f.patch b/package/kernel/mac80211/patches/600-0032-rt2x00-rt2800lib-enable-RT2800_HAS_HIGH_SHARED_MEM-f.patch -index 25753af..2ffa5a4 100644 ---- a/package/kernel/mac80211/patches/600-0032-rt2x00-rt2800lib-enable-RT2800_HAS_HIGH_SHARED_MEM-f.patch -+++ b/package/kernel/mac80211/patches/600-0032-rt2x00-rt2800lib-enable-RT2800_HAS_HIGH_SHARED_MEM-f.patch -@@ -11,7 +11,7 @@ Signed-off-by: Gabor Juhos - - --- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c - +++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c --@@ -8416,7 +8416,8 @@ int rt2800_probe_hw(struct rt2x00_dev *r -+@@ -8420,7 +8420,8 @@ int rt2800_probe_hw(struct rt2x00_dev *r - if (retval) - return retval; - -diff --git a/package/kernel/mac80211/patches/602-rt2x00-introduce-rt2x00_platform_h.patch b/package/kernel/mac80211/patches/602-rt2x00-introduce-rt2x00_platform_h.patch -index 7a183a4..daa5dc6 100644 ---- a/package/kernel/mac80211/patches/602-rt2x00-introduce-rt2x00_platform_h.patch -+++ b/package/kernel/mac80211/patches/602-rt2x00-introduce-rt2x00_platform_h.patch -@@ -22,10 +22,10 @@ - +#endif /* _RT2X00_PLATFORM_H */ - --- a/drivers/net/wireless/ralink/rt2x00/rt2x00.h - +++ b/drivers/net/wireless/ralink/rt2x00/rt2x00.h --@@ -38,6 +38,7 @@ -- #include -+@@ -39,6 +39,7 @@ - #include - #include -+ #include - +#include - - #include -diff --git a/package/kernel/mac80211/patches/603-rt2x00-introduce-rt2x00eeprom.patch b/package/kernel/mac80211/patches/603-rt2x00-introduce-rt2x00eeprom.patch -index bc056cd..8ae5da3 100644 ---- a/package/kernel/mac80211/patches/603-rt2x00-introduce-rt2x00eeprom.patch -+++ b/package/kernel/mac80211/patches/603-rt2x00-introduce-rt2x00eeprom.patch -@@ -1,6 +1,6 @@ - --- a/.local-symbols - +++ b/.local-symbols --@@ -329,6 +329,7 @@ RT2X00_LIB_FIRMWARE= -+@@ -331,6 +331,7 @@ RT2X00_LIB_FIRMWARE= - RT2X00_LIB_CRYPTO= - RT2X00_LIB_LEDS= - RT2X00_LIB_DEBUGFS= -@@ -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 --@@ -697,6 +697,7 @@ enum rt2x00_capability_flags { -+@@ -699,6 +699,7 @@ enum rt2x00_capability_flags { - REQUIRE_HT_TX_DESC, - REQUIRE_PS_AUTOWAKE, - REQUIRE_DELAYED_RFKILL, -@@ -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 --@@ -1335,6 +1335,10 @@ int rt2x00lib_probe_dev(struct rt2x00_de -+@@ -1334,6 +1334,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. - */ --@@ -1475,6 +1479,11 @@ void rt2x00lib_remove_dev(struct rt2x00_ -+@@ -1477,6 +1481,11 @@ void rt2x00lib_remove_dev(struct rt2x00_ - * Free the driver data. - */ - kfree(rt2x00dev->drv_data); -diff --git a/package/kernel/mac80211/patches/607-rt2x00-allow_disabling_bands_through_platform_data.patch b/package/kernel/mac80211/patches/607-rt2x00-allow_disabling_bands_through_platform_data.patch -index d923e05..a2e1faf 100644 ---- a/package/kernel/mac80211/patches/607-rt2x00-allow_disabling_bands_through_platform_data.patch -+++ b/package/kernel/mac80211/patches/607-rt2x00-allow_disabling_bands_through_platform_data.patch -@@ -37,7 +37,7 @@ - num_rates += 4; - --- a/drivers/net/wireless/ralink/rt2x00/rt2x00.h - +++ b/drivers/net/wireless/ralink/rt2x00/rt2x00.h --@@ -405,6 +405,7 @@ struct hw_mode_spec { -+@@ -406,6 +406,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/608-add_platform_data_mac_addr.patch b/package/kernel/mac80211/patches/608-add_platform_data_mac_addr.patch -index a645ba1..6704ff8 100644 ---- a/package/kernel/mac80211/patches/608-add_platform_data_mac_addr.patch -+++ b/package/kernel/mac80211/patches/608-add_platform_data_mac_addr.patch -@@ -31,7 +31,7 @@ - { - --- a/drivers/net/wireless/ralink/rt2x00/rt2x00.h - +++ b/drivers/net/wireless/ralink/rt2x00/rt2x00.h --@@ -1414,6 +1414,7 @@ static inline void rt2x00debug_dump_fram -+@@ -1416,6 +1416,7 @@ static inline void rt2x00debug_dump_fram - */ - u32 rt2x00lib_get_bssidx(struct rt2x00_dev *rt2x00dev, - struct ieee80211_vif *vif); -diff --git a/package/kernel/mac80211/patches/610-rt2x00-fix-rt3352-ext-pa.patch b/package/kernel/mac80211/patches/610-rt2x00-fix-rt3352-ext-pa.patch -index c69d330..9f10fe3 100644 ---- a/package/kernel/mac80211/patches/610-rt2x00-fix-rt3352-ext-pa.patch -+++ b/package/kernel/mac80211/patches/610-rt2x00-fix-rt3352-ext-pa.patch -@@ -200,7 +200,7 @@ - * EEPROM frequency - --- a/drivers/net/wireless/ralink/rt2x00/rt2x00.h - +++ b/drivers/net/wireless/ralink/rt2x00/rt2x00.h --@@ -717,6 +717,8 @@ enum rt2x00_capability_flags { -+@@ -719,6 +719,8 @@ enum rt2x00_capability_flags { - CAPABILITY_DOUBLE_ANTENNA, - CAPABILITY_BT_COEXIST, - CAPABILITY_VCO_RECALIBRATION, -diff --git a/package/kernel/mac80211/patches/611-rt2x00-rf_vals-rt3352-xtal20.patch b/package/kernel/mac80211/patches/611-rt2x00-rf_vals-rt3352-xtal20.patch -index b44fe90..860fdc0 100644 ---- a/package/kernel/mac80211/patches/611-rt2x00-rf_vals-rt3352-xtal20.patch -+++ b/package/kernel/mac80211/patches/611-rt2x00-rf_vals-rt3352-xtal20.patch -@@ -28,7 +28,7 @@ - static int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev) - { - struct hw_mode_spec *spec = &rt2x00dev->spec; --@@ -8272,7 +8293,10 @@ static int rt2800_probe_hw_mode(struct r -+@@ -8276,7 +8297,10 @@ static int rt2800_probe_hw_mode(struct r - case RF5390: - case RF5392: - spec->num_channels = 14; -@@ -40,7 +40,7 @@ - break; - - case RF3052: --@@ -8456,6 +8480,19 @@ static int rt2800_probe_rt(struct rt2x00 -+@@ -8460,6 +8484,19 @@ static int rt2800_probe_rt(struct rt2x00 - return 0; - } - -@@ -60,7 +60,7 @@ - int rt2800_probe_hw(struct rt2x00_dev *rt2x00dev) - { - struct rt2800_drv_data *drv_data = rt2x00dev->drv_data; --@@ -8498,6 +8535,15 @@ int rt2800_probe_hw(struct rt2x00_dev *r -+@@ -8502,6 +8539,15 @@ int rt2800_probe_hw(struct rt2x00_dev *r - rt2800_register_write(rt2x00dev, GPIO_CTRL, reg); - - /* -@@ -78,7 +78,7 @@ - retval = rt2800_probe_hw_mode(rt2x00dev); - --- a/drivers/net/wireless/ralink/rt2x00/rt2x00.h - +++ b/drivers/net/wireless/ralink/rt2x00/rt2x00.h --@@ -400,6 +400,7 @@ static inline struct rt2x00_intf* vif_to -+@@ -401,6 +401,7 @@ static inline struct rt2x00_intf* vif_to - * @channels: Device/chipset specific channel values (See &struct rf_channel). - * @channels_info: Additional information for channels (See &struct channel_info). - * @ht: Driver HT Capabilities (See &ieee80211_sta_ht_cap). -@@ -86,7 +86,7 @@ - */ - struct hw_mode_spec { - unsigned int supported_bands; --@@ -416,6 +417,7 @@ struct hw_mode_spec { -+@@ -417,6 +418,7 @@ struct hw_mode_spec { - const struct channel_info *channels_info; - - struct ieee80211_sta_ht_cap ht; -diff --git a/package/kernel/mac80211/patches/615-rt2x00-fix_20mhz_clk.patch b/package/kernel/mac80211/patches/615-rt2x00-fix_20mhz_clk.patch -index 8e3bd2a..e7b2a8c 100644 ---- a/package/kernel/mac80211/patches/615-rt2x00-fix_20mhz_clk.patch -+++ b/package/kernel/mac80211/patches/615-rt2x00-fix_20mhz_clk.patch -@@ -8,7 +8,7 @@ - - #include "rt2x00.h" - #include "rt2800lib.h" --@@ -8482,13 +8483,14 @@ static int rt2800_probe_rt(struct rt2x00 -+@@ -8486,13 +8487,14 @@ static int rt2800_probe_rt(struct rt2x00 - - int rt2800_probe_clk(struct rt2x00_dev *rt2x00dev) - { -diff --git a/package/kernel/mac80211/patches/616-rt2x00-support-rt5350.patch b/package/kernel/mac80211/patches/616-rt2x00-support-rt5350.patch -index faa5879..44bd8a1 100644 ---- a/package/kernel/mac80211/patches/616-rt2x00-support-rt5350.patch -+++ b/package/kernel/mac80211/patches/616-rt2x00-support-rt5350.patch -@@ -240,7 +240,7 @@ - case RF5360: - case RF5362: - case RF5370: --@@ -8287,6 +8398,7 @@ static int rt2800_probe_hw_mode(struct r -+@@ -8291,6 +8402,7 @@ static int rt2800_probe_hw_mode(struct r - case RF3290: - case RF3320: - case RF3322: -@@ -248,7 +248,7 @@ - case RF5360: - case RF5362: - case RF5370: --@@ -8426,6 +8538,7 @@ static int rt2800_probe_hw_mode(struct r -+@@ -8430,6 +8542,7 @@ static int rt2800_probe_hw_mode(struct r - case RF3070: - case RF3290: - case RF3853: -@@ -256,7 +256,7 @@ - case RF5360: - case RF5362: - case RF5370: --@@ -8466,6 +8579,7 @@ static int rt2800_probe_rt(struct rt2x00 -+@@ -8470,6 +8583,7 @@ static int rt2800_probe_rt(struct rt2x00 - case RT3572: - case RT3593: - case RT3883: -@@ -266,7 +266,7 @@ - case RT5592: - --- a/drivers/net/wireless/ralink/rt2x00/rt2x00.h - +++ b/drivers/net/wireless/ralink/rt2x00/rt2x00.h --@@ -169,6 +169,7 @@ struct rt2x00_chip { -+@@ -170,6 +170,7 @@ struct rt2x00_chip { - #define RT3572 0x3572 - #define RT3593 0x3593 - #define RT3883 0x3883 /* WSOC */ -diff --git a/package/kernel/mac80211/patches/620-rt2x00-add-AP+STA-support.patch b/package/kernel/mac80211/patches/620-rt2x00-add-AP+STA-support.patch -index 55452b9..dba6033 100644 ---- a/package/kernel/mac80211/patches/620-rt2x00-add-AP+STA-support.patch -+++ b/package/kernel/mac80211/patches/620-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 --@@ -1284,7 +1284,7 @@ static inline void rt2x00lib_set_if_comb -+@@ -1283,7 +1283,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/801-libertas-configure-sysfs-links.patch b/package/kernel/mac80211/patches/801-libertas-configure-sysfs-links.patch -index fd885cc..02f3053 100644 ---- a/package/kernel/mac80211/patches/801-libertas-configure-sysfs-links.patch -+++ b/package/kernel/mac80211/patches/801-libertas-configure-sysfs-links.patch -@@ -1,6 +1,6 @@ - --- a/drivers/net/wireless/marvell/libertas/cfg.c - +++ b/drivers/net/wireless/marvell/libertas/cfg.c --@@ -2084,6 +2084,8 @@ struct wireless_dev *lbs_cfg_alloc(struc -+@@ -2122,6 +2122,8 @@ struct wireless_dev *lbs_cfg_alloc(struc - goto err_wiphy_new; - } - -diff --git a/package/kernel/mac80211/patches/802-libertas-set-wireless-macaddr.patch b/package/kernel/mac80211/patches/802-libertas-set-wireless-macaddr.patch -index b67a95f..ad30608 100644 ---- a/package/kernel/mac80211/patches/802-libertas-set-wireless-macaddr.patch -+++ b/package/kernel/mac80211/patches/802-libertas-set-wireless-macaddr.patch -@@ -1,6 +1,6 @@ - --- a/drivers/net/wireless/marvell/libertas/cfg.c - +++ b/drivers/net/wireless/marvell/libertas/cfg.c --@@ -2174,6 +2174,8 @@ int lbs_cfg_register(struct lbs_private -+@@ -2212,6 +2212,8 @@ int lbs_cfg_register(struct lbs_private - wdev->wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites); - wdev->wiphy->reg_notifier = lbs_reg_notifier; - -diff --git a/package/kernel/mac80211/patches/804-b43-sync-with-bcma.patch b/package/kernel/mac80211/patches/804-b43-sync-with-bcma.patch -deleted file mode 100644 -index 74cd448..0000000 ---- a/package/kernel/mac80211/patches/804-b43-sync-with-bcma.patch -+++ /dev/null -@@ -1,17 +0,0 @@ ----- a/drivers/net/wireless/broadcom/b43/main.c --+++ b/drivers/net/wireless/broadcom/b43/main.c --@@ -1215,10 +1215,10 @@ void b43_wireless_core_phy_pll_reset(str -- case B43_BUS_BCMA: -- bcma_cc = &dev->dev->bdev->bus->drv_cc; -- --- bcma_cc_write32(bcma_cc, BCMA_CC_CHIPCTL_ADDR, 0); --- bcma_cc_mask32(bcma_cc, BCMA_CC_CHIPCTL_DATA, ~0x4); --- bcma_cc_set32(bcma_cc, BCMA_CC_CHIPCTL_DATA, 0x4); --- bcma_cc_mask32(bcma_cc, BCMA_CC_CHIPCTL_DATA, ~0x4); --+ bcma_cc_write32(bcma_cc, BCMA_CC_PMU_CHIPCTL_ADDR, 0); --+ bcma_cc_mask32(bcma_cc, BCMA_CC_PMU_CHIPCTL_DATA, ~0x4); --+ bcma_cc_set32(bcma_cc, BCMA_CC_PMU_CHIPCTL_DATA, 0x4); --+ bcma_cc_mask32(bcma_cc, BCMA_CC_PMU_CHIPCTL_DATA, ~0x4); -- break; -- #endif -- #ifdef CPTCFG_B43_SSB -diff --git a/package/kernel/mac80211/patches/820-b43-add-antenna-control.patch b/package/kernel/mac80211/patches/820-b43-add-antenna-control.patch -index 06c731f..f8f555f 100644 ---- a/package/kernel/mac80211/patches/820-b43-add-antenna-control.patch -+++ b/package/kernel/mac80211/patches/820-b43-add-antenna-control.patch -@@ -9,7 +9,7 @@ - antenna = b43_antenna_to_phyctl(antenna); - ctl = b43_shm_read16(dev, B43_SHM_SHARED, B43_SHM_SH_BEACPHYCTL); - /* We can't send beacons with short preamble. Would get PHY errors. */ --@@ -3300,8 +3300,8 @@ static int b43_chip_init(struct b43_wlde -+@@ -3297,8 +3297,8 @@ static int b43_chip_init(struct b43_wlde - - /* Select the antennae */ - if (phy->ops->set_rx_antenna) -@@ -20,7 +20,7 @@ - - if (phy->type == B43_PHYTYPE_B) { - value16 = b43_read16(dev, 0x005E); --@@ -4001,7 +4001,6 @@ static int b43_op_config(struct ieee8021 -+@@ -3998,7 +3998,6 @@ static int b43_op_config(struct ieee8021 - struct b43_wldev *dev = wl->current_dev; - struct b43_phy *phy = &dev->phy; - struct ieee80211_conf *conf = &hw->conf; -@@ -28,7 +28,7 @@ - int err = 0; - - mutex_lock(&wl->mutex); --@@ -4044,11 +4043,9 @@ static int b43_op_config(struct ieee8021 -+@@ -4041,11 +4040,9 @@ static int b43_op_config(struct ieee8021 - } - - /* Antennas for RX and management frame TX. */ -@@ -42,7 +42,7 @@ - - if (wl->radio_enabled != phy->radio_on) { - if (wl->radio_enabled) { --@@ -5209,6 +5206,47 @@ static int b43_op_get_survey(struct ieee -+@@ -5189,6 +5186,47 @@ static int b43_op_get_survey(struct ieee - return 0; - } - -@@ -90,7 +90,7 @@ - static const struct ieee80211_ops b43_hw_ops = { - .tx = b43_op_tx, - .conf_tx = b43_op_conf_tx, --@@ -5230,6 +5268,8 @@ static const struct ieee80211_ops b43_hw -+@@ -5210,6 +5248,8 @@ static const struct ieee80211_ops b43_hw - .sw_scan_complete = b43_op_sw_scan_complete_notifier, - .get_survey = b43_op_get_survey, - .rfkill_poll = b43_rfkill_poll, -@@ -99,7 +99,7 @@ - }; - - /* Hard-reset the chip. Do not call this directly. --@@ -5538,6 +5578,8 @@ static int b43_one_core_attach(struct b4 -+@@ -5513,6 +5553,8 @@ static int b43_one_core_attach(struct b4 - if (!wldev) - goto out; - -@@ -108,7 +108,7 @@ - wldev->use_pio = b43_modparam_pio; - wldev->dev = dev; - wldev->wl = wl; --@@ -5628,6 +5670,9 @@ static struct b43_wl *b43_wireless_init( -+@@ -5603,6 +5645,9 @@ static struct b43_wl *b43_wireless_init( - - hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN; - -diff --git a/package/kernel/mac80211/patches/860-brcmfmac-add-missing-eth_type_trans-call.patch b/package/kernel/mac80211/patches/860-brcmfmac-add-missing-eth_type_trans-call.patch -deleted file mode 100644 -index e265354..0000000 ---- a/package/kernel/mac80211/patches/860-brcmfmac-add-missing-eth_type_trans-call.patch -+++ /dev/null -@@ -1,26 +0,0 @@ --From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= --Subject: [PATCH] brcmfmac: add missing eth_type_trans call --MIME-Version: 1.0 --Content-Type: text/plain; charset=UTF-8 --Content-Transfer-Encoding: 8bit -- --There are 2 protocols supported by brcmfmac and msgbuf one was missing a --proper skb setup before passing it to the netif. This was triggering --"NULL pointer dereference". -- --Fixes: 9c349892ccc9 ("brcmfmac: revise handling events in receive path") --Signed-off-by: Rafał Miłecki ----- -- ----- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c --+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c --@@ -1157,6 +1157,9 @@ brcmf_msgbuf_process_rx_complete(struct -- brcmu_pkt_buf_free_skb(skb); -- return; -- } --+ --+ skb->protocol = eth_type_trans(skb, ifp->ndev); --+ -- brcmf_netif_rx(ifp, skb); -- } -- -diff --git a/package/kernel/mac80211/patches/860-brcmfmac-register-wiphy-s-during-module_init.patch b/package/kernel/mac80211/patches/860-brcmfmac-register-wiphy-s-during-module_init.patch -new file mode 100644 -index 0000000..ae571c9 ---- /dev/null -+++ b/package/kernel/mac80211/patches/860-brcmfmac-register-wiphy-s-during-module_init.patch -@@ -0,0 +1,97 @@ -+From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= -+Date: Mon, 8 Jun 2015 16:11:40 +0200 -+Subject: [PATCH] brcmfmac: register wiphy(s) during module_init -+MIME-Version: 1.0 -+Content-Type: text/plain; charset=UTF-8 -+Content-Transfer-Encoding: 8bit -+ -+This is needed by OpenWrt which expects all PHYs to be created after -+module loads successfully. -+ -+Signed-off-by: RafaÅ‚ MiÅ‚ecki -+--- -+ -+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c -++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c -+@@ -1213,6 +1213,7 @@ int __init brcmf_core_init(void) -+ { -+ if (!schedule_work(&brcmf_driver_work)) -+ return -EBUSY; -++ flush_work(&brcmf_driver_work); -+ -+ return 0; -+ } -+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c -++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c -+@@ -444,6 +444,7 @@ struct brcmf_fw { -+ u16 bus_nr; -+ void (*done)(struct device *dev, const struct firmware *fw, -+ void *nvram_image, u32 nvram_len); -++ struct completion *completion; -+ }; -+ -+ static void brcmf_fw_request_nvram_done(const struct firmware *fw, void *ctx) -+@@ -478,6 +479,8 @@ static void brcmf_fw_request_nvram_done( -+ goto fail; -+ -+ fwctx->done(fwctx->dev, fwctx->code, nvram, nvram_length); -++ if (fwctx->completion) -++ complete(fwctx->completion); -+ kfree(fwctx); -+ return; -+ -+@@ -485,6 +488,8 @@ fail: -+ brcmf_dbg(TRACE, "failed: dev=%s\n", dev_name(fwctx->dev)); -+ release_firmware(fwctx->code); -+ device_release_driver(fwctx->dev); -++ if (fwctx->completion) -++ complete(fwctx->completion); -+ kfree(fwctx); -+ } -+ -+@@ -500,6 +505,8 @@ static void brcmf_fw_request_code_done(c -+ /* only requested code so done here */ -+ if (!(fwctx->flags & BRCMF_FW_REQUEST_NVRAM)) { -+ fwctx->done(fwctx->dev, fw, NULL, 0); -++ if (fwctx->completion) -++ complete(fwctx->completion); -+ kfree(fwctx); -+ return; -+ } -+@@ -517,6 +524,8 @@ static void brcmf_fw_request_code_done(c -+ fail: -+ brcmf_dbg(TRACE, "failed: dev=%s\n", dev_name(fwctx->dev)); -+ device_release_driver(fwctx->dev); -++ if (fwctx->completion) -++ complete(fwctx->completion); -+ kfree(fwctx); -+ } -+ -+@@ -528,6 +537,8 @@ int brcmf_fw_get_firmwares_pcie(struct d -+ u16 domain_nr, u16 bus_nr) -+ { -+ struct brcmf_fw *fwctx; -++ struct completion completion; -++ int err; -+ -+ brcmf_dbg(TRACE, "enter: dev=%s\n", dev_name(dev)); -+ if (!fw_cb || !code) -+@@ -548,9 +559,17 @@ int brcmf_fw_get_firmwares_pcie(struct d -+ fwctx->domain_nr = domain_nr; -+ fwctx->bus_nr = bus_nr; -+ -+- return request_firmware_nowait(THIS_MODULE, true, code, dev, -++ init_completion(&completion); -++ fwctx->completion = &completion; -++ -++ err = request_firmware_nowait(THIS_MODULE, true, code, dev, -+ GFP_KERNEL, fwctx, -+ brcmf_fw_request_code_done); -++ if (!err) -++ wait_for_completion_timeout(fwctx->completion, -++ msecs_to_jiffies(5000)); -++ fwctx->completion = NULL; -++ return err; -+ } -+ -+ int brcmf_fw_get_firmwares(struct device *dev, u16 flags, -diff --git a/package/kernel/mac80211/patches/861-brcmfmac-register-wiphy-s-during-module_init.patch b/package/kernel/mac80211/patches/861-brcmfmac-register-wiphy-s-during-module_init.patch -deleted file mode 100644 -index f7f44f5..0000000 ---- a/package/kernel/mac80211/patches/861-brcmfmac-register-wiphy-s-during-module_init.patch -+++ /dev/null -@@ -1,97 +0,0 @@ --From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= --Date: Mon, 8 Jun 2015 16:11:40 +0200 --Subject: [PATCH] brcmfmac: register wiphy(s) during module_init --MIME-Version: 1.0 --Content-Type: text/plain; charset=UTF-8 --Content-Transfer-Encoding: 8bit -- --This is needed by OpenWrt which expects all PHYs to be created after --module loads successfully. -- --Signed-off-by: RafaÅ‚ MiÅ‚ecki ----- -- ----- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c --+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c --@@ -1200,6 +1200,7 @@ int __init brcmf_core_init(void) -- { -- if (!schedule_work(&brcmf_driver_work)) -- return -EBUSY; --+ flush_work(&brcmf_driver_work); -- -- return 0; -- } ----- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c --+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c --@@ -444,6 +444,7 @@ struct brcmf_fw { -- u16 bus_nr; -- void (*done)(struct device *dev, const struct firmware *fw, -- void *nvram_image, u32 nvram_len); --+ struct completion *completion; -- }; -- -- static void brcmf_fw_request_nvram_done(const struct firmware *fw, void *ctx) --@@ -478,6 +479,8 @@ static void brcmf_fw_request_nvram_done( -- goto fail; -- -- fwctx->done(fwctx->dev, fwctx->code, nvram, nvram_length); --+ if (fwctx->completion) --+ complete(fwctx->completion); -- kfree(fwctx); -- return; -- --@@ -485,6 +488,8 @@ fail: -- brcmf_dbg(TRACE, "failed: dev=%s\n", dev_name(fwctx->dev)); -- release_firmware(fwctx->code); -- device_release_driver(fwctx->dev); --+ if (fwctx->completion) --+ complete(fwctx->completion); -- kfree(fwctx); -- } -- --@@ -500,6 +505,8 @@ static void brcmf_fw_request_code_done(c -- /* only requested code so done here */ -- if (!(fwctx->flags & BRCMF_FW_REQUEST_NVRAM)) { -- fwctx->done(fwctx->dev, fw, NULL, 0); --+ if (fwctx->completion) --+ complete(fwctx->completion); -- kfree(fwctx); -- return; -- } --@@ -517,6 +524,8 @@ static void brcmf_fw_request_code_done(c -- fail: -- brcmf_dbg(TRACE, "failed: dev=%s\n", dev_name(fwctx->dev)); -- device_release_driver(fwctx->dev); --+ if (fwctx->completion) --+ complete(fwctx->completion); -- kfree(fwctx); -- } -- --@@ -528,6 +537,8 @@ int brcmf_fw_get_firmwares_pcie(struct d -- u16 domain_nr, u16 bus_nr) -- { -- struct brcmf_fw *fwctx; --+ struct completion completion; --+ int err; -- -- brcmf_dbg(TRACE, "enter: dev=%s\n", dev_name(dev)); -- if (!fw_cb || !code) --@@ -548,9 +559,17 @@ int brcmf_fw_get_firmwares_pcie(struct d -- fwctx->domain_nr = domain_nr; -- fwctx->bus_nr = bus_nr; -- --- return request_firmware_nowait(THIS_MODULE, true, code, dev, --+ init_completion(&completion); --+ fwctx->completion = &completion; --+ --+ err = request_firmware_nowait(THIS_MODULE, true, code, dev, -- GFP_KERNEL, fwctx, -- brcmf_fw_request_code_done); --+ if (!err) --+ wait_for_completion_timeout(fwctx->completion, --+ msecs_to_jiffies(5000)); --+ fwctx->completion = NULL; --+ return err; -- } -- -- int brcmf_fw_get_firmwares(struct device *dev, u16 flags, -diff --git a/package/kernel/mac80211/patches/861-brcmfmac-workaround-bug-with-some-inconsistent-BSSes.patch b/package/kernel/mac80211/patches/861-brcmfmac-workaround-bug-with-some-inconsistent-BSSes.patch -new file mode 100644 -index 0000000..8721155 ---- /dev/null -+++ b/package/kernel/mac80211/patches/861-brcmfmac-workaround-bug-with-some-inconsistent-BSSes.patch -@@ -0,0 +1,50 @@ -+From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= -+Date: Thu, 9 Jul 2015 00:07:59 +0200 -+Subject: [PATCH] brcmfmac: workaround bug with some inconsistent BSSes state -+MIME-Version: 1.0 -+Content-Type: text/plain; charset=UTF-8 -+Content-Transfer-Encoding: 8bit -+ -+Signed-off-by: RafaÅ‚ MiÅ‚ecki -+--- -+ -+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c -++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c -+@@ -665,9 +665,37 @@ static struct wireless_dev *brcmf_cfg802 -+ u32 *flags, -+ struct vif_params *params) -+ { -++ struct net_device *dev; -+ struct wireless_dev *wdev; -+ int err; -+ -++ /* -++ * There is a bug with in-firmware BSS management. When adding virtual -++ * interface brcmfmac first tells firmware to create new BSS and then -++ * it creates new struct net_device. -++ * -++ * If creating/registering netdev(ice) fails, BSS remains in some bugged -++ * state. It conflicts with existing BSSes by overtaking their auth -++ * requests. -++ * -++ * It results in one BSS (addresss X) sending beacons and another BSS -++ * (address Y) replying to authentication requests. This makes interface -++ * unusable as AP. -++ * -++ * To workaround this bug we may try to guess if register_netdev(ice) -++ * will fail. The most obvious case is using interface name that already -++ * exists. This is actually quite likely with brcmfmac & some user space -++ * scripts as brcmfmac doesn't allow deleting virtual interfaces. -++ * So this bug can be triggered even by something trivial like: -++ * iw dev wlan0 delete -++ * iw phy phy0 interface add wlan0 type __ap -++ */ -++ dev = dev_get_by_name(&init_net, name); -++ if (dev) { -++ dev_put(dev); -++ return ERR_PTR(-ENFILE); -++ } -++ -+ brcmf_dbg(TRACE, "enter: %s type %d\n", name, type); -+ err = brcmf_vif_add_validate(wiphy_to_cfg(wiphy), type); -+ if (err) { -diff --git a/package/kernel/mac80211/patches/862-brcmfmac-Disable-power-management.patch b/package/kernel/mac80211/patches/862-brcmfmac-Disable-power-management.patch -new file mode 100644 -index 0000000..f301fe1 ---- /dev/null -+++ b/package/kernel/mac80211/patches/862-brcmfmac-Disable-power-management.patch -@@ -0,0 +1,27 @@ -+From 66ae1b1750720a33e29792a177b1e696f4f005fb Mon Sep 17 00:00:00 2001 -+From: Phil Elwell -+Date: Wed, 9 Mar 2016 17:25:59 +0000 -+Subject: [PATCH] brcmfmac: Disable power management -+ -+Disable wireless power saving in the brcmfmac WLAN driver. This is a -+temporary measure until the connectivity loss resulting from power -+saving is resolved. -+ -+Signed-off-by: Phil Elwell -+--- -+ drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c | 2 ++ -+ 1 file changed, 2 insertions(+) -+ -+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c -++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c -+@@ -2783,6 +2783,10 @@ brcmf_cfg80211_set_power_mgmt(struct wip -+ * preference in cfg struct to apply this to -+ * FW later while initializing the dongle -+ */ -++#if defined(CONFIG_BCM2708) || defined(CONFIG_BCM2709) -++ pr_info("power management disabled\n"); -++ enabled = false; -++#endif -+ cfg->pwr_save = enabled; -+ if (!check_vif_up(ifp->vif)) { -+ -diff --git a/package/kernel/mac80211/patches/862-brcmfmac-workaround-bug-with-some-inconsistent-BSSes.patch b/package/kernel/mac80211/patches/862-brcmfmac-workaround-bug-with-some-inconsistent-BSSes.patch -deleted file mode 100644 -index 1e440c0..0000000 ---- a/package/kernel/mac80211/patches/862-brcmfmac-workaround-bug-with-some-inconsistent-BSSes.patch -+++ /dev/null -@@ -1,50 +0,0 @@ --From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= --Date: Thu, 9 Jul 2015 00:07:59 +0200 --Subject: [PATCH] brcmfmac: workaround bug with some inconsistent BSSes state --MIME-Version: 1.0 --Content-Type: text/plain; charset=UTF-8 --Content-Transfer-Encoding: 8bit -- --Signed-off-by: RafaÅ‚ MiÅ‚ecki ----- -- ----- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c --+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c --@@ -651,9 +651,37 @@ static struct wireless_dev *brcmf_cfg802 -- u32 *flags, -- struct vif_params *params) -- { --+ struct net_device *dev; -- struct wireless_dev *wdev; -- int err; -- --+ /* --+ * There is a bug with in-firmware BSS management. When adding virtual --+ * interface brcmfmac first tells firmware to create new BSS and then --+ * it creates new struct net_device. --+ * --+ * If creating/registering netdev(ice) fails, BSS remains in some bugged --+ * state. It conflicts with existing BSSes by overtaking their auth --+ * requests. --+ * --+ * It results in one BSS (addresss X) sending beacons and another BSS --+ * (address Y) replying to authentication requests. This makes interface --+ * unusable as AP. --+ * --+ * To workaround this bug we may try to guess if register_netdev(ice) --+ * will fail. The most obvious case is using interface name that already --+ * exists. This is actually quite likely with brcmfmac & some user space --+ * scripts as brcmfmac doesn't allow deleting virtual interfaces. --+ * So this bug can be triggered even by something trivial like: --+ * iw dev wlan0 delete --+ * iw phy phy0 interface add wlan0 type __ap --+ */ --+ dev = dev_get_by_name(&init_net, name); --+ if (dev) { --+ dev_put(dev); --+ return ERR_PTR(-ENFILE); --+ } --+ -- brcmf_dbg(TRACE, "enter: %s type %d\n", name, type); -- err = brcmf_vif_add_validate(wiphy_to_cfg(wiphy), type); -- if (err) { -diff --git a/package/kernel/mac80211/patches/910-01-add-support-for-mt7620.patch b/package/kernel/mac80211/patches/910-01-add-support-for-mt7620.patch -index f2e21ea..be210f2 100644 ---- a/package/kernel/mac80211/patches/910-01-add-support-for-mt7620.patch -+++ b/package/kernel/mac80211/patches/910-01-add-support-for-mt7620.patch -@@ -1184,7 +1184,7 @@ - break; - default: - rt2x00_err(rt2x00dev, "Invalid RF chipset 0x%04x detected\n", --@@ -8423,6 +9363,7 @@ static int rt2800_probe_hw_mode(struct r -+@@ -8427,6 +9367,7 @@ static int rt2800_probe_hw_mode(struct r - case RF5372: - case RF5390: - case RF5392: -@@ -1192,7 +1192,7 @@ - spec->num_channels = 14; - if (spec->clk_is_20mhz) - spec->channels = rf_vals_xtal20mhz_3x; --@@ -8563,6 +9504,7 @@ static int rt2800_probe_hw_mode(struct r -+@@ -8567,6 +9508,7 @@ static int rt2800_probe_hw_mode(struct r - case RF5372: - case RF5390: - case RF5392: -diff --git a/package/kernel/mac80211/patches/921-ath10k_init_devices_synchronously.patch b/package/kernel/mac80211/patches/921-ath10k_init_devices_synchronously.patch -index 8c6d720..e842d61 100644 ---- a/package/kernel/mac80211/patches/921-ath10k_init_devices_synchronously.patch -+++ b/package/kernel/mac80211/patches/921-ath10k_init_devices_synchronously.patch -@@ -14,7 +14,7 @@ Signed-off-by: Sven Eckelmann - - --- a/drivers/net/wireless/ath/ath10k/core.c - +++ b/drivers/net/wireless/ath/ath10k/core.c --@@ -1914,6 +1914,16 @@ int ath10k_core_register(struct ath10k * -+@@ -2107,6 +2107,16 @@ int ath10k_core_register(struct ath10k * - ar->chip_id = chip_id; - queue_work(ar->workqueue, &ar->register_work); - -diff --git a/package/kernel/mac80211/patches/930-ath10k_add_tpt_led_trigger.patch b/package/kernel/mac80211/patches/930-ath10k_add_tpt_led_trigger.patch -index 281b447..a501b99 100644 ---- a/package/kernel/mac80211/patches/930-ath10k_add_tpt_led_trigger.patch -+++ b/package/kernel/mac80211/patches/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 --@@ -7141,6 +7141,21 @@ struct ath10k_vif *ath10k_get_arvif(stru -+@@ -7742,6 +7742,21 @@ struct ath10k_vif *ath10k_get_arvif(stru - return arvif_iter.arvif; - } - -@@ -22,11 +22,11 @@ - int ath10k_mac_register(struct ath10k *ar) - { - static const u32 cipher_suites[] = { --@@ -7357,6 +7372,12 @@ int ath10k_mac_register(struct ath10k *a -+@@ -7975,6 +7990,12 @@ int ath10k_mac_register(struct ath10k *a - ar->hw->wiphy->cipher_suites = cipher_suites; - ar->hw->wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites); - --+#if CPTCFG_MAC80211_LEDS -++#ifdef CPTCFG_MAC80211_LEDS - + ieee80211_create_tpt_led_trigger(ar->hw, - + IEEE80211_TPT_LEDTRIG_FL_RADIO, ath10k_tpt_blink, - + ARRAY_SIZE(ath10k_tpt_blink)); -diff --git a/package/kernel/mac80211/patches/936-ath10k_skip_otp_check.patch b/package/kernel/mac80211/patches/936-ath10k_skip_otp_check.patch -new file mode 100644 -index 0000000..596ef98 ---- /dev/null -+++ b/package/kernel/mac80211/patches/936-ath10k_skip_otp_check.patch -@@ -0,0 +1,51 @@ -+--- a/drivers/net/wireless/ath/ath10k/core.c -++++ b/drivers/net/wireless/ath/ath10k/core.c -+@@ -1243,9 +1243,6 @@ static int ath10k_core_fetch_firmware_fi -+ { -+ int ret; -+ -+- /* calibration file is optional, don't check for any errors */ -+- ath10k_fetch_cal_file(ar); -+- -+ ar->fw_api = 5; -+ ath10k_dbg(ar, ATH10K_DBG_BOOT, "trying fw api %d\n", ar->fw_api); -+ -+@@ -1944,7 +1941,7 @@ EXPORT_SYMBOL(ath10k_core_stop); -+ static int ath10k_core_probe_fw(struct ath10k *ar) -+ { -+ struct bmi_target_info target_info; -+- int ret = 0; -++ int calret, ret = 0; -+ -+ ret = ath10k_hif_power_up(ar); -+ if (ret) { -+@@ -1968,6 +1965,9 @@ static int ath10k_core_probe_fw(struct a -+ goto err_power_down; -+ } -+ -++ /* calibration file is optional, don't check for any errors */ -++ calret = ath10k_fetch_cal_file(ar); -++ -+ ret = ath10k_core_fetch_firmware_files(ar); -+ if (ret) { -+ ath10k_err(ar, "could not fetch firmware files (%d)\n", ret); -+@@ -1990,11 +1990,14 @@ static int ath10k_core_probe_fw(struct a -+ "could not load pre cal data: %d\n", ret); -+ } -+ -+- ret = ath10k_core_get_board_id_from_otp(ar); -+- if (ret && ret != -EOPNOTSUPP) { -+- ath10k_err(ar, "failed to get board id from otp: %d\n", -+- ret); -+- goto err_free_firmware_files; -++ /* otp and board file not needed if calibration data is present */ -++ if (calret) { -++ ret = ath10k_core_get_board_id_from_otp(ar); -++ if (ret && ret != -EOPNOTSUPP) { -++ ath10k_err(ar, "failed to get board id from otp: %d\n", -++ ret); -++ goto err_free_firmware_files; -++ } -+ } -+ -+ ret = ath10k_core_fetch_board_file(ar); -diff --git a/package/kernel/mt76/Makefile b/package/kernel/mt76/Makefile -index e49dd48..bd851e6 100644 ---- a/package/kernel/mt76/Makefile -+++ b/package/kernel/mt76/Makefile -@@ -1,7 +1,7 @@ - include $(TOPDIR)/rules.mk - - PKG_NAME:=mt76 --PKG_VERSION:=2016-03-03 -+PKG_VERSION:=2016-08-25 - PKG_RELEASE=1 - - PKG_LICENSE:=GPLv2 -@@ -10,23 +10,26 @@ PKG_LICENSE_FILES:= - PKG_SOURCE_URL:=https://github.com/openwrt/mt76 - PKG_SOURCE_PROTO:=git - PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION) --PKG_SOURCE_VERSION:=310d420178c86e253a172413da30ecf479b64251 -+PKG_SOURCE_VERSION:=c3127d2acc354b4a27c8604716b0591093601971 - PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)-$(PKG_SOURCE_VERSION).tar.xz - --PKG_MAINTAINER:=Felix Fietkau -+PKG_MAINTAINER:=Felix Fietkau - PKG_BUILD_PARALLEL:=1 - -+STAMP_CONFIGURED_DEPENDS := $(STAGING_DIR)/usr/include/mac80211-backport/backport/autoconf.h -+ - include $(INCLUDE_DIR)/kernel.mk - include $(INCLUDE_DIR)/package.mk - - define KernelPackage/mt76 - SUBMENU:=Wireless Drivers -- TITLE:=MediaTek MT76x2 wireless driver -- DEPENDS:=+kmod-mac80211 +@DRIVER_11N_SUPPORT @PCI_SUPPORT -+ TITLE:=MediaTek MT76x2/MT7603 wireless driver -+ DEPENDS:=+kmod-mac80211 +@DRIVER_11N_SUPPORT @PCI_SUPPORT @!LINUX_3_18 - FILES:=\ - $(PKG_BUILD_DIR)/mt76.ko \ -- $(PKG_BUILD_DIR)/mt76x2e.ko -- AUTOLOAD:=$(call AutoLoad,50,mac80211 mt76 mt76x2e) -+ $(PKG_BUILD_DIR)/mt76x2e.ko \ -+ $(PKG_BUILD_DIR)/mt7603e.ko -+ AUTOLOAD:=$(call AutoLoad,50,mac80211 mt76 mt76x2e mt7603e) - endef - - NOSTDINC_FLAGS = \ -@@ -54,6 +57,12 @@ endef - define KernelPackage/mt76/install - $(INSTALL_DIR) $(1)/lib/firmware - cp \ -+ $(if $(CONFIG_TARGET_ramips_mt7628) || $(CONFIG_TARGET_ramips_mt7688), \ -+ $(PKG_BUILD_DIR)/firmware/mt7628_e1.bin \ -+ $(PKG_BUILD_DIR)/firmware/mt7628_e2.bin \ -+ ) \ -+ $(PKG_BUILD_DIR)/firmware/mt7603_e1.bin \ -+ $(PKG_BUILD_DIR)/firmware/mt7603_e2.bin \ - $(PKG_BUILD_DIR)/firmware/mt7662_rom_patch.bin \ - $(PKG_BUILD_DIR)/firmware/mt7662.bin \ - $(1)/lib/firmware -diff --git a/package/network/services/hostapd/Config.in b/package/network/services/hostapd/Config.in -index aee2a15..645888e 100644 ---- a/package/network/services/hostapd/Config.in -+++ b/package/network/services/hostapd/Config.in -@@ -10,11 +10,10 @@ config WPA_SUPPLICANT_NO_TIMESTAMP_CHECK - choice - prompt "Choose TLS provider" - default WPA_SUPPLICANT_INTERNAL -- depends on PACKAGE_wpa-supplicant || PACKAGE_wpa-supplicant-mesh || PACKAGE_wpad || PACKAGE_wpad-mesh -+ depends on PACKAGE_wpa-supplicant || PACKAGE_wpad - - config WPA_SUPPLICANT_INTERNAL - bool "internal" -- depends on PACKAGE_wpa-supplicant || PACKAGE_wpad - - config WPA_SUPPLICANT_OPENSSL - bool "openssl" -diff --git a/package/network/services/hostapd/Makefile b/package/network/services/hostapd/Makefile -index 8e706dc..5caf3e3 100644 ---- a/package/network/services/hostapd/Makefile -+++ b/package/network/services/hostapd/Makefile -@@ -7,18 +7,18 @@ - include $(TOPDIR)/rules.mk - - PKG_NAME:=hostapd --PKG_VERSION:=2015-03-25 -+PKG_VERSION:=2016-06-15 - PKG_RELEASE:=1 --PKG_REV:=8278138e679174b1ec8af7f169c2810a8888e202 -+PKG_REV:=31d3692fe5d56c05753ed4a70c7943979e1d29e7 - - PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2 --PKG_SOURCE_URL:=git://w1.fi/srv/git/hostap.git -+PKG_SOURCE_URL:=http://w1.fi/hostap.git - PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION) - PKG_SOURCE_VERSION:=$(PKG_REV) - PKG_SOURCE_PROTO:=git - # PKG_MIRROR_MD5SUM:=4e7c1f97edd7514535056fce54ae053a - --PKG_MAINTAINER:=Felix Fietkau -+PKG_MAINTAINER:=Felix Fietkau - PKG_LICENSE:=BSD-3-Clause - - PKG_BUILD_PARALLEL:=1 -@@ -29,7 +29,6 @@ PKG_CONFIG_DEPENDS:= \ - CONFIG_PACKAGE_kmod-cfg80211 \ - CONFIG_PACKAGE_hostapd \ - CONFIG_PACKAGE_hostapd-mini \ -- CONFIG_PACKAGE_kmod-hostap \ - CONFIG_WPA_RFKILL_SUPPORT \ - CONFIG_DRIVER_WEXT_SUPPORT \ - CONFIG_DRIVER_11N_SUPPORT -@@ -40,6 +39,10 @@ LOCAL_TYPE=$(strip \ - hostapd \ - ))) - LOCAL_VARIANT=$(patsubst wpad-%,%,$(patsubst supplicant-%,%,$(BUILD_VARIANT))) -+CONFIG_VARIANT:=$(LOCAL_VARIANT) -+ifeq ($(LOCAL_VARIANT),mesh) -+ CONFIG_VARIANT:=full -+endif - - ifeq ($(LOCAL_TYPE),supplicant) - ifeq ($(LOCAL_VARIANT),full) -@@ -47,10 +50,6 @@ ifeq ($(LOCAL_TYPE),supplicant) - CONFIG_WPA_SUPPLICANT_INTERNAL \ - CONFIG_WPA_SUPPLICANT_OPENSSL - endif -- ifeq ($(LOCAL_VARIANT),mesh) -- PKG_CONFIG_DEPENDS += \ -- CONFIG_WPA_SUPPLICANT_OPENSSL -- endif - endif - - PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(BUILD_VARIANT)/$(PKG_NAME)-$(PKG_VERSION) -@@ -66,7 +65,6 @@ endif - DRIVER_MAKEOPTS= \ - CONFIG_ACS=$(CONFIG_PACKAGE_kmod-cfg80211) \ - CONFIG_DRIVER_NL80211=$(CONFIG_PACKAGE_kmod-cfg80211) \ -- CONFIG_DRIVER_HOSTAP=$(CONFIG_PACKAGE_kmod-hostap) \ - CONFIG_IEEE80211N=$(HOSTAPD_IEEE80211N) \ - CONFIG_DRIVER_WEXT=$(CONFIG_DRIVER_WEXT_SUPPORT) \ - -@@ -82,7 +80,7 @@ ifneq ($(LOCAL_TYPE),hostapd) - endif - endif - ifeq ($(LOCAL_VARIANT),mesh) -- DRIVER_MAKEOPTS += CONFIG_TLS=openssl -+ DRIVER_MAKEOPTS += CONFIG_TLS=openssl CONFIG_AP=y CONFIG_SAE=y CONFIG_MESH=y - TARGET_LDFLAGS += -lcrypto -lssl - endif - ifdef CONFIG_WPA_SUPPLICANT_NO_TIMESTAMP_CHECK -@@ -177,8 +175,7 @@ endef - define Package/wpad-mesh - $(call Package/wpad/Default) - TITLE+= (with 802.11s mesh and SAE support) -- DEPENDS:=$(DRV_DEPENDS) +libubus +libopenssl +@CONFIG_WPA_SUPPLICANT_OPENSSL @(!TARGET_uml||BROKEN) -- CONFLICTS:=@WPA_SUPPLICANT_INTERNAL -+ DEPENDS:=$(DRV_DEPENDS) +libubus +PACKAGE_wpad-mesh:libopenssl @(!TARGET_uml||BROKEN) - VARIANT:=wpad-mesh - endef - -@@ -257,12 +254,6 @@ define Package/hostapd-common - CATEGORY:=Network - endef - --define Package/hostapd-common-old -- TITLE:=hostapd/wpa_supplicant common support files (legacy drivers) -- SECTION:=net -- CATEGORY:=Network --endef -- - define Package/eapol-test - TITLE:=802.1x authentication test utility - SECTION:=net -@@ -284,10 +275,10 @@ endif - - define Build/Configure - $(Build/Configure/rebuild) -- $(if $(wildcard ./files/hostapd-$(LOCAL_VARIANT).config), \ -- $(CP) ./files/hostapd-$(LOCAL_VARIANT).config $(PKG_BUILD_DIR)/hostapd/.config \ -+ $(if $(wildcard ./files/hostapd-$(CONFIG_VARIANT).config), \ -+ $(CP) ./files/hostapd-$(CONFIG_VARIANT).config $(PKG_BUILD_DIR)/hostapd/.config \ - ) -- $(CP) ./files/wpa_supplicant-$(LOCAL_VARIANT).config $(PKG_BUILD_DIR)/wpa_supplicant/.config -+ $(CP) ./files/wpa_supplicant-$(CONFIG_VARIANT).config $(PKG_BUILD_DIR)/wpa_supplicant/.config - endef - - TARGET_CPPFLAGS := \ -@@ -379,12 +370,6 @@ define Package/hostapd-common/install - $(INSTALL_DATA) ./files/netifd.sh $(1)/lib/netifd/hostapd.sh - endef - --define Package/hostapd-common-old/install -- $(INSTALL_DIR) $(1)/lib/wifi -- $(INSTALL_DATA) ./files/hostapd.sh $(1)/lib/wifi/hostapd.sh -- $(INSTALL_DATA) ./files/wpa_supplicant.sh $(1)/lib/wifi/wpa_supplicant.sh --endef -- - define Package/hostapd/install - $(call Install/hostapd,$(1)) - $(INSTALL_BIN) $(PKG_BUILD_DIR)/hostapd/hostapd $(1)/usr/sbin/ -@@ -442,5 +427,4 @@ $(eval $(call BuildPackage,wpa-supplicant-p2p)) - $(eval $(call BuildPackage,wpa-cli)) - $(eval $(call BuildPackage,hostapd-utils)) - $(eval $(call BuildPackage,hostapd-common)) --$(eval $(call BuildPackage,hostapd-common-old)) - $(eval $(call BuildPackage,eapol-test)) -diff --git a/package/network/services/hostapd/files/hostapd-full.config b/package/network/services/hostapd/files/hostapd-full.config -index f1b2655..e388109 100644 ---- a/package/network/services/hostapd/files/hostapd-full.config -+++ b/package/network/services/hostapd/files/hostapd-full.config -@@ -10,7 +10,7 @@ - # to override previous values of the variables. - - # Driver interface for Host AP driver --CONFIG_DRIVER_HOSTAP=y -+#CONFIG_DRIVER_HOSTAP=y - - # Driver interface for wired authenticator - CONFIG_DRIVER_WIRED=y -@@ -53,6 +53,9 @@ CONFIG_PEERKEY=y - # Integrated EAP server - CONFIG_EAP=y - -+# EAP-FAST for the integrated EAP server -+CONFIG_EAP_FAST=y -+ - # EAP-MD5 for the integrated EAP server - CONFIG_EAP_MD5=y - -diff --git a/package/network/services/hostapd/files/hostapd-mini.config b/package/network/services/hostapd/files/hostapd-mini.config -index 118d97c..8baff18 100644 ---- a/package/network/services/hostapd/files/hostapd-mini.config -+++ b/package/network/services/hostapd/files/hostapd-mini.config -@@ -10,7 +10,7 @@ - # to override previous values of the variables. - - # Driver interface for Host AP driver --CONFIG_DRIVER_HOSTAP=y -+#CONFIG_DRIVER_HOSTAP=y - - # Driver interface for wired authenticator - CONFIG_DRIVER_WIRED=y -diff --git a/package/network/services/hostapd/files/hostapd.sh b/package/network/services/hostapd/files/hostapd.sh -deleted file mode 100644 -index 7aec7ad..0000000 ---- a/package/network/services/hostapd/files/hostapd.sh -+++ /dev/null -@@ -1,394 +0,0 @@ --hostapd_set_bss_options() { -- local var="$1" -- local vif="$2" -- local enc wep_rekey wpa_group_rekey wpa_pair_rekey wpa_master_rekey wps_possible wpa_key_mgmt -- -- config_get enc "$vif" encryption "none" -- config_get wep_rekey "$vif" wep_rekey # 300 -- config_get wpa_group_rekey "$vif" wpa_group_rekey # 300 -- config_get wpa_pair_rekey "$vif" wpa_pair_rekey # 300 -- config_get wpa_master_rekey "$vif" wpa_master_rekey # 640 -- config_get_bool ap_isolate "$vif" isolate 0 -- config_get_bool disassoc_low_ack "$vif" disassoc_low_ack 1 -- config_get max_num_sta "$vif" max_num_sta 0 -- config_get max_inactivity "$vif" max_inactivity 0 -- config_get_bool preamble "$vif" short_preamble 1 -- -- config_get device "$vif" device -- config_get hwmode "$device" hwmode -- config_get phy "$device" phy -- -- append "$var" "ctrl_interface=/var/run/hostapd-$phy" "$N" -- -- if [ "$ap_isolate" -gt 0 ]; then -- append "$var" "ap_isolate=$ap_isolate" "$N" -- fi -- if [ "$max_num_sta" -gt 0 ]; then -- append "$var" "max_num_sta=$max_num_sta" "$N" -- fi -- if [ "$max_inactivity" -gt 0 ]; then -- append "$var" "ap_max_inactivity=$max_inactivity" "$N" -- fi -- append "$var" "disassoc_low_ack=$disassoc_low_ack" "$N" -- if [ "$preamble" -gt 0 ]; then -- append "$var" "preamble=$preamble" "$N" -- fi -- -- # Examples: -- # psk-mixed/tkip => WPA1+2 PSK, TKIP -- # wpa-psk2/tkip+aes => WPA2 PSK, CCMP+TKIP -- # wpa2/tkip+aes => WPA2 RADIUS, CCMP+TKIP -- # ... -- -- # TODO: move this parsing function somewhere generic, so that -- # later it can be reused by drivers that don't use hostapd -- -- # crypto defaults: WPA2 vs WPA1 -- case "$enc" in -- wpa2*|*psk2*) -- wpa=2 -- crypto="CCMP" -- ;; -- *mixed*) -- wpa=3 -- crypto="CCMP TKIP" -- ;; -- *) -- wpa=1 -- crypto="TKIP" -- ;; -- esac -- -- # explicit override for crypto setting -- case "$enc" in -- *tkip+aes|*tkip+ccmp|*aes+tkip|*ccmp+tkip) crypto="CCMP TKIP";; -- *aes|*ccmp) crypto="CCMP";; -- *tkip) crypto="TKIP";; -- esac -- -- # enforce CCMP for 11ng and 11na -- case "$hwmode:$crypto" in -- *ng:TKIP|*na:TKIP) crypto="CCMP TKIP";; -- esac -- -- # use crypto/auth settings for building the hostapd config -- case "$enc" in -- none) -- wps_possible=1 -- wpa=0 -- crypto= -- # Here we make the assumption that if we're in open mode -- # with WPS enabled, we got to be in unconfigured state. -- wps_not_configured=1 -- ;; -- *psk*) -- config_get psk "$vif" key -- if [ ${#psk} -eq 64 ]; then -- append "$var" "wpa_psk=$psk" "$N" -- else -- append "$var" "wpa_passphrase=$psk" "$N" -- fi -- wps_possible=1 -- [ -n "$wpa_group_rekey" ] && append "$var" "wpa_group_rekey=$wpa_group_rekey" "$N" -- [ -n "$wpa_pair_rekey" ] && append "$var" "wpa_ptk_rekey=$wpa_pair_rekey" "$N" -- [ -n "$wpa_master_rekey" ] && append "$var" "wpa_gmk_rekey=$wpa_master_rekey" "$N" -- append wpa_key_mgmt "WPA-PSK" -- ;; -- *wpa*|*8021x*) -- # required fields? formats? -- # hostapd is particular, maybe a default configuration for failures -- config_get auth_server "$vif" auth_server -- [ -z "$auth_server" ] && config_get auth_server "$vif" server -- append "$var" "auth_server_addr=$auth_server" "$N" -- config_get auth_port "$vif" auth_port -- [ -z "$auth_port" ] && config_get auth_port "$vif" port -- auth_port=${auth_port:-1812} -- append "$var" "auth_server_port=$auth_port" "$N" -- config_get auth_secret "$vif" auth_secret -- [ -z "$auth_secret" ] && config_get auth_secret "$vif" key -- append "$var" "auth_server_shared_secret=$auth_secret" "$N" -- # You don't really want to enable this unless you are doing -- # some corner case testing or are using OpenWrt as a work around -- # for some systematic issues. -- config_get_bool auth_cache "$vif" auth_cache 0 -- config_get rsn_preauth "$vif" rsn_preauth -- [ "$auth_cache" -gt 0 ] || [[ "$rsn_preauth" = 1 ]] || append "$var" "disable_pmksa_caching=1" "$N" -- [ "$auth_cache" -gt 0 ] || [[ "$rsn_preauth" = 1 ]] || append "$var" "okc=0" "$N" -- config_get acct_server "$vif" acct_server -- [ -n "$acct_server" ] && append "$var" "acct_server_addr=$acct_server" "$N" -- config_get acct_port "$vif" acct_port -- [ -n "$acct_port" ] && acct_port=${acct_port:-1813} -- [ -n "$acct_port" ] && append "$var" "acct_server_port=$acct_port" "$N" -- config_get acct_secret "$vif" acct_secret -- [ -n "$acct_secret" ] && append "$var" "acct_server_shared_secret=$acct_secret" "$N" -- config_get eap_reauth_period "$vif" eap_reauth_period -- [ -n "$eap_reauth_period" ] && append "$var" "eap_reauth_period=$eap_reauth_period" "$N" -- config_get dae_client "$vif" dae_client -- config_get dae_secret "$vif" dae_secret -- [ -n "$dae_client" -a -n "$dae_secret" ] && { -- config_get dae_port "$vif" dae_port -- append "$var" "radius_das_port=${dae_port:-3799}" "$N" -- append "$var" "radius_das_client=$dae_client $dae_secret" "$N" -- } -- config_get ownip "$vif" ownip -- append "$var" "own_ip_addr=$ownip" "$N" -- append "$var" "eapol_key_index_workaround=1" "$N" -- append "$var" "ieee8021x=1" "$N" -- append wpa_key_mgmt "WPA-EAP" -- [ -n "$wpa_group_rekey" ] && append "$var" "wpa_group_rekey=$wpa_group_rekey" "$N" -- [ -n "$wpa_pair_rekey" ] && append "$var" "wpa_ptk_rekey=$wpa_pair_rekey" "$N" -- [ -n "$wpa_master_rekey" ] && append "$var" "wpa_gmk_rekey=$wpa_master_rekey" "$N" -- ;; -- *wep*) -- config_get key "$vif" key -- key="${key:-1}" -- case "$key" in -- [1234]) -- for idx in 1 2 3 4; do -- local zidx -- zidx=$(($idx - 1)) -- config_get ckey "$vif" "key${idx}" -- [ -n "$ckey" ] && \ -- append "$var" "wep_key${zidx}=$(prepare_key_wep "$ckey")" "$N" -- done -- append "$var" "wep_default_key=$((key - 1))" "$N" -- ;; -- *) -- append "$var" "wep_key0=$(prepare_key_wep "$key")" "$N" -- append "$var" "wep_default_key=0" "$N" -- [ -n "$wep_rekey" ] && append "$var" "wep_rekey_period=$wep_rekey" "$N" -- ;; -- esac -- case "$enc" in -- *shared*) -- auth_algs=2 -- ;; -- *mixed*) -- auth_algs=3 -- ;; -- esac -- wpa=0 -- crypto= -- ;; -- *) -- wpa=0 -- crypto= -- ;; -- esac -- append "$var" "auth_algs=${auth_algs:-1}" "$N" -- append "$var" "wpa=$wpa" "$N" -- [ -n "$crypto" ] && append "$var" "wpa_pairwise=$crypto" "$N" -- [ -n "$wpa_group_rekey" ] && append "$var" "wpa_group_rekey=$wpa_group_rekey" "$N" -- -- config_get ssid "$vif" ssid -- config_get bridge "$vif" bridge -- config_get ieee80211d "$vif" ieee80211d -- config_get iapp_interface "$vif" iapp_interface -- -- config_get_bool wps_pbc "$vif" wps_pushbutton 0 -- config_get_bool wps_label "$vif" wps_label 0 -- -- config_get config_methods "$vif" wps_config -- [ "$wps_pbc" -gt 0 ] && append config_methods push_button -- -- [ -n "$wps_possible" -a -n "$config_methods" ] && { -- config_get device_type "$vif" wps_device_type "6-0050F204-1" -- config_get device_name "$vif" wps_device_name "OpenWrt AP" -- config_get manufacturer "$vif" wps_manufacturer "openwrt.org" -- config_get wps_pin "$vif" wps_pin -- -- config_get_bool ext_registrar "$vif" ext_registrar 0 -- [ "$ext_registrar" -gt 0 -a -n "$bridge" ] && append "$var" "upnp_iface=$bridge" "$N" -- -- append "$var" "eap_server=1" "$N" -- [ -n "$wps_pin" ] && append "$var" "ap_pin=$wps_pin" "$N" -- append "$var" "wps_state=${wps_not_configured:-2}" "$N" -- append "$var" "ap_setup_locked=0" "$N" -- append "$var" "device_type=$device_type" "$N" -- append "$var" "device_name=$device_name" "$N" -- append "$var" "manufacturer=$manufacturer" "$N" -- append "$var" "config_methods=$config_methods" "$N" -- } -- -- append "$var" "ssid=$ssid" "$N" -- [ -n "$bridge" ] && append "$var" "bridge=$bridge" "$N" -- [ -n "$ieee80211d" ] && append "$var" "ieee80211d=$ieee80211d" "$N" -- [ -n "$iapp_interface" ] && append "$var" iapp_interface=$(uci_get_state network "$iapp_interface" ifname "$iapp_interface") "$N" -- -- if [ "$wpa" -ge "1" ] -- then -- config_get nasid "$vif" nasid -- [ -n "$nasid" ] && append "$var" "nas_identifier=$nasid" "$N" -- -- config_get_bool ieee80211r "$vif" ieee80211r 0 -- if [ "$ieee80211r" -gt 0 ] -- then -- config_get mobility_domain "$vif" mobility_domain "4f57" -- config_get r0_key_lifetime "$vif" r0_key_lifetime "10000" -- config_get r1_key_holder "$vif" r1_key_holder "00004f577274" -- config_get reassociation_deadline "$vif" reassociation_deadline "1000" -- config_get r0kh "$vif" r0kh -- config_get r1kh "$vif" r1kh -- config_get_bool pmk_r1_push "$vif" pmk_r1_push 0 -- -- append "$var" "mobility_domain=$mobility_domain" "$N" -- append "$var" "r0_key_lifetime=$r0_key_lifetime" "$N" -- append "$var" "r1_key_holder=$r1_key_holder" "$N" -- append "$var" "reassociation_deadline=$reassociation_deadline" "$N" -- append "$var" "pmk_r1_push=$pmk_r1_push" "$N" -- -- for kh in $r0kh; do -- "$var" "r0kh=${kh//,/ }" "$N" -- done -- for kh in $r1kh; do -- "$var" "r1kh=${kh//,/ }" "$N" -- done -- -- [ "$wpa_key_mgmt" != "${wpa_key_mgmt/EAP/}" ] && append wpa_key_mgmt "FT-EAP" -- [ "$wpa_key_mgmt" != "${wpa_key_mgmt/PSK/}" ] && append wpa_key_mgmt "FT-PSK" -- fi -- -- [ -n "wpa_key_mgmt" ] && append "$var" "wpa_key_mgmt=$wpa_key_mgmt" -- fi -- -- if [ "$wpa" -ge "2" ] -- then -- # RSN -> allow preauthentication. You have two -- # options, rsn_preauth for production or rsn_preauth_testing -- # for validation / testing. -- if [ -n "$bridge" -a "$rsn_preauth" = 1 ] -- then -- append "$var" "rsn_preauth=1" "$N" -- append "$var" "rsn_preauth_interfaces=$bridge" "$N" -- append "$var" "okc=1" "$N" -- else -- # RSN preauthentication testings hould disable -- # Opportunistic Key Caching (okc) as otherwise the PMKSA -- # entry for a test could come from the Opportunistic Key Caching -- config_get rsn_preauth_testing "$vif" rsn_preauth_testing -- if [ -n "$bridge" -a "$rsn_preauth_testing" = 1 ] -- then -- append "$var" "rsn_preauth=1" "$N" -- append "$var" "rsn_preauth_interfaces=$bridge" "$N" -- append "$var" "okc=0" "$N" -- fi -- fi -- -- # RSN -> allow management frame protection -- config_get ieee80211w "$vif" ieee80211w -- case "$ieee80211w" in -- [012]) -- append "$var" "ieee80211w=$ieee80211w" "$N" -- [ "$ieee80211w" -gt "0" ] && { -- config_get ieee80211w_max_timeout "$vif" ieee80211w_max_timeout -- config_get ieee80211w_retry_timeout "$vif" ieee80211w_retry_timeout -- [ -n "$ieee80211w_max_timeout" ] && \ -- append "$var" "assoc_sa_query_max_timeout=$ieee80211w_max_timeout" "$N" -- [ -n "$ieee80211w_retry_timeout" ] && \ -- append "$var" "assoc_sa_query_retry_timeout=$ieee80211w_retry_timeout" "$N" -- } -- ;; -- esac -- fi -- -- config_get macfile "$vif" macfile -- config_get maclist "$vif" maclist -- if [ -z "$macfile" ] -- then -- # if no macfile has been specified, fallback to the default name -- # and truncate file to avoid aggregating entries over time -- macfile="/var/run/hostapd-$ifname.maclist" -- echo "" > "$macfile" -- else -- if [ -n "$maclist" ] -- then -- # to avoid to overwrite the original file, make a copy -- # before appending the entries specified by the maclist -- # option -- cp $macfile $macfile.maclist -- macfile=$macfile.maclist -- fi -- fi -- -- if [ -n "$maclist" ] -- then -- for mac in $maclist; do -- echo "$mac" >> $macfile -- done -- fi -- -- config_get macfilter "$vif" macfilter -- case "$macfilter" in -- allow) -- append "$var" "macaddr_acl=1" "$N" -- append "$var" "accept_mac_file=$macfile" "$N" -- ;; -- deny) -- append "$var" "macaddr_acl=0" "$N" -- append "$var" "deny_mac_file=$macfile" "$N" -- ;; -- esac --} -- --hostapd_set_log_options() { -- local var="$1" -- local cfg="$2" -- local log_level log_80211 log_8021x log_radius log_wpa log_driver log_iapp log_mlme -- -- config_get log_level "$cfg" log_level 2 -- -- config_get_bool log_80211 "$cfg" log_80211 1 -- config_get_bool log_8021x "$cfg" log_8021x 1 -- config_get_bool log_radius "$cfg" log_radius 1 -- config_get_bool log_wpa "$cfg" log_wpa 1 -- config_get_bool log_driver "$cfg" log_driver 1 -- config_get_bool log_iapp "$cfg" log_iapp 1 -- config_get_bool log_mlme "$cfg" log_mlme 1 -- -- local log_mask=$(( \ -- ($log_80211 << 0) | \ -- ($log_8021x << 1) | \ -- ($log_radius << 2) | \ -- ($log_wpa << 3) | \ -- ($log_driver << 4) | \ -- ($log_iapp << 5) | \ -- ($log_mlme << 6) \ -- )) -- -- append "$var" "logger_syslog=$log_mask" "$N" -- append "$var" "logger_syslog_level=$log_level" "$N" -- append "$var" "logger_stdout=$log_mask" "$N" -- append "$var" "logger_stdout_level=$log_level" "$N" --} -- --hostapd_setup_vif() { -- local vif="$1" -- local driver="$2" -- local ifname device channel hwmode -- -- hostapd_cfg= -- -- config_get ifname "$vif" ifname -- config_get device "$vif" device -- config_get channel "$device" channel -- config_get hwmode "$device" hwmode -- -- hostapd_set_log_options hostapd_cfg "$device" -- hostapd_set_bss_options hostapd_cfg "$vif" -- -- case "$hwmode" in -- *bg|*gdt|*gst|*fh) hwmode=g;; -- *adt|*ast) hwmode=a;; -- esac -- [ "$channel" = auto ] && channel= -- [ -n "$channel" -a -z "$hwmode" ] && wifi_fixup_hwmode "$device" -- cat > /var/run/hostapd-$ifname.conf <