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/LICENSE b/LICENSE index 81ed5a23..a9adc369 100644 --- a/LICENSE +++ b/LICENSE @@ -1,7 +1,7 @@ The code of Project Gluon may be distributed under the following terms, unless noted otherwise in individual files or subtrees. -Copyright (c) 2013, Project Gluon +Copyright (c) 2013-2017, Project Gluon All rights reserved. Redistribution and use in source and binary forms, with or without @@ -25,10 +25,10 @@ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -OpenWrt is licensed under the terms of the GNU General Public License Version 2, -which can be found under openwrt/LICENSE after the openwrt submodule has been -obtained. This applies to the following submodules: - * openwrt +LEDE and OpenWrt are licensed under the terms of the GNU General Public License +Version 2, which can be found at lede/LICENSE after the lede repository has been +obtained. This applies to the following repositories: + * lede * packages/openwrt * packages/routing * packages/luci diff --git a/Makefile b/Makefile index 5c02c752..d1d925f8 100644 --- a/Makefile +++ b/Makefile @@ -4,502 +4,153 @@ 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_PACKAGEDIR ?= $(GLUON_OUTPUTDIR)/packages -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_PACKAGEDIR DEVICES -ifneq ($(OPENWRT_BUILD),1) -GLUONDIR:=${CURDIR} +$(GLUON_SITEDIR)/site.mk: + $(error No site configuration was found. Please check out a site configuration to $(GLUON_SITEDIR)) -include $(GLUONDIR)/include/gluon.mk +-include $(GLUON_SITEDIR)/site.mk -TOPDIR:=$(GLUON_ORIGOPENWRTDIR) -export TOPDIR +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 + @GLUON_SITEDIR='$(GLUON_SITEDIR)' scripts/update.sh + @GLUON_SITEDIR='$(GLUON_SITEDIR)' scripts/patch.sh + @GLUON_SITEDIR='$(GLUON_SITEDIR)' scripts/feeds.sh update-patches: FORCE - $(GLUONDIR)/scripts/update.sh - $(GLUONDIR)/scripts/update-patches.sh - $(GLUONDIR)/scripts/patch.sh + @GLUON_SITEDIR='$(GLUON_SITEDIR)' scripts/update.sh + @GLUON_SITEDIR='$(GLUON_SITEDIR)' scripts/update-patches.sh + @GLUON_SITEDIR='$(GLUON_SITEDIR)' 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 + @GLUON_SITEDIR='$(GLUON_SITEDIR)' 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 := [ '$(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 -wpad-mini gluon-core ip6tables hostapd-mini -prepare-target: FORCE +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))) + + +config: 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 \ + && GLUON_SITEDIR='$(GLUON_SITEDIR)' 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_RELEASE="$(GLUON_RELEASE)"' \ + && echo 'CONFIG_GLUON_SITEDIR="$(GLUON_SITEDIR)"' \ + && echo 'CONFIG_GLUON_BRANCH="$(GLUON_BRANCH)"' \ + ) > lede/.config + +@$(LEDEMAKE) defconfig + + @GLUON_SITEDIR='$(GLUON_SITEDIR)' scripts/target_config_check.sh '$(GLUON_TARGET)' '$(GLUON_PACKAGES_YES)' + + +LUA := lede/staging_dir/hostpkg/bin/lua + +$(LUA): + @$(CheckExternal) + + +@[ -e lede/.config ] || $(LEDEMAKE) defconfig + +@$(LEDEMAKE) tools/install + +@$(LEDEMAKE) package/lua/host/install + +prepare-target: config $(LUA) ; all: prepare-target - +@$(GLUONMAKE) build-key - +@$(GLUONMAKE) prepare - +@$(GLUONMAKE) images - +@$(GLUONMAKE) modules + @GLUON_SITEDIR='$(GLUON_SITEDIR)' $(LUA) scripts/site_config.lua \ + || (echo 'Your site configuration did not pass validation.'; false) -prepare: prepare-target - +@$(GLUONMAKE) build-key - +@$(GLUONMAKE) $@ + @scripts/clean_output.sh + +@$(LEDEMAKE) + @GLUON_SITEDIR='$(GLUON_SITEDIR)' scripts/copy_output.sh '$(GLUON_TARGET)' -clean download images modules: FORCE - @$(CheckExternal) - @$(CheckTarget) - +@$(GLUONMAKE_EARLY) maybe-prepare-target - +@$(GLUONMAKE) build-key - +@$(GLUONMAKE) $@ +clean download: config + +@$(LEDEMAKE) $@ -toolchain/% package/% target/% image/%: FORCE - @$(CheckExternal) - @$(CheckTarget) - +@$(GLUONMAKE_EARLY) maybe-prepare-target - +@$(GLUONMAKE) build-key - +@$(GLUONMAKE) $@ +dirclean: FORCE + +@[ -e lede/.config ] || $(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) +manifest: $(LUA) FORCE + @[ '$(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 "DATE=$$($(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 - -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:= \ - IPKG_TMP="$(TMP_DIR)/ipkgtmp" \ - 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)); \ + echo && \ + $(foreach GLUON_TARGET,$(GLUON_TARGETS), \ + GLUON_SITEDIR='$(GLUON_SITEDIR)' scripts/generate_manifest.sh '$(GLUON_TARGET)' && \ ) : \ - ) + ) > 'tmp/$(GLUON_BRANCH).manifest.tmp' + @mkdir -p '$(GLUON_IMAGEDIR)/sysupgrade' + @mv 'tmp/$(GLUON_BRANCH).manifest.tmp' '$(GLUON_IMAGEDIR)/sysupgrade/$(GLUON_BRANCH).manifest' -# 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)) +FORCE: ; -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 - -# 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 +.PHONY: FORCE +.NOTPARALLEL: diff --git a/README.md b/README.md index 0fb2f2bf..0726e8cc 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,7 @@ the future development of Gluon. Please refrain from using the `master` branch for anything else but development purposes! Use the most recent release instead. You can list all relaseses by running `git branch -a` -and switch to one by running `git checkout v2016.1.6 && make update`. +and switch to one by running `git checkout v2016.2.2 && make update`. If you're using the autoupdater, do not autoupdate nodes with anything but releases. If you upgrade using random master commits the nodes *will break* eventually. @@ -28,11 +28,11 @@ If you upgrade using random master commits the nodes *will break* eventually. To subscribe to the list, send a message to: - gluon-subscribe@luebeck.freifunk.net + gluon+subscribe@luebeck.freifunk.net To remove your address from the list, just send a message to the address in the `List-Unsubscribe` header of any list message. If you haven't changed addresses since subscribing, you can also send a message to: - gluon-unsubscribe@luebeck.freifunk.net + gluon+unsubscribe@luebeck.freifunk.net diff --git a/docs/conf.py b/docs/conf.py index fd329bda..c66cbf62 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -54,9 +54,9 @@ copyright = '2015-2016, Project Gluon' # built documents. # # The short X.Y version. -version = '2016.1+' +version = '2016.2+' # The full version, including alpha/beta/rc tags. -release = '2016.1+' +release = '2016.2+' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. diff --git a/docs/dev/basics.rst b/docs/dev/basics.rst index 7e7d9f58..2f4d1d89 100644 --- a/docs/dev/basics.rst +++ b/docs/dev/basics.rst @@ -34,21 +34,7 @@ rerun `patches`; the resulting branch will be called `patched`, while the commit specified in `modules` can be refered to by the branch `base`. -:: - - make unpatch - -sets the repositories to the `base` branch, - -:: - - make patch - -re-applies the patches by resetting the `patched` branch to `base` and calling `git am` -for the patch files. Calling `make` or a similar command after calling `make unpatch` -is generally not a good idea. - -After new patches have been commited on top of the patched branch (or existing commits +After new patches have been commited on top of the `patched` branch (or existing commits since the base commit have been edited or removed), the patch directories can be regenerated using @@ -61,3 +47,19 @@ and you can try rebasing it onto the new `base` branch yourself and after that c Always call `make update-patches` after making changes to a module repository as `make update` will overwrite your commits, making `git reflog` the only way to recover them! + +Development Guidelines +---------------------- +lua should be used instead of sh whenever sensible. The following criteria +should be considered: + +- Is the script doing more than just executing external commands? if so, use lua +- Is the script parsing/editing json-data? If so, use lua for speed +- When using sh, use jsonfilter instead of json_* functions for speed + +Code formatting may sound like a topic for the pedantic, however it helps if +the code in the project is formatted in the same way. The following rules +apply: + +- use tabs instead of spaces +- trailing whitespaces must be eliminated diff --git a/docs/dev/hardware.rst b/docs/dev/hardware.rst index b7f7c174..54ae75e0 100644 --- a/docs/dev/hardware.rst +++ b/docs/dev/hardware.rst @@ -11,57 +11,114 @@ is a requirement. At the moment, Gluon's scripts can't handle devices without WLAN adapters (although such environments may also be interesting, e.g. for automated testing in virtual machines). + .. _hardware-adding-profiles: Adding profiles --------------- -The vast majority of devices with ath9k WLAN uses the ar71xx target of OpenWrt. +The vast majority of devices with ath9k WLAN uses the ar71xx target of LEDE. If the hardware you want to add support for is also ar71xx, adding a new profile is enough. -Profiles are defined in ``targets/-/profiles.mk``. There are two macros -used to define which images are generated: ``GluonProfile`` and ``GluonModel``. The following examples -are taken from ``profiles.mk`` of the ``ar71xx-generic`` target:: +Profiles are defined in ``targets/*`` in a shell-based DSL (so common shell +commands syntax like ``if`` can be used. - $(eval $(call GluonProfile,TLWR1043)) - $(eval $(call GluonModel,TLWR1043,tl-wr1043nd-v1-squashfs,tp-link-tl-wr1043n-nd-v1)) - $(eval $(call GluonModel,TLWR1043,tl-wr1043nd-v2-squashfs,tp-link-tl-wr1043n-nd-v2)) +The ``device`` command is used to define an image build for a device. It takes +two or three parameters. -The ``GluonProfile`` macro takes at least one parameter, the profile name as it is -defined in the Makefiles of OpenWrt (``openwrt/target/linux///profiles/*`` -and ``openwrt/target/linux//image/Makefile``). If the target you are on doesn't define -profiles (e.g. on x86), just add a single profile called ``Generic`` or similar. - -It may optionally take a second parameter which defines additional packages to include for the profile -(e.g. ath10k). The additional packages defined in ``openwrt/target/linux///profiles/*`` -aren't used. - -The ``GluonModel`` macro takes three parameters: The profile name, the suffix of the image file -generated by OpenWrt (without the file extension), and the final image name of the Gluon image. -The final image name must be the same that is returned by the following command. - -:: +The first parameter defines the Gluon profile name, which is used to refer to the +device and is part of the generated image name. The profile name must be same as +the output of the following command (on the target device), so the autoupdater +can work:: lua -e 'print(require("platform_info").get_image_name())' +The second parameter defines the name of the image files generated by LEDE. Usually, +it is also the LEDE profile name; for devices that still use the old image build +code, a third parameter with the LEDE profile name can be passed. The profile names +can be found in the image Makefiles in ``lede/target/linux//image/Makefile``. -This is just so the autoupdater can work. The command has to be executed _on_ the target (eg. the hardware router with a flashed image). So you'll first have to build an image with a guessed name, and afterwards build a new, correctly named image. On targets which aren't supported by the autoupdater, -``require("platform_info").get_image_name()`` will just return ``nil`` and the final image name -may be defined arbitrarily. +Examples:: + + device tp-link-tl-wr1043n-nd-v1 tl-wr1043nd-v1 + device alfa-network-hornet-ub hornet-ub HORNETUB + +Suffixes and extensions +''''''''''''''''''''''' + +By default, image files are expected to have the extension ``.bin``. In addition, +the images generated by LEDE have a suffix before the extension that defaults to +``-squashfs-factory`` and ``-squashfs-sysupgrade``. + +This can be changed using the ``factory`` and ``sysupgrade`` commands, either at +the top of the file to set the defaults for all images, or for a single image. There +are three forms with 0 to 2 arguments (all work with ``sysupgrade`` as well):: + + factory SUFFIX .EXT + factory .EXT + factory + +When only an extension is given, the default suffix is retained. When no arguments +are given, this signals that no factory (or sysupgrade) image exists. + +Aliases +''''''' + +Sometimes multiple models use the same LEDE images. In this case, the ``alias`` +command can be used to create symlinks and additional entries in the autoupdater +manifest for the alternative models. + +Standalone images +''''''''''''''''' + +On targets without *per-device rootfs* support in LEDE, the commands described above +can't be used. Instead, ``factory_image`` and ``sysupgrade_image`` are used:: + + factory_image PROFILE IMAGE .EXT + sysupgrade_image PROFILE IMAGE .EXT + +Again, the profile name must match the value printed by the aforementioned Lua +command. The image name must match the part between the target name and the extension +as generated by LEDE and is to be omitted when no such part exists. + +Packages +'''''''' + +The ``packages`` command takes an arbitrary number of arguments. Each argument +defines an additional package to include in the images in addition to the default +package sets defined by LEDE. When a package name is prefixed by a minus sign, the +packages are excluded instead. + +The ``packages`` command may be used at the top of a target definition to modify +the default package list for all images, or just for a single device (when the +target supports *per-default rootfs*). + + +Configuration +''''''''''''' + +The ``config`` command allows to add arbitary target-specific LEDE configuration +to be emitted to ``.config``. + +Notes +''''' On devices with multiple WLAN adapters, care must also be taken that the primary MAC address is configured correctly. ``/lib/gluon/core/sysconfig/primary_mac`` should contain the MAC address which can be found on a label on most hardware; if it does not, ``/lib/gluon/upgrade/010-primary-mac`` in ``gluon-core`` might need a fix. (There have also been cases in which the address was incorrect -even on devices with only one WLAN adapter, in these cases an OpenWrt bug was the cause). +even on devices with only one WLAN adapter, in these cases a LEDE bug was the cause). + Adding support for new hardware targets --------------------------------------- + Adding a new target is much more complex than adding a new profile. There are two basic steps required for adding a new target: -Adjust packages -''''''''''''''' +Package adjustments +''''''''''''''''''' + One package that definitely needs adjustments for every new target added is ``libplatforminfo`` (to be found in `packages/gluon/libs/libplatforminfo `_). Start with a copy of an existing platform info source file and adjust it for the new target (or just add a symlink if @@ -71,15 +128,14 @@ On many targets, Gluon's network setup scripts (mainly in the packages ``gluon-c won't run correctly without some adjustments, so better double check that everything is fine there (and the files ``primary_mac``, ``lan_ifname`` and ``wan_ifname`` in ``/lib/gluon/core/sysconfig/`` contain sensible values). -Add support to the build system -''''''''''''''''''''''''''''''' -A directory for the new target must be created under ``targets``, and it must be added -to ``targets/targets.mk``. In the new target directory, the following files must be created: +Build system support +'''''''''''''''''''' -* profiles.mk -* config (optional) - -For ``profiles.mk``, see :ref:`hardware-adding-profiles`. -The file ``config`` can be used to add additional, target-specific options to the OpenWrt config. +A definition for the new target must be created under ``targets``, and it must be added +to ``targets/targets.mk``. The ``GluonTarget`` macro takes one to three arguments: +the target name, the Gluon subtarget name (if the target has subtargets), and the +LEDE subtarget name (if it differs from the Gluon subtarget). The third argument +can be used to define multiple Gluon targets with different configuration for the +same LEDE target, like it is done for the ``ar71xx-tiny`` target. After this, is should be sufficient to call ``make GLUON_TARGET=`` to build the images for the new target. diff --git a/docs/features/autoupdater.rst b/docs/features/autoupdater.rst index 8c4ca73f..7cfd0f21 100644 --- a/docs/features/autoupdater.rst +++ b/docs/features/autoupdater.rst @@ -28,7 +28,8 @@ A fully automated nightly build could use the following commands: (cd site && git pull) make update make clean - make -j5 GLUON_TARGET=ar71xx-generic GLUON_BRANCH=experimental + NUM_CORES_PLUS_ONE=$(expr $(nproc) + 1) + make -j$NUM_CORES_PLUS_ONE GLUON_TARGET=ar71xx-generic GLUON_BRANCH=experimental make manifest GLUON_BRANCH=experimental contrib/sign.sh $SECRETKEY output/images/sysupgrade/experimental.manifest diff --git a/docs/features/dns-cache.rst b/docs/features/dns-cache.rst new file mode 100644 index 00000000..65119b5b --- /dev/null +++ b/docs/features/dns-cache.rst @@ -0,0 +1,30 @@ +DNS-Caching +=========== +User experience may be greatly improved when dns is accelerated. Also, it +seems like a good idea to keep the number of packages being exchanged +between node and gateway as small as possible. In order to do this, a +dns-cache may be used on a node. The dnsmasq instance listening on port +53 on the node will be reconfigured to answer requests, use a list of +upstream servers and a specific cache size if the options listed below are +added to site.conf. All settings are optional, though if no dns server is +set, the configuration will not be altered by gluon-core. + +Besides caching dns requests from clients, the next_node-addresses are set to +resolve to a configurable name that may optionally be placed in next_node.name. + +:: + + dns = { + cacheentries = 5000, + servers = { '2001:db8::1', }, + }, + + next_node = { + name = 'nextnode', + ip6 = '2001:db8:8::1', + ip4 = '198.51.100.1', + } + + +The cache will be initialized during startup. +Each cache entry will occupy about 90 bytes of RAM. diff --git a/docs/features/roles.rst b/docs/features/roles.rst index 4cbf1f29..38d84f85 100644 --- a/docs/features/roles.rst +++ b/docs/features/roles.rst @@ -2,7 +2,7 @@ Roles ===== It is possible to define a set of roles you want to distinguish at backend side. One node can own one -role which it will announce via alfred inside the mesh. This will make it easier to differentiate +role which it will announce via alfred inside the mesh. This will make it easier to differentiate nodes when parsing alfred data. E.g to count only **normal** nodes and not the gateways or servers (nodemap). A lot of things are possible. @@ -11,18 +11,20 @@ For this the section ``roles`` in ``site.conf`` is needed:: roles = { default = 'node', list = { - node = 'Normal Node', - test = 'Test Node', - backbone = 'Backbone Node', - service = 'Service Node', + 'node', + 'test', + 'backbone', + 'service', }, }, +The strings to display in the LuCI interface are configured per language in the +``i18n/en.po``, ``i18n/de.po``, etc. files of the site repository using message IDs like +``gluon-luci-node-role:role:node`` and ``gluon-luci-node-role:role:backbone``. + The value of ``default`` is the role every node will initially own. This value should be part of ``list`` as well. If you want node owners to change the defined roles via config-mode you can add the package -``gluon-luci-node-role`` to your ``site.mk``. Then, you can select one of the defined roles from a dropdown list -where the right-handed value is the one which is displayed and the left-handed key the one which is configured into -the system. +``gluon-luci-node-role`` to your ``site.mk``. The role is saved in ``gluon-node-info.system.role``. To change the role using command line do:: diff --git a/docs/features/wired-mesh.rst b/docs/features/wired-mesh.rst index b9996335..63341f1f 100644 --- a/docs/features/wired-mesh.rst +++ b/docs/features/wired-mesh.rst @@ -33,12 +33,12 @@ Mesh-on-WAN It's possible to enable Mesh-on-WAN like this:: uci set network.mesh_wan.auto=1 - uci commit + uci commit network It may be disabled by running:: uci set network.mesh_wan.auto=0 - uci commit + uci commit network Mesh-on-LAN @@ -50,7 +50,7 @@ Configuring Mesh-on-LAN is a bit more complicated:: for ifname in $(cat /lib/gluon/core/sysconfig/lan_ifname); do uci del_list network.client.ifname=$ifname done - uci commit + uci commit network It may be disabled by running:: @@ -58,8 +58,8 @@ It may be disabled by running:: for ifname in $(cat /lib/gluon/core/sysconfig/lan_ifname); do uci add_list network.client.ifname=$ifname done - uci commit + uci commit network Please note that this configuration has changed in Gluon v2016.1. Using -the old commands on v2016.1 will break the corresponding options in the -*Advanced settings*. +the old commands on v2016.1 and later will break the corresponding options +in the *Advanced settings*. diff --git a/docs/features/wlan-configuration.rst b/docs/features/wlan-configuration.rst index 1c1e3e54..445b4bf1 100644 --- a/docs/features/wlan-configuration.rst +++ b/docs/features/wlan-configuration.rst @@ -13,7 +13,7 @@ Upgrade behaviour For each of these networks, the site configuration may define a `disabled` flag (by default, all configured networks are enabled). This flag is merely a default setting, on upgrades the existing setting is always retained (as this setting may have been changed -by the user). This means that is is not possible to enable or disable an existing network +by the user). This means that it is not possible to enable or disable an existing network configurations during upgrades. For the "mesh" and "ibss" networks, the default setting only has an effect if none diff --git a/docs/index.rst b/docs/index.rst index f1f36c29..c5226c27 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -64,6 +64,8 @@ Releases .. toctree:: :maxdepth: 1 + releases/v2016.2.2 + releases/v2016.2.1 releases/v2016.2 releases/v2016.1.6 releases/v2016.1.5 @@ -110,11 +112,6 @@ ar71xx-generic - WZR-HP-G300NH2 - WZR-HP-G450H -* Cisco Meraki - - - MR12 / MR62 - - MR16 / MR66 - * D-Link - DIR-505 (A1, A2) @@ -169,11 +166,11 @@ ar71xx-generic - TL-WA701N/ND (v1, v2) - TL-WA750RE (v1) - TL-WA7510N (v1) - - TL-WA801N/ND (v1, v2) + - TL-WA801N/ND (v1, v2, v3) - TL-WA830RE (v1, v2) - TL-WA850RE (v1) - TL-WA860RE (v1) - - TL-WA901N/ND (v1, v2, v3) + - TL-WA901N/ND (v1, v2, v3, v4) - TL-WDR3500 (v1) - TL-WDR3600 (v1) - TL-WDR4300 (v1) @@ -186,10 +183,12 @@ ar71xx-generic - TL-WR841N/ND (v3, v5, v7, v8, v9, v10, v11) - TL-WR842N/ND (v1, v2, v3) - TL-WR843N/ND (v1) - - TL-WR940N (v1, v2, v3) + - TL-WR940N (v1, v2, v3, v4) - TL-WR941ND (v2, v3, v4, v5, v6) - - TL-WR1043N/ND (v1, v2, v3) + - TL-WR1043N/ND (v1, v2, v3, v4) - TL-WR2543N/ND (v1) + - WBS210 (v1.20) + - WBS510 (v1.20) * Ubiquiti diff --git a/docs/releases/v2016.2.1.rst b/docs/releases/v2016.2.1.rst new file mode 100644 index 00000000..2f71205c --- /dev/null +++ b/docs/releases/v2016.2.1.rst @@ -0,0 +1,59 @@ +Gluon 2016.2.1 +============== + +Added hardware support +~~~~~~~~~~~~~~~~~~~~~~ + +ar71xx-generic +^^^^^^^^^^^^^^ + +* TP-Link + + - TL-WA901ND v4 + +Bugfixes +~~~~~~~~ + +* Make status page work with disabled cookies/local storage + (`#912 `_) + +* Update kernel to 3.18.44 + + Fixes CVE-2016-5195 and CVE-2016-7117. It is unlikely that these issues pose + a threat to usual Gluon setups, but installing additional packages may make a + system vulnerable. In any case, updating is highly recommended. + +* Downgrade mac80211 to an earlier state + + Unfortunately, a mac80211 update that was done shortly before the release of + Gluon v2016.2 (that seemed necessary to properly support ath10k devices) had + again caused severe ath9k stability issues that remained unreported until v2016.2 + was out. + + We have now reverted mac80211 to an earlier state that was reported to be very + stable (while keeping the ath10k-specific changes); in addition, some patches + that were reported to cause connection or performance issues with certain clients + have been reverted. While is it still not perfectly stable, is should be at least + as good as (and probably better than) the v2016.1.x release series. + +Known Issues +~~~~~~~~~~~~ + +* Default TX power on many Ubiquiti devices is too high, correct offsets are unknown (`#94 `_) + + Reducing the TX power in the Advanced Settings is recommended. + +* The MAC address of the WAN interface is modified even when Mesh-on-WAN is disabled (`#496 `_) + + This may lead to issues in environments where a fixed MAC address is expected (like VMware when promicious mode is disallowed). + +* Inconsistent respondd API (`#522 `_) + + The current API is inconsistent and will be replaced eventually. The old API will still be supported for a while. + +* Git HTTPS downloads from git.kernel.org fail on Debian Wheezy (`#919 `_) + + The GnuTLS version on Debian Wheezy is too old and can't establish a connection with + git.kernel.org anymore. A newer GnuTLS version is available in wheezy-backports, but + as there is no libcurl3-gnutls package linked against the new version, installing the + new version has no effect. diff --git a/docs/releases/v2016.2.2.rst b/docs/releases/v2016.2.2.rst new file mode 100644 index 00000000..fe054f54 --- /dev/null +++ b/docs/releases/v2016.2.2.rst @@ -0,0 +1,78 @@ +Gluon 2016.2.2 +============== + +Added hardware support +~~~~~~~~~~~~~~~~~~~~~~ + +ar71xx-generic +^^^^^^^^^^^^^^ + +* TP-Link + + - CPE210/510 EU/US versions + - TL-WA801N/ND v3 + - TL-WR841ND v11 EU/US versions + +Bugfixes +~~~~~~~~ + +* Fix boot on certain QCA955x-based devices (e.g. OpenMesh OM5P AC v2) (`#965 `_) + + This issue was a regression in Gluon v2016.2.1. + +* Build: Fix git downloads from git.kernel.org on Debian Wheezy (`#919 `_) + + We've switched back from HTTPS to the git protocol for now to avoid using + the old GnuTLS version of Debian Wheezy which can't establish a HTTPS connection + with git.kernel.org anymore. + + This issue was a regression in Gluon v2016.2. + +* Fix RX filter of Ubiquiti UAP Outdoor+ (`d43147a8e03d `_) + + This issue was a regression in Gluon v2016.2. + +* Fix switched WAN/LAN interface assignment on CPE210 (`59deb2064d54 `_) + + This issue was a regression in Gluon v2016.2. + +* Significantly reduce CPU load used by signal strength LEDs (`#897 `_) + +* Fix ethernet port of the Ubiquiti UAP AC Lite (`#911 `_) + +* Build: Don't use host ``/tmp`` directory (`f9072a36411b `_) + + Fixes build when ``/tmp`` is mounted with *noexec*. + +* Fix mesh interface type respondd/alfred announcements when using VLANs over IBSS (`#941 `_) + +* Fix next-node ebtables rules without *next_node.ip4* (`9dbe9f785d2b `_) + + Gluon v2016.2 added support for using the next-node feature without specifying an IPv4 + address. Some scripts had not been adjusted, making the next-node unreliable when + no IPv4 address was specified. + +Other changes +~~~~~~~~~~~~~ + +* x86-generic and x86-64 images now have PATA and MMC support to allow using them + on various devices that were previously unsupported. + +* Clean up opkg postinst scripts up on image generation + + OpenWrt does this by default to save a little space. + +Known Issues +~~~~~~~~~~~~ + +* Default TX power on many Ubiquiti devices is too high, correct offsets are unknown (`#94 `_) + + Reducing the TX power in the Advanced Settings is recommended. + +* The MAC address of the WAN interface is modified even when Mesh-on-WAN is disabled (`#496 `_) + + This may lead to issues in environments where a fixed MAC address is expected (like VMware when promicious mode is disallowed). + +* Inconsistent respondd API (`#522 `_) + + The current API is inconsistent and will be replaced eventually. The old API will still be supported for a while. diff --git a/docs/releases/v2016.2.rst b/docs/releases/v2016.2.rst index ca43e61b..7693e447 100644 --- a/docs/releases/v2016.2.rst +++ b/docs/releases/v2016.2.rst @@ -1,5 +1,5 @@ -Gluon 2016.2 (in development) -============================= +Gluon 2016.2 +============ Added hardware support ~~~~~~~~~~~~~~~~~~~~~~ @@ -76,7 +76,7 @@ New features the ``config_mode.owner.obligatory`` site.conf option * The *node name* setting in the config mode is no longer restricted to valid DNS - hostnames, but allows any UTF-8 string (`#414 `_) + hostnames, but allows any UTF-8 string (`#414 `_) * Besides the hostname, public key, site config and primary MAC address, the contact information can now be accessed from config mode site texts @@ -85,24 +85,35 @@ New features site texts. They should always be used when including user-provided information like hostnames and contact information in HTML code or URLs. -* Dropbear is updated to a newer version, enabling new SSH crytpo methods and removing +* Dropbear has been updated to a newer version, enabling new SSH crypto methods and removing some old ones like DSA. This reduces the time needed for the first boot and makes SSH logins faster (`#223 `_) * WLAN basic and supported rate sets have been made configurable, to allow disabling 802.11b rates (`#810 `_) -* ath10k-based devices are now officially supported, it's possible to choose between +* ath10k-based devices are now supported officially; it's possible to choose between IBSS- and 11s-capable firmwares in site.mk (`#864 `_) -* The ``prefix4`` and ``next_node.ip4`` site.conf options are now optional. +* The ``prefix4`` and ``next_node.ip4`` site.conf options are optional now. Bugfixes ~~~~~~~~ +* The stability of the ath9k WLAN driver has been improved significantly + (`#605 `_) + + mac80211, hostapd and other related drivers and services have been backported from LEDE ``42f559e``. + * Extremely slow downloads could lead to multiple instances of the autoupdater - running concurrently. Use lockfile to prevent this and add timeouts to download - processes. (`#582 `_) + running concurrently (`#582 `_) + + A lockfile is used to prevent this and timeouts have been added to download processes. + +* Usage of static DNS servers on the WAN port has been fixed + (`#886 `_) + + This is a regression introduced in Gluon v2016.1.6. Other changes ~~~~~~~~~~~~~ @@ -141,8 +152,6 @@ Inside of URLs, ``urlescape`` must be used instead of ``escape``. Internals ~~~~~~~~~ -* mac80211, hostapd and other related drivers and services have been backported from LEDE ``42f559e`` - * Mesh interfaces are now configured in a protocol-independent way in UCI (`#870 `_) The MAC address assignment of all mesh and WLAN interfaces has been modified to prepare for support of diff --git a/docs/site-example/i18n/de.po b/docs/site-example/i18n/de.po index 30f5c838..6eb0e469 100644 --- a/docs/site-example/i18n/de.po +++ b/docs/site-example/i18n/de.po @@ -12,18 +12,18 @@ msgstr "" msgid "gluon-config-mode:welcome" msgstr "" -"Willkommen zum Einrichtungsassistenten für deinen neuen Entenhausener " +"Willkommen zum Einrichtungsassistenten für deinen neuen Alpha Centauri " "Freifunk-Knoten. Fülle das folgende Formular deinen Vorstellungen " "entsprechend aus und sende es ab." msgid "gluon-config-mode:pubkey" msgstr "" "

Dies ist der öffentliche Schlüssel deines Freifunk-Knotens. Erst nachdem " -"er auf den Servern des Entenhausener Freifunk-Projektes eingetragen wurde, " -"kann sich dein Knoten mit dem Entenhausener Mesh-VPN verbinden. Bitte " +"er auf den Servern des Freifunk-Projektes auf Alpha Centauri eingetragen wurde, " +"kann sich dein Knoten mit dem Mesh-VPN dort verbinden. Bitte " "schicke dazu diesen Schlüssel und den Namen deines Knotens " "(<%=escape(hostname)%>) an " -"keys@entenhausen.freifunk.net." +"keys@alpha-centauri.freifunk.net." "

" "
" " # <%= escape(hostname) %>" @@ -33,12 +33,20 @@ msgstr "" msgid "gluon-config-mode:reboot" msgstr "" -"

Dein Knoten startet gerade neu und wird anschließend versuchen, " -"sich mit anderen Freifunkknoten in seiner Nähe zu " +"

Dein Knoten <%= escape(hostname) %> startet gerade neu und wird " +"anschließend versuchen, sich mit anderen Freifunkknoten in seiner Nähe zu " "verbinden. Weitere Informationen zur " -"Entenhausener Freifunk-Community findest du auf " -"unserer Webseite.

" +"Alpha Centauri Freifunk-Community findest du auf " +"unserer Webseite.

" "

Um zu dieser Konfigurationsseite zurückzugelangen, drücke im normalen " "Betrieb für drei Sekunden den Reset-Button. Das Gerät wird dann im Config " "Mode neustarten.

" "

Viel Spaß mit deinem Knoten und der Erkundung von Freifunk!

" + +msgid "gluon-config-mode:altitude-label" +msgstr "Höhe" + +msgid "gluon-config-mode:altitude-help" +msgstr "" +"Die Höhenangabe ist optional und sollte nur gesetzt werden, wenn ein " +"exakter Wert bekannt ist." diff --git a/docs/site-example/i18n/en.po b/docs/site-example/i18n/en.po index e6d1e672..7df16365 100644 --- a/docs/site-example/i18n/en.po +++ b/docs/site-example/i18n/en.po @@ -12,16 +12,15 @@ msgstr "" msgid "gluon-config-mode:welcome" msgstr "" -"Welcome to the setup wizard of your new Freifunk Duckburg node. " +"Welcome to the setup wizard of your new Freifunk Alpha Centauri node. " "Please fill out the following form and submit it." msgid "gluon-config-mode:pubkey" msgstr "" "

This is your Freifunk node's public key. The node won't be able to " -"connect to the mesh VPN until the key has been registered on the Freifunk " -"Duckburg servers. " +"connect to the mesh VPN until the key has been registered on the Freifunk servers. " "To register, send the key together with your node's name (<%=escape(hostname)%>) to " -"keys@entenhausen.freifunk.net." +"keys@alpha-centauri.freifunk.net." "

" "
" " # <%= escape(hostname) %>" @@ -29,14 +28,21 @@ msgstr "" "<%= pubkey %>" "
" - msgid "gluon-config-mode:reboot" msgstr "" -"

The node is currently rebooting and will try to connect to other " -"nearby Freifunk nodes after that. " -"For more information on the Freifunk Duckburg community, have a look at " -"our homepage.

" +"

Your node <%= escape(hostname) %> is currently rebooting and will " +"try to connect to other nearby Freifunk nodes after that. For more " +"information about the Freifunk community on Alpha Centauri, have a look at " +"our homepage.

" "

To get back to this configuration interface, press the reset button for " "3 seconds during normal operation. The device will then reboot into config " "mode.

" "

Have fun with your node and exploring of the Freifunk network!

" + +msgid "gluon-config-mode:altitude-label" +msgstr "Altitude" + +msgid "gluon-config-mode:altitude-help" +msgstr "" +"Specifying the altitude is optional and should only be done if a proper " +"value is known." diff --git a/docs/site-example/i18n/fr.po b/docs/site-example/i18n/fr.po index 1462fdbf..2e05db22 100644 --- a/docs/site-example/i18n/fr.po +++ b/docs/site-example/i18n/fr.po @@ -14,7 +14,7 @@ msgid "gluon-config-mode:welcome" msgstr "" "Bienvenue dans l'assistant de configuration pour votre nouveau nœud " "Freifunk. Remplissez le formulaire suivant en fonction de vos besoins " -"et enregistrez le" +"et enregistrez le" msgid "gluon-config-mode:pubkey" msgstr "" @@ -23,7 +23,7 @@ msgstr "" "sur les serveur Mesh-VPN de votre groupe Freifunk. Veuillez envoyer la clé avec le " "nom de votre nœud " "(<%=escape(hostname)%>) à " -"keys@entenhausen.freifunk.net." +"keys@alpha-centauri.freifunk.net." "

" "
" " # <%= escape(hostname) %>" @@ -33,11 +33,19 @@ msgstr "" msgid "gluon-config-mode:reboot" msgstr "" -"

Votre nœud es en train de redémarrer et va ensuite éssayer de se connecter " -"avec les autres nœuds du réseau Freifunk " +"

Votre nœud <%= escape(hostname) %> es en train de redémarrer et " +"va ensuite éssayer de se connecter avec les autres nœuds du réseau Freifunk " "Vous pourrez trouver plus d'informations sur votre groupe Freifunk sur la page " -" de ton groupe .

" +" de ton groupe .

" "

Pour retrouver cette page de configuration veuillier appuyez pendant le " "fonctionement normal pendant 3 Secondes sur le bouton reset. L'appareil va ensuite " "redémarer en mode configuration.

" "

Profitez votre de nœud et amusez vous à découvrir le réseau Freifunk!

" + +msgid "gluon-config-mode:altitude-label" +msgstr "Hauteur" + +msgid "gluon-config-mode:altitude-help" +msgstr "" +"La altitude est optionelle et ne devrait que être ajoutée si la valeur " +"exacte est connue." diff --git a/docs/site-example/i18n/gluon-site.pot b/docs/site-example/i18n/gluon-site.pot index 670de410..a161a12b 100644 --- a/docs/site-example/i18n/gluon-site.pot +++ b/docs/site-example/i18n/gluon-site.pot @@ -9,3 +9,9 @@ msgstr "" msgid "gluon-config-mode:reboot" msgstr "" + +msgid "gluon-config-mode:altitude-label" +msgstr "" + +msgid "gluon-config-mode:altitude-help" +msgstr "" diff --git a/docs/site-example/site.conf b/docs/site-example/site.conf index 66320956..07639b18 100644 --- a/docs/site-example/site.conf +++ b/docs/site-example/site.conf @@ -1,4 +1,4 @@ --- This is an example site configuration for Gluon v2016.1+ +-- This is an example site configuration for Gluon v2016.2+ -- -- Take a look at the documentation located at -- http://gluon.readthedocs.org/ for details. @@ -10,7 +10,7 @@ -- hostname_prefix = 'freifunk-', -- Name of the community. - site_name = 'Freifunk Entenhausen', + site_name = 'Freifunk Alpha Centauri', -- Shorthand of the community. site_code = 'ffxx', @@ -47,7 +47,7 @@ -- ESSID used for client network. ap = { - ssid = 'entenhausen.freifunk.net', + ssid = 'alpha-centauri.freifunk.net', -- disabled = true, (optional) }, @@ -65,7 +65,7 @@ wifi5 = { channel = 44, ap = { - ssid = 'entenhausen.freifunk.net', + ssid = 'alpha-centauri.freifunk.net', }, mesh = { id = 'ffxx-mesh', @@ -102,6 +102,7 @@ methods = {'salsa2012+umac'}, -- enabled = true, -- configurable = true, + -- syslog_level = 'warn', mtu = 1280, groups = { diff --git a/docs/site-example/site.mk b/docs/site-example/site.mk index 9f729890..79ecf37a 100644 --- a/docs/site-example/site.mk +++ b/docs/site-example/site.mk @@ -1,11 +1,9 @@ ## gluon site.mk makefile example ## GLUON_SITE_PACKAGES -# specify gluon/openwrt packages to include here -# The gluon-mesh-batman-adv-* package must come first because of the dependency resolution +# specify Gluon/LEDE packages to include here GLUON_SITE_PACKAGES := \ - gluon-mesh-batman-adv-15 \ gluon-alfred \ gluon-respondd \ gluon-autoupdater \ @@ -21,7 +19,7 @@ GLUON_SITE_PACKAGES := \ gluon-luci-autoupdater \ gluon-luci-portconfig \ gluon-luci-wifi-config \ - gluon-next-node \ + gluon-mesh-batman-adv-15 \ gluon-mesh-vpn-fastd \ gluon-radvd \ gluon-setup-mode \ diff --git a/docs/user/getting_started.rst b/docs/user/getting_started.rst index 66a94f81..dd4ac422 100644 --- a/docs/user/getting_started.rst +++ b/docs/user/getting_started.rst @@ -8,7 +8,7 @@ Gluon's releases are managed using `Git tags`_. If you are just getting started with Gluon we recommend to use the latest stable release of Gluon. Take a look at the `list of gluon releases`_ and notice the latest release, -e.g. *v2016.1.6*. Always get Gluon using git and don't try to download it +e.g. *v2016.2.2*. Always get Gluon using git and don't try to download it as a Zip archive as the archive will be missing version information. Please keep in mind that there is no "default Gluon" build; a site configuration @@ -36,13 +36,14 @@ freshly installed Debian Wheezy system the following packages are required: * `libncurses-dev` (actually `libncurses5-dev`) * `libz-dev` (actually `zlib1g-dev`) * `libssl-dev` +* `wget` Building the images ------------------- To build Gluon, first check out the repository. Replace *RELEASE* with the -version you'd like to checkout, e.g. *v2016.1.6*. +version you'd like to checkout, e.g. *v2016.2.2*. :: @@ -58,7 +59,7 @@ Now, enter the freshly created directory:: It's time to add (or create) your site configuration. If you already have a site repository, just clone it:: - git clone https://github.com/freifunk-duckburg/site-ffdb.git site + git clone https://github.com/freifunk-alpha-centauri/site-ffac.git site If you want to build a new site, create a new git repository *site/*:: @@ -84,7 +85,6 @@ Next go back to the top-level Gluon directory and build Gluon:: make update # Get other repositories used by Gluon make GLUON_TARGET=ar71xx-generic # Build Gluon -When calling make, the OpenWrt build environment is prepared/updated. In case of errors read the messages carefully and try to fix the stated issues (e.g. install tools not available yet). ``ar71xx-generic`` is the most common target and will generate images for most of the supported hardware. @@ -94,7 +94,7 @@ You should reserve about 10GB of disk space for each `GLUON_TARGET`. The built images can be found in the directory `output/images`. Of these, the `factory` images are to be used when flashing from the original firmware a device came with, -and `sysupgrade` is to upgrade from other versions of Gluon or any other OpenWrt-based +and `sysupgrade` is to upgrade from other versions of Gluon or any other OpenWrt/LEDE-based system. **Note:** The images for some models are identical; to save disk space, symlinks are generated instead @@ -110,39 +110,25 @@ There are two levels of `make clean`:: make clean GLUON_TARGET=ar71xx-generic -will ensure all packages are rebuilt for a single target; this is what you normally want to do after an update. +will ensure all packages are rebuilt for a single target. This normally not +necessary, but may fix certain kinds of build failures. :: make dirclean -will clean the entire tree, so the toolchain will be rebuilt as well, which is -not necessary in most cases, and will take a while. - -So in summary, to update and rebuild a Gluon build tree, the following commands should be used (repeat the -``make clean`` and ``make`` for all targets you want to build): - -:: - - git pull - (cd site && git pull) - make update - make clean GLUON_TARGET=ar71xx-generic - make GLUON_TARGET=ar71xx-generic - +will clean the entire tree, so the toolchain will be rebuilt as well, which will take a while. opkg repositories ----------------- -Gluon is mostly compatible with OpenWrt, so the normal OpenWrt package repositories -can be used for Gluon as well. It is advisable to setup a mirror or reverse proxy -reachable over IPv6 and add it to ``site.conf`` as http://downloads.openwrt.org/ does -not support IPv6. +Gluon is mostly compatible with LEDE, so the normal LEDE package repositories +can be used for Gluon as well. This is not true for kernel modules; the Gluon kernel is incompatible with the -kernel of the default OpenWrt images. Therefore, Gluon will not only generate images, -but also an opkg repository containing all kernel modules provided by OpenWrt/Gluon -for the kernel of the generated images. +kernel of the default LEDE images. Therefore, Gluon will not only generate images, +but also an opkg repository containing all core packages provided by LEDE, +including modules for the kernel of the generated images. Signing keys ............ @@ -150,18 +136,14 @@ Signing keys Gluon does not support HTTPS for downloading packages; fortunately, opkg deploys public-key cryptography to ensure package integrity. -The Gluon images will contain two public keys: the official OpenWrt signing key +The Gluon images will contain public keys from two sources: the official LEDE keyring (to allow installing userspace packages) and a Gluon-specific key (which is used -to sign the generated module repository). +to sign the generated package repository). -By default, Gluon will handle the generation and handling of the keys itself. +LEDE will handle the generation and handling of the keys itself. When making firmware releases based on Gluon, it might make sense to store the keypair, so updating the module repository later is possible. -The location the keys are stored at and read from can be changed -(see :ref:`getting-started-make-variables`). To only generate the keypair -at the configured location without doing a full build, use ``make create-key``. - .. _getting-started-make-variables: Make variables @@ -216,13 +198,8 @@ GLUON_BUILDDIR GLUON_IMAGEDIR Path where images will be stored. Defaults to ``$(GLUON_OUTPUTDIR)/images``. -GLUON_MODULEDIR - Path where the kernel module opkg repository will be stored. Defaults to ``$(GLUON_OUTPUTDIR)/modules``. - -GLUON_OPKG_KEY - Path key file used to sign the module opkg repository. Defaults to ``$(GLUON_BULDDIR)/gluon-opkg-key``. - - The private key will be stored as ``$(GLUON_OPKG_KEY)``, the public key as ``$(GLUON_OPKG_KEY).pub``. +GLUON_PACKAGEDIR + Path where the opkg package repository will be stored. Defaults to ``$(GLUON_OUTPUTDIR)/packages``. GLUON_OUTPUTDIR Path where output files will be stored. Defaults to ``output``. diff --git a/docs/user/site.rst b/docs/user/site.rst index b1f00c69..42ef85c6 100644 --- a/docs/user/site.rst +++ b/docs/user/site.rst @@ -46,7 +46,7 @@ ntp_server List of NTP servers available in your community or used by your community, e.g.: :: - ntp_servers = {'1.ntp.services.ffeh','2.ntp.services.ffeh'} + ntp_servers = {'1.ntp.services.ffac','2.ntp.services.ffac'} This NTP servers must be reachable via IPv6 from the nodes. If you don't want to set an IPv6 address explicitly, but use a hostname (which is recommended), see also the :ref:`FAQ `. @@ -56,23 +56,27 @@ opkg \: optional There are two optional fields in the ``opkg`` section: - - ``openwrt`` overrides the default OpenWrt repository URL + - ``lede`` overrides the default LEDE repository URL. The default URL would + correspond to ``http://downloads.lede-project.org/snapshots/packages/%A`` + and usually doesn't need to be changed when nodes are expected to have IPv6 + internet connectivity. - ``extra`` specifies a table of additional repositories (with arbitrary keys) :: opkg = { - openwrt = 'http://opkg.services.ffeh/openwrt/%n/%v/%S/packages', + lede = 'http://opkg.services.ffac/lede/snapshots/packages/%A', extra = { - modules = 'http://opkg.services.ffeh/modules/gluon-%GS-%GR/%S', + gluon = 'http://opkg.services.ffac/modules/gluon-%GS-%GR/%S', }, } There are various patterns which can be used in the URLs: - - ``%n`` is replaced by the OpenWrt version codename (e.g. "chaos_calmer") - - ``%v`` is replaced by the OpenWrt version number (e.g. "15.05") - - ``%S`` is replaced by the target architecture (e.g. "ar71xx/generic") + - ``%n`` is replaced by the LEDE version codename + - ``%v`` is replaced by the LEDE version number (e.g. "17.01") + - ``%S`` is replaced by the target board (e.g. "ar71xx/generic") + - ``%A`` is replaced by the target architecture (e.g. "mips_24kc") - ``%GS`` is replaced by the Gluon site code (as specified in ``site.conf``) - ``%GV`` is replaced by the Gluon version - ``%GR`` is replaced by the Gluon release (as specified in ``site.mk``) @@ -83,7 +87,7 @@ regdom \: optional regdom = 'DE' - Setting ``regdom`` in mandatory if ``wifi24`` or ``wifi5`` is defined. + Setting ``regdom`` is mandatory if ``wifi24`` or ``wifi5`` is defined. wifi24 \: optional WLAN configuration for 2.4 GHz devices. @@ -98,7 +102,7 @@ wifi24 \: optional Each interface may be disabled by setting ``disabled`` to ``true``. This will only affect new installations. - Upgrades will not changed the disabled state. + Upgrades will not change the disabled state. Additionally it is possible to configure the ``supported_rates`` and ``basic_rate`` of each radio. Both are optional, by default hostapd/driver dictate the rates. @@ -115,7 +119,8 @@ wifi24 \: optional An optional parameter ``vlan`` (integer) is supported. Both ``mesh`` and ``ibss`` accept an optional ``mcast_rate`` (kbit/s) parameter for - setting the default multicast datarate. + setting the multicast bitrate. Increasing the default value of 1000 to something + like 12000 is recommended. :: wifi24 = { @@ -123,10 +128,10 @@ wifi24 \: optional supported_rates = {6000, 9000, 12000, 18000, 24000, 36000, 48000, 54000}, basic_rate = {6000, 9000, 18000, 36000, 54000}, ap = { - ssid = 'entenhausen.freifunk.net', + ssid = 'alpha-centauri.freifunk.net', }, mesh = { - id = 'entenhausen-mesh', + id = 'alpha-centauri-mesh', mcast_rate = 12000, }, ibss = { @@ -182,12 +187,15 @@ fastd_mesh_vpn In any case, the ``null`` method should always be the first method in the list if it is supported at all. You should only set `configurable` to `true` if the configured peers support both the ``null`` method and methods with encryption. + + You can set syslog_level from verbose (default) to warn to reduce syslog output. :: fastd_mesh_vpn = { methods = {'salsa2012+umac'}, -- enabled = true, -- configurable = true, + -- syslog_level = 'warn', mtu = 1280, groups = { backbone = { @@ -198,14 +206,14 @@ fastd_mesh_vpn key = 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX', -- Having multiple domains prevents SPOF in freifunk.net remotes = { - 'ipv4 "vpn1.entenhausen.freifunk.net" port 10000', - 'ipv4 "vpn1.entenhausener-freifunk.de" port 10000', + 'ipv4 "vpn1.alpha-centauri.freifunk.net" port 10000', + 'ipv4 "vpn1.alpha-centauri-freifunk.de" port 10000', }, }, peer2 = { key = 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX', -- You can also omit the ipv4 to allow both connection via ipv4 and ipv6 - remotes = {'"vpn2.entenhausen.freifunk.net" port 10000'}, + remotes = {'"vpn2.alpha-centauri.freifunk.net" port 10000'}, }, }, -- Optional: nested peer groups @@ -258,7 +266,7 @@ autoupdater \: package name = 'stable', mirrors = { 'http://[fdca:ffee:babe:1::fec1]/firmware/stable/sysupgrade/', - 'http://autoupdate.entenhausen.freifunk.net/firmware/stable/sysupgrade/', + 'http://autoupdate.alpha-centauri.freifunk.net/firmware/stable/sysupgrade/', }, -- Number of good signatures required good_signatures = 2, @@ -282,7 +290,7 @@ roles \: optional part of ``list``. If you want node owners to change the role via config mode add the package ``gluon-luci-node-role`` to ``site.mk``. - The strings to display in the LuCI interface can be configured per language in the + The strings to display in the LuCI interface are configured per language in the ``i18n/en.po``, ``i18n/de.po``, etc. files of the site repository using message IDs like ``gluon-luci-node-role:role:node`` and ``gluon-luci-node-role:role:backbone``. :: @@ -313,9 +321,9 @@ legacy \: package legacy = { version_files = {'/etc/.freifunk_version_keep', '/etc/.eff_version_keep'}, - old_files = {'/etc/config/config_mode', '/etc/config/ffeh', '/etc/config/freifunk'}, - config_mode_configs = {'config_mode', 'ffeh', 'freifunk'}, - fastd_configs = {'ffeh_mesh_vpn', 'mesh_vpn'}, + old_files = {'/etc/config/config_mode', '/etc/config/ffac', '/etc/config/freifunk'}, + config_mode_configs = {'config_mode', 'ffac', 'freifunk'}, + fastd_configs = {'ffac_mesh_vpn', 'mesh_vpn'}, mesh_ifname = 'freifunk', tc_configs = {'ffki', 'freifunk'}, wifi_names = {'wifi_freifunk', 'wifi_freifunk5', 'wifi_mesh', 'wifi_mesh5'}, @@ -360,6 +368,12 @@ gluon-config-mode:welcome gluon-config-mode:pubkey Information about the public VPN key on the reboot page. +gluon-config-mode:altitude-label + Label for the ``altitude`` field + +gluon-config-mode:altitude-help + Description for the usage of the ``altitude`` field + gluon-config-mode:reboot General information shown on the reboot page. @@ -469,7 +483,7 @@ This is a non-exhaustive list of site-repos from various communities: * `site-ffhl `_ (Lübeck) * `site-fflg `_ (Lüneburg) * `site-ffmd `_ (Magdeburg) -* `site-ffmwu `_ (Mainz, Wiesbaden & Umgebung) +* `site-ffmwu `_ (Mainz, Wiesbaden & Umgebung) * `site-ffmyk `_ (Mayen-Koblenz) * `site-ffmo `_ (Moers) * `site-ffmg `_ (Mönchengladbach) @@ -480,6 +494,7 @@ This is a non-exhaustive list of site-repos from various communities: * `site-ffniers `_ (Niersufer) * `site-ffnw `_ (Nordwest) * `site-ffrgb `_ (Regensburg) +* `site-ffrn `_ (Rhein-Neckar) * `site-ffruhr `_ (Ruhrgebiet, Multi-Communities) * `site-ffs `_ (Stuttgart) * `site-fftr `_ (Trier) 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 ef0f5311..00000000 --- a/include/gluon.mk +++ /dev/null @@ -1,82 +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 2>/dev/null || echo unknown) -export GLUON_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 c185e366..dc031027 100644 --- a/modules +++ b/modules @@ -1,19 +1,16 @@ GLUON_FEEDS='openwrt gluon routing luci' -OPENWRT_REPO=git://github.com/openwrt/openwrt.git -OPENWRT_COMMIT=e663db7bb1797740c4a29ac0fc96eda1b88f9e6e -OPENWRT_BRANCH=chaos_calmer +LEDE_REPO=git://git.lede-project.org/source.git +LEDE_COMMIT=b9a408c2b49ccfa0e906bda00ef77f4002e401fd PACKAGES_OPENWRT_REPO=git://github.com/openwrt/packages.git -PACKAGES_OPENWRT_COMMIT=73776792f7d58e982be9e5819450d4875b273159 -PACKAGES_OPENWRT_BRANCH=for-15.05 +PACKAGES_OPENWRT_COMMIT=ee211f94ec292f7ec3d563fcbc147359b6cf8290 PACKAGES_GLUON_REPO=git://github.com/freifunk-gluon/packages.git -PACKAGES_GLUON_COMMIT=90380414f10842238b7ebc21c34dbaf986659320 +PACKAGES_GLUON_COMMIT=485186ace270564393b464bb4ff07686df31cd96 PACKAGES_ROUTING_REPO=git://github.com/openwrt-routing/packages.git -PACKAGES_ROUTING_COMMIT=a4eae82c155079a4372e4b910ec733f77288b717 +PACKAGES_ROUTING_COMMIT=d848d49d2443448b147c564c2dd8f64433b5fb9c PACKAGES_LUCI_REPO=git://github.com/openwrt/luci.git -PACKAGES_LUCI_COMMIT=70a4d43cc895b7d728b4fc201f2b6fd9f4b8aaec -PACKAGES_LUCI_BRANCH=for-15.05 +PACKAGES_LUCI_COMMIT=d7328360632d7fbf5fd4006b4172a9fe9861d838 diff --git a/overlay/opkg.mk b/overlay/opkg.mk new file mode 100644 index 00000000..2506dbe6 --- /dev/null +++ b/overlay/opkg.mk @@ -0,0 +1,2 @@ +FEEDS_ENABLED := $(FEEDS_DISABLED) +FEEDS_DISABLED := diff --git a/package/gluon-alfred/Makefile b/package/gluon-alfred/Makefile index f38b0dbe..be0ff0da 100644 --- a/package/gluon-alfred/Makefile +++ b/package/gluon-alfred/Makefile @@ -6,13 +6,13 @@ PKG_RELEASE:=1 PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME) -include $(GLUONDIR)/include/package.mk +include ../gluon.mk define Package/gluon-alfred SECTION:=gluon CATEGORY:=Gluon - DEPENDS:=+gluon-core +gluon-respondd +gluon-neighbour-info +micrond +alfred + DEPENDS:=+gluon-core +gluon-respondd +gluon-neighbour-info gluon-mesh-batman-adv +micrond +alfred TITLE:=Configure alfred endef diff --git a/package/gluon-alfred/luasrc/lib/gluon/upgrade/500-enable-alfred b/package/gluon-alfred/luasrc/lib/gluon/upgrade/500-enable-alfred index d3802d8a..ce4ac0ad 100755 --- a/package/gluon-alfred/luasrc/lib/gluon/upgrade/500-enable-alfred +++ b/package/gluon-alfred/luasrc/lib/gluon/upgrade/500-enable-alfred @@ -7,7 +7,7 @@ local c = uci.cursor() c:delete('alfred', 'alfred') c:section('alfred', 'alfred', 'alfred', { - interface = 'br-client', + interface = 'local-node', mode = 'slave', batmanif = 'bat0', start_vis = '1', diff --git a/package/gluon-authorized-keys/Makefile b/package/gluon-authorized-keys/Makefile index 83eaf04f..7d010dc9 100644 --- a/package/gluon-authorized-keys/Makefile +++ b/package/gluon-authorized-keys/Makefile @@ -5,7 +5,7 @@ PKG_VERSION:=2 PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME) -include $(GLUONDIR)/include/package.mk +include ../gluon.mk define Package/gluon-authorized-keys diff --git a/package/gluon-autoupdater/Makefile b/package/gluon-autoupdater/Makefile index baae06ba..eacf80c1 100644 --- a/package/gluon-autoupdater/Makefile +++ b/package/gluon-autoupdater/Makefile @@ -2,12 +2,14 @@ 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 $(GLUONDIR)/include/package.mk + +include ../gluon.mk define Package/gluon-autoupdater @@ -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-autoupdater/files/lib/gluon/autoupdater/lib.sh b/package/gluon-autoupdater/files/lib/gluon/autoupdater/lib.sh index 36ddd971..24ef2f90 100644 --- a/package/gluon-autoupdater/files/lib/gluon/autoupdater/lib.sh +++ b/package/gluon-autoupdater/files/lib/gluon/autoupdater/lib.sh @@ -2,15 +2,15 @@ stop() { - if [ -x /etc/init.d/$1 ]; then + if [ -x /etc/init.d/"$1" ]; then echo "Stopping $1..." - /etc/init.d/$1 stop + /etc/init.d/"$1" stop fi } start_enabled() { - if [ -x /etc/init.d/$1 ] && /etc/init.d/$1 enabled; then + if [ -x /etc/init.d/"$1" ] && /etc/init.d/"$1" enabled; then echo "Starting $1..." - /etc/init.d/$1 start + /etc/init.d/"$1" start fi } diff --git a/package/gluon-client-bridge/Makefile b/package/gluon-client-bridge/Makefile index cbd62a38..57d5b314 100644 --- a/package/gluon-client-bridge/Makefile +++ b/package/gluon-client-bridge/Makefile @@ -5,7 +5,7 @@ PKG_VERSION:=1 PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME) -include $(GLUONDIR)/include/package.mk +include ../gluon.mk define Package/gluon-client-bridge diff --git a/package/gluon-client-bridge/check_site.lua b/package/gluon-client-bridge/check_site.lua index 3a7d81ee..c71f11c0 100644 --- a/package/gluon-client-bridge/check_site.lua +++ b/package/gluon-client-bridge/check_site.lua @@ -1,3 +1,12 @@ +need_string_match('next_node.mac', '^%x[02468aAcCeE]:%x%x:%x%x:%x%x:%x%x:%x%x$') + +if need_string_match('next_node.ip4', '^%d+.%d+.%d+.%d+$', false) then + need_string_match('prefix4', '^%d+.%d+.%d+.%d+/%d+$') +end + +need_string_match('next_node.ip6', '^[%x:]+$', false) + + for _, config in ipairs({'wifi24', 'wifi5'}) do if need_table(config .. '.ap', nil, false) then need_string(config .. '.ap.ssid') diff --git a/package/gluon-client-bridge/luasrc/lib/gluon/upgrade/300-gluon-client-bridge-network b/package/gluon-client-bridge/luasrc/lib/gluon/upgrade/300-gluon-client-bridge-network index f5ab8582..7540ecb5 100755 --- a/package/gluon-client-bridge/luasrc/lib/gluon/upgrade/300-gluon-client-bridge-network +++ b/package/gluon-client-bridge/luasrc/lib/gluon/upgrade/300-gluon-client-bridge-network @@ -1,33 +1,73 @@ #!/usr/bin/lua +local site = require 'gluon.site_config' local sysconfig = require 'gluon.sysconfig' +local util = require 'gluon.util' +local ip = require 'luci.ip' local lutil = require 'luci.util' local uci = require('luci.model.uci').cursor() +local ip4, netmask, ip6 + +if site.next_node.ip4 then + ip4 = site.next_node.ip4 + netmask = ip.IPv4(site.prefix4):mask():string() +end + +if site.next_node.ip6 then + ip6 = site.next_node.ip6 .. '/128' +end + uci:section('network', 'interface', 'client', - { - type = 'bridge', - } + { + type = 'bridge', + proto = 'static', + macaddr = site.next_node.mac, + ipaddr = ip4, + netmask = netmask, + ip6addr = ip6, + } ) -local ifname = uci:get('network', 'client', 'ifname') +uci:delete('network', 'client', 'reqprefix') +uci:delete('network', 'client', 'peerdns') +uci:delete('network', 'client', 'sourcefilter') -if type(ifname) == 'string' then - uci:delete('network', 'client', 'ifname') - for x in ifname:gmatch("[^%s]+") do - uci:add_to_set('network', 'client', 'ifname', x) - end + +local interfaces = uci:get('network', 'client', 'ifname') or {} + +if type(interfaces) == 'string' then + local ifname = interfaces + interfaces = {} + for iface in ifname:gmatch("[^%s]+") do + util.add_to_set(interfaces, iface) + end end if sysconfig.lan_ifname and not ifname and not uci:get_bool('network', 'mesh_lan', 'auto') then - for _, lanif in ipairs(lutil.split(sysconfig.lan_ifname, ' ')) do - uci:add_to_set('network', 'client', 'ifname', lanif) - end + for _, lanif in ipairs(lutil.split(sysconfig.lan_ifname, ' ')) do + util.add_to_set(interfaces, lanif) + end end - -uci:set('network', 'client', 'macaddr', sysconfig.primary_mac) +uci:set_list('network', 'client', 'ifname', interfaces) uci:save('network') + + +local dnsmasq = uci:get_first('dhcp', 'dnsmasq') +uci:set('dhcp', dnsmasq, 'boguspriv', 0) +uci:set('dhcp', dnsmasq, 'localise_queries', 0) +uci:set('dhcp', dnsmasq, 'rebind_protection', 0) + +uci:delete('dhcp', 'client') +uci:section('dhcp', 'dhcp', 'client', + { + interface = 'client', + ignore = 1, + } +) + +uci:save('dhcp') diff --git a/package/gluon-config-mode-autoupdater/Makefile b/package/gluon-config-mode-autoupdater/Makefile index ab5d1adc..2fe1ccb2 100644 --- a/package/gluon-config-mode-autoupdater/Makefile +++ b/package/gluon-config-mode-autoupdater/Makefile @@ -5,7 +5,7 @@ PKG_VERSION:=1 PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME) -include $(GLUONDIR)/include/package.mk +include ../gluon.mk PKG_CONFIG_DEPENDS += $(GLUON_I18N_CONFIG) diff --git a/package/gluon-config-mode-contact-info/Makefile b/package/gluon-config-mode-contact-info/Makefile index 3ac8a0b3..7a3780a6 100644 --- a/package/gluon-config-mode-contact-info/Makefile +++ b/package/gluon-config-mode-contact-info/Makefile @@ -5,7 +5,7 @@ PKG_VERSION:=1 PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME) -include $(GLUONDIR)/include/package.mk +include ../gluon.mk PKG_CONFIG_DEPENDS += $(GLUON_I18N_CONFIG) diff --git a/package/gluon-config-mode-core/Makefile b/package/gluon-config-mode-core/Makefile index 52a4f0e1..d629c265 100644 --- a/package/gluon-config-mode-core/Makefile +++ b/package/gluon-config-mode-core/Makefile @@ -8,7 +8,7 @@ PKG_VERSION:=2 PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME) -include $(GLUONDIR)/include/package.mk +include ../gluon.mk PKG_CONFIG_DEPENDS += $(GLUON_I18N_CONFIG) diff --git a/package/gluon-config-mode-core/files/usr/lib/lua/luci/view/gluon/cbi/config-mode.htm b/package/gluon-config-mode-core/files/usr/lib/lua/luci/view/gluon/cbi/config-mode.htm index b4aca92e..e608b52c 100644 --- a/package/gluon-config-mode-core/files/usr/lib/lua/luci/view/gluon/cbi/config-mode.htm +++ b/package/gluon-config-mode-core/files/usr/lib/lua/luci/view/gluon/cbi/config-mode.htm @@ -19,6 +19,7 @@
+
<% end %> diff --git a/package/gluon-config-mode-core/luasrc/lib/gluon/config-mode/reboot/0900-msg-reboot.lua b/package/gluon-config-mode-core/luasrc/lib/gluon/config-mode/reboot/0900-msg-reboot.lua index bf27c07f..96557f41 100644 --- a/package/gluon-config-mode-core/luasrc/lib/gluon/config-mode/reboot/0900-msg-reboot.lua +++ b/package/gluon-config-mode-core/luasrc/lib/gluon/config-mode/reboot/0900-msg-reboot.lua @@ -1,3 +1,23 @@ local i18n = require 'luci.i18n' +local site = require 'gluon.site_config' +local gluon_luci = require 'gluon.luci' +local sysconfig = require 'gluon.sysconfig' +local pretty_hostname = require 'pretty_hostname' -return function () luci.template.render_string(i18n.translate('gluon-config-mode:reboot')) end +local uci = luci.model.uci.cursor() + +local hostname = pretty_hostname.get(uci) +local contact = uci:get_first('gluon-node-info', 'owner', 'contact') + +local msg = i18n.translate('gluon-config-mode:reboot') + +return function () + luci.template.render_string(msg, { + hostname = hostname, + site = site, + sysconfig = sysconfig, + contact = contact, + escape = gluon_luci.escape, + urlescape = gluon_luci.urlescape, + }) +end diff --git a/package/gluon-config-mode-core/luasrc/usr/lib/lua/luci/controller/gluon-config-mode/index.lua b/package/gluon-config-mode-core/luasrc/usr/lib/lua/luci/controller/gluon-config-mode/index.lua index 0a6a5495..4e1f5232 100644 --- a/package/gluon-config-mode-core/luasrc/usr/lib/lua/luci/controller/gluon-config-mode/index.lua +++ b/package/gluon-config-mode-core/luasrc/usr/lib/lua/luci/controller/gluon-config-mode/index.lua @@ -32,11 +32,11 @@ function index() page.title = _("Wizard") page.target = alias("gluon-config-mode", "wizard") page.order = 5 - page.setuser = "root" - page.setgroup = "root" + page.sysauth = "root" + page.sysauth_authenticator = function() return "root" end page.index = true - entry({"gluon-config-mode", "wizard"}, form("gluon-config-mode/wizard")).index = true + entry({"gluon-config-mode", "wizard"}, cbi("gluon-config-mode/wizard")).index = true entry({"gluon-config-mode", "reboot"}, call("action_reboot")) end end diff --git a/package/gluon-config-mode-geo-location/Makefile b/package/gluon-config-mode-geo-location/Makefile index aa16ad06..af523f09 100644 --- a/package/gluon-config-mode-geo-location/Makefile +++ b/package/gluon-config-mode-geo-location/Makefile @@ -5,7 +5,7 @@ PKG_VERSION:=1 PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME) -include $(GLUONDIR)/include/package.mk +include ../gluon.mk PKG_CONFIG_DEPENDS += $(GLUON_I18N_CONFIG) diff --git a/package/gluon-config-mode-geo-location/i18n/de.po b/package/gluon-config-mode-geo-location/i18n/de.po index 3580732b..c8bc906a 100644 --- a/package/gluon-config-mode-geo-location/i18n/de.po +++ b/package/gluon-config-mode-geo-location/i18n/de.po @@ -17,22 +17,12 @@ msgstr "" "Um deinen Knoten auf der Karte anzeigen zu können, benötigen wir seine " "Koordinaten. Hier hast du die Möglichkeit, diese zu hinterlegen." -msgid "" -"Specifying the altitude is optional and should only be done if a proper " -"value is known." -msgstr "" -"Die Höhenangabe ist optional und sollte nur gesetzt werden, wenn ein " -"exakter Wert bekannt ist." - msgid "Latitude" msgstr "Breitengrad" msgid "Longitude" msgstr "Längengrad" -msgid "Altitude" -msgstr "Höhe" - msgid "Show node on the map" msgstr "Knoten auf der Karte anzeigen" diff --git a/package/gluon-config-mode-geo-location/i18n/fr.po b/package/gluon-config-mode-geo-location/i18n/fr.po index b239c84c..d3d7c6e8 100644 --- a/package/gluon-config-mode-geo-location/i18n/fr.po +++ b/package/gluon-config-mode-geo-location/i18n/fr.po @@ -17,22 +17,12 @@ msgstr "" "Pour Afficher votre nœud sur la Carte nous avons besoin de ses coordonnées. " "Ici vous pouvez entrer sa position." -msgid "" -"Specifying the altitude is optional and should only be done if a proper " -"value is known." -msgstr "" -"La altitude est optionelle et ne devrait que être ajoutée si la valeur " -"exacte est connue." - msgid "Latitude" msgstr "Latitude" msgid "Longitude" msgstr "Longitude" -msgid "Altitude" -msgstr "Hauteur" - msgid "Show node on the map" msgstr "Afficher le nœud sur la carte" diff --git a/package/gluon-config-mode-geo-location/i18n/gluon-config-mode-geo-location.pot b/package/gluon-config-mode-geo-location/i18n/gluon-config-mode-geo-location.pot index 48f26f70..7acf7f28 100644 --- a/package/gluon-config-mode-geo-location/i18n/gluon-config-mode-geo-location.pot +++ b/package/gluon-config-mode-geo-location/i18n/gluon-config-mode-geo-location.pot @@ -6,20 +6,12 @@ msgid "" "enter its coordinates here." msgstr "" -msgid "" -"Specifying the altitude is optional and should only be done if a proper " -"value is known." -msgstr "" - msgid "Latitude" msgstr "" msgid "Longitude" msgstr "" -msgid "Altitude" -msgstr "" - msgid "Show node on the map" msgstr "" diff --git a/package/gluon-config-mode-geo-location/luasrc/lib/gluon/config-mode/wizard/0400-geo-location.lua b/package/gluon-config-mode-geo-location/luasrc/lib/gluon/config-mode/wizard/0400-geo-location.lua index 9bc70301..04e9b144 100644 --- a/package/gluon-config-mode-geo-location/luasrc/lib/gluon/config-mode/wizard/0400-geo-location.lua +++ b/package/gluon-config-mode-geo-location/luasrc/lib/gluon/config-mode/wizard/0400-geo-location.lua @@ -19,8 +19,7 @@ function M.section(form) local text = i18n.translate('If you want the location of your node to ' .. 'be displayed on the map, you can enter its coordinates here.') if show_altitude() then - text = text .. ' ' .. i18n.translate('Specifying the altitude is ' - .. 'optional and should only be done if a proper value is known.') + text = text .. ' ' .. i18n.translate("gluon-config-mode:altitude-help") end local s = form:section(cbi.SimpleSection, nil, text) @@ -46,7 +45,7 @@ function M.section(form) o.description = i18n.translatef("e.g. %s", "10.689901") if show_altitude() then - o = s:option(cbi.Value, "_altitude", i18n.translate("Altitude")) + o = s:option(cbi.Value, "_altitude", i18n.translate("gluon-config-mode:altitude-label")) o.default = uci:get_first("gluon-node-info", "location", "altitude") o:depends("_location", "1") o.rmempty = true diff --git a/package/gluon-config-mode-hostname/Makefile b/package/gluon-config-mode-hostname/Makefile index 6e30466d..2b24a640 100644 --- a/package/gluon-config-mode-hostname/Makefile +++ b/package/gluon-config-mode-hostname/Makefile @@ -5,7 +5,7 @@ PKG_VERSION:=1 PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME) -include $(GLUONDIR)/include/package.mk +include ../gluon.mk PKG_CONFIG_DEPENDS += $(GLUON_I18N_CONFIG) diff --git a/package/gluon-config-mode-mesh-vpn/Makefile b/package/gluon-config-mode-mesh-vpn/Makefile index ec819a9c..c52ffed1 100644 --- a/package/gluon-config-mode-mesh-vpn/Makefile +++ b/package/gluon-config-mode-mesh-vpn/Makefile @@ -5,7 +5,7 @@ PKG_VERSION:=2 PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME) -include $(GLUONDIR)/include/package.mk +include ../gluon.mk PKG_CONFIG_DEPENDS += $(GLUON_I18N_CONFIG) diff --git a/package/gluon-core/Makefile b/package/gluon-core/Makefile index 2b9cfb47..5a15fc36 100644 --- a/package/gluon-core/Makefile +++ b/package/gluon-core/Makefile @@ -1,12 +1,14 @@ include $(TOPDIR)/rules.mk PKG_NAME:=gluon-core -PKG_VERSION:=3 -PKG_RELEASE:=$(GLUON_VERSION) + +GLUON_VERSION = $(shell git describe --always --dirty=+ 2>/dev/null || echo unknown) +PKG_VERSION:=$(if $(DUMP),x,$(GLUON_VERSION)) + PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME) -include $(GLUONDIR)/include/package.mk +include ../gluon.mk define Package/gluon-core @@ -20,10 +22,6 @@ define Package/gluon-core/description Gluon community wifi mesh firmware framework: core endef -define Build/Prepare - mkdir -p $(PKG_BUILD_DIR) -endef - define Build/Configure endef @@ -34,10 +32,9 @@ 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_VERSION)' > $(1)/lib/gluon/gluon-version endef define Package/gluon-core/postinst diff --git a/package/gluon-core/check_site.lua b/package/gluon-core/check_site.lua index 480b367c..c78e89dc 100644 --- a/package/gluon-core/check_site.lua +++ b/package/gluon-core/check_site.lua @@ -2,16 +2,16 @@ need_string 'site_code' need_string 'site_name' if need_table('opkg', nil, false) then - need_string('opkg.openwrt', false) + need_string('opkg.lede', false) - function check_repo(k, _) - -- this is not actually a uci name, but using the same naming rules here is fine - assert_uci_name(k) + function check_repo(k, _) + -- this is not actually a uci name, but using the same naming rules here is fine + assert_uci_name(k) - need_string(string.format('opkg.extra[%q]', k)) - end + need_string(string.format('opkg.extra[%q]', k)) + end - need_table('opkg.extra', check_repo, false) + need_table('opkg.extra', check_repo, false) end need_string('hostname_prefix', false) @@ -19,23 +19,32 @@ need_string 'timezone' need_string_array('ntp_servers', false) -need_string_match('prefix6', '^[%x:]+/%d+$') +need_string_match('prefix6', '^[%x:]+/64$') for _, config in ipairs({'wifi24', 'wifi5'}) do - if need_table(config, nil, false) then - need_string('regdom') -- regdom is only required when wifi24 or wifi5 is configured + if need_table(config, nil, false) then + need_string('regdom') -- regdom is only required when wifi24 or wifi5 is configured - need_number(config .. '.channel') + need_number(config .. '.channel') - local rates = {1000, 2000, 5500, 6000, 9000, 11000, 12000, 18000, 24000, 36000, 48000, 54000} - local supported_rates = need_array_of(config .. '.supported_rates', rates, false) - if supported_rates then - need_array_of(config .. '.basic_rate', supported_rates, true) - else - need_array_of(config .. '.basic_rate', rates, false) - end - end + local rates = {1000, 2000, 5500, 6000, 9000, 11000, 12000, 18000, 24000, 36000, 48000, 54000} + local supported_rates = need_array_of(config .. '.supported_rates', rates, false) + if supported_rates then + need_array_of(config .. '.basic_rate', supported_rates, true) + else + need_array_of(config .. '.basic_rate', rates, false) + end + end end need_boolean('poe_passthrough', false) +if need_table('dns', nil, false) then + need_number('dns.cacheentries', false) + need_string_array('dns.servers', false) +end + +if need_table('next_node', nil, false) then + need_string_match('next_node.ip6', '^[%x:]+$', false) + need_string_match('next_node.ip4', '^%d+.%d+.%d+.%d+$', false) +end diff --git a/package/gluon-core/luasrc/lib/gluon/upgrade/020-interfaces b/package/gluon-core/luasrc/lib/gluon/upgrade/020-interfaces index 34e1c8bb..7ce1af4d 100755 --- a/package/gluon-core/luasrc/lib/gluon/upgrade/020-interfaces +++ b/package/gluon-core/luasrc/lib/gluon/upgrade/020-interfaces @@ -16,7 +16,7 @@ if not (sysconfig.lan_ifname or sysconfig.wan_ifname) then local lan_ifname = uci:get('network', 'lan', 'ifname') local wan_ifname = uci:get('network', 'wan', 'ifname') - if platform.match('ar71xx', 'generic', {'cpe510', 'nanostation-m', 'nanostation-m-xw', 'unifi-outdoor-plus', 'uap-pro', 'unifiac-pro'}) then + if platform.match('ar71xx', 'generic', {'cpe210', 'cpe510', 'wbs210', 'wbs510', 'nanostation-m', 'nanostation-m-xw', 'unifi-outdoor-plus', 'uap-pro', 'unifiac-pro'}) then lan_ifname, wan_ifname = wan_ifname, lan_ifname end diff --git a/package/gluon-core/luasrc/lib/gluon/upgrade/500-opkg b/package/gluon-core/luasrc/lib/gluon/upgrade/500-opkg index 4380050c..353cf8d8 100755 --- a/package/gluon-core/luasrc/lib/gluon/upgrade/500-opkg +++ b/package/gluon-core/luasrc/lib/gluon/upgrade/500-opkg @@ -8,42 +8,53 @@ local util = require 'luci.util' local subst = {} subst['%%v'] = util.trim(fs.readfile('/etc/openwrt_version')) -subst['%%n'], subst['%%S'] = util.exec('. /etc/openwrt_release; echo $DISTRIB_CODENAME; echo $DISTRIB_TARGET'):match('([^\n]*)\n([^\n]*)') +subst['%%n'], subst['%%S'], subst['%%A'] = util.exec('. /etc/openwrt_release; echo "$DISTRIB_CODENAME"; echo "$DISTRIB_TARGET"; echo "$DISTRIB_ARCH"'):match('([^\n]*)\n([^\n]*)\n([^\n]*)') subst['%%GS'] = site.site_code subst['%%GV'] = util.trim(fs.readfile('/lib/gluon/gluon-version')) subst['%%GR'] = util.trim(fs.readfile('/lib/gluon/release')) function replace_patterns(url) - for k, v in pairs(subst) do - url = url:gsub(k, v) - end + for k, v in pairs(subst) do + url = url:gsub(k, v) + end - return url + return url 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') +local prefix = subst['%%n'] .. '_' - for _, v in ipairs(__GLUON_OPENWRT_FEEDS__) do - f:write(replace_patterns(string.format('src/gz %%n_%s %s/%s\n', v, site.opkg.openwrt, v))) - end +if fs.access('/etc/opkg/distfeeds.conf') then + local distfeeds = {} + for line in io.lines('/etc/opkg/distfeeds.conf') do + table.insert(distfeeds, line) + end - f:close() - end + local f = io.open('/etc/opkg/distfeeds.conf', 'w') - if site.opkg.extra and next(site.opkg.extra) then - local f = io.open('/etc/opkg/gluon.conf', 'w') + for _, line in ipairs(distfeeds) do + local name = line:match('^src/gz%s' .. prefix .. '(%S+)%s') + if name == 'core' then + f:write('# ' .. line .. '\n') + elseif name and site.opkg and site.opkg.lede then + f:write(string.format('src/gz %s %s/%s\n', prefix .. name, replace_patterns(site.opkg.lede), name)) + else + f:write(line .. '\n') + end + end - for k, v in pairs(site.opkg.extra) do - f:write(string.format('src/gz %s %s\n', k, replace_patterns(v))) - end + f:close() - f:close() + if site.opkg and site.opkg.extra and next(site.opkg.extra) then + local f = io.open('/etc/opkg/gluon.conf', 'w') - else - os.remove('/etc/opkg/gluon.conf') - end + for k, v in pairs(site.opkg.extra) do + f:write(string.format('src/gz %s %s\n', k, replace_patterns(v))) + end + + f:close() + + else + os.remove('/etc/opkg/gluon.conf') + end end diff --git a/package/gluon-core/luasrc/lib/gluon/upgrade/820-dns-config b/package/gluon-core/luasrc/lib/gluon/upgrade/820-dns-config new file mode 100755 index 00000000..e95a53a1 --- /dev/null +++ b/package/gluon-core/luasrc/lib/gluon/upgrade/820-dns-config @@ -0,0 +1,40 @@ +#!/usr/bin/lua +local site = require 'gluon.site_config' +local uci = require('luci.model.uci').cursor() + +dnsmasq=uci:get_first("dhcp", "dnsmasq") + +uci:set('dhcp', dnsmasq, 'localise_queries', '1') +uci:set('dhcp', dnsmasq, 'localservice', '0') + +if site.dns and site.dns.servers then + uci:set('dhcp', dnsmasq, 'server', site.dns.servers) +else + uci:delete('dhcp', dnsmasq, 'server') +end + +if site.dns and site.dns.cacheentries then + uci:set('dhcp', dnsmasq, 'cachesize', site.dns.cacheentries) +else + uci:delete('dhcp', dnsmasq, 'cachesize') +end + +if site.next_node and site.next_node.name and site.next_node.ip4 then + uci:section('dhcp','domain','nextnode4',{ + name=site.next_node.name, + ip=site.next_node.ip4, + }) +else + uci:delete('dhcp', 'domain', 'nextnode4') +end + +if site.next_node and site.next_node.name and site.next_node.ip6 then + uci:section('dhcp','domain','nextnode6',{ + name=site.next_node.name, + ip=site.next_node.ip6, + }) +else + uci:delete('dhcp', 'domain', 'nextnode6') +end +uci:save('dhcp') + diff --git a/package/gluon-core/luasrc/usr/lib/lua/gluon/sysctl.lua b/package/gluon-core/luasrc/usr/lib/lua/gluon/sysctl.lua index 44b0c217..ee429437 100644 --- a/package/gluon-core/luasrc/usr/lib/lua/gluon/sysctl.lua +++ b/package/gluon-core/luasrc/usr/lib/lua/gluon/sysctl.lua @@ -4,5 +4,9 @@ local util = require 'gluon.util' module 'gluon.sysctl' function set(name, value) - util.replace_prefix('/etc/sysctl.conf', name .. '=', name .. '=' .. value .. '\n') + local new + if value then + new = name .. '=' .. value .. '\n' + end + util.replace_prefix('/etc/sysctl.conf', name .. '=', new) end diff --git a/package/gluon-core/luasrc/usr/lib/lua/gluon/util.lua b/package/gluon-core/luasrc/usr/lib/lua/gluon/util.lua index 0ae50b4d..f013ec23 100644 --- a/package/gluon-core/luasrc/usr/lib/lua/gluon/util.lua +++ b/package/gluon-core/luasrc/usr/lib/lua/gluon/util.lua @@ -1,25 +1,25 @@ -- Writes all lines from the file input to the file output except those starting with prefix -- Doesn't close the output file, but returns the file object local function do_filter_prefix(input, output, prefix) - local f = io.open(output, 'w+') - local l = prefix:len() + local f = io.open(output, 'w+') + local l = prefix:len() - for line in io.lines(input) do - if line:sub(1, l) ~= prefix then - f:write(line, '\n') - end - end + for line in io.lines(input) do + if line:sub(1, l) ~= prefix then + f:write(line, '\n') + end + end - return f + return f end local function escape_args(ret, arg0, ...) - if not arg0 then - return ret - end + if not arg0 then + return ret + end - return escape_args(ret .. "'" .. string.gsub(arg0, "'", "'\\''") .. "' ", ...) + return escape_args(ret .. "'" .. string.gsub(arg0, "'", "'\\''") .. "' ", ...) end @@ -41,76 +41,109 @@ local fs = require 'nixio.fs' module 'gluon.util' +function add_to_set(t, itm) + for _,v in ipairs(t) do + if v == itm then return false end + end + table.insert(t, itm) + return true +end + +function remove_from_set(t, itm) + local i = 1 + local changed = false + while i <= #t do + if t[i] == itm then + table.remove(t, i) + changed = true + else + i = i + 1 + end + end + return changed +end + + function exec(...) - return os.execute(escape_args('', 'exec', ...)) + return os.execute(escape_args('', 'exec', ...)) end -- Removes all lines starting with a prefix from a file, optionally adding a new one function replace_prefix(file, prefix, add) - local tmp = file .. '.tmp' - local f = do_filter_prefix(file, tmp, prefix) - if add then - f:write(add) - end - f:close() - os.rename(tmp, file) + local tmp = file .. '.tmp' + local f = do_filter_prefix(file, tmp, prefix) + if add then + f:write(add) + end + f:close() + os.rename(tmp, file) end function readline(fd) - local line = fd:read('*l') - fd:close() - return line + local line = fd:read('*l') + fd:close() + return line end function lock(file) - exec('lock', file) + exec('lock', file) end function unlock(file) - exec('lock', '-u', file) + exec('lock', '-u', file) end function node_id() - return string.gsub(sysconfig.primary_mac, ':', '') + return string.gsub(sysconfig.primary_mac, ':', '') end +function get_mesh_devices(uconn) + local dump = uconn:call("network.interface", "dump", {}) + local devices = {} + for _, interface in ipairs(dump.interface) do + if ( (interface.proto == "gluon_mesh") and interface.up ) then + table.insert(devices, interface.device) + end + end + return devices +end local function find_phy_by_path(path) - for phy in fs.glob('/sys/devices/' .. path .. '/ieee80211/phy*') do - return phy:match('([^/]+)$') - end + for phy in fs.glob('/sys/devices/' .. path .. '/ieee80211/phy*') do + return phy:match('([^/]+)$') + end end local function find_phy_by_macaddr(macaddr) - local addr = macaddr:lower() - for file in fs.glob('/sys/class/ieee80211/*/macaddress') do - if lutil.trim(fs.readfile(file)) == addr then - return file:match('([^/]+)/macaddress$') - end - end + local addr = macaddr:lower() + for file in fs.glob('/sys/class/ieee80211/*/macaddress') do + if lutil.trim(fs.readfile(file)) == addr then + return file:match('([^/]+)/macaddress$') + end + end end local function find_phy(radio) - local config = uci:get_all('wireless', radio) + local config = uci:get_all('wireless', radio) - if not config or config.type ~= 'mac80211' then - return nil - elseif config.path then - return find_phy_by_path(config.path) - elseif config.macaddr then - return find_phy_by_macaddr(config.macaddr) - else - return nil - end + if not config or config.type ~= 'mac80211' then + return nil + elseif config.path then + return find_phy_by_path(config.path) + elseif config.macaddr then + return find_phy_by_macaddr(config.macaddr) + else + return nil + end end local function get_addresses(radio) - local phy = find_phy(radio) - if not phy then - return function() end - end + local phy = find_phy(radio) + if not phy then + return function() end + end - return io.lines('/sys/class/ieee80211/' .. phy .. '/addresses') + return io.lines('/sys/class/ieee80211/' .. phy .. '/addresses') end -- Generates a (hopefully) unique MAC address @@ -126,70 +159,70 @@ end -- 6: ibss1 -- 7: wan_radio1 (private WLAN); mesh VPN function generate_mac(i) - if i > 7 or i < 0 then return nil end -- max allowed id (0b111) + if i > 7 or i < 0 then return nil end -- max allowed id (0b111) - local hashed = string.sub(hash.md5(sysconfig.primary_mac), 0, 12) - local m1, m2, m3, m4, m5, m6 = string.match(hashed, '(%x%x)(%x%x)(%x%x)(%x%x)(%x%x)(%x%x)') + local hashed = string.sub(hash.md5(sysconfig.primary_mac), 0, 12) + local m1, m2, m3, m4, m5, m6 = string.match(hashed, '(%x%x)(%x%x)(%x%x)(%x%x)(%x%x)(%x%x)') - m1 = tonumber(m1, 16) - m6 = tonumber(m6, 16) + m1 = tonumber(m1, 16) + m6 = tonumber(m6, 16) - m1 = nixio.bit.bor(m1, 0x02) -- set locally administered bit - m1 = nixio.bit.band(m1, 0xFE) -- unset the multicast bit + m1 = nixio.bit.bor(m1, 0x02) -- set locally administered bit + m1 = nixio.bit.band(m1, 0xFE) -- unset the multicast bit - -- It's necessary that the first 45 bits of the MAC address don't - -- vary on a single hardware interface, since some chips are using - -- a hardware MAC filter. (e.g 'rt305x') + -- It's necessary that the first 45 bits of the MAC address don't + -- vary on a single hardware interface, since some chips are using + -- a hardware MAC filter. (e.g 'rt305x') - m6 = nixio.bit.band(m6, 0xF8) -- zero the last three bits (space needed for counting) - m6 = m6 + i -- add virtual interface id + m6 = nixio.bit.band(m6, 0xF8) -- zero the last three bits (space needed for counting) + m6 = m6 + i -- add virtual interface id - return string.format('%02x:%s:%s:%s:%s:%02x', m1, m2, m3, m4, m5, m6) + return string.format('%02x:%s:%s:%s:%s:%02x', m1, m2, m3, m4, m5, m6) end local function get_wlan_mac_from_driver(radio, vif) - local primary = sysconfig.primary_mac:lower() + local primary = sysconfig.primary_mac:lower() - local i = 1 - for addr in get_addresses(radio) do - if addr:lower() ~= primary then - if i == vif then - return addr - end + local i = 1 + for addr in get_addresses(radio) do + if addr:lower() ~= primary then + if i == vif then + return addr + end - i = i + 1 - end - end + i = i + 1 + end + end end function get_wlan_mac(radio, index, vif) - local addr = get_wlan_mac_from_driver(radio, vif) - if addr then - return addr - end + local addr = get_wlan_mac_from_driver(radio, vif) + if addr then + return addr + end - return generate_mac(4*(index-1) + (vif-1)) + return generate_mac(4*(index-1) + (vif-1)) end -- Iterate over all radios defined in UCI calling -- f(radio, index, site.wifiX) for each radio found while passing -- site.wifi24 for 2.4 GHz devices and site.wifi5 for 5 GHz ones. function iterate_radios(f) - local radios = {} + local radios = {} - uci:foreach('wireless', 'wifi-device', - function(s) - table.insert(radios, s['.name']) - end - ) + uci:foreach('wireless', 'wifi-device', + function(s) + table.insert(radios, s['.name']) + end + ) - for index, radio in ipairs(radios) do - local hwmode = uci:get('wireless', radio, 'hwmode') + for index, radio in ipairs(radios) do + local hwmode = uci:get('wireless', radio, 'hwmode') - if hwmode == '11g' or hwmode == '11ng' then - f(radio, index, site.wifi24) - elseif hwmode == '11a' or hwmode == '11na' then - f(radio, index, site.wifi5) - end - end + if hwmode == '11g' or hwmode == '11ng' then + f(radio, index, site.wifi24) + elseif hwmode == '11a' or hwmode == '11na' then + f(radio, index, site.wifi5) + end + end end diff --git a/package/gluon-legacy/Makefile b/package/gluon-legacy/Makefile index 1cb2e5f4..64607ea3 100644 --- a/package/gluon-legacy/Makefile +++ b/package/gluon-legacy/Makefile @@ -5,7 +5,7 @@ PKG_VERSION:=2 PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME) -include $(GLUONDIR)/include/package.mk +include ../gluon.mk define Package/gluon-legacy diff --git a/package/gluon-luci-admin/Makefile b/package/gluon-luci-admin/Makefile index 7b5f632a..bb6f8350 100644 --- a/package/gluon-luci-admin/Makefile +++ b/package/gluon-luci-admin/Makefile @@ -9,7 +9,7 @@ PKG_RELEASE:=1 PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME) -include $(GLUONDIR)/include/package.mk +include ../gluon.mk PKG_CONFIG_DEPENDS += $(GLUON_I18N_CONFIG) diff --git a/package/gluon-luci-admin/files/usr/lib/lua/luci/view/admin/expertmode.htm b/package/gluon-luci-admin/files/usr/lib/lua/luci/view/admin/expertmode.htm deleted file mode 100644 index 53947f3c..00000000 --- a/package/gluon-luci-admin/files/usr/lib/lua/luci/view/admin/expertmode.htm +++ /dev/null @@ -1,56 +0,0 @@ -<% if not self.embedded then %> - -
- - -
-<% end %> -
- <% if self.title and #self.title > 0 then %>

<%=self.title%>

<% end %> - <%- if self.message then %> -

<%=self.message%>

- <%- end %> - <%- if self.errmessage then %> -

<%=self.errmessage%>

- <%- end %> - <% if self.description and #self.description > 0 then %>
<%=self.description%>
<% end %> - <% self:render_children() %> -
-<% if not self.embedded then %> -
-<%- - if type(self.hidden) == "table" then - for k, v in pairs(self.hidden) do --%> - -<%- - end - end -%> -<% if redirect then %> -
- -
-<% end %> -<%- if self.flow and self.flow.skip then %> - -<% end %> -<%- if self.submit ~= false then %> - -<% end %> -<%- if self.reset ~= false then %> - -<% end %> -<%- if self.cancel ~= false and self.on_cancel then %> - -<% end %> - -
-
-<% end %> diff --git a/package/gluon-luci-admin/files/usr/lib/lua/luci/view/admin/upgrade.htm b/package/gluon-luci-admin/files/usr/lib/lua/luci/view/admin/upgrade.htm index a2b82235..87702918 100644 --- a/package/gluon-luci-admin/files/usr/lib/lua/luci/view/admin/upgrade.htm +++ b/package/gluon-luci-admin/files/usr/lib/lua/luci/view/admin/upgrade.htm @@ -48,8 +48,8 @@ $Id$
+
<%+footer%> - diff --git a/package/gluon-luci-admin/files/usr/lib/lua/luci/view/admin/upgrade_confirm.htm b/package/gluon-luci-admin/files/usr/lib/lua/luci/view/admin/upgrade_confirm.htm index 5618728f..a5ef8109 100644 --- a/package/gluon-luci-admin/files/usr/lib/lua/luci/view/admin/upgrade_confirm.htm +++ b/package/gluon-luci-admin/files/usr/lib/lua/luci/view/admin/upgrade_confirm.htm @@ -45,23 +45,24 @@ $Id$ if flashsize > 0 then write(luci.i18n.translatef( " (%s available)", - w.byte_format(flashsize) + byte_format(flashsize) )) end %>

-
+ " /> +
-
+ " /> +
<%+footer%> - diff --git a/package/gluon-luci-admin/luasrc/usr/lib/lua/luci/controller/admin/upgrade.lua b/package/gluon-luci-admin/luasrc/usr/lib/lua/luci/controller/admin/upgrade.lua index 2365f02c..1930e9ec 100644 --- a/package/gluon-luci-admin/luasrc/usr/lib/lua/luci/controller/admin/upgrade.lua +++ b/package/gluon-luci-admin/luasrc/usr/lib/lua/luci/controller/admin/upgrade.lua @@ -44,6 +44,12 @@ function action_upgrade() -- Determine state local step = tonumber(luci.http.formvalue("step") or 1) + + if step ~= 1 and not luci.dispatcher.test_post_security() then + nixio.fs.unlink(tmpfile) + return + end + local has_image = nixio.fs.access(tmpfile) local has_support = image_supported(tmpfile) diff --git a/package/gluon-luci-admin/luasrc/usr/lib/lua/luci/model/cbi/admin/remote.lua b/package/gluon-luci-admin/luasrc/usr/lib/lua/luci/model/cbi/admin/remote.lua index c79c0195..655dd66e 100644 --- a/package/gluon-luci-admin/luasrc/usr/lib/lua/luci/model/cbi/admin/remote.lua +++ b/package/gluon-luci-admin/luasrc/usr/lib/lua/luci/model/cbi/admin/remote.lua @@ -16,90 +16,74 @@ $Id$ local fs = require "nixio.fs" -local m = Map("system", translate("SSH keys")) -m.pageaction = false -m.template = "admin/expertmode" +local f_keys = SimpleForm('keys', translate("SSH keys"), translate("You can provide your SSH keys here (one per line):")) +f_keys.hidden = { submit_keys = '1' } -if fs.access("/etc/config/dropbear") then - local s = m:section(TypedSection, "_dummy1", nil, - translate("You can provide your SSH keys here (one per line):")) +local keys - s.addremove = false - s.anonymous = true +keys = f_keys:field(TextValue, "keys", "") +keys.wrap = "off" +keys.rows = 5 +keys.rmempty = true - function s.cfgsections() - return { "_keys" } - end - - local keys - - keys = s:option(TextValue, "_data", "") - keys.wrap = "off" - keys.rows = 5 - keys.rmempty = true - - function keys.cfgvalue() - return fs.readfile("/etc/dropbear/authorized_keys") or "" - end - - function keys.write(self, section, value) - if value then - fs.writefile("/etc/dropbear/authorized_keys", value:gsub("\r\n", "\n"):trim() .. "\n") - end - end - - function keys.remove(self, section) - if keys:formvalue("_keys") then - fs.remove("/etc/dropbear/authorized_keys") - end - end +function keys.cfgvalue() + return fs.readfile("/etc/dropbear/authorized_keys") or "" end -local m2 = Map("system", translate("Password")) -m2.reset = false -m2.pageaction = false -m2.template = "admin/expertmode" +function keys.write(self, section, value) + if not f_keys:formvalue('submit_keys') then return end -local s = m2:section(TypedSection, "_dummy2", nil, translate( - "Alternatively, you can set a password to access you node. Please choose a secure password you don't use anywhere else.

" - .. "If you set an empty password, login via password will be disabled. This is the default.")) + fs.writefile("/etc/dropbear/authorized_keys", value:gsub("\r\n", "\n"):trim() .. "\n") +end -s.addremove = false -s.anonymous = true +function keys.remove(self, section) + if not f_keys:formvalue('submit_keys') then return end -local pw1 = s:option(Value, "pw1", translate("Password")) + fs.remove("/etc/dropbear/authorized_keys") +end + +local f_password = SimpleForm('password', translate("Password"), + translate( + "Alternatively, you can set a password to access you node. Please choose a secure password you don't use anywhere else.

" + .. "If you set an empty password, login via password will be disabled. This is the default." + ) +) +f_password.hidden = { submit_password = '1' } +f_password.reset = false + +local pw1 = f_password:field(Value, "pw1", translate("Password")) pw1.password = true +function pw1.cfgvalue() + return '' +end -local pw2 = s:option(Value, "pw2", translate("Confirmation")) +local pw2 = f_password:field(Value, "pw2", translate("Confirmation")) pw2.password = true - -function s.cfgsections() - return { "_pass" } +function pw2.cfgvalue() + return '' end -function m2.on_commit(map) - local v1 = pw1:formvalue("_pass") - local v2 = pw2:formvalue("_pass") +function f_password:handle(state, data) + if not f_password:formvalue('submit_password') then return end - if v1 and v2 then - if v1 == v2 then - if #v1 > 0 then - if luci.sys.user.setpasswd('root', v1) == 0 then - m2.message = translate("Password changed.") - else - m2.errmessage = translate("Unable to change the password.") - end - else - -- We don't check the return code here as the error 'password for root is already locked' is normal... - os.execute('passwd -l root >/dev/null') - m2.message = translate("Password removed.") - end - else - m2.errmessage = translate("The password and the confirmation differ.") - end - end + if data.pw1 ~= data.pw2 then + f_password.errmessage = translate("The password and the confirmation differ.") + return + end + + if data.pw1 and #data.pw1 > 0 then + if luci.sys.user.setpasswd('root', data.pw1) == 0 then + f_password.message = translate("Password changed.") + else + f_password.errmessage = translate("Unable to change the password.") + end + else + -- We don't check the return code here as the error 'password for root is already locked' is normal... + os.execute('passwd -l root >/dev/null') + f_password.message = translate("Password removed.") + end end -local c = Compound(m, m2) +local c = Compound(f_keys, f_password) c.pageaction = false return c diff --git a/package/gluon-luci-autoupdater/Makefile b/package/gluon-luci-autoupdater/Makefile index 908a0879..4cecb10a 100644 --- a/package/gluon-luci-autoupdater/Makefile +++ b/package/gluon-luci-autoupdater/Makefile @@ -9,7 +9,7 @@ PKG_RELEASE:=1 PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME) -include $(GLUONDIR)/include/package.mk +include ../gluon.mk PKG_CONFIG_DEPENDS += $(GLUON_I18N_CONFIG) diff --git a/package/gluon-luci-autoupdater/luasrc/usr/lib/lua/luci/model/cbi/admin/autoupdater.lua b/package/gluon-luci-autoupdater/luasrc/usr/lib/lua/luci/model/cbi/admin/autoupdater.lua index a8f9d3b3..5c1d81a0 100644 --- a/package/gluon-luci-autoupdater/luasrc/usr/lib/lua/luci/model/cbi/admin/autoupdater.lua +++ b/package/gluon-luci-autoupdater/luasrc/usr/lib/lua/luci/model/cbi/admin/autoupdater.lua @@ -14,7 +14,7 @@ $Id$ m = Map("autoupdater", translate("Automatic updates")) m.pageaction = false -m.template = "admin/expertmode" +m.template = "cbi/simpleform" s = m:section(TypedSection, "autoupdater", nil) s.addremove = false diff --git a/package/gluon-luci-mesh-vpn-fastd/Makefile b/package/gluon-luci-mesh-vpn-fastd/Makefile index b6b7ce4f..71dadce7 100644 --- a/package/gluon-luci-mesh-vpn-fastd/Makefile +++ b/package/gluon-luci-mesh-vpn-fastd/Makefile @@ -6,7 +6,7 @@ PKG_RELEASE:=1 PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME) -include $(GLUONDIR)/include/package.mk +include ../gluon.mk PKG_CONFIG_DEPENDS += $(GLUON_I18N_CONFIG) diff --git a/package/gluon-luci-mesh-vpn-fastd/luasrc/usr/lib/lua/luci/model/cbi/admin/mesh_vpn_fastd.lua b/package/gluon-luci-mesh-vpn-fastd/luasrc/usr/lib/lua/luci/model/cbi/admin/mesh_vpn_fastd.lua index 14bb5783..1e918936 100644 --- a/package/gluon-luci-mesh-vpn-fastd/luasrc/usr/lib/lua/luci/model/cbi/admin/mesh_vpn_fastd.lua +++ b/package/gluon-luci-mesh-vpn-fastd/luasrc/usr/lib/lua/luci/model/cbi/admin/mesh_vpn_fastd.lua @@ -2,7 +2,6 @@ local uci = luci.model.uci.cursor() local util = luci.util local f = SimpleForm('mesh_vpn', translate('Mesh VPN')) -f.template = "admin/expertmode" local s = f:section(SimpleSection) diff --git a/package/gluon-luci-node-role/Makefile b/package/gluon-luci-node-role/Makefile index 2c862610..058e879c 100644 --- a/package/gluon-luci-node-role/Makefile +++ b/package/gluon-luci-node-role/Makefile @@ -6,7 +6,7 @@ PKG_RELEASE:=1 PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME) -include $(GLUONDIR)/include/package.mk +include ../gluon.mk PKG_CONFIG_DEPENDS += $(GLUON_I18N_CONFIG) diff --git a/package/gluon-luci-node-role/luasrc/usr/lib/lua/luci/model/cbi/admin/noderole.lua b/package/gluon-luci-node-role/luasrc/usr/lib/lua/luci/model/cbi/admin/noderole.lua index e7832ad9..8450a39c 100644 --- a/package/gluon-luci-node-role/luasrc/usr/lib/lua/luci/model/cbi/admin/noderole.lua +++ b/package/gluon-luci-node-role/luasrc/usr/lib/lua/luci/model/cbi/admin/noderole.lua @@ -8,7 +8,6 @@ local config = 'gluon-node-info' local role = uci:get(config, uci:get_first(config, "system"), "role") f = SimpleForm("role", i18n.translate("Node role")) -f.template = "admin/expertmode" s = f:section(SimpleSection, nil, i18n.translate( "If this node has a special role within the freifunk network you can specify this role here. " diff --git a/package/gluon-luci-portconfig/Makefile b/package/gluon-luci-portconfig/Makefile index d4590864..eaec9db4 100644 --- a/package/gluon-luci-portconfig/Makefile +++ b/package/gluon-luci-portconfig/Makefile @@ -9,7 +9,7 @@ PKG_RELEASE:=1 PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME) -include $(GLUONDIR)/include/package.mk +include ../gluon.mk PKG_CONFIG_DEPENDS += $(GLUON_I18N_CONFIG) diff --git a/package/gluon-luci-portconfig/luasrc/usr/lib/lua/luci/model/cbi/admin/portconfig.lua b/package/gluon-luci-portconfig/luasrc/usr/lib/lua/luci/model/cbi/admin/portconfig.lua index 2e40577a..2cab7606 100644 --- a/package/gluon-luci-portconfig/luasrc/usr/lib/lua/luci/model/cbi/admin/portconfig.lua +++ b/package/gluon-luci-portconfig/luasrc/usr/lib/lua/luci/model/cbi/admin/portconfig.lua @@ -7,7 +7,7 @@ Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at - http://www.apache.org/licenses/LICENSE-2.0 +http://www.apache.org/licenses/LICENSE-2.0 $Id$ ]]-- @@ -15,13 +15,13 @@ $Id$ local uci = luci.model.uci.cursor() local lutil = require 'luci.util' local sysconfig = require 'gluon.sysconfig' +local util = require 'gluon.util' local wan = uci:get_all("network", "wan") local wan6 = uci:get_all("network", "wan6") local dns = uci:get_first("gluon-wan-dnsmasq", "static") local f = SimpleForm("portconfig", translate("WAN connection")) -f.template = "admin/expertmode" local s local o @@ -75,11 +75,11 @@ o.rmempty = false if dns then - s = f:section(SimpleSection, nil, nil) + s = f:section(SimpleSection, nil, nil) - o = s:option(DynamicList, "dns", translate("Static DNS servers")) - o:write(nil, uci:get("gluon-wan-dnsmasq", dns, "server")) - o.datatype = "ipaddr" + o = s:option(DynamicList, "dns", translate("Static DNS servers")) + o:write(nil, uci:get("gluon-wan-dnsmasq", dns, "server")) + o.datatype = "ipaddr" end s = f:section(SimpleSection, nil, nil) @@ -89,80 +89,80 @@ o.default = uci:get_bool("network", "mesh_wan", "auto") and o.enabled or o.disab o.rmempty = false if sysconfig.lan_ifname then - o = s:option(Flag, "mesh_lan", translate("Enable meshing on the LAN interface")) - o.default = uci:get_bool("network", "mesh_lan", "auto") and o.enabled or o.disabled - o.rmempty = false + o = s:option(Flag, "mesh_lan", translate("Enable meshing on the LAN interface")) + o.default = uci:get_bool("network", "mesh_lan", "auto") and o.enabled or o.disabled + o.rmempty = false end if uci:get('system', 'gpio_switch_poe_passthrough') then - s = f:section(SimpleSection, nil, nil) - o = s:option(Flag, "poe_passthrough", translate("Enable PoE passthrough")) - o.default = uci:get_bool("system", "gpio_switch_poe_passthrough", "value") and o.enabled or o.disabled - o.rmempty = false + s = f:section(SimpleSection, nil, nil) + o = s:option(Flag, "poe_passthrough", translate("Enable PoE passthrough")) + o.default = uci:get_bool("system", "gpio_switch_poe_passthrough", "value") and o.enabled or o.disabled + o.rmempty = false end - function f.handle(self, state, data) - if state == FORM_VALID then - uci:set("network", "wan", "proto", data.ipv4) - if data.ipv4 == "static" then - uci:set("network", "wan", "ipaddr", data.ipv4_addr:trim()) - uci:set("network", "wan", "netmask", data.ipv4_netmask:trim()) - uci:set("network", "wan", "gateway", data.ipv4_gateway:trim()) - else - uci:delete("network", "wan", "ipaddr") - uci:delete("network", "wan", "netmask") - uci:delete("network", "wan", "gateway") - end + if state == FORM_VALID then + uci:set("network", "wan", "proto", data.ipv4) + if data.ipv4 == "static" then + uci:set("network", "wan", "ipaddr", data.ipv4_addr:trim()) + uci:set("network", "wan", "netmask", data.ipv4_netmask:trim()) + uci:set("network", "wan", "gateway", data.ipv4_gateway:trim()) + else + uci:delete("network", "wan", "ipaddr") + uci:delete("network", "wan", "netmask") + uci:delete("network", "wan", "gateway") + end - uci:set("network", "wan6", "proto", data.ipv6) - if data.ipv6 == "static" then - uci:set("network", "wan6", "ip6addr", data.ipv6_addr:trim()) - uci:set("network", "wan6", "ip6gw", data.ipv6_gateway:trim()) - else - uci:delete("network", "wan6", "ip6addr") - uci:delete("network", "wan6", "ip6gw") - end + uci:set("network", "wan6", "proto", data.ipv6) + if data.ipv6 == "static" then + uci:set("network", "wan6", "ip6addr", data.ipv6_addr:trim()) + uci:set("network", "wan6", "ip6gw", data.ipv6_gateway:trim()) + else + uci:delete("network", "wan6", "ip6addr") + uci:delete("network", "wan6", "ip6gw") + end - uci:set("network", "mesh_wan", "auto", data.mesh_wan) + uci:set("network", "mesh_wan", "auto", data.mesh_wan) - if sysconfig.lan_ifname then - uci:set("network", "mesh_lan", "auto", data.mesh_lan) + if sysconfig.lan_ifname then + uci:set("network", "mesh_lan", "auto", data.mesh_lan) - local doit - if data.mesh_lan == '1' then - doit = uci.remove_from_set - else - doit = uci.add_to_set - end + local interfaces = uci:get_list("network", "client", "ifname") - for _, lanif in ipairs(lutil.split(sysconfig.lan_ifname, ' ')) do - doit(uci, "network", "client", "ifname", lanif) - end - end + for _, lanif in ipairs(lutil.split(sysconfig.lan_ifname, ' ')) do + if data.mesh_lan == '1' then + util.remove_from_set(interfaces, lanif) + else + util.add_to_set(interfaces, lanif) + end + end - uci:save("network") - uci:commit("network") + uci:set_list("network", "client", "ifname", interfaces) + end - if uci:get('system', 'gpio_switch_poe_passthrough') then - uci:set('system', 'gpio_switch_poe_passthrough', 'value', data.poe_passthrough) - uci:save('system') - uci:commit('system') - end + uci:save("network") + uci:commit("network") - if dns then - if #data.dns > 0 then - uci:set("gluon-wan-dnsmasq", dns, "server", data.dns) - else - uci:delete("gluon-wan-dnsmasq", dns, "server") - end + if uci:get('system', 'gpio_switch_poe_passthrough') then + uci:set('system', 'gpio_switch_poe_passthrough', 'value', data.poe_passthrough) + uci:save('system') + uci:commit('system') + end - uci:save("gluon-wan-dnsmasq") - uci:commit("gluon-wan-dnsmasq") - end - end + if dns then + if #data.dns > 0 then + uci:set("gluon-wan-dnsmasq", dns, "server", data.dns) + else + uci:delete("gluon-wan-dnsmasq", dns, "server") + end - return true + uci:save("gluon-wan-dnsmasq") + uci:commit("gluon-wan-dnsmasq") + end + end + + return true end return f diff --git a/package/gluon-luci-private-wifi/Makefile b/package/gluon-luci-private-wifi/Makefile index 34608900..ef6f2a0a 100644 --- a/package/gluon-luci-private-wifi/Makefile +++ b/package/gluon-luci-private-wifi/Makefile @@ -6,7 +6,7 @@ PKG_RELEASE:=1 PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME) -include $(GLUONDIR)/include/package.mk +include ../gluon.mk PKG_CONFIG_DEPENDS += $(GLUON_I18N_CONFIG) diff --git a/package/gluon-luci-private-wifi/luasrc/usr/lib/lua/luci/model/cbi/admin/privatewifi.lua b/package/gluon-luci-private-wifi/luasrc/usr/lib/lua/luci/model/cbi/admin/privatewifi.lua index 46a1a9d7..c4ff78d9 100644 --- a/package/gluon-luci-private-wifi/luasrc/usr/lib/lua/luci/model/cbi/admin/privatewifi.lua +++ b/package/gluon-luci-private-wifi/luasrc/usr/lib/lua/luci/model/cbi/admin/privatewifi.lua @@ -8,7 +8,6 @@ local primary_iface = 'wan_radio0' local ssid = uci:get('wireless', primary_iface, "ssid") f = SimpleForm("wifi", translate("Private WLAN")) -f.template = "admin/expertmode" s = f:section(SimpleSection, nil, translate( 'Your node can additionally extend your private network by bridging the WAN interface ' diff --git a/package/gluon-luci-theme/Makefile b/package/gluon-luci-theme/Makefile index 6e65db3c..2486519a 100644 --- a/package/gluon-luci-theme/Makefile +++ b/package/gluon-luci-theme/Makefile @@ -9,7 +9,7 @@ PKG_RELEASE:=1 PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME) -include $(GLUONDIR)/include/package.mk +include ../gluon.mk define Package/gluon-luci-theme diff --git a/package/gluon-luci-wifi-config/Makefile b/package/gluon-luci-wifi-config/Makefile index 0f0d90f2..881f2f0e 100644 --- a/package/gluon-luci-wifi-config/Makefile +++ b/package/gluon-luci-wifi-config/Makefile @@ -6,7 +6,7 @@ PKG_RELEASE:=1 PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME) -include $(GLUONDIR)/include/package.mk +include ../gluon.mk PKG_CONFIG_DEPENDS += $(GLUON_I18N_CONFIG) diff --git a/package/gluon-luci-wifi-config/luasrc/usr/lib/lua/luci/model/cbi/admin/wifi-config.lua b/package/gluon-luci-wifi-config/luasrc/usr/lib/lua/luci/model/cbi/admin/wifi-config.lua index efff8657..4f280de1 100644 --- a/package/gluon-luci-wifi-config/luasrc/usr/lib/lua/luci/model/cbi/admin/wifi-config.lua +++ b/package/gluon-luci-wifi-config/luasrc/usr/lib/lua/luci/model/cbi/admin/wifi-config.lua @@ -41,7 +41,6 @@ end local f = SimpleForm("wifi", translate("WLAN")) -f.template = "admin/expertmode" local s = f:section(SimpleSection, nil, translate( "You can enable or disable your node's client and mesh network " diff --git a/package/gluon-mesh-batman-adv-14/Makefile b/package/gluon-mesh-batman-adv-14/Makefile index aa53e85f..cd3aa2fb 100644 --- a/package/gluon-mesh-batman-adv-14/Makefile +++ b/package/gluon-mesh-batman-adv-14/Makefile @@ -5,7 +5,7 @@ PKG_VERSION:=1 PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME) -include $(GLUONDIR)/include/package.mk +include ../gluon.mk define Package/gluon-mesh-batman-adv-14 diff --git a/package/gluon-mesh-batman-adv-15/Makefile b/package/gluon-mesh-batman-adv-15/Makefile index d64fea88..7f8d8a80 100644 --- a/package/gluon-mesh-batman-adv-15/Makefile +++ b/package/gluon-mesh-batman-adv-15/Makefile @@ -5,7 +5,7 @@ PKG_VERSION:=1 PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME) -include $(GLUONDIR)/include/package.mk +include ../gluon.mk define Package/gluon-mesh-batman-adv-15 diff --git a/package/gluon-mesh-batman-adv-core/Makefile b/package/gluon-mesh-batman-adv-core/Makefile index efcf1698..d476d4f8 100644 --- a/package/gluon-mesh-batman-adv-core/Makefile +++ b/package/gluon-mesh-batman-adv-core/Makefile @@ -6,14 +6,14 @@ PKG_VERSION:=1 PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME) PKG_BUILD_DEPENDS := respondd -include $(GLUONDIR)/include/package.mk +include ../gluon.mk define Package/gluon-mesh-batman-adv-core SECTION:=gluon CATEGORY:=Gluon TITLE:=Support for batman-adv meshing (core) - DEPENDS:=+gluon-core +libgluonutil +gluon-client-bridge +firewall +libiwinfo +kmod-dummy + DEPENDS:=+gluon-core +libgluonutil +gluon-client-bridge +gluon-ebtables +firewall +libiwinfo +kmod-dummy +kmod-macvlan +libnl-tiny endef define Build/Prepare diff --git a/package/gluon-mesh-batman-adv-core/check_site.lua b/package/gluon-mesh-batman-adv-core/check_site.lua index 07bf9a0a..d1f577c8 100644 --- a/package/gluon-mesh-batman-adv-core/check_site.lua +++ b/package/gluon-mesh-batman-adv-core/check_site.lua @@ -1,25 +1,25 @@ for _, config in ipairs({'wifi24', 'wifi5'}) do - local rates = {1000, 2000, 5500, 6000, 9000, 11000, 12000, 18000, 24000, 36000, 48000, 54000} - rates = need_array_of(config .. '.supported_rates', rates, false) or rates + local rates = {1000, 2000, 5500, 6000, 9000, 11000, 12000, 18000, 24000, 36000, 48000, 54000} + rates = need_array_of(config .. '.supported_rates', rates, false) or rates - if need_table(config .. '.ibss', nil, false) then - need_string(config .. '.ibss.ssid') - need_string_match(config .. '.ibss.bssid', '^%x[02468aAcCeE]:%x%x:%x%x:%x%x:%x%x:%x%x$') - need_one_of(config .. '.ibss.mcast_rate', rates, false) - need_number(config .. '.ibss.vlan', false) - need_boolean(config .. '.ibss.disabled', false) - end + if need_table(config .. '.ibss', nil, false) then + need_string(config .. '.ibss.ssid') + need_string_match(config .. '.ibss.bssid', '^%x[02468aAcCeE]:%x%x:%x%x:%x%x:%x%x:%x%x$') + need_one_of(config .. '.ibss.mcast_rate', rates, false) + need_number(config .. '.ibss.vlan', false) + need_boolean(config .. '.ibss.disabled', false) + end - if need_table(config .. '.mesh', nil, false) then - need_string(config .. '.mesh.id') - need_one_of(config .. '.mesh.mcast_rate', rates, false) - need_boolean(config .. '.mesh.disabled', false) - end + if need_table(config .. '.mesh', nil, false) then + need_string(config .. '.mesh.id') + need_one_of(config .. '.mesh.mcast_rate', rates, false) + need_boolean(config .. '.mesh.disabled', false) + end end need_boolean('mesh_on_wan', false) need_boolean('mesh_on_lan', false) if need_table('mesh', nil, false) and need_table('mesh.batman_adv', nil, false) then - need_number('mesh.batman_adv.gw_sel_class', false) + need_number('mesh.batman_adv.gw_sel_class', false) end diff --git a/package/gluon-mesh-batman-adv-core/files/lib/gluon/ebtables/250-next-node b/package/gluon-mesh-batman-adv-core/files/lib/gluon/ebtables/250-next-node new file mode 100644 index 00000000..64b32859 --- /dev/null +++ b/package/gluon-mesh-batman-adv-core/files/lib/gluon/ebtables/250-next-node @@ -0,0 +1,24 @@ +local site = require 'gluon.site_config' +local next_node = site.next_node + +rule('FORWARD --logical-out br-client -o bat0 -d ' .. next_node.mac .. ' -j DROP') +rule('OUTPUT --logical-out br-client -o bat0 -d ' .. next_node.mac .. ' -j DROP') +rule('FORWARD --logical-out br-client -o bat0 -s ' .. next_node.mac .. ' -j DROP') +rule('OUTPUT --logical-out br-client -o bat0 -s ' .. next_node.mac .. ' -j DROP') + +if next_node.ip4 then + rule('FORWARD --logical-in br-client -p ARP --arp-ip-src ' .. next_node.ip4 .. ' -j DROP') + rule('FORWARD --logical-in br-client -p ARP --arp-ip-dst ' .. next_node.ip4 .. ' -j DROP') + + rule('FORWARD --logical-out br-client -o bat0 -p IPv4 --ip-destination ' .. next_node.ip4 .. ' -j DROP') + rule('OUTPUT --logical-out br-client -o bat0 -p IPv4 --ip-destination ' .. next_node.ip4 .. ' -j DROP') + rule('FORWARD --logical-out br-client -o bat0 -p IPv4 --ip-source ' .. next_node.ip4 .. ' -j DROP') + rule('OUTPUT --logical-out br-client -o bat0 -p IPv4 --ip-source ' .. next_node.ip4 .. ' -j DROP') +end + +if next_node.ip6 then + rule('FORWARD --logical-out br-client -o bat0 -p IPv6 --ip6-destination ' .. next_node.ip6 .. ' -j DROP') + rule('OUTPUT --logical-out br-client -o bat0 -p IPv6 --ip6-destination ' .. next_node.ip6 .. ' -j DROP') + rule('FORWARD --logical-out br-client -o bat0 -p IPv6 --ip6-source ' .. next_node.ip6 .. ' -j DROP') + rule('OUTPUT --logical-out br-client -o bat0 -p IPv6 --ip6-source ' .. next_node.ip6 .. ' -j DROP') +end diff --git a/package/gluon-mesh-batman-adv-core/files/lib/gluon/respondd/client.dev b/package/gluon-mesh-batman-adv-core/files/lib/gluon/respondd/client.dev new file mode 100644 index 00000000..9a074885 --- /dev/null +++ b/package/gluon-mesh-batman-adv-core/files/lib/gluon/respondd/client.dev @@ -0,0 +1 @@ +local_node diff --git a/package/gluon-mesh-batman-adv-core/luasrc/lib/gluon/upgrade/310-gluon-mesh-batman-adv-core-mesh b/package/gluon-mesh-batman-adv-core/luasrc/lib/gluon/upgrade/310-gluon-mesh-batman-adv-core-mesh index 4710d47c..6558671c 100755 --- a/package/gluon-mesh-batman-adv-core/luasrc/lib/gluon/upgrade/310-gluon-mesh-batman-adv-core-mesh +++ b/package/gluon-mesh-batman-adv-core/luasrc/lib/gluon/upgrade/310-gluon-mesh-batman-adv-core-mesh @@ -1,102 +1,42 @@ #!/usr/bin/lua local sysconfig = require 'gluon.sysconfig' -local sysctl = require 'gluon.sysctl' local site = require 'gluon.site_config' +local util = require 'gluon.util' local uci = require('luci.model.uci').cursor() local gw_sel_class if site.mesh and site.mesh.batman_adv then - gw_sel_class = site.mesh.batman_adv.gw_sel_class + gw_sel_class = site.mesh.batman_adv.gw_sel_class end uci:delete('batman-adv', 'bat0') uci:section('batman-adv', 'mesh', 'bat0', - { - orig_interval = 5000, - gw_mode = 'client', - gw_sel_class = gw_sel_class, - hop_penalty = 15, - multicast_mode = 0, - } + { + orig_interval = 5000, + gw_mode = 'client', + gw_sel_class = gw_sel_class, + hop_penalty = 15, + multicast_mode = 0, + } ) uci:save('batman-adv') - -uci:add_to_set('network', 'client', 'ifname', 'bat0') - -uci:set('network', 'client', 'proto', 'dhcpv6') -uci:set('network', 'client', 'reqprefix', 'no') -uci:delete('network', 'client', 'igmp_snooping') -uci:set('network', 'client', 'robustness', 3) -uci:set('network', 'client', 'query_interval', 2000) -uci:set('network', 'client', 'query_response_interval', 500) -uci:set('network', 'client', 'peerdns', 1) -uci:set('network', 'client', 'sourcefilter', 0) - uci:delete('network', 'bat0') uci:section('network', 'interface', 'bat0', - { - ifname = 'bat0', - proto = 'none', - macaddr = sysconfig.primary_mac, - multicast_router = 2, - learning = 0, - } + { + ifname = 'bat0', + proto = 'none', + macaddr = sysconfig.primary_mac, + multicast_router = 2, + learning = 0, + } ) -uci:delete('network', 'client_lan') -if sysconfig.lan_ifname then - uci:section('network', 'interface', 'client_lan', - { - unicast_flood = 0, - } - ) - uci:set('network', 'client_lan', 'ifname', sysconfig.lan_ifname) -end +local interfaces = uci:get_list('network', 'client', 'ifname') +util.add_to_set(interfaces, 'bat0') +uci:set_list('network', 'client', 'ifname', interfaces) uci:save('network') - - -uci:delete('firewall', 'client') -uci:section('firewall', 'zone', 'client', - { - name = 'client', - network = {'client'}, - input = 'ACCEPT', - output = 'ACCEPT', - forward = 'REJECT', - } -) - -uci:section('firewall', 'rule', 'client_dns', - { - name = 'client_dns', - src = 'client', - dest_port = '53', - target = 'REJECT', - } -) - -uci:save('firewall') - - -local dnsmasq = uci:get_first('dhcp', 'dnsmasq') -uci:set('dhcp', dnsmasq, 'boguspriv', 0) -uci:set('dhcp', dnsmasq, 'localise_queries', 0) -uci:set('dhcp', dnsmasq, 'rebind_protection', 0) - -uci:delete('dhcp', 'client') -uci:section('dhcp', 'dhcp', 'client', - { - interface = 'client', - ignore = 1, - } -) - -uci:save('dhcp') - - -sysctl.set('net.ipv6.conf.br-client.forwarding', 0) diff --git a/package/gluon-mesh-batman-adv-core/luasrc/lib/gluon/upgrade/320-gluon-mesh-batman-adv-core-client-bridge b/package/gluon-mesh-batman-adv-core/luasrc/lib/gluon/upgrade/320-gluon-mesh-batman-adv-core-client-bridge new file mode 100755 index 00000000..30a0dfb2 --- /dev/null +++ b/package/gluon-mesh-batman-adv-core/luasrc/lib/gluon/upgrade/320-gluon-mesh-batman-adv-core-client-bridge @@ -0,0 +1,45 @@ +#!/usr/bin/lua + +local sysconfig = require 'gluon.sysconfig' +local sysctl = require 'gluon.sysctl' + +local uci = require('luci.model.uci').cursor() + +uci:section('network', 'interface', 'client', + { + robustness = 3, + query_interval = 2000, + query_response_interval = 500, + } +) +uci:delete('network', 'client', 'igmp_snooping') + +uci:delete('network', 'client_lan') +if sysconfig.lan_ifname then + uci:section('network', 'interface', 'client_lan', + { + unicast_flood = 0, + } + ) + uci:set('network', 'client_lan', 'ifname', sysconfig.lan_ifname) +end + +uci:save('network') + + +uci:delete('firewall', 'client') +uci:section('firewall', 'zone', 'client', + { + name = 'client', + network = {'client'}, + input = 'ACCEPT', + output = 'ACCEPT', + forward = 'REJECT', + } +) + +uci:delete('firewall', 'client_dns') + +uci:save('firewall') + +sysctl.set('net.ipv6.conf.br-client.forwarding') diff --git a/package/gluon-mesh-batman-adv-core/luasrc/lib/gluon/upgrade/330-gluon-mesh-batman-adv-core-local-node b/package/gluon-mesh-batman-adv-core/luasrc/lib/gluon/upgrade/330-gluon-mesh-batman-adv-core-local-node new file mode 100755 index 00000000..ea3a29d0 --- /dev/null +++ b/package/gluon-mesh-batman-adv-core/luasrc/lib/gluon/upgrade/330-gluon-mesh-batman-adv-core-local-node @@ -0,0 +1,82 @@ +#!/usr/bin/lua + +local site = require 'gluon.site_config' +local sysconfig = require 'gluon.sysconfig' +local sysctl = require 'gluon.sysctl' + +local uci = require('luci.model.uci').cursor() + + +uci:delete('network', 'local_node_dev') +uci:section('network', 'device', 'local_node_dev', + { + name = 'local-node', + ifname = 'br-client', + type = 'macvlan', + macaddr = sysconfig.primary_mac, + } +) + +uci:delete('network', 'local_node') +uci:section('network', 'interface', 'local_node', + { + ifname = 'local-node', + proto = 'dhcpv6', + reqprefix = 'no', + peerdns = 1, + sourcefilter = 0, + keep_ra_dnslifetime = 1, + } +) + +if site.dns and site.dns.servers then + uci:set('network', 'local-node', 'peerdns','0') +end + +uci:delete('network', 'local_node_route6') +uci:section('network', 'route6', 'local_node_route6', + { + interface = 'local-node', + target = site.prefix6, + gateway = '::', + } +) + +uci:save('network') + + +uci:delete('firewall', 'local_node') +uci:section('firewall', 'zone', 'local_node', + { + name = 'local_node', + network = {'local_node'}, + input = 'ACCEPT', + output = 'ACCEPT', + forward = 'REJECT', + } +) + +uci:section('firewall', 'rule', 'local_node_dns', + { + name = 'local_node_dns', + src = 'local_node', + dest_port = '53', + target = 'REJECT', + } +) + +uci:save('firewall') + + +uci:delete('dhcp', 'local_node') +uci:section('dhcp', 'dhcp', 'local_node', + { + interface = 'local_node', + ignore = 1, + } +) + +uci:save('dhcp') + + +sysctl.set('net.ipv6.conf.local_node.forwarding', 0) diff --git a/package/gluon-mesh-batman-adv-core/luasrc/lib/gluon/upgrade/320-gluon-mesh-batman-adv-core-mac-addresses b/package/gluon-mesh-batman-adv-core/luasrc/lib/gluon/upgrade/340-gluon-mesh-batman-adv-core-mac-addresses similarity index 100% rename from package/gluon-mesh-batman-adv-core/luasrc/lib/gluon/upgrade/320-gluon-mesh-batman-adv-core-mac-addresses rename to package/gluon-mesh-batman-adv-core/luasrc/lib/gluon/upgrade/340-gluon-mesh-batman-adv-core-mac-addresses diff --git a/package/gluon-mesh-batman-adv-core/src/Makefile b/package/gluon-mesh-batman-adv-core/src/Makefile index 84d9d48e..9206a067 100644 --- a/package/gluon-mesh-batman-adv-core/src/Makefile +++ b/package/gluon-mesh-batman-adv-core/src/Makefile @@ -2,5 +2,23 @@ all: respondd.so CFLAGS += -Wall -respondd.so: respondd.c +ifeq ($(origin PKG_CONFIG), undefined) + PKG_CONFIG = pkg-config + ifeq ($(shell which $(PKG_CONFIG) 2>/dev/null),) + $(error $(PKG_CONFIG) not found) + endif +endif + +ifeq ($(origin LIBNL_CFLAGS) $(origin LIBNL_LDLIBS), undefined undefined) + LIBNL_NAME ?= libnl-tiny + ifeq ($(shell $(PKG_CONFIG) --modversion $(LIBNL_NAME) 2>/dev/null),) + $(error No $(LIBNL_NAME) development libraries found!) + endif + LIBNL_CFLAGS += $(shell $(PKG_CONFIG) --cflags $(LIBNL_NAME)) + LIBNL_LDLIBS += $(shell $(PKG_CONFIG) --libs $(LIBNL_NAME)) +endif +CFLAGS += $(LIBNL_CFLAGS) +LDLIBS += $(LIBNL_LDLIBS) + +respondd.so: respondd.c batadv-netlink.c $(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) -shared -fPIC -D_GNU_SOURCE -o $@ $^ $(LDLIBS) -lgluonutil -liwinfo -luci diff --git a/package/gluon-mesh-batman-adv-core/src/batadv-netlink.c b/package/gluon-mesh-batman-adv-core/src/batadv-netlink.c new file mode 100644 index 00000000..aeea7624 --- /dev/null +++ b/package/gluon-mesh-batman-adv-core/src/batadv-netlink.c @@ -0,0 +1,149 @@ +/* + * Copyright (C) 2009-2016 B.A.T.M.A.N. contributors: + * + * Marek Lindner , Andrew Lunn + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA + * + */ + +#include "batadv-netlink.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "batman_adv.h" + +#ifndef __maybe_unused +#define __maybe_unused __attribute__((unused)) +#endif + +struct nla_policy batadv_netlink_policy[NUM_BATADV_ATTR] = { + [BATADV_ATTR_HARD_IFINDEX] = { .type = NLA_U32 }, + [BATADV_ATTR_ORIG_ADDRESS] = { .type = NLA_UNSPEC, + .minlen = ETH_ALEN, + .maxlen = ETH_ALEN }, + [BATADV_ATTR_TT_FLAGS] = { .type = NLA_U32 }, + [BATADV_ATTR_FLAG_BEST] = { .type = NLA_FLAG }, + [BATADV_ATTR_LAST_SEEN_MSECS] = { .type = NLA_U32 }, + [BATADV_ATTR_NEIGH_ADDRESS] = { .type = NLA_UNSPEC, + .minlen = ETH_ALEN, + .maxlen = ETH_ALEN }, + [BATADV_ATTR_TQ] = { .type = NLA_U8 }, + [BATADV_ATTR_ROUTER] = { .type = NLA_UNSPEC, + .minlen = ETH_ALEN, + .maxlen = ETH_ALEN }, +}; + +static int nlquery_error_cb(struct sockaddr_nl *nla __maybe_unused, + struct nlmsgerr *nlerr, void *arg) +{ + struct batadv_nlquery_opts *query_opts = arg; + + query_opts->err = nlerr->error; + + return NL_STOP; +} + +static int nlquery_stop_cb(struct nl_msg *msg, void *arg) +{ + struct nlmsghdr *nlh = nlmsg_hdr(msg); + struct batadv_nlquery_opts *query_opts = arg; + int *error = nlmsg_data(nlh); + + if (*error) + query_opts->err = *error; + + return NL_STOP; +} + +int batadv_nl_query_common(const char *mesh_iface, + enum batadv_nl_commands nl_cmd, + nl_recvmsg_msg_cb_t callback, int flags, + struct batadv_nlquery_opts *query_opts) +{ + struct nl_sock *sock; + struct nl_msg *msg; + struct nl_cb *cb; + int ifindex; + int family; + int ret; + + query_opts->err = 0; + + sock = nl_socket_alloc(); + if (!sock) + return -ENOMEM; + + ret = genl_connect(sock); + if (ret < 0) { + query_opts->err = ret; + goto err_free_sock; + } + + family = genl_ctrl_resolve(sock, BATADV_NL_NAME); + if (family < 0) { + query_opts->err = -EOPNOTSUPP; + goto err_free_sock; + } + + ifindex = if_nametoindex(mesh_iface); + if (!ifindex) { + query_opts->err = -ENODEV; + goto err_free_sock; + } + + cb = nl_cb_alloc(NL_CB_DEFAULT); + if (!cb) { + query_opts->err = -ENOMEM; + goto err_free_sock; + } + + nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, callback, query_opts); + nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, nlquery_stop_cb, query_opts); + nl_cb_err(cb, NL_CB_CUSTOM, nlquery_error_cb, query_opts); + + msg = nlmsg_alloc(); + if (!msg) { + query_opts->err = -ENOMEM; + goto err_free_cb; + } + + genlmsg_put(msg, NL_AUTO_PID, NL_AUTO_SEQ, family, 0, flags, + nl_cmd, 1); + + nla_put_u32(msg, BATADV_ATTR_MESH_IFINDEX, ifindex); + nl_send_auto_complete(sock, msg); + nlmsg_free(msg); + + nl_recvmsgs(sock, cb); + +err_free_cb: + nl_cb_put(cb); +err_free_sock: + nl_socket_free(sock); + + return query_opts->err; +} diff --git a/package/gluon-mesh-batman-adv-core/src/batadv-netlink.h b/package/gluon-mesh-batman-adv-core/src/batadv-netlink.h new file mode 100644 index 00000000..8b85a6c2 --- /dev/null +++ b/package/gluon-mesh-batman-adv-core/src/batadv-netlink.h @@ -0,0 +1,68 @@ +/* + * Copyright (C) 2009-2016 B.A.T.M.A.N. contributors: + * + * Marek Lindner , Andrew Lunn + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA + * + */ + +#ifndef _BATADV_NETLINK_H +#define _BATADV_NETLINK_H + +#include +#include +#include +#include +#include + +#include "batman_adv.h" + +struct batadv_nlquery_opts { + int err; +}; + +#ifndef ARRAY_SIZE +#define ARRAY_SIZE(x) (sizeof(x) / sizeof(*(x))) +#endif + +#ifndef container_of +#define container_of(ptr, type, member) __extension__ ({ \ + const __typeof__(((type *)0)->member) *__pmember = (ptr); \ + (type *)((char *)__pmember - offsetof(type, member)); }) +#endif + +int batadv_nl_query_common(const char *mesh_iface, + enum batadv_nl_commands nl_cmd, + nl_recvmsg_msg_cb_t callback, int flags, + struct batadv_nlquery_opts *query_opts); + +static inline bool batadv_nl_missing_attrs(struct nlattr *attrs[], + const enum batadv_nl_attrs mandatory[], + size_t num) +{ + size_t i; + + for (i = 0; i < num; i++) { + if (!attrs[mandatory[i]]) + return true; + } + + return false; +} + +extern struct nla_policy batadv_netlink_policy[]; + +#endif /* _BATADV_NETLINK_H */ diff --git a/package/gluon-mesh-batman-adv-core/src/batman_adv.h b/package/gluon-mesh-batman-adv-core/src/batman_adv.h new file mode 100644 index 00000000..734fe83a --- /dev/null +++ b/package/gluon-mesh-batman-adv-core/src/batman_adv.h @@ -0,0 +1,208 @@ +/* Copyright (C) 2016 B.A.T.M.A.N. contributors: + * + * Matthias Schiffer + * + * 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 _UAPI_LINUX_BATMAN_ADV_H_ +#define _UAPI_LINUX_BATMAN_ADV_H_ + +#define BATADV_NL_NAME "batadv" + +#define BATADV_NL_MCAST_GROUP_TPMETER "tpmeter" + +/** + * enum batadv_tt_client_flags - TT client specific flags + * @BATADV_TT_CLIENT_DEL: the client has to be deleted from the table + * @BATADV_TT_CLIENT_ROAM: the client roamed to/from another node and the new + * update telling its new real location has not been received/sent yet + * @BATADV_TT_CLIENT_WIFI: this client is connected through a wifi interface. + * This information is used by the "AP Isolation" feature + * @BATADV_TT_CLIENT_ISOLA: this client is considered "isolated". This + * information is used by the Extended Isolation feature + * @BATADV_TT_CLIENT_NOPURGE: this client should never be removed from the table + * @BATADV_TT_CLIENT_NEW: this client has been added to the local table but has + * not been announced yet + * @BATADV_TT_CLIENT_PENDING: this client is marked for removal but it is kept + * in the table for one more originator interval for consistency purposes + * @BATADV_TT_CLIENT_TEMP: this global client has been detected to be part of + * the network but no nnode has already announced it + * + * Bits from 0 to 7 are called _remote flags_ because they are sent on the wire. + * Bits from 8 to 15 are called _local flags_ because they are used for local + * computations only. + * + * Bits from 4 to 7 - a subset of remote flags - are ensured to be in sync with + * the other nodes in the network. To achieve this goal these flags are included + * in the TT CRC computation. + */ +enum batadv_tt_client_flags { + BATADV_TT_CLIENT_DEL = (1 << 0), + BATADV_TT_CLIENT_ROAM = (1 << 1), + BATADV_TT_CLIENT_WIFI = (1 << 4), + BATADV_TT_CLIENT_ISOLA = (1 << 5), + BATADV_TT_CLIENT_NOPURGE = (1 << 8), + BATADV_TT_CLIENT_NEW = (1 << 9), + BATADV_TT_CLIENT_PENDING = (1 << 10), + BATADV_TT_CLIENT_TEMP = (1 << 11), +}; + +/** + * enum batadv_nl_attrs - batman-adv netlink attributes + * + * @BATADV_ATTR_UNSPEC: unspecified attribute to catch errors + * @BATADV_ATTR_VERSION: batman-adv version string + * @BATADV_ATTR_ALGO_NAME: name of routing algorithm + * @BATADV_ATTR_MESH_IFINDEX: index of the batman-adv interface + * @BATADV_ATTR_MESH_IFNAME: name of the batman-adv interface + * @BATADV_ATTR_MESH_ADDRESS: mac address of the batman-adv interface + * @BATADV_ATTR_HARD_IFINDEX: index of the non-batman-adv interface + * @BATADV_ATTR_HARD_IFNAME: name of the non-batman-adv interface + * @BATADV_ATTR_HARD_ADDRESS: mac address of the non-batman-adv interface + * @BATADV_ATTR_ORIG_ADDRESS: originator mac address + * @BATADV_ATTR_TPMETER_RESULT: result of run (see batadv_tp_meter_status) + * @BATADV_ATTR_TPMETER_TEST_TIME: time (msec) the run took + * @BATADV_ATTR_TPMETER_BYTES: amount of acked bytes during run + * @BATADV_ATTR_TPMETER_COOKIE: session cookie to match tp_meter session + * @BATADV_ATTR_PAD: attribute used for padding for 64-bit alignment + * @BATADV_ATTR_ACTIVE: Flag indicating if the hard interface is active + * @BATADV_ATTR_TT_ADDRESS: Client MAC address + * @BATADV_ATTR_TT_TTVN: Translation table version + * @BATADV_ATTR_TT_LAST_TTVN: Previous translation table version + * @BATADV_ATTR_TT_CRC32: CRC32 over translation table + * @BATADV_ATTR_TT_VID: VLAN ID + * @BATADV_ATTR_TT_FLAGS: Translation table client flags + * @BATADV_ATTR_FLAG_BEST: Flags indicating entry is the best + * @BATADV_ATTR_LAST_SEEN_MSECS: Time in milliseconds since last seen + * @BATADV_ATTR_NEIGH_ADDRESS: Neighbour MAC address + * @BATADV_ATTR_TQ: TQ to neighbour + * @BATADV_ATTR_THROUGHPUT: Estimated throughput to Neighbour + * @BATADV_ATTR_BANDWIDTH_UP: Reported uplink bandwidth + * @BATADV_ATTR_BANDWIDTH_DOWN: Reported downlink bandwidth + * @BATADV_ATTR_ROUTER: Gateway router MAC address + * @BATADV_ATTR_BLA_OWN: Flag indicating own originator + * @BATADV_ATTR_BLA_ADDRESS: Bridge loop avoidance claim MAC address + * @BATADV_ATTR_BLA_VID: BLA VLAN ID + * @BATADV_ATTR_BLA_BACKBONE: BLA gateway originator MAC address + * @BATADV_ATTR_BLA_CRC: BLA CRC + * @__BATADV_ATTR_AFTER_LAST: internal use + * @NUM_BATADV_ATTR: total number of batadv_nl_attrs available + * @BATADV_ATTR_MAX: highest attribute number currently defined + */ +enum batadv_nl_attrs { + BATADV_ATTR_UNSPEC, + BATADV_ATTR_VERSION, + BATADV_ATTR_ALGO_NAME, + BATADV_ATTR_MESH_IFINDEX, + BATADV_ATTR_MESH_IFNAME, + BATADV_ATTR_MESH_ADDRESS, + BATADV_ATTR_HARD_IFINDEX, + BATADV_ATTR_HARD_IFNAME, + BATADV_ATTR_HARD_ADDRESS, + BATADV_ATTR_ORIG_ADDRESS, + BATADV_ATTR_TPMETER_RESULT, + BATADV_ATTR_TPMETER_TEST_TIME, + BATADV_ATTR_TPMETER_BYTES, + BATADV_ATTR_TPMETER_COOKIE, + BATADV_ATTR_PAD, + BATADV_ATTR_ACTIVE, + BATADV_ATTR_TT_ADDRESS, + BATADV_ATTR_TT_TTVN, + BATADV_ATTR_TT_LAST_TTVN, + BATADV_ATTR_TT_CRC32, + BATADV_ATTR_TT_VID, + BATADV_ATTR_TT_FLAGS, + BATADV_ATTR_FLAG_BEST, + BATADV_ATTR_LAST_SEEN_MSECS, + BATADV_ATTR_NEIGH_ADDRESS, + BATADV_ATTR_TQ, + BATADV_ATTR_THROUGHPUT, + BATADV_ATTR_BANDWIDTH_UP, + BATADV_ATTR_BANDWIDTH_DOWN, + BATADV_ATTR_ROUTER, + BATADV_ATTR_BLA_OWN, + BATADV_ATTR_BLA_ADDRESS, + BATADV_ATTR_BLA_VID, + BATADV_ATTR_BLA_BACKBONE, + BATADV_ATTR_BLA_CRC, + /* add attributes above here, update the policy in netlink.c */ + __BATADV_ATTR_AFTER_LAST, + NUM_BATADV_ATTR = __BATADV_ATTR_AFTER_LAST, + BATADV_ATTR_MAX = __BATADV_ATTR_AFTER_LAST - 1 +}; + +/** + * enum batadv_nl_commands - supported batman-adv netlink commands + * + * @BATADV_CMD_UNSPEC: unspecified command to catch errors + * @BATADV_CMD_GET_MESH_INFO: Query basic information about batman-adv device + * @BATADV_CMD_TP_METER: Start a tp meter session + * @BATADV_CMD_TP_METER_CANCEL: Cancel a tp meter session + * @BATADV_CMD_GET_ROUTING_ALGOS: Query the list of routing algorithms. + * @BATADV_CMD_GET_HARDIFS: Query list of hard interfaces + * @BATADV_CMD_GET_TRANSTABLE_LOCAL: Query list of local translations + * @BATADV_CMD_GET_TRANSTABLE_GLOBAL Query list of global translations + * @BATADV_CMD_GET_ORIGINATORS: Query list of originators + * @BATADV_CMD_GET_NEIGHBORS: Query list of neighbours + * @BATADV_CMD_GET_GATEWAYS: Query list of gateways + * @BATADV_CMD_GET_BLA_CLAIM: Query list of bridge loop avoidance claims + * @BATADV_CMD_GET_BLA_BACKBONE: Query list of bridge loop avoidance backbones + * @__BATADV_CMD_AFTER_LAST: internal use + * @BATADV_CMD_MAX: highest used command number + */ +enum batadv_nl_commands { + BATADV_CMD_UNSPEC, + BATADV_CMD_GET_MESH_INFO, + BATADV_CMD_TP_METER, + BATADV_CMD_TP_METER_CANCEL, + BATADV_CMD_GET_ROUTING_ALGOS, + BATADV_CMD_GET_HARDIFS, + BATADV_CMD_GET_TRANSTABLE_LOCAL, + BATADV_CMD_GET_TRANSTABLE_GLOBAL, + BATADV_CMD_GET_ORIGINATORS, + BATADV_CMD_GET_NEIGHBORS, + BATADV_CMD_GET_GATEWAYS, + BATADV_CMD_GET_BLA_CLAIM, + BATADV_CMD_GET_BLA_BACKBONE, + /* add new commands above here */ + __BATADV_CMD_AFTER_LAST, + BATADV_CMD_MAX = __BATADV_CMD_AFTER_LAST - 1 +}; + +/** + * enum batadv_tp_meter_reason - reason of a tp meter test run stop + * @BATADV_TP_REASON_COMPLETE: sender finished tp run + * @BATADV_TP_REASON_CANCEL: sender was stopped during run + * @BATADV_TP_REASON_DST_UNREACHABLE: receiver could not be reached or didn't + * answer + * @BATADV_TP_REASON_RESEND_LIMIT: (unused) sender retry reached limit + * @BATADV_TP_REASON_ALREADY_ONGOING: test to or from the same node already + * ongoing + * @BATADV_TP_REASON_MEMORY_ERROR: test was stopped due to low memory + * @BATADV_TP_REASON_CANT_SEND: failed to send via outgoing interface + * @BATADV_TP_REASON_TOO_MANY: too many ongoing sessions + */ +enum batadv_tp_meter_reason { + BATADV_TP_REASON_COMPLETE = 3, + BATADV_TP_REASON_CANCEL = 4, + /* error status >= 128 */ + BATADV_TP_REASON_DST_UNREACHABLE = 128, + BATADV_TP_REASON_RESEND_LIMIT = 129, + BATADV_TP_REASON_ALREADY_ONGOING = 130, + BATADV_TP_REASON_MEMORY_ERROR = 131, + BATADV_TP_REASON_CANT_SEND = 132, + BATADV_TP_REASON_TOO_MANY = 133, +}; + +#endif /* _UAPI_LINUX_BATMAN_ADV_H_ */ diff --git a/package/gluon-mesh-batman-adv-core/src/respondd.c b/package/gluon-mesh-batman-adv-core/src/respondd.c index f21eb62e..33e1e0d5 100644 --- a/package/gluon-mesh-batman-adv-core/src/respondd.c +++ b/package/gluon-mesh-batman-adv-core/src/respondd.c @@ -51,11 +51,28 @@ #include #include +#include "batadv-netlink.h" #define _STRINGIFY(s) #s #define STRINGIFY(s) _STRINGIFY(s) +struct neigh_netlink_opts { + struct json_object *interfaces; + struct batadv_nlquery_opts query_opts; +}; + +struct gw_netlink_opts { + struct json_object *obj; + struct batadv_nlquery_opts query_opts; +}; + +struct clients_netlink_opts { + size_t total; + size_t wifi; + struct batadv_nlquery_opts query_opts; +}; + static struct json_object * get_addresses(void) { FILE *f = fopen("/proc/net/if_inet6", "r"); @@ -85,7 +102,7 @@ static struct json_object * get_addresses(void) { &flags, ifname) != 18) continue; - if (strcmp(ifname, "br-client")) + if (strcmp(ifname, "local-node")) continue; if (flags & (IFA_F_TENTATIVE|IFA_F_DEPRECATED)) @@ -121,9 +138,31 @@ static void mesh_add_subif(const char *ifname, struct json_object *wireless, struct json_object *tunnel, struct json_object *other) { struct json_object *address = gluonutil_wrap_and_free_string(gluonutil_get_interface_address(ifname)); - if (interface_file_exists(ifname, "wireless")) + char lowername[IFNAMSIZ]; + strncpy(lowername, ifname, sizeof(lowername)-1); + lowername[sizeof(lowername)-1] = 0; + + const char *format = "/sys/class/net/%s/lower_*"; + char pattern[strlen(format) + IFNAMSIZ]; + + /* In case of VLAN and bridge interfaces, we want the lower interface + * to determine the interface type (but not for the interface address) */ + while (true) { + snprintf(pattern, sizeof(pattern), format, lowername); + size_t pattern_len = strlen(pattern); + + glob_t lower; + if (glob(pattern, GLOB_NOSORT, NULL, &lower)) + break; + + strncpy(lowername, lower.gl_pathv[0] + pattern_len - 1, sizeof(lowername)-1); + + globfree(&lower); + } + + if (interface_file_exists(lowername, "wireless")) json_object_array_add(wireless, address); - else if (interface_file_exists(ifname, "tun_flags")) + else if (interface_file_exists(lowername, "tun_flags")) json_object_array_add(tunnel, address); else json_object_array_add(other, address); @@ -201,29 +240,70 @@ static struct json_object * respondd_provider_nodeinfo(void) { return ret; } +static const enum batadv_nl_attrs gateways_mandatory[] = { + BATADV_ATTR_ORIG_ADDRESS, + BATADV_ATTR_ROUTER, +}; + +static int parse_gw_list_netlink_cb(struct nl_msg *msg, void *arg) +{ + struct nlattr *attrs[BATADV_ATTR_MAX+1]; + struct nlmsghdr *nlh = nlmsg_hdr(msg); + struct batadv_nlquery_opts *query_opts = arg; + struct genlmsghdr *ghdr; + uint8_t *orig; + uint8_t *router; + struct gw_netlink_opts *opts; + char addr[18]; + + opts = container_of(query_opts, struct gw_netlink_opts, query_opts); + + if (!genlmsg_valid_hdr(nlh, 0)) + return NL_OK; + + ghdr = nlmsg_data(nlh); + + if (ghdr->cmd != BATADV_CMD_GET_GATEWAYS) + return NL_OK; + + if (nla_parse(attrs, BATADV_ATTR_MAX, genlmsg_attrdata(ghdr, 0), + genlmsg_len(ghdr), batadv_netlink_policy)) + return NL_OK; + + if (batadv_nl_missing_attrs(attrs, gateways_mandatory, + ARRAY_SIZE(gateways_mandatory))) + return NL_OK; + + if (!attrs[BATADV_ATTR_FLAG_BEST]) + return NL_OK; + + orig = nla_data(attrs[BATADV_ATTR_ORIG_ADDRESS]); + router = nla_data(attrs[BATADV_ATTR_ROUTER]); + + sprintf(addr, "%02x:%02x:%02x:%02x:%02x:%02x", + orig[0], orig[1], orig[2], orig[3], orig[4], orig[5]); + + json_object_object_add(opts->obj, "gateway", json_object_new_string(addr)); + + sprintf(addr, "%02x:%02x:%02x:%02x:%02x:%02x", + router[0], router[1], router[2], router[3], router[4], router[5]); + + json_object_object_add(opts->obj, "gateway_nexthop", json_object_new_string(addr)); + + return NL_STOP; +} static void add_gateway(struct json_object *obj) { - FILE *f = fopen("/sys/kernel/debug/batman_adv/bat0/gateways", "r"); - if (!f) - return; + struct gw_netlink_opts opts = { + .obj = obj, + .query_opts = { + .err = 0, + }, + }; - char *line = NULL; - size_t len = 0; - - while (getline(&line, &len, f) >= 0) { - char addr[18]; - char nexthop[18]; - - if (sscanf(line, "=> %17[0-9a-fA-F:] ( %*u) %17[0-9a-fA-F:]", addr, nexthop) != 2) - continue; - - json_object_object_add(obj, "gateway", json_object_new_string(addr)); - json_object_object_add(obj, "gateway_nexthop", json_object_new_string(nexthop)); - break; - } - - free(line); - fclose(f); + batadv_nl_query_common("bat0", BATADV_CMD_GET_GATEWAYS, + parse_gw_list_netlink_cb, NLM_F_DUMP, + &opts.query_opts); } static inline bool ethtool_ioctl(int fd, struct ifreq *ifr, void *data) { @@ -399,39 +479,69 @@ static void count_stations(size_t *wifi24, size_t *wifi5) { uci_free_context(ctx); } +static const enum batadv_nl_attrs clients_mandatory[] = { + BATADV_ATTR_TT_FLAGS, +}; + +static int parse_clients_list_netlink_cb(struct nl_msg *msg, void *arg) +{ + struct nlattr *attrs[BATADV_ATTR_MAX+1]; + struct nlmsghdr *nlh = nlmsg_hdr(msg); + struct batadv_nlquery_opts *query_opts = arg; + struct genlmsghdr *ghdr; + struct clients_netlink_opts *opts; + uint32_t flags; + + opts = container_of(query_opts, struct clients_netlink_opts, query_opts); + + if (!genlmsg_valid_hdr(nlh, 0)) + return NL_OK; + + ghdr = nlmsg_data(nlh); + + if (ghdr->cmd != BATADV_CMD_GET_TRANSTABLE_LOCAL) + return NL_OK; + + if (nla_parse(attrs, BATADV_ATTR_MAX, genlmsg_attrdata(ghdr, 0), + genlmsg_len(ghdr), batadv_netlink_policy)) + return NL_OK; + + if (batadv_nl_missing_attrs(attrs, clients_mandatory, + ARRAY_SIZE(clients_mandatory))) + return NL_OK; + + flags = nla_get_u32(attrs[BATADV_ATTR_TT_FLAGS]); + + if (flags & BATADV_TT_CLIENT_NOPURGE) + return NL_OK; + + if (flags & BATADV_TT_CLIENT_WIFI) + opts->wifi++; + + opts->total++; + + return NL_OK; +} + static struct json_object * get_clients(void) { - size_t total = 0, wifi = 0, wifi24 = 0, wifi5 = 0; + size_t wifi24 = 0, wifi5 = 0; + struct clients_netlink_opts opts = { + .total = 0, + .wifi = 0, + .query_opts = { + .err = 0, + }, + }; - FILE *f = fopen("/sys/kernel/debug/batman_adv/bat0/transtable_local", "r"); - if (!f) - return NULL; - - char *line = NULL; - size_t len = 0; - - while (getline(&line, &len, f) >= 0) { - char flags[16]; - - if (sscanf(line, " * %*[^[] [%15[^]]]", flags) != 1) - continue; - - if (strchr(flags, 'P')) - continue; - - total++; - - if (strchr(flags, 'W')) - wifi++; - } - - free(line); - fclose(f); + batadv_nl_query_common("bat0", BATADV_CMD_GET_TRANSTABLE_LOCAL, + parse_clients_list_netlink_cb, NLM_F_DUMP, + &opts.query_opts); count_stations(&wifi24, &wifi5); struct json_object *ret = json_object_new_object(); - json_object_object_add(ret, "total", json_object_new_int(total)); - json_object_object_add(ret, "wifi", json_object_new_int(wifi)); + json_object_object_add(ret, "total", json_object_new_int(opts.total)); + json_object_object_add(ret, "wifi", json_object_new_int(opts.wifi)); json_object_object_add(ret, "wifi24", json_object_new_int(wifi24)); json_object_object_add(ret, "wifi5", json_object_new_int(wifi5)); return ret; @@ -470,49 +580,104 @@ static struct json_object * ifnames2addrs(struct json_object *interfaces) { return ret; } -static struct json_object * get_batadv(void) { - FILE *f = fopen("/sys/kernel/debug/batman_adv/bat0/originators", "r"); - if (!f) - return NULL; +static const enum batadv_nl_attrs parse_orig_list_mandatory[] = { + BATADV_ATTR_ORIG_ADDRESS, + BATADV_ATTR_NEIGH_ADDRESS, + BATADV_ATTR_TQ, + BATADV_ATTR_HARD_IFINDEX, + BATADV_ATTR_LAST_SEEN_MSECS, +}; - char *line = NULL; - size_t len = 0; +static int parse_orig_list_netlink_cb(struct nl_msg *msg, void *arg) +{ + struct nlattr *attrs[BATADV_ATTR_MAX+1]; + struct nlmsghdr *nlh = nlmsg_hdr(msg); + struct batadv_nlquery_opts *query_opts = arg; + struct genlmsghdr *ghdr; + uint8_t *orig; + uint8_t *dest; + uint8_t tq; + uint32_t hardif; + uint32_t lastseen; + char ifname_buf[IF_NAMESIZE], *ifname; + struct neigh_netlink_opts *opts; + char mac1[18]; - struct json_object *interfaces = json_object_new_object(); + opts = container_of(query_opts, struct neigh_netlink_opts, query_opts); - while (getline(&line, &len, f) >= 0) { - char mac1[18], mac2[18]; - /* IF_NAMESIZE would be enough, but adding 1 here is simpler than subtracting 1 in the format string */ - char ifname[IF_NAMESIZE+1]; - double lastseen; - int tq; + if (!genlmsg_valid_hdr(nlh, 0)) + return NL_OK; - if (sscanf(line, - "%17[0-9a-fA-F:] %lfs ( %i ) %17[0-9a-fA-F:] [ %"STRINGIFY(IF_NAMESIZE)"[^]] ]", - mac1, &lastseen, &tq, mac2, ifname) != 5) - continue; + ghdr = nlmsg_data(nlh); - if (strcmp(mac1, mac2)) - continue; + if (ghdr->cmd != BATADV_CMD_GET_ORIGINATORS) + return NL_OK; - struct json_object *interface; - if (!json_object_object_get_ex(interfaces, ifname, &interface)) { - interface = json_object_new_object(); - json_object_object_add(interfaces, ifname, interface); - } + if (nla_parse(attrs, BATADV_ATTR_MAX, genlmsg_attrdata(ghdr, 0), + genlmsg_len(ghdr), batadv_netlink_policy)) + return NL_OK; - struct json_object *obj = json_object_new_object(); - json_object_object_add(obj, "tq", json_object_new_int(tq)); - struct json_object *jso = json_object_new_double(lastseen); - json_object_set_serializer(jso, json_object_double_to_json_string, "%.3f", NULL); - json_object_object_add(obj, "lastseen", jso); - json_object_object_add(interface, mac1, obj); + if (batadv_nl_missing_attrs(attrs, parse_orig_list_mandatory, + ARRAY_SIZE(parse_orig_list_mandatory))) + return NL_OK; + + if (!attrs[BATADV_ATTR_FLAG_BEST]) + return NL_OK; + + orig = nla_data(attrs[BATADV_ATTR_ORIG_ADDRESS]); + dest = nla_data(attrs[BATADV_ATTR_NEIGH_ADDRESS]); + tq = nla_get_u8(attrs[BATADV_ATTR_TQ]); + hardif = nla_get_u32(attrs[BATADV_ATTR_HARD_IFINDEX]); + lastseen = nla_get_u32(attrs[BATADV_ATTR_LAST_SEEN_MSECS]); + + if (memcmp(orig, dest, 6) != 0) + return NL_OK; + + ifname = if_indextoname(hardif, ifname_buf); + if (!ifname) + return NL_OK; + + sprintf(mac1, "%02x:%02x:%02x:%02x:%02x:%02x", + orig[0], orig[1], orig[2], orig[3], orig[4], orig[5]); + + struct json_object *obj = json_object_new_object(); + if (!obj) + return NL_OK; + + struct json_object *interface; + if (!json_object_object_get_ex(opts->interfaces, ifname, &interface)) { + interface = json_object_new_object(); + json_object_object_add(opts->interfaces, ifname, interface); } - fclose(f); - free(line); + json_object_object_add(obj, "tq", json_object_new_int(tq)); + json_object_object_add(obj, "lastseen", json_object_new_double(lastseen / 1000.)); + json_object_object_add(interface, mac1, obj); - return ifnames2addrs(interfaces); + return NL_OK; +} + +static struct json_object * get_batadv(void) { + struct neigh_netlink_opts opts = { + .query_opts = { + .err = 0, + }, + }; + int ret; + + opts.interfaces = json_object_new_object(); + if (!opts.interfaces) + return NULL; + + ret = batadv_nl_query_common("bat0", BATADV_CMD_GET_ORIGINATORS, + parse_orig_list_netlink_cb, NLM_F_DUMP, + &opts.query_opts); + if (ret < 0) { + json_object_put(opts.interfaces); + return NULL; + } + + return ifnames2addrs(opts.interfaces); } static struct json_object * get_wifi_neighbours(const char *ifname) { diff --git a/package/gluon-mesh-vpn-fastd/Makefile b/package/gluon-mesh-vpn-fastd/Makefile index 4d75116e..8fceae1a 100644 --- a/package/gluon-mesh-vpn-fastd/Makefile +++ b/package/gluon-mesh-vpn-fastd/Makefile @@ -6,7 +6,7 @@ PKG_VERSION:=3 PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME) PKG_BUILD_DEPENDS := respondd -include $(GLUONDIR)/include/package.mk +include ../gluon.mk define Package/gluon-mesh-vpn-fastd diff --git a/package/gluon-mesh-vpn-fastd/check_site.lua b/package/gluon-mesh-vpn-fastd/check_site.lua index 30cca11d..c1bf0ea1 100644 --- a/package/gluon-mesh-vpn-fastd/check_site.lua +++ b/package/gluon-mesh-vpn-fastd/check_site.lua @@ -3,6 +3,7 @@ need_number('fastd_mesh_vpn.mtu') need_boolean('fastd_mesh_vpn.enabled', false) need_boolean('fastd_mesh_vpn.configurable', false) +need_one_of('fastd_mesh_vpn.syslog_level', {'error', 'warn', 'info', 'verbose', 'debug', 'debug2'}, false) local function check_peer(prefix) return function(k, _) diff --git a/package/gluon-mesh-vpn-fastd/luasrc/lib/gluon/upgrade/400-mesh-vpn-fastd b/package/gluon-mesh-vpn-fastd/luasrc/lib/gluon/upgrade/400-mesh-vpn-fastd index 74ab4a41..102ae0b4 100755 --- a/package/gluon-mesh-vpn-fastd/luasrc/lib/gluon/upgrade/400-mesh-vpn-fastd +++ b/package/gluon-mesh-vpn-fastd/luasrc/lib/gluon/upgrade/400-mesh-vpn-fastd @@ -20,6 +20,7 @@ if not enabled then enabled = site.fastd_mesh_vpn.enabled and 1 or 0 end +local syslog_level = uci:get('fastd', 'mesh_vpn', 'syslog_level') or 'verbose' local methods @@ -31,7 +32,6 @@ if site.fastd_mesh_vpn.configurable then has_null = lutil.contains(old_methods, 'null') end - methods = {} if has_null then table.insert(methods, 'null') @@ -52,7 +52,7 @@ uci:section('fastd', 'fastd', 'mesh_vpn', { enabled = enabled, group = 'gluon-fastd', - syslog_level = 'verbose', + syslog_level = syslog_level, interface = 'mesh-vpn', mode = 'tap', mtu = site.fastd_mesh_vpn.mtu, diff --git a/package/gluon-neighbour-info/Makefile b/package/gluon-neighbour-info/Makefile index 498abc4f..867f32f6 100644 --- a/package/gluon-neighbour-info/Makefile +++ b/package/gluon-neighbour-info/Makefile @@ -6,7 +6,7 @@ PKG_RELEASE:=1 PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME) -include $(GLUONDIR)/include/package.mk +include ../gluon.mk define Package/gluon-neighbour-info diff --git a/package/gluon-next-node/Makefile b/package/gluon-next-node/Makefile deleted file mode 100644 index 87c8edf9..00000000 --- a/package/gluon-next-node/Makefile +++ /dev/null @@ -1,41 +0,0 @@ -include $(TOPDIR)/rules.mk - -PKG_NAME:=gluon-next-node -PKG_VERSION:=3 - -PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME) - -include $(GLUONDIR)/include/package.mk - - -define Package/gluon-next-node - SECTION:=gluon - CATEGORY:=Gluon - TITLE:=Next-node anycast address - DEPENDS:=+gluon-core +gluon-ebtables +gluon-mesh-batman-adv +kmod-macvlan -endef - -define Package/gluon-next-node/description - Gluon community wifi mesh firmware framework: next-node anycast address -endef - -define Build/Prepare - mkdir -p $(PKG_BUILD_DIR) -endef - -define Build/Configure -endef - -define Build/Compile -endef - -define Package/gluon-next-node/install - $(CP) ./files/* $(1)/ -endef - -define Package/gluon-next-node/postinst -#!/bin/sh -$(call GluonCheckSite,check_site.lua) -endef - -$(eval $(call BuildPackage,gluon-next-node)) diff --git a/package/gluon-next-node/check_site.lua b/package/gluon-next-node/check_site.lua deleted file mode 100644 index b38de2a4..00000000 --- a/package/gluon-next-node/check_site.lua +++ /dev/null @@ -1,7 +0,0 @@ -if need_string_match('next_node.ip4', '^%d+.%d+.%d+.%d+$', false) then - need_string_match('prefix4', '^%d+.%d+.%d+.%d+/%d+$') -end - -need_string_match('next_node.ip6', '^[%x:]+$') - -need_string_match('next_node.mac', '^%x[02468aAcCeE]:%x%x:%x%x:%x%x:%x%x:%x%x$') diff --git a/package/gluon-next-node/files/lib/gluon/ebtables/250-next-node b/package/gluon-next-node/files/lib/gluon/ebtables/250-next-node deleted file mode 100644 index 0df7abcc..00000000 --- a/package/gluon-next-node/files/lib/gluon/ebtables/250-next-node +++ /dev/null @@ -1,20 +0,0 @@ -local site = require 'gluon.site_config' -local next_node = site.next_node - -rule('FORWARD --logical-in br-client -p ARP --arp-ip-src ' .. next_node.ip4 .. ' -j DROP') -rule('FORWARD --logical-in br-client -p ARP --arp-ip-dst ' .. next_node.ip4 .. ' -j DROP') - -rule('FORWARD --logical-out br-client -o bat0 -d ' .. next_node.mac .. ' -j DROP') -rule('OUTPUT --logical-out br-client -o bat0 -d ' .. next_node.mac .. ' -j DROP') -rule('FORWARD --logical-out br-client -o bat0 -s ' .. next_node.mac .. ' -j DROP') -rule('OUTPUT --logical-out br-client -o bat0 -s ' .. next_node.mac .. ' -j DROP') - -rule('FORWARD --logical-out br-client -o bat0 -p IPv4 --ip-destination ' .. next_node.ip4 .. ' -j DROP') -rule('OUTPUT --logical-out br-client -o bat0 -p IPv4 --ip-destination ' .. next_node.ip4 .. ' -j DROP') -rule('FORWARD --logical-out br-client -o bat0 -p IPv4 --ip-source ' .. next_node.ip4 .. ' -j DROP') -rule('OUTPUT --logical-out br-client -o bat0 -p IPv4 --ip-source ' .. next_node.ip4 .. ' -j DROP') - -rule('FORWARD --logical-out br-client -o bat0 -p IPv6 --ip6-destination ' .. next_node.ip6 .. ' -j DROP') -rule('OUTPUT --logical-out br-client -o bat0 -p IPv6 --ip6-destination ' .. next_node.ip6 .. ' -j DROP') -rule('FORWARD --logical-out br-client -o bat0 -p IPv6 --ip6-source ' .. next_node.ip6 .. ' -j DROP') -rule('OUTPUT --logical-out br-client -o bat0 -p IPv6 --ip6-source ' .. next_node.ip6 .. ' -j DROP') diff --git a/package/gluon-next-node/files/lib/gluon/upgrade/400-next-node b/package/gluon-next-node/files/lib/gluon/upgrade/400-next-node deleted file mode 100755 index e8ecfca4..00000000 --- a/package/gluon-next-node/files/lib/gluon/upgrade/400-next-node +++ /dev/null @@ -1,59 +0,0 @@ -#!/usr/bin/lua - -local site = require 'gluon.site_config' -local uci = require 'luci.model.uci' -local ip = require 'luci.ip' - -local c = uci.cursor() - - -c:delete('network', 'local_node_dev') -c:section('network', 'device', 'local_node_dev', - { - name = 'local-node', - ifname = 'br-client', - type = 'macvlan', - macaddr = site.next_node.mac, - } -) - -local ip4, netmask - -if site.next_node.ip4 then - ip4 = site.next_node.ip4 - netmask = ip.IPv4(site.prefix4):mask():string() -end - -c:delete('network', 'local_node') -c:section('network', 'interface', 'local_node', - { - ifname = 'local-node', - proto = 'static', - ipaddr = ip4, - netmask = netmask, - ip6addr = site.next_node.ip6 .. '/128', - } -) - -c:delete('network', 'local_node_route6') -c:section('network', 'route6', 'local_node_route6', - { - interface = 'client', - target = site.prefix6, - gateway = '::', - } -) - -c:save('network') - -c:delete('firewall', 'local_node') -c:section('firewall', 'zone', 'local_node', - { - name = 'local_node', - network = {'local_node'}, - input = 'ACCEPT', - output = 'ACCEPT', - forward = 'REJECT', - } -) -c:save('firewall') diff --git a/package/gluon-node-info/Makefile b/package/gluon-node-info/Makefile index 8dd31553..59f60dfd 100644 --- a/package/gluon-node-info/Makefile +++ b/package/gluon-node-info/Makefile @@ -7,7 +7,7 @@ PKG_RELEASE:=1 PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME) PKG_BUILD_DEPENDS := respondd -include $(GLUONDIR)/include/package.mk +include ../gluon.mk define Package/gluon-node-info diff --git a/package/gluon-radvd/Makefile b/package/gluon-radvd/Makefile index 0ca18177..ba04c04e 100644 --- a/package/gluon-radvd/Makefile +++ b/package/gluon-radvd/Makefile @@ -5,7 +5,7 @@ PKG_VERSION:=3 PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME) -include $(GLUONDIR)/include/package.mk +include ../gluon.mk define Package/gluon-radvd diff --git a/package/gluon-respondd/Makefile b/package/gluon-respondd/Makefile index c6cc71e4..c0b201fa 100644 --- a/package/gluon-respondd/Makefile +++ b/package/gluon-respondd/Makefile @@ -5,7 +5,7 @@ PKG_VERSION:=1 PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME) -include $(GLUONDIR)/include/package.mk +include ../gluon.mk define Package/gluon-respondd diff --git a/package/gluon-respondd/files/etc/hotplug.d/iface/10-gluon-respondd b/package/gluon-respondd/files/etc/hotplug.d/iface/10-gluon-respondd deleted file mode 100644 index 4f49be52..00000000 --- a/package/gluon-respondd/files/etc/hotplug.d/iface/10-gluon-respondd +++ /dev/null @@ -1,34 +0,0 @@ -#!/bin/sh - -. /usr/share/libubox/jshn.sh -. /lib/functions/service.sh - -DEVLIST=/var/run/gluon-respondd.devs - -ifname_to_dev () { - json_load "$(ubus call network.interface.$1 status)" - json_get_var dev device - - echo "$dev" -} - -case "$ACTION" in - ifdown) - sed "/ $INTERFACE$/d" $DEVLIST > $DEVLIST.new - mv $DEVLIST.new $DEVLIST - ;; - ifup) - DEVICE="$(ifname_to_dev "$INTERFACE")" - MESH="$(cat "/sys/class/net/$DEVICE/batman_adv/mesh_iface" 2>/dev/null)" - - [ "$MESH" = "bat0" -o "$INTERFACE" = "client" ] || exit 0 - - DEVS=$(cat $DEVLIST 2>/dev/null; echo $DEVICE $INTERFACE) - - echo "$DEVS" | sort -u > $DEVLIST.new - mv $DEVLIST.new $DEVLIST - - /etc/init.d/gluon-respondd restart_if_running & - - ;; -esac diff --git a/package/gluon-respondd/files/etc/init.d/gluon-respondd b/package/gluon-respondd/files/etc/init.d/gluon-respondd index a1bf979f..5ec99101 100755 --- a/package/gluon-respondd/files/etc/init.d/gluon-respondd +++ b/package/gluon-respondd/files/etc/init.d/gluon-respondd @@ -1,45 +1,35 @@ #!/bin/sh /etc/rc.common -EXTRA_COMMANDS='restart_if_running' - +USE_PROCD=1 START=50 -SERVICE_WRITE_PID=1 -SERVICE_DAEMONIZE=1 - -DEVLIST=/var/run/gluon-respondd.devs DAEMON=/usr/bin/respondd -LOCK=/var/run/gluon-respondd.lock +MAXDELAY=10 +start_service() { + local ifdump="$(ubus call network.interface dump)" -do_start() { - DEVS=$(cat $DEVLIST 2>/dev/null | while read dev iface; do echo -n " -i $dev"; done) - service_start $DAEMON -g ff02::2:1001 -p 1001 -d /lib/gluon/respondd $DEVS + local devs='' + local dev + for dev in $(echo "$ifdump" | jsonfilter -e "@.interface[@.proto='gluon_mesh' && @.up=true].device"); do + devs="$devs -i $dev" + done + for dev in $(echo "$ifdump" | jsonfilter -e "@.interface[@.interface='$(cat /lib/gluon/respondd/client.dev 2>/dev/null)' && @.up=true].device"); do + devs="$devs -i $dev -t $MAXDELAY" + done + + procd_open_instance + procd_set_param command $DAEMON -g ff02::2:1001 -p 1001 -d /usr/lib/respondd -d /lib/gluon/respondd $devs + procd_set_param respawn ${respawn_threshold:-3600} ${respawn_timeout:-5} ${respawn_retry:-5} + procd_set_param stderr 1 + procd_close_instance } -do_stop() { - service_stop $DAEMON -} - -start() { - lock $LOCK - do_start - lock -u $LOCK -} - -stop() { - lock $LOCK - do_stop - lock -u $LOCK -} - -restart_if_running() { - lock $LOCK - - if service_check $DAEMON; then - do_stop - do_start - fi - - lock -u $LOCK +service_triggers() { + local script=$(readlink "$initscript") + local name=$(basename ${script:-$initscript}) + + procd_open_trigger + procd_add_raw_trigger "interface.*" 0 "/etc/init.d/$name" reload + procd_close_trigger } diff --git a/package/gluon-setup-mode/Makefile b/package/gluon-setup-mode/Makefile index ea9722c0..e34f4858 100644 --- a/package/gluon-setup-mode/Makefile +++ b/package/gluon-setup-mode/Makefile @@ -8,7 +8,7 @@ PKG_VERSION:=1 PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME) -include $(GLUONDIR)/include/package.mk +include ../gluon.mk define Package/gluon-setup-mode 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/S12rpcd b/package/gluon-setup-mode/files/lib/gluon/setup-mode/rc.d/S12rpcd new file mode 100755 index 00000000..3791a8ce --- /dev/null +++ b/package/gluon-setup-mode/files/lib/gluon/setup-mode/rc.d/S12rpcd @@ -0,0 +1,5 @@ +#!/bin/sh /etc/rc.common + +if [ -x /etc/init.d/rpcd ]; then + . /etc/init.d/rpcd +fi 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-setup-mode/luasrc/lib/gluon/upgrade/320-setup-ifname b/package/gluon-setup-mode/luasrc/lib/gluon/upgrade/320-setup-ifname index 3dba79a9..822aaedc 100755 --- a/package/gluon-setup-mode/luasrc/lib/gluon/upgrade/320-setup-ifname +++ b/package/gluon-setup-mode/luasrc/lib/gluon/upgrade/320-setup-ifname @@ -9,7 +9,7 @@ if sysconfig.setup_ifname then end if - platform.match('ar71xx', 'generic', {'cpe510', 'nanostation-m', 'nanostation-m-xw', 'unifi-outdoor-plus', 'uap-pro', 'unifiac-pro'}) or + platform.match('ar71xx', 'generic', {'cpe210', 'cpe510', 'wbs210', 'wbs510', 'nanostation-m', 'nanostation-m-xw', 'unifi-outdoor-plus', 'uap-pro', 'unifiac-pro'}) or platform.match('ar71xx', 'mikrotik') then sysconfig.setup_ifname = sysconfig.config_ifname or sysconfig.wan_ifname or sysconfig.lan_ifname diff --git a/package/gluon-site/Makefile b/package/gluon-site/Makefile index a7084ad0..0f803889 100644 --- a/package/gluon-site/Makefile +++ b/package/gluon-site/Makefile @@ -1,15 +1,19 @@ include $(TOPDIR)/rules.mk PKG_NAME:=gluon-site -PKG_VERSION:=$(if $(GLUON_SITE_CODE),$(GLUON_SITE_CODE),1) -PKG_RELEASE:=$(GLUON_RELEASE) +GLUON_SITEDIR = '$(call qstrip,$(CONFIG_GLUON_SITEDIR))' +GLUON_SITE_VERSION = $(shell ( cd $(GLUON_SITEDIR) && git --git-dir=.git describe --always --dirty=+ ) 2>/dev/null || echo unknown) +PKG_VERSION:=$(if $(DUMP),x,$(GLUON_SITE_VERSION)) + + +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 PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME) -include $(GLUONDIR)/include/package.mk +include ../gluon.mk PKG_CONFIG_DEPENDS += $(GLUON_I18N_CONFIG) @@ -20,6 +24,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,13 +44,15 @@ define Build/Configure endef define Build/Compile + GLUON_SITEDIR='$(call qstrip,$(CONFIG_GLUON_SITEDIR))' lua -e '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 - lua -e 'print(require("cjson").encode(assert(dofile("$(GLUONDIR)/scripts/site_config.lua"))))' > $(1)/lib/gluon/site.json - echo "$(GLUON_RELEASE)" > $(1)/lib/gluon/release + $(INSTALL_DATA) $(PKG_BUILD_DIR)/site.json $(1)/lib/gluon/ + echo '$(GLUON_SITE_VERSION)' > $(1)/lib/gluon/site-version + echo '$(call qstrip,$(CONFIG_GLUON_RELEASE))' > $(1)/lib/gluon/release $(call GluonInstallI18N,gluon-site,$(1)) endef diff --git a/package/gluon-status-page-api/Makefile b/package/gluon-status-page-api/Makefile index ddad2cab..1c54dac0 100644 --- a/package/gluon-status-page-api/Makefile +++ b/package/gluon-status-page-api/Makefile @@ -7,14 +7,14 @@ PKG_RELEASE:=1 PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME) PKG_BUILD_DEPENDS := respondd -include $(GLUONDIR)/include/package.mk +include ../gluon.mk define Package/gluon-status-page-api SECTION:=gluon CATEGORY:=Gluon TITLE:=API for gluon-status-page - DEPENDS:=+gluon-core +uhttpd +sse-multiplex +gluon-neighbour-info +gluon-respondd +libiwinfo +libjson-c + DEPENDS:=+gluon-core +uhttpd +sse-multiplex +gluon-neighbour-info +gluon-respondd +libiwinfo +libjson-c +libnl-tiny endef define Build/Prepare diff --git a/package/gluon-status-page-api/files/lib/gluon/upgrade/500-status-page-api b/package/gluon-status-page-api/files/lib/gluon/upgrade/500-status-page-api index ce1bf06e..854d1d26 100755 --- a/package/gluon-status-page-api/files/lib/gluon/upgrade/500-status-page-api +++ b/package/gluon-status-page-api/files/lib/gluon/upgrade/500-status-page-api @@ -11,3 +11,5 @@ uci -q batch <<-EOF set uhttpd.main.max_requests=32 EOF + +/etc/init.d/rpcd disable diff --git a/package/gluon-status-page-api/src/Makefile b/package/gluon-status-page-api/src/Makefile index 81b48b6d..e67a595e 100644 --- a/package/gluon-status-page-api/src/Makefile +++ b/package/gluon-status-page-api/src/Makefile @@ -1,12 +1,29 @@ CFLAGS += -std=c99 -D_BSD_SOURCE +CPPFLAGS += -D_GNU_SOURCE + +ifeq ($(origin PKG_CONFIG), undefined) + PKG_CONFIG = pkg-config + ifeq ($(shell which $(PKG_CONFIG) 2>/dev/null),) + $(error $(PKG_CONFIG) not found) + endif +endif + +ifeq ($(origin LIBNL_CFLAGS) $(origin LIBNL_LDLIBS), undefined undefined) + LIBNL_NAME ?= libnl-tiny + ifeq ($(shell $(PKG_CONFIG) --modversion $(LIBNL_NAME) 2>/dev/null),) + $(error No $(LIBNL_NAME) development libraries found!) + endif + LIBNL_CFLAGS += $(shell $(PKG_CONFIG) --cflags $(LIBNL_NAME)) + LIBNL_LDLIBS += $(shell $(PKG_CONFIG) --libs $(LIBNL_NAME)) +endif CFLAGS_JSONC = $(shell pkg-config --cflags json-c) LDFLAGS_JSONC = $(shell pkg-config --libs json-c) all: neighbours-batadv stations respondd.so -neighbours-batadv: neighbours-batadv.c - $(CC) $(CPPFLAGS) $(CFLAGS) $(CFLAGS_JSONC) $(LDFLAGS) $(LDFLAGS_JSONC) -Wall -o $@ $^ $(LDLIBS) +neighbours-batadv: neighbours-batadv.c batadv-netlink.c + $(CC) $(CPPFLAGS) $(CFLAGS) $(CFLAGS_JSONC) $(LIBNL_CFLAGS) $(LDFLAGS) $(LDFLAGS_JSONC) $(LIBNL_LDLIBS) -Wall -o $@ $^ $(LDLIBS) stations: stations.c $(CC) $(CPPFLAGS) $(CFLAGS) $(CFLAGS_JSONC) $(LDFLAGS) $(LDFLAGS_JSONC) -Wall -o $@ $^ $(LDLIBS) -liwinfo diff --git a/package/gluon-status-page-api/src/batadv-netlink.c b/package/gluon-status-page-api/src/batadv-netlink.c new file mode 100644 index 00000000..ca965d48 --- /dev/null +++ b/package/gluon-status-page-api/src/batadv-netlink.c @@ -0,0 +1,145 @@ +/* + * Copyright (C) 2009-2016 B.A.T.M.A.N. contributors: + * + * Marek Lindner , Andrew Lunn + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA + * + */ + +#include "batadv-netlink.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "batman_adv.h" + +#ifndef __maybe_unused +#define __maybe_unused __attribute__((unused)) +#endif + +struct nla_policy batadv_netlink_policy[NUM_BATADV_ATTR] = { + [BATADV_ATTR_HARD_IFINDEX] = { .type = NLA_U32 }, + [BATADV_ATTR_ORIG_ADDRESS] = { .type = NLA_UNSPEC, + .minlen = ETH_ALEN, + .maxlen = ETH_ALEN }, + [BATADV_ATTR_FLAG_BEST] = { .type = NLA_FLAG }, + [BATADV_ATTR_LAST_SEEN_MSECS] = { .type = NLA_U32 }, + [BATADV_ATTR_NEIGH_ADDRESS] = { .type = NLA_UNSPEC, + .minlen = ETH_ALEN, + .maxlen = ETH_ALEN }, + [BATADV_ATTR_TQ] = { .type = NLA_U8 }, +}; + +static int nlquery_error_cb(struct sockaddr_nl *nla __maybe_unused, + struct nlmsgerr *nlerr, void *arg) +{ + struct batadv_nlquery_opts *query_opts = arg; + + query_opts->err = nlerr->error; + + return NL_STOP; +} + +static int nlquery_stop_cb(struct nl_msg *msg, void *arg) +{ + struct nlmsghdr *nlh = nlmsg_hdr(msg); + struct batadv_nlquery_opts *query_opts = arg; + int *error = nlmsg_data(nlh); + + if (*error) + query_opts->err = *error; + + return NL_STOP; +} + +int batadv_nl_query_common(const char *mesh_iface, + enum batadv_nl_commands nl_cmd, + nl_recvmsg_msg_cb_t callback, int flags, + struct batadv_nlquery_opts *query_opts) +{ + struct nl_sock *sock; + struct nl_msg *msg; + struct nl_cb *cb; + int ifindex; + int family; + int ret; + + query_opts->err = 0; + + sock = nl_socket_alloc(); + if (!sock) + return -ENOMEM; + + ret = genl_connect(sock); + if (ret < 0) { + query_opts->err = ret; + goto err_free_sock; + } + + family = genl_ctrl_resolve(sock, BATADV_NL_NAME); + if (family < 0) { + query_opts->err = -EOPNOTSUPP; + goto err_free_sock; + } + + ifindex = if_nametoindex(mesh_iface); + if (!ifindex) { + query_opts->err = -ENODEV; + goto err_free_sock; + } + + cb = nl_cb_alloc(NL_CB_DEFAULT); + if (!cb) { + query_opts->err = -ENOMEM; + goto err_free_sock; + } + + nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, callback, query_opts); + nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, nlquery_stop_cb, query_opts); + nl_cb_err(cb, NL_CB_CUSTOM, nlquery_error_cb, query_opts); + + msg = nlmsg_alloc(); + if (!msg) { + query_opts->err = -ENOMEM; + goto err_free_cb; + } + + genlmsg_put(msg, NL_AUTO_PID, NL_AUTO_SEQ, family, 0, flags, + nl_cmd, 1); + + nla_put_u32(msg, BATADV_ATTR_MESH_IFINDEX, ifindex); + nl_send_auto_complete(sock, msg); + nlmsg_free(msg); + + nl_recvmsgs(sock, cb); + +err_free_cb: + nl_cb_put(cb); +err_free_sock: + nl_socket_free(sock); + + return query_opts->err; +} diff --git a/package/gluon-status-page-api/src/batadv-netlink.h b/package/gluon-status-page-api/src/batadv-netlink.h new file mode 100644 index 00000000..8b85a6c2 --- /dev/null +++ b/package/gluon-status-page-api/src/batadv-netlink.h @@ -0,0 +1,68 @@ +/* + * Copyright (C) 2009-2016 B.A.T.M.A.N. contributors: + * + * Marek Lindner , Andrew Lunn + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA + * + */ + +#ifndef _BATADV_NETLINK_H +#define _BATADV_NETLINK_H + +#include +#include +#include +#include +#include + +#include "batman_adv.h" + +struct batadv_nlquery_opts { + int err; +}; + +#ifndef ARRAY_SIZE +#define ARRAY_SIZE(x) (sizeof(x) / sizeof(*(x))) +#endif + +#ifndef container_of +#define container_of(ptr, type, member) __extension__ ({ \ + const __typeof__(((type *)0)->member) *__pmember = (ptr); \ + (type *)((char *)__pmember - offsetof(type, member)); }) +#endif + +int batadv_nl_query_common(const char *mesh_iface, + enum batadv_nl_commands nl_cmd, + nl_recvmsg_msg_cb_t callback, int flags, + struct batadv_nlquery_opts *query_opts); + +static inline bool batadv_nl_missing_attrs(struct nlattr *attrs[], + const enum batadv_nl_attrs mandatory[], + size_t num) +{ + size_t i; + + for (i = 0; i < num; i++) { + if (!attrs[mandatory[i]]) + return true; + } + + return false; +} + +extern struct nla_policy batadv_netlink_policy[]; + +#endif /* _BATADV_NETLINK_H */ diff --git a/package/gluon-status-page-api/src/batman_adv.h b/package/gluon-status-page-api/src/batman_adv.h new file mode 100644 index 00000000..734fe83a --- /dev/null +++ b/package/gluon-status-page-api/src/batman_adv.h @@ -0,0 +1,208 @@ +/* Copyright (C) 2016 B.A.T.M.A.N. contributors: + * + * Matthias Schiffer + * + * 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 _UAPI_LINUX_BATMAN_ADV_H_ +#define _UAPI_LINUX_BATMAN_ADV_H_ + +#define BATADV_NL_NAME "batadv" + +#define BATADV_NL_MCAST_GROUP_TPMETER "tpmeter" + +/** + * enum batadv_tt_client_flags - TT client specific flags + * @BATADV_TT_CLIENT_DEL: the client has to be deleted from the table + * @BATADV_TT_CLIENT_ROAM: the client roamed to/from another node and the new + * update telling its new real location has not been received/sent yet + * @BATADV_TT_CLIENT_WIFI: this client is connected through a wifi interface. + * This information is used by the "AP Isolation" feature + * @BATADV_TT_CLIENT_ISOLA: this client is considered "isolated". This + * information is used by the Extended Isolation feature + * @BATADV_TT_CLIENT_NOPURGE: this client should never be removed from the table + * @BATADV_TT_CLIENT_NEW: this client has been added to the local table but has + * not been announced yet + * @BATADV_TT_CLIENT_PENDING: this client is marked for removal but it is kept + * in the table for one more originator interval for consistency purposes + * @BATADV_TT_CLIENT_TEMP: this global client has been detected to be part of + * the network but no nnode has already announced it + * + * Bits from 0 to 7 are called _remote flags_ because they are sent on the wire. + * Bits from 8 to 15 are called _local flags_ because they are used for local + * computations only. + * + * Bits from 4 to 7 - a subset of remote flags - are ensured to be in sync with + * the other nodes in the network. To achieve this goal these flags are included + * in the TT CRC computation. + */ +enum batadv_tt_client_flags { + BATADV_TT_CLIENT_DEL = (1 << 0), + BATADV_TT_CLIENT_ROAM = (1 << 1), + BATADV_TT_CLIENT_WIFI = (1 << 4), + BATADV_TT_CLIENT_ISOLA = (1 << 5), + BATADV_TT_CLIENT_NOPURGE = (1 << 8), + BATADV_TT_CLIENT_NEW = (1 << 9), + BATADV_TT_CLIENT_PENDING = (1 << 10), + BATADV_TT_CLIENT_TEMP = (1 << 11), +}; + +/** + * enum batadv_nl_attrs - batman-adv netlink attributes + * + * @BATADV_ATTR_UNSPEC: unspecified attribute to catch errors + * @BATADV_ATTR_VERSION: batman-adv version string + * @BATADV_ATTR_ALGO_NAME: name of routing algorithm + * @BATADV_ATTR_MESH_IFINDEX: index of the batman-adv interface + * @BATADV_ATTR_MESH_IFNAME: name of the batman-adv interface + * @BATADV_ATTR_MESH_ADDRESS: mac address of the batman-adv interface + * @BATADV_ATTR_HARD_IFINDEX: index of the non-batman-adv interface + * @BATADV_ATTR_HARD_IFNAME: name of the non-batman-adv interface + * @BATADV_ATTR_HARD_ADDRESS: mac address of the non-batman-adv interface + * @BATADV_ATTR_ORIG_ADDRESS: originator mac address + * @BATADV_ATTR_TPMETER_RESULT: result of run (see batadv_tp_meter_status) + * @BATADV_ATTR_TPMETER_TEST_TIME: time (msec) the run took + * @BATADV_ATTR_TPMETER_BYTES: amount of acked bytes during run + * @BATADV_ATTR_TPMETER_COOKIE: session cookie to match tp_meter session + * @BATADV_ATTR_PAD: attribute used for padding for 64-bit alignment + * @BATADV_ATTR_ACTIVE: Flag indicating if the hard interface is active + * @BATADV_ATTR_TT_ADDRESS: Client MAC address + * @BATADV_ATTR_TT_TTVN: Translation table version + * @BATADV_ATTR_TT_LAST_TTVN: Previous translation table version + * @BATADV_ATTR_TT_CRC32: CRC32 over translation table + * @BATADV_ATTR_TT_VID: VLAN ID + * @BATADV_ATTR_TT_FLAGS: Translation table client flags + * @BATADV_ATTR_FLAG_BEST: Flags indicating entry is the best + * @BATADV_ATTR_LAST_SEEN_MSECS: Time in milliseconds since last seen + * @BATADV_ATTR_NEIGH_ADDRESS: Neighbour MAC address + * @BATADV_ATTR_TQ: TQ to neighbour + * @BATADV_ATTR_THROUGHPUT: Estimated throughput to Neighbour + * @BATADV_ATTR_BANDWIDTH_UP: Reported uplink bandwidth + * @BATADV_ATTR_BANDWIDTH_DOWN: Reported downlink bandwidth + * @BATADV_ATTR_ROUTER: Gateway router MAC address + * @BATADV_ATTR_BLA_OWN: Flag indicating own originator + * @BATADV_ATTR_BLA_ADDRESS: Bridge loop avoidance claim MAC address + * @BATADV_ATTR_BLA_VID: BLA VLAN ID + * @BATADV_ATTR_BLA_BACKBONE: BLA gateway originator MAC address + * @BATADV_ATTR_BLA_CRC: BLA CRC + * @__BATADV_ATTR_AFTER_LAST: internal use + * @NUM_BATADV_ATTR: total number of batadv_nl_attrs available + * @BATADV_ATTR_MAX: highest attribute number currently defined + */ +enum batadv_nl_attrs { + BATADV_ATTR_UNSPEC, + BATADV_ATTR_VERSION, + BATADV_ATTR_ALGO_NAME, + BATADV_ATTR_MESH_IFINDEX, + BATADV_ATTR_MESH_IFNAME, + BATADV_ATTR_MESH_ADDRESS, + BATADV_ATTR_HARD_IFINDEX, + BATADV_ATTR_HARD_IFNAME, + BATADV_ATTR_HARD_ADDRESS, + BATADV_ATTR_ORIG_ADDRESS, + BATADV_ATTR_TPMETER_RESULT, + BATADV_ATTR_TPMETER_TEST_TIME, + BATADV_ATTR_TPMETER_BYTES, + BATADV_ATTR_TPMETER_COOKIE, + BATADV_ATTR_PAD, + BATADV_ATTR_ACTIVE, + BATADV_ATTR_TT_ADDRESS, + BATADV_ATTR_TT_TTVN, + BATADV_ATTR_TT_LAST_TTVN, + BATADV_ATTR_TT_CRC32, + BATADV_ATTR_TT_VID, + BATADV_ATTR_TT_FLAGS, + BATADV_ATTR_FLAG_BEST, + BATADV_ATTR_LAST_SEEN_MSECS, + BATADV_ATTR_NEIGH_ADDRESS, + BATADV_ATTR_TQ, + BATADV_ATTR_THROUGHPUT, + BATADV_ATTR_BANDWIDTH_UP, + BATADV_ATTR_BANDWIDTH_DOWN, + BATADV_ATTR_ROUTER, + BATADV_ATTR_BLA_OWN, + BATADV_ATTR_BLA_ADDRESS, + BATADV_ATTR_BLA_VID, + BATADV_ATTR_BLA_BACKBONE, + BATADV_ATTR_BLA_CRC, + /* add attributes above here, update the policy in netlink.c */ + __BATADV_ATTR_AFTER_LAST, + NUM_BATADV_ATTR = __BATADV_ATTR_AFTER_LAST, + BATADV_ATTR_MAX = __BATADV_ATTR_AFTER_LAST - 1 +}; + +/** + * enum batadv_nl_commands - supported batman-adv netlink commands + * + * @BATADV_CMD_UNSPEC: unspecified command to catch errors + * @BATADV_CMD_GET_MESH_INFO: Query basic information about batman-adv device + * @BATADV_CMD_TP_METER: Start a tp meter session + * @BATADV_CMD_TP_METER_CANCEL: Cancel a tp meter session + * @BATADV_CMD_GET_ROUTING_ALGOS: Query the list of routing algorithms. + * @BATADV_CMD_GET_HARDIFS: Query list of hard interfaces + * @BATADV_CMD_GET_TRANSTABLE_LOCAL: Query list of local translations + * @BATADV_CMD_GET_TRANSTABLE_GLOBAL Query list of global translations + * @BATADV_CMD_GET_ORIGINATORS: Query list of originators + * @BATADV_CMD_GET_NEIGHBORS: Query list of neighbours + * @BATADV_CMD_GET_GATEWAYS: Query list of gateways + * @BATADV_CMD_GET_BLA_CLAIM: Query list of bridge loop avoidance claims + * @BATADV_CMD_GET_BLA_BACKBONE: Query list of bridge loop avoidance backbones + * @__BATADV_CMD_AFTER_LAST: internal use + * @BATADV_CMD_MAX: highest used command number + */ +enum batadv_nl_commands { + BATADV_CMD_UNSPEC, + BATADV_CMD_GET_MESH_INFO, + BATADV_CMD_TP_METER, + BATADV_CMD_TP_METER_CANCEL, + BATADV_CMD_GET_ROUTING_ALGOS, + BATADV_CMD_GET_HARDIFS, + BATADV_CMD_GET_TRANSTABLE_LOCAL, + BATADV_CMD_GET_TRANSTABLE_GLOBAL, + BATADV_CMD_GET_ORIGINATORS, + BATADV_CMD_GET_NEIGHBORS, + BATADV_CMD_GET_GATEWAYS, + BATADV_CMD_GET_BLA_CLAIM, + BATADV_CMD_GET_BLA_BACKBONE, + /* add new commands above here */ + __BATADV_CMD_AFTER_LAST, + BATADV_CMD_MAX = __BATADV_CMD_AFTER_LAST - 1 +}; + +/** + * enum batadv_tp_meter_reason - reason of a tp meter test run stop + * @BATADV_TP_REASON_COMPLETE: sender finished tp run + * @BATADV_TP_REASON_CANCEL: sender was stopped during run + * @BATADV_TP_REASON_DST_UNREACHABLE: receiver could not be reached or didn't + * answer + * @BATADV_TP_REASON_RESEND_LIMIT: (unused) sender retry reached limit + * @BATADV_TP_REASON_ALREADY_ONGOING: test to or from the same node already + * ongoing + * @BATADV_TP_REASON_MEMORY_ERROR: test was stopped due to low memory + * @BATADV_TP_REASON_CANT_SEND: failed to send via outgoing interface + * @BATADV_TP_REASON_TOO_MANY: too many ongoing sessions + */ +enum batadv_tp_meter_reason { + BATADV_TP_REASON_COMPLETE = 3, + BATADV_TP_REASON_CANCEL = 4, + /* error status >= 128 */ + BATADV_TP_REASON_DST_UNREACHABLE = 128, + BATADV_TP_REASON_RESEND_LIMIT = 129, + BATADV_TP_REASON_ALREADY_ONGOING = 130, + BATADV_TP_REASON_MEMORY_ERROR = 131, + BATADV_TP_REASON_CANT_SEND = 132, + BATADV_TP_REASON_TOO_MANY = 133, +}; + +#endif /* _UAPI_LINUX_BATMAN_ADV_H_ */ diff --git a/package/gluon-status-page-api/src/neighbours-batadv.c b/package/gluon-status-page-api/src/neighbours-batadv.c index f0a484b2..7d5d0211 100644 --- a/package/gluon-status-page-api/src/neighbours-batadv.c +++ b/package/gluon-status-page-api/src/neighbours-batadv.c @@ -4,45 +4,110 @@ #include #include +#include "batadv-netlink.h" + #define STR(x) #x #define XSTR(x) STR(x) +struct neigh_netlink_opts { + struct json_object *obj; + struct batadv_nlquery_opts query_opts; +}; + +static const enum batadv_nl_attrs parse_orig_list_mandatory[] = { + BATADV_ATTR_ORIG_ADDRESS, + BATADV_ATTR_NEIGH_ADDRESS, + BATADV_ATTR_TQ, + BATADV_ATTR_HARD_IFINDEX, + BATADV_ATTR_LAST_SEEN_MSECS, +}; + +static int parse_orig_list_netlink_cb(struct nl_msg *msg, void *arg) +{ + struct nlattr *attrs[BATADV_ATTR_MAX+1]; + struct nlmsghdr *nlh = nlmsg_hdr(msg); + struct batadv_nlquery_opts *query_opts = arg; + struct genlmsghdr *ghdr; + uint8_t *orig; + uint8_t *dest; + uint8_t tq; + uint32_t hardif; + uint32_t lastseen; + char ifname_buf[IF_NAMESIZE], *ifname; + struct neigh_netlink_opts *opts; + char mac1[18]; + + opts = container_of(query_opts, struct neigh_netlink_opts, query_opts); + + if (!genlmsg_valid_hdr(nlh, 0)) + return NL_OK; + + ghdr = nlmsg_data(nlh); + + if (ghdr->cmd != BATADV_CMD_GET_ORIGINATORS) + return NL_OK; + + if (nla_parse(attrs, BATADV_ATTR_MAX, genlmsg_attrdata(ghdr, 0), + genlmsg_len(ghdr), batadv_netlink_policy)) + return NL_OK; + + if (batadv_nl_missing_attrs(attrs, parse_orig_list_mandatory, + ARRAY_SIZE(parse_orig_list_mandatory))) + return NL_OK; + + if (!attrs[BATADV_ATTR_FLAG_BEST]) + return NL_OK; + + orig = nla_data(attrs[BATADV_ATTR_ORIG_ADDRESS]); + dest = nla_data(attrs[BATADV_ATTR_NEIGH_ADDRESS]); + tq = nla_get_u8(attrs[BATADV_ATTR_TQ]); + hardif = nla_get_u32(attrs[BATADV_ATTR_HARD_IFINDEX]); + lastseen = nla_get_u32(attrs[BATADV_ATTR_LAST_SEEN_MSECS]); + + if (memcmp(orig, dest, 6) != 0) + return NL_OK; + + ifname = if_indextoname(hardif, ifname_buf); + if (!ifname) + return NL_OK; + + sprintf(mac1, "%02x:%02x:%02x:%02x:%02x:%02x", + orig[0], orig[1], orig[2], orig[3], orig[4], orig[5]); + + struct json_object *neigh = json_object_new_object(); + if (!neigh) + return NL_OK; + + json_object_object_add(neigh, "tq", json_object_new_int(tq)); + json_object_object_add(neigh, "lastseen", json_object_new_double(lastseen / 1000.)); + json_object_object_add(neigh, "ifname", json_object_new_string(ifname)); + + json_object_object_add(opts->obj, mac1, neigh); + + return NL_OK; +} + static json_object *neighbours(void) { - struct json_object *obj = json_object_new_object(); + struct neigh_netlink_opts opts = { + .query_opts = { + .err = 0, + }, + }; + int ret; - FILE *f; - - f = fopen("/sys/kernel/debug/batman_adv/bat0/originators" , "r"); - - if (f == NULL) + opts.obj = json_object_new_object(); + if (!opts.obj) return NULL; - while (!feof(f)) { - char mac1[18]; - char mac2[18]; - char ifname[IF_NAMESIZE+1]; - int tq; - double lastseen; - - int count = fscanf(f, "%17s%*[\t ]%lfs%*[\t (]%d) %17s%*[[ ]%" XSTR(IF_NAMESIZE) "[^]]]", mac1, &lastseen, &tq, mac2, ifname); - - if (count != 5) - continue; - - if (strcmp(mac1, mac2) == 0) { - struct json_object *neigh = json_object_new_object(); - - json_object_object_add(neigh, "tq", json_object_new_int(tq)); - json_object_object_add(neigh, "lastseen", json_object_new_double(lastseen)); - json_object_object_add(neigh, "ifname", json_object_new_string(ifname)); - - json_object_object_add(obj, mac1, neigh); - } + ret = batadv_nl_query_common("bat0", BATADV_CMD_GET_ORIGINATORS, + parse_orig_list_netlink_cb, NLM_F_DUMP, + &opts.query_opts); + if (ret < 0) { + json_object_put(opts.obj); + return NULL; } - fclose(f); - - return obj; + return opts.obj; } int main(void) { diff --git a/package/gluon-status-page/src/index.html.m4 b/package/gluon-status-page/src/index.html.m4 index 489c1cf0..2726f2e3 100644 --- a/package/gluon-status-page/src/index.html.m4 +++ b/package/gluon-status-page/src/index.html.m4 @@ -13,5 +13,6 @@ + diff --git a/package/gluon-status-page/src/js/main.js b/package/gluon-status-page/src/js/main.js index 3bdbe2a0..eb668698 100644 --- a/package/gluon-status-page/src/js/main.js +++ b/package/gluon-status-page/src/js/main.js @@ -83,7 +83,17 @@ require([ "bacon" return a } - if (localStorage.nodes) + var lsavailable = false + try { + localStorage.setItem("t", "t") + localStorage.removeItem("t") + lsavailable = true + } catch(e) { + lsavailable = false + } + + + if ( lsavailable && localStorage.nodes) JSON.parse(localStorage.nodes).forEach(nodesBusIn.push) nodesBus.map(".nodes").onValue(function (nodes) { @@ -92,7 +102,8 @@ require([ "bacon" for (var k in nodes) out.push(nodes[k]) - localStorage.nodes = JSON.stringify(out) + if (lsavailable) + localStorage.nodes = JSON.stringify(out) }) var bootstrap = Helper.getJSON(bootstrapUrl) diff --git a/package/gluon-wan-dnsmasq/Makefile b/package/gluon-wan-dnsmasq/Makefile index c672902d..c7c63ca9 100644 --- a/package/gluon-wan-dnsmasq/Makefile +++ b/package/gluon-wan-dnsmasq/Makefile @@ -5,7 +5,7 @@ PKG_VERSION:=1 PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME) -include $(GLUONDIR)/include/package.mk +include ../gluon.mk define Package/gluon-wan-dnsmasq diff --git a/package/gluon-wan-dnsmasq/luasrc/lib/gluon/wan-dnsmasq/update.lua b/package/gluon-wan-dnsmasq/luasrc/lib/gluon/wan-dnsmasq/update.lua index cceb7225..2997f1c4 100755 --- a/package/gluon-wan-dnsmasq/luasrc/lib/gluon/wan-dnsmasq/update.lua +++ b/package/gluon-wan-dnsmasq/luasrc/lib/gluon/wan-dnsmasq/update.lua @@ -11,6 +11,10 @@ local fs = require 'nixio.fs' local new_servers = '' +local function append_server(server) + new_servers = new_servers .. 'nameserver ' .. server .. '\n' +end + local function handle_interface(status) local ifname = status.device @@ -18,9 +22,10 @@ local function handle_interface(status) for _, server in ipairs(servers) do if server:match('^fe80:') then - server = server .. '%' .. ifname + append_server(server .. '%' .. ifname) + else + append_server(server) end - new_servers = new_servers .. 'nameserver ' .. server .. '\n' end end @@ -32,7 +37,9 @@ end local static = uci:get_first('gluon-wan-dnsmasq', 'static', 'server') if type(static) == 'table' and #static > 0 then - append_servers(static) + for _, server in ipairs(static) do + append_server(server) + end else pcall(append_interface_servers, 'wan6') pcall(append_interface_servers, 'wan') diff --git a/include/package.mk b/package/gluon.mk similarity index 65% rename from include/package.mk rename to package/gluon.mk index 9d35ad3c..a36a9836 100644 --- a/include/package.mk +++ b/package/gluon.mk @@ -5,13 +5,18 @@ 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 -$(shell cat $(1) | sed -ne '1h; 1!H; $$ {g; s/@/+@/g; s/\n/-@/g; p}') +[ -z "$$IPKG_INSTROOT" ] || sed -e 's/-@/\n/g' -e 's/+@/@/g' <<'END__GLUON__CHECK__SITE' | "${TOPDIR}/staging_dir/hostpkg/bin/lua" -e 'dofile()' +local f = assert(io.open(os.getenv('IPKG_INSTROOT') .. '/lib/gluon/site.json')) +local site_json = f:read('*a') +f:close() + +site = require('cjson').decode(site_json) +$(shell cat '$(TOPDIR)/../scripts/check_site_lib.lua' '$(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 +46,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/package/libgluonutil/Makefile b/package/libgluonutil/Makefile index bebeb2b3..489a9ba9 100644 --- a/package/libgluonutil/Makefile +++ b/package/libgluonutil/Makefile @@ -8,7 +8,7 @@ PKG_LICENSE:=BSD-2-Clause PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME) -include $(GLUONDIR)/include/package.mk +include ../gluon.mk include $(INCLUDE_DIR)/cmake.mk diff --git a/patches/lede/0001-build-move-STAGING_DIR_HOSTPKG-and-BUILD_DIR_HOST-back-to-a-common-directory-for-all-targets.patch b/patches/lede/0001-build-move-STAGING_DIR_HOSTPKG-and-BUILD_DIR_HOST-back-to-a-common-directory-for-all-targets.patch new file mode 100644 index 00000000..3aecb9f5 --- /dev/null +++ b/patches/lede/0001-build-move-STAGING_DIR_HOSTPKG-and-BUILD_DIR_HOST-back-to-a-common-directory-for-all-targets.patch @@ -0,0 +1,111 @@ +From: Matthias Schiffer +Date: Sat, 14 Jan 2017 18:13:14 +0100 +Subject: build: move STAGING_DIR_HOSTPKG and BUILD_DIR_HOST back to a common directory for all targets + +$(STAGING_DIR)/host is kept in addition to $(STAGING_DIR_HOSTPKG) in most +places; it is still used as destination for host files in Build/InstallDev. + +Signed-off-by: Matthias Schiffer + +diff --git a/Makefile b/Makefile +index b220dfd3c56a11f3e27d70e3d6e58cc6448abd2f..c1a7285c83df310e987eaef8376500d2b614eafb 100644 +--- a/Makefile ++++ b/Makefile +@@ -55,7 +55,7 @@ clean: FORCE + rm -rf $(BUILD_DIR) $(STAGING_DIR) $(BIN_DIR) $(OUTPUT_DIR)/packages/$(ARCH_PACKAGES) $(BUILD_LOG_DIR) $(TOPDIR)/staging_dir/packages + + dirclean: clean +- rm -rf $(STAGING_DIR_HOST) $(TOOLCHAIN_DIR) $(BUILD_DIR_HOST) $(BUILD_DIR_TOOLCHAIN) ++ rm -rf $(STAGING_DIR_HOST) $(STAGING_DIR_HOSTPKG) $(TOOLCHAIN_DIR) $(BUILD_DIR_BASE)/host $(BUILD_DIR_BASE)/hostpkg $(BUILD_DIR_TOOLCHAIN) + rm -rf $(TMP_DIR) + + ifndef DUMP_TARGET_DB +diff --git a/include/autotools.mk b/include/autotools.mk +index c6aa47e0bef311697b4def7a7183d1ac59dcf599..7bd400ab36d052b39fcb76a66873c8673eb189a0 100644 +--- a/include/autotools.mk ++++ b/include/autotools.mk +@@ -75,7 +75,7 @@ define autoreconf_target + $(strip $(call autoreconf, \ + $(PKG_BUILD_DIR), $(PKG_REMOVE_FILES), \ + $(PKG_AUTOMAKE_PATHS), $(PKG_LIBTOOL_PATHS), \ +- $(STAGING_DIR)/host/share/aclocal $(STAGING_DIR)/usr/share/aclocal $(PKG_MACRO_PATHS))) ++ $(STAGING_DIR)/host/share/aclocal $(STAGING_DIR_HOSTPKG)/share/aclocal $(STAGING_DIR)/usr/share/aclocal $(PKG_MACRO_PATHS))) + endef + + define patch_libtool_target +diff --git a/include/cmake.mk b/include/cmake.mk +index 5f572e9d7475e807ea56713ee2069dc98f5c1f6b..80c1b05937410cb9fce20e7b759577480cf390e7 100644 +--- a/include/cmake.mk ++++ b/include/cmake.mk +@@ -34,7 +34,7 @@ CMAKE_NM:=$(call cmake_tool,$(TARGET_NM)) + CMAKE_RANLIB:=$(call cmake_tool,$(TARGET_RANLIB)) + + CMAKE_FIND_ROOT_PATH:=$(STAGING_DIR)/usr;$(TOOLCHAIN_DIR)$(if $(CONFIG_EXTERNAL_TOOLCHAIN),;$(CONFIG_TOOLCHAIN_ROOT)) +-CMAKE_HOST_FIND_ROOT_PATH:=$(STAGING_DIR)/host;$(STAGING_DIR_HOST) ++CMAKE_HOST_FIND_ROOT_PATH:=$(STAGING_DIR)/host;$(STAGING_DIR_HOSTPKG);$(STAGING_DIR_HOST) + CMAKE_SHARED_LDFLAGS:=-Wl,-Bsymbolic-functions + + define Build/Configure/Default +diff --git a/include/host-build.mk b/include/host-build.mk +index 5cfbdeba5138c4362f82b7ae86b910a1f41f082a..fee7c6ce8fca6160a7055a8ccb9c0ebd0759032b 100644 +--- a/include/host-build.mk ++++ b/include/host-build.mk +@@ -115,7 +115,7 @@ ifneq ($(if $(HOST_QUILT),,$(CONFIG_AUTOREBUILD)),) + endif + + define Host/Exports/Default +- $(1) : export ACLOCAL_INCLUDE=$$(foreach p,$$(wildcard $$(STAGING_DIR_HOST)/share/aclocal $$(STAGING_DIR_HOST)/share/aclocal-* $(if $(IS_PACKAGE_BUILD),$$(STAGING_DIR)/host/share/aclocal $$(STAGING_DIR)/host/share/aclocal-*)),-I $$(p)) ++ $(1) : export ACLOCAL_INCLUDE=$$(foreach p,$$(wildcard $$(STAGING_DIR_HOST)/share/aclocal $$(STAGING_DIR_HOST)/share/aclocal-* $(if $(IS_PACKAGE_BUILD),$$(STAGING_DIR)/host/share/aclocal $$(STAGING_DIR_HOSTPKG)/share/aclocal $$(STAGING_DIR)/host/share/aclocal-*)),-I $$(p)) + $(1) : export STAGING_PREFIX=$$(HOST_BUILD_PREFIX) + $(1) : export PKG_CONFIG_PATH=$$(STAGING_DIR_HOST)/lib/pkgconfig:$$(HOST_BUILD_PREFIX)/lib/pkgconfig + $(1) : export PKG_CONFIG_LIBDIR=$$(HOST_BUILD_PREFIX)/lib/pkgconfig +diff --git a/include/package.mk b/include/package.mk +index 32485176577b040f6e4a561c5d1144509877bcdf..ea801288eadb139cc0dd2412b4c927c6bd7330e0 100644 +--- a/include/package.mk ++++ b/include/package.mk +@@ -130,7 +130,7 @@ ifdef USE_SOURCE_DIR + endif + + define Build/Exports/Default +- $(1) : export ACLOCAL_INCLUDE=$$(foreach p,$$(wildcard $$(STAGING_DIR)/usr/share/aclocal $$(STAGING_DIR)/usr/share/aclocal-* $$(STAGING_DIR)/host/share/aclocal $$(STAGING_DIR)/host/share/aclocal-*),-I $$(p)) ++ $(1) : export ACLOCAL_INCLUDE=$$(foreach p,$$(wildcard $$(STAGING_DIR)/usr/share/aclocal $$(STAGING_DIR)/usr/share/aclocal-* $$(STAGING_DIR_HOSTPKG)/share/aclocal $$(STAGING_DIR_HOSTPKG)/share/aclocal-* $$(STAGING_DIR)/host/share/aclocal $$(STAGING_DIR)/host/share/aclocal-*),-I $$(p)) + $(1) : export STAGING_PREFIX=$$(STAGING_DIR)/usr + $(1) : export PATH=$$(TARGET_PATH_PKG) + $(1) : export CONFIG_SITE:=$$(CONFIG_SITE) +diff --git a/rules.mk b/rules.mk +index 04fd936660bef4af49de5500cd2d7c3601c1b9f6..95b18f9e5c69de479db54c5bdb740103140dcf74 100644 +--- a/rules.mk ++++ b/rules.mk +@@ -145,9 +145,9 @@ STAGING_DIR_ROOT:=$(STAGING_DIR)/root-$(BOARD) + BUILD_LOG_DIR:=$(TOPDIR)/logs + PKG_INFO_DIR := $(STAGING_DIR)/pkginfo + +-BUILD_DIR_HOST:=$(if $(IS_PACKAGE_BUILD),$(BUILD_DIR)/host,$(BUILD_DIR_BASE)/host) ++BUILD_DIR_HOST:=$(if $(IS_PACKAGE_BUILD),$(BUILD_DIR_BASE)/hostpkg,$(BUILD_DIR_BASE)/host) + STAGING_DIR_HOST:=$(TOPDIR)/staging_dir/host +-STAGING_DIR_HOSTPKG:=$(STAGING_DIR)/host ++STAGING_DIR_HOSTPKG:=$(TOPDIR)/staging_dir/hostpkg + + TARGET_PATH:=$(subst $(space),:,$(filter-out .,$(filter-out ./,$(subst :,$(space),$(PATH))))) + TARGET_INIT_PATH:=$(call qstrip,$(CONFIG_TARGET_INIT_PATH)) +@@ -206,7 +206,7 @@ ifndef DUMP + endif + endif + endif +-TARGET_PATH_PKG:=$(STAGING_DIR)/host/bin:$(TARGET_PATH) ++TARGET_PATH_PKG:=$(STAGING_DIR)/host/bin:$(STAGING_DIR_HOSTPKG)/bin:$(TARGET_PATH) + + ifeq ($(CONFIG_SOFT_FLOAT),y) + SOFT_FLOAT_CONFIG_OPTION:=--with-float=soft +@@ -232,9 +232,9 @@ export PKG_CONFIG + + HOSTCC:=gcc + HOSTCXX:=g++ +-HOST_CPPFLAGS:=-I$(STAGING_DIR_HOST)/include -I$(STAGING_DIR_HOST)/usr/include $(if $(IS_PACKAGE_BUILD),-I$(STAGING_DIR)/host/include) ++HOST_CPPFLAGS:=-I$(STAGING_DIR_HOST)/include -I$(STAGING_DIR_HOST)/usr/include $(if $(IS_PACKAGE_BUILD),-I$(STAGING_DIR_HOSTPKG)/include -I$(STAGING_DIR)/host/include) + HOST_CFLAGS:=-O2 $(HOST_CPPFLAGS) +-HOST_LDFLAGS:=-L$(STAGING_DIR_HOST)/lib -L$(STAGING_DIR_HOST)/usr/lib $(if $(IS_PACKAGE_BUILD),-L$(STAGING_DIR)/host/lib) ++HOST_LDFLAGS:=-L$(STAGING_DIR_HOST)/lib -L$(STAGING_DIR_HOST)/usr/lib $(if $(IS_PACKAGE_BUILD),-L$(STAGING_DIR_HOSTPKG)/lib -L$(STAGING_DIR)/host/lib) + + ifeq ($(CONFIG_EXTERNAL_TOOLCHAIN),) + TARGET_AR:=$(TARGET_CROSS)gcc-ar diff --git a/patches/openwrt/0002-procd-add-support-for-alternative-rc.d-directories.patch b/patches/lede/0002-procd-add-support-for-alternative-rc.d-directories.patch similarity index 96% rename from patches/openwrt/0002-procd-add-support-for-alternative-rc.d-directories.patch rename to patches/lede/0002-procd-add-support-for-alternative-rc.d-directories.patch index ced85fed..db29794d 100644 --- a/patches/openwrt/0002-procd-add-support-for-alternative-rc.d-directories.patch +++ b/patches/lede/0002-procd-add-support-for-alternative-rc.d-directories.patch @@ -4,7 +4,7 @@ Subject: procd: add support for alternative rc.d directories diff --git a/package/system/procd/patches/0001-Add-support-for-alternative-rc.d-directories.patch b/package/system/procd/patches/0001-Add-support-for-alternative-rc.d-directories.patch new file mode 100644 -index 0000000..bc24342 +index 0000000000000000000000000000000000000000..bc2434200364b46f1db4c2eec22c4e8b973844d5 --- /dev/null +++ b/package/system/procd/patches/0001-Add-support-for-alternative-rc.d-directories.patch @@ -0,0 +1,97 @@ diff --git a/patches/lede/0003-base-files-disable-reset-button-handling.patch b/patches/lede/0003-base-files-disable-reset-button-handling.patch new file mode 100644 index 00000000..7e44f290 --- /dev/null +++ b/patches/lede/0003-base-files-disable-reset-button-handling.patch @@ -0,0 +1,43 @@ +From: Matthias Schiffer +Date: Sat, 21 Mar 2015 16:40:52 +0100 +Subject: base-files: disable reset button handling + +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 4265767437e8eda3c758fe7f7941d7f608c95782..0000000000000000000000000000000000000000 +--- a/package/base-files/files/etc/rc.button/reset ++++ /dev/null +@@ -1,31 +0,0 @@ +-#!/bin/sh +- +-. /lib/functions.sh +- +-OVERLAY="$( grep ' /overlay ' /proc/mounts )" +- +-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 96% rename from patches/openwrt/0009-hostapd-prevent-channel-switch-for-5GHz.patch rename to patches/lede/0004-hostapd-prevent-channel-switch-for-5GHz.patch index 712393b7..3eda369d 100644 --- a/patches/openwrt/0009-hostapd-prevent-channel-switch-for-5GHz.patch +++ b/patches/lede/0004-hostapd-prevent-channel-switch-for-5GHz.patch @@ -10,7 +10,7 @@ As a temporary fix, disable this channel switch function. diff --git a/package/network/services/hostapd/patches/900-no_channel_switch.patch b/package/network/services/hostapd/patches/900-no_channel_switch.patch new file mode 100644 -index 0000000..c614515 +index 0000000000000000000000000000000000000000..c6145156928ffa5a5195ca145b0655bb88c92091 --- /dev/null +++ b/package/network/services/hostapd/patches/900-no_channel_switch.patch @@ -0,0 +1,68 @@ diff --git a/patches/openwrt/0079-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 97% rename from patches/openwrt/0079-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 index 690d3ebb..662d8960 100644 --- a/patches/openwrt/0079-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 @@ -4,7 +4,7 @@ Subject: libjson-c: Add support for custom format strings for doubles diff --git a/package/libs/libjson-c/patches/002-custom-format-string.patch b/package/libs/libjson-c/patches/002-custom-format-string.patch new file mode 100644 -index 0000000..2f454c5 +index 0000000000000000000000000000000000000000..2f454c560ff78c1edd4654b9651f0e6299bd5e6f --- /dev/null +++ b/package/libs/libjson-c/patches/002-custom-format-string.patch @@ -0,0 +1,98 @@ 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..d0a36b27 --- /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 0000000000000000000000000000000000000000..c6e45423e2dba1258549a5bfe4b5a59ac32d73d8 +--- /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/lede/0007-rules.mk-export-STAGING_DIR_HOSTPKG.patch b/patches/lede/0007-rules.mk-export-STAGING_DIR_HOSTPKG.patch new file mode 100644 index 00000000..6656c47f --- /dev/null +++ b/patches/lede/0007-rules.mk-export-STAGING_DIR_HOSTPKG.patch @@ -0,0 +1,19 @@ +From: Matthias Schiffer +Date: Thu, 19 Jan 2017 00:03:32 +0100 +Subject: rules.mk: export STAGING_DIR_HOSTPKG + +Signed-off-by: Matthias Schiffer + +diff --git a/rules.mk b/rules.mk +index 95b18f9e5c69de479db54c5bdb740103140dcf74..1b9de5f35e3890c2759ab2cdbd98ac80df942124 100644 +--- a/rules.mk ++++ b/rules.mk +@@ -223,7 +223,7 @@ else + endif + + export PATH:=$(TARGET_PATH) +-export STAGING_DIR STAGING_DIR_HOST ++export STAGING_DIR STAGING_DIR_HOST STAGING_DIR_HOSTPKG + export SH_FUNC:=. $(INCLUDE_DIR)/shell.sh; + + PKG_CONFIG:=$(STAGING_DIR_HOST)/bin/pkg-config diff --git a/patches/lede/0008-gettext-full-fix-to-use-STAGING_DIR_HOSTPKG-instead-of-STAGING_DIR-host.patch b/patches/lede/0008-gettext-full-fix-to-use-STAGING_DIR_HOSTPKG-instead-of-STAGING_DIR-host.patch new file mode 100644 index 00000000..4aa04521 --- /dev/null +++ b/patches/lede/0008-gettext-full-fix-to-use-STAGING_DIR_HOSTPKG-instead-of-STAGING_DIR-host.patch @@ -0,0 +1,32 @@ +From: Matthias Schiffer +Date: Thu, 19 Jan 2017 00:04:09 +0100 +Subject: gettext-full: fix to use $STAGING_DIR_HOSTPKG instead of $STAGING_DIR/host + +Signed-off-by: Matthias Schiffer + +diff --git a/package/libs/gettext-full/patches/000-relocatable.patch b/package/libs/gettext-full/patches/000-relocatable.patch +index c14be728367b57c08024d848cf8ff847cfe865be..a95c268f5bc94ed8ec3784ae2044aa77e0322491 100644 +--- a/package/libs/gettext-full/patches/000-relocatable.patch ++++ b/package/libs/gettext-full/patches/000-relocatable.patch +@@ -5,8 +5,8 @@ + # Set variables + # - gettext_datadir directory where the data files are stored. + -prefix="@prefix@" +-+if [ -n "$STAGING_DIR" ]; then +-+ prefix="$STAGING_DIR/host" +++if [ -n "$STAGING_DIR_HOSTPKG" ]; then +++ prefix="$STAGING_DIR_HOSTPKG" + +else + + prefix="@prefix@" + +fi +@@ -20,8 +20,8 @@ + # Set variables + # - gettext_datadir directory where the data files are stored. + -prefix="@prefix@" +-+if [ -n "$STAGING_DIR" ]; then +-+ prefix="$STAGING_DIR/host" +++if [ -n "$STAGING_DIR_HOSTPKG" ]; then +++ prefix="$STAGING_DIR_HOSTPKG" + +else + + prefix="@prefix@" + +fi diff --git a/patches/lede/0009-include-rootfs.mk-keep-Require-User-lines-with-CONFIG_CLEAN_IPKG.patch b/patches/lede/0009-include-rootfs.mk-keep-Require-User-lines-with-CONFIG_CLEAN_IPKG.patch new file mode 100644 index 00000000..45c1fa72 --- /dev/null +++ b/patches/lede/0009-include-rootfs.mk-keep-Require-User-lines-with-CONFIG_CLEAN_IPKG.patch @@ -0,0 +1,37 @@ +From: Matthias Schiffer +Date: Tue, 24 Jan 2017 17:00:43 +0100 +Subject: include/rootfs.mk: keep Require-User lines with CONFIG_CLEAN_IPKG + +Require-User is handled by /etc/uci-defaults/13_fix_group_user on first +boot, so we need to keep these when removing all opkg data with +CONFIG_CLEAN_IPKG. + +Signed-off-by: Matthias Schiffer + +diff --git a/include/rootfs.mk b/include/rootfs.mk +index 90d70a11f2e775c83b9907ec1f296c0e4d535ad6..c014b1d14ab0963687417809431abc0bf314830c 100644 +--- a/include/rootfs.mk ++++ b/include/rootfs.mk +@@ -47,6 +47,14 @@ opkg = \ + + TARGET_DIR_ORIG := $(TARGET_ROOTFS_DIR)/root.orig-$(BOARD) + ++ifdef CONFIG_CLEAN_IPKG ++ define clean_ipkg ++ -find $(1)/usr/lib/opkg -type f -and -not -name '*.control' | $(XARGS) rm -rf ++ -sed -i -ne '/^Require-User: /p' $(1)/usr/lib/opkg/info/*.control ++ -find $(1)/usr/lib/opkg -empty | $(XARGS) rm -rf ++ endef ++endif ++ + define prepare_rootfs + @if [ -d $(TOPDIR)/files ]; then \ + $(call file_copy,$(TOPDIR)/files/.,$(1)); \ +@@ -75,6 +83,6 @@ define prepare_rootfs + rm -f $(1)/usr/lib/opkg/lists/* + rm -f $(1)/usr/lib/opkg/info/*.postinst* + rm -f $(1)/usr/lib/opkg/info/*.prerm* +- $(if $(CONFIG_CLEAN_IPKG),rm -rf $(1)/usr/lib/opkg) ++ $(call clean_ipkg,$(1)) + $(call mklibs,$(1)) + endef diff --git a/patches/lede/0010-base-files-fix-user-creation-on-sysupgrade-with-few-opkg-control-files.patch b/patches/lede/0010-base-files-fix-user-creation-on-sysupgrade-with-few-opkg-control-files.patch new file mode 100644 index 00000000..43b0b97f --- /dev/null +++ b/patches/lede/0010-base-files-fix-user-creation-on-sysupgrade-with-few-opkg-control-files.patch @@ -0,0 +1,26 @@ +From: Matthias Schiffer +Date: Tue, 24 Jan 2017 18:55:13 +0100 +Subject: base-files: fix user creation on sysupgrade with few opkg control files + +If only a single opkg control file exists (which can happen with +CONFIG_CLEAN_IPKG), grep would not print the file name by default. Instead +of forcing it using -H, we just switch to -l (print only file names) and +get rid of the cut. + +Add -s to suppress an error message when no control files exist. + +Signed-off-by: Matthias Schiffer + +diff --git a/package/base-files/files/etc/uci-defaults/13_fix_group_user b/package/base-files/files/etc/uci-defaults/13_fix_group_user +index deade5bbd1876cd3f009d4c0b18be258c3bf36d1..e6dae2419f65a830ebd039fbbfa0fd22d1a2d0a1 100644 +--- a/package/base-files/files/etc/uci-defaults/13_fix_group_user ++++ b/package/base-files/files/etc/uci-defaults/13_fix_group_user +@@ -2,7 +2,7 @@ + + . /lib/functions.sh + +-for file in `grep Require-User /usr/lib/opkg/info/*.control | cut -d: -f1`; do ++for file in `grep -sl Require-User /usr/lib/opkg/info/*.control`; do + file="${file##*/}" + file="${file%.control}" + add_group_and_user "${file}" 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/0003-odhcp6c-always-accept-RDNSS-independent-of-the-default-router-lifetime.patch b/patches/openwrt/0003-odhcp6c-always-accept-RDNSS-independent-of-the-default-router-lifetime.patch deleted file mode 100644 index 82de5300..00000000 --- a/patches/openwrt/0003-odhcp6c-always-accept-RDNSS-independent-of-the-default-router-lifetime.patch +++ /dev/null @@ -1,31 +0,0 @@ -From: Matthias Schiffer -Date: Thu, 13 Nov 2014 01:17:24 +0100 -Subject: odhcp6c: always accept RDNSS, independent 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 ---- /dev/null -+++ b/package/network/ipv6/odhcp6c/patches/001-always_accept_rdnss.patch -@@ -0,0 +1,21 @@ -+--- a/src/ra.c -++++ b/src/ra.c -+@@ -438,18 +438,6 @@ bool ra_process(void) -+ } -+ } -+ } -+- -+- int states[2] = {STATE_RA_DNS, STATE_RA_SEARCH}; -+- for (size_t i = 0; i < 2; ++i) { -+- 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])) -+- if (IN6_ARE_ADDR_EQUAL(&c->router, &from.sin6_addr) && -+- c->valid > router_valid) -+- c->valid = router_valid; -+- } -+ } -+ -+ if (found) 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/0005-base-files-disable-reset-button-handling.patch b/patches/openwrt/0005-base-files-disable-reset-button-handling.patch deleted file mode 100644 index a889df96..00000000 --- a/patches/openwrt/0005-base-files-disable-reset-button-handling.patch +++ /dev/null @@ -1,32 +0,0 @@ -From: Matthias Schiffer -Date: Sat, 21 Mar 2015 16:40:52 +0100 -Subject: base-files: disable reset button handling - -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 ---- a/package/base-files/files/etc/rc.button/reset -+++ /dev/null -@@ -1,20 +0,0 @@ --#!/bin/sh -- --[ "${ACTION}" = "released" ] || exit 0 -- --. /lib/functions.sh -- --logger "$BUTTON pressed for $SEEN seconds" -- --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 -- --return 0 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-to-LEDE-42f559ed70897a7b74dd3e6293b42e6d2e511eaa.patch b/patches/openwrt/0007-mac80211-hostapd-iw-.-update-to-LEDE-42f559ed70897a7b74dd3e6293b42e6d2e511eaa.patch deleted file mode 100644 index 4858efde..00000000 --- a/patches/openwrt/0007-mac80211-hostapd-iw-.-update-to-LEDE-42f559ed70897a7b74dd3e6293b42e6d2e511eaa.patch +++ /dev/null @@ -1,19251 +0,0 @@ -From: Matthias Schiffer -Date: Wed, 7 Sep 2016 05:04:06 +0200 -Subject: mac80211, hostapd, iw, ...: update to LEDE 42f559ed70897a7b74dd3e6293b42e6d2e511eaa - -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..7a2e977 100644 ---- a/package/firmware/linux-firmware/Makefile -+++ b/package/firmware/linux-firmware/Makefile -@@ -16,10 +16,10 @@ PKG_SOURCE_PROTO:=git - 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_SOURCE_URL:=https://git.kernel.org/pub/scm/linux/kernel/git/firmware/linux-firmware.git -+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..5c0ca3f 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,8 +1491,10 @@ 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_DEBUG) += ATH_DEBUG ATH10K_DEBUG ATH9K_STATION_STATISTICS - config-$(CONFIG_PACKAGE_ATH_DFS) += ATH9K_DFS_CERTIFIED ATH10K_DFS_CERTIFIED - - config-$(call config_package,ath9k) += ATH9K -@@ -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/files/regdb.txt b/package/kernel/mac80211/files/regdb.txt -index 463ace3..c4a9b2d 100644 ---- a/package/kernel/mac80211/files/regdb.txt -+++ b/package/kernel/mac80211/files/regdb.txt -@@ -136,19 +136,35 @@ country BF: DFS-FCC - (5490 - 5730 @ 160), (24), DFS - (5735 - 5835 @ 80), (30) - -+# Bulgarian rules as defined by the Communications Regulation Commission in the -+# following documents: -+# -+# Rules for carrying out electronic communications through radio equipment using -+# radio spectrum, which does not need to be individually assigned (the Rules): -+# http://www.crc.bg/files/_bg/Pravila_09_06_2015.pdf -+# -+# List of radio equipment that uses harmonized within the European Union bands -+# and electronic communications terminal equipment (the List): -+# http://www.crc.bg/files/_bg/Spisak_2015.pdf -+# -+# Note: The transmit power limits in the 5250-5350 MHz and 5470-5725 MHz bands -+# can be raised by 3 dBm if TPC is enabled. Refer to BDS EN 301 893 for details. - country BG: DFS-ETSI -+ # Wideband data transmission systems (WDTS) in the 2.4GHz ISM band, ref: -+ # I.22 of the List, BDS EN 300 328 - (2402 - 2482 @ 40), (20) -- (5170 - 5250 @ 80), (20), AUTO-BW -+ # 5 GHz Radio Local Area Networks (RLANs), ref: -+ # II.H01 of the List, BDS EN 301 893 -+ (5170 - 5250 @ 80), (23), AUTO-BW - (5250 - 5330 @ 80), (20), DFS, AUTO-BW -+ # II.H01 of the List, I.54 from the List, BDS EN 301 893 - (5490 - 5710 @ 160), (27), DFS -- # 5 GHz Short Range Devices, ref: -- # Etsi EN 300 440-1 -- # Etsi EN 300 440-2 -- # http://crc.bg/files/_bg/Spisak_2015.pdf -- # http://crc.bg/files/_bg/Pravila_2015_resh24.pdf -+ # Short range devices (SRDs) in the 5725-5875 MHz frequency range, ref: -+ # I.43 of the List, BDS EN 300 440-2, BDS EN 300 440-1 - (5725 - 5875 @ 80), (14) -- # 60 GHz band channels 1-4, ref: Etsi En 302 567 -- (57000 - 66000 @ 2160), (40) -+ # 60 GHz Multiple-Gigabit RLAN Systems, ref: -+ # II.H03 of the List, BDS EN 302 567-2 -+ (57000 - 66000 @ 2160), (40), NO-OUTDOOR - - country BH: DFS-JP - (2402 - 2482 @ 40), (20) -@@ -275,6 +291,12 @@ country CR: DFS-FCC - (5490 - 5730 @ 20), (24), DFS - (5735 - 5835 @ 20), (30) - -+# http://www.mincom.gob.cu/?q=marcoregulatorio -+# - Redes Informáticas -+# Resolución 127, 2011 - Reglamento Banda 2,4 GHz. -+country CU: DFS-FCC -+ (2400 - 2483.5 @ 40), (200 mW) -+ - country CX: DFS-FCC - (2402 - 2482 @ 40), (20) - (5170 - 5250 @ 80), (24), AUTO-BW -@@ -302,28 +324,41 @@ country CZ: DFS-ETSI - # 60 GHz band channels 1-4, ref: Etsi En 302 567 - (57000 - 66000 @ 2160), (40) - --# Data from "Frequenznutzungsplan" (as published in April 2008), downloaded from --# http://www.bundesnetzagentur.de/cae/servlet/contentblob/38448/publicationFile/2659/Frequenznutzungsplan2008_Id17448pdf.pdf --# For the 5GHz range also see --# http://www.bundesnetzagentur.de/cae/servlet/contentblob/38216/publicationFile/6579/WLAN5GHzVfg7_2010_28042010pdf.pdf --# The values have been reduced by a factor of 2 (3db) for non TPC devices --# (in other words: devices with TPC can use twice the tx power of this table). --# Note that the docs do not require TPC for 5150--5250; the reduction to --# 100mW thus is not strictly required -- however the conservative 100mW -+# Allocation for the 2.4 GHz band (Vfg 10 / 2013, Allgemeinzuteilung von -+# Frequenzen für die Nutzung in lokalen Netzwerken; Wireless Local Area -+# Networks (WLAN-Funkanwendungen). -+# https://www.bundesnetzagentur.de/SharedDocs/Downloads/DE/Sachgebiete/Telekommunikation/Unternehmen_Institutionen/Frequenzen/Allgemeinzuteilungen/2013_10_WLAN_2,4GHz_pdf.pdf -+# -+# Allocation for the 5 GHz band (Vfg. 7 / 2010, Allgemeinzuteilung von -+# Frequenzen in den Bereichen 5150 MHz - 5350 MHz und 5470 MHz - 5725 MHz für -+# Funkanwendungen zur breitbandigen Datenübertragung, WAS/WLAN („Wireless -+# Access Systems including Wireless Local Area Networks“). -+# https://www.bundesnetzagentur.de/SharedDocs/Downloads/DE/Sachgebiete/Telekommunikation/Unternehmen_Institutionen/Frequenzen/Allgemeinzuteilungen/2010_07_WLAN_5GHz_pdf.pdf -+# The values for the 5 GHz have been reduced by a factor of 2 (3db) for non TPC -+# devices (in other words: devices with TPC can use twice the tx power of this -+# table). Note that the docs do not require TPC for 5150--5250; the reduction -+# to 100mW thus is not strictly required -- however the conservative 100mW - # limit is used here as the non-interference with radar and satellite - # apps relies on the attenuation by the building walls only in the - # absence of DFS; the neighbour countries have 100mW limit here as well. -+# -+# The ETSI EN 300 440-1 standard for short range devices in the 5 GHz band has -+# been implemented in Germany: -+# https://www.bundesnetzagentur.de/SharedDocs/Downloads/DE/Sachgebiete/Telekommunikation/Unternehmen_Institutionen/Frequenzen/Allgemeinzuteilungen/2014_69_SRD_pdf.pdf -+# -+# Allocation for the 60 GHz band (Allgemeinzuteilung von Frequenzen im -+# Bereich 57 GHz - 66 GHz für Funkanwendungen für weitbandige -+# Datenübertragungssysteme; „Multiple Gigabit WAS/RLAN Systems (MGWS)“). -+# https://www.bundesnetzagentur.de/SharedDocs/Downloads/DE/Sachgebiete/Telekommunikation/Unternehmen_Institutionen/Frequenzen/Allgemeinzuteilungen/2011_08_MGWS_pdf.pdf - - country DE: DFS-ETSI -- # entries 279004 and 280006 - (2400 - 2483.5 @ 40), (100 mW) -- # entry 303005 - (5150 - 5250 @ 80), (100 mW), NO-OUTDOOR, AUTO-BW -- # entries 304002 and 305002 - (5250 - 5350 @ 80), (100 mW), NO-OUTDOOR, DFS, AUTO-BW -- # entries 308002, 309001 and 310003 - (5470 - 5725 @ 160), (500 mW), DFS -- # 60 GHz band channels 1-4, ref: Etsi En 302 567 -+ # short range devices (ETSI EN 300 440-1) -+ (5725 - 5875 @ 80), (25 mW) -+ # 60 GHz band channels 1-4 (ETSI EN 302 567) - (57000 - 66000 @ 2160), (40) - - country DK: DFS-ETSI -@@ -629,6 +664,9 @@ country KR: DFS-JP - (5250 - 5330 @ 80), (20), DFS, AUTO-BW - (5490 - 5710 @ 160), (30), DFS - (5735 - 5835 @ 80), (30) -+ # 60 GHz band channels 1-4, -+ # ref: http://www.law.go.kr/%ED%96%89%EC%A0%95%EA%B7%9C%EC%B9%99/%EB%AC%B4%EC%84%A0%EC%84%A4%EB%B9%84%EA%B7%9C%EC%B9%99 -+ (57000 - 66000 @ 2160), (43) - - country KW: DFS-ETSI - (2402 - 2482 @ 40), (20) -@@ -844,11 +882,18 @@ country NI: DFS-FCC - (5490 - 5730 @ 160), (24), DFS - (5735 - 5835 @ 80), (30) - -+# Regulation on the use of frequency space without a license and -+# without notification 2015 -+# -+# http://wetten.overheid.nl/BWBR0036378/2015-03-05 -+ - country NL: DFS-ETSI - (2402 - 2482 @ 40), (20) - (5170 - 5250 @ 80), (20), NO-OUTDOOR, AUTO-BW - (5250 - 5330 @ 80), (20), NO-OUTDOOR, DFS, AUTO-BW - (5490 - 5710 @ 160), (27), DFS -+ # short range devices (ETSI EN 300 440-1) -+ (5725 - 5875 @ 80), (25 mW) - # 60 GHz band channels 1-4, ref: Etsi En 302 567 - (57000 - 66000 @ 2160), (40) - -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/006-add-basic-register-field-manipulation-macros.patch b/package/kernel/mac80211/patches/006-add-basic-register-field-manipulation-macros.patch -new file mode 100644 -index 0000000..a51edf8 ---- /dev/null -+++ b/package/kernel/mac80211/patches/006-add-basic-register-field-manipulation-macros.patch -@@ -0,0 +1,145 @@ -+From: Jakub Kicinski -+Date: Wed, 31 Aug 2016 12:46:44 +0100 -+Subject: [PATCH] add basic register-field manipulation macros -+ -+Common approach to accessing register fields is to define -+structures or sets of macros containing mask and shift pair. -+Operations on the register are then performed as follows: -+ -+ field = (reg >> shift) & mask; -+ -+ reg &= ~(mask << shift); -+ reg |= (field & mask) << shift; -+ -+Defining shift and mask separately is tedious. Ivo van Doorn -+came up with an idea of computing them at compilation time -+based on a single shifted mask (later refined by Felix) which -+can be used like this: -+ -+ #define REG_FIELD 0x000ff000 -+ -+ field = FIELD_GET(REG_FIELD, reg); -+ -+ reg &= ~REG_FIELD; -+ reg |= FIELD_PREP(REG_FIELD, field); -+ -+FIELD_{GET,PREP} macros take care of finding out what the -+appropriate shift is based on compilation time ffs operation. -+ -+GENMASK can be used to define registers (which is usually -+less error-prone and easier to match with datasheets). -+ -+This approach is the most convenient I've seen so to limit code -+multiplication let's move the macros to a global header file. -+Attempts to use static inlines instead of macros failed due -+to false positive triggering of BUILD_BUG_ON()s, especially with -+GCC < 6.0. -+ -+Signed-off-by: Jakub Kicinski -+Reviewed-by: Dinan Gunawardena -+--- -+ create mode 100644 include/linux/bitfield.h -+ -+--- /dev/null -++++ b/include/linux/bitfield.h -+@@ -0,0 +1,100 @@ -++/* -++ * Copyright (C) 2014 Felix Fietkau -++ * Copyright (C) 2004 - 2009 Ivo van Doorn -++ * -++ * This program is free software; you can redistribute it and/or modify -++ * it under the terms of the GNU General Public License version 2 -++ * as published by the Free Software Foundation -++ * -++ * This program is distributed in the hope that it will be useful, -++ * but WITHOUT ANY WARRANTY; without even the implied warranty of -++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -++ * GNU General Public License for more details. -++ */ -++ -++#ifndef _LINUX_BITFIELD_H -++#define _LINUX_BITFIELD_H -++ -++#include -++ -++#ifdef __CHECKER__ -++#define __BUILD_BUG_ON_NOT_POWER_OF_2(n) (0) -++#else -++#define __BUILD_BUG_ON_NOT_POWER_OF_2(n) \ -++ BUILD_BUG_ON(((n) & ((n) - 1)) != 0) -++#endif -++ -++/* -++ * Bitfield access macros -++ * -++ * FIELD_{GET,PREP} macros take as first parameter shifted mask -++ * from which they extract the base mask and shift amount. -++ * Mask must be a compilation time constant. -++ * -++ * Example: -++ * -++ * #define REG_FIELD_A GENMASK(6, 0) -++ * #define REG_FIELD_B BIT(7) -++ * #define REG_FIELD_C GENMASK(15, 8) -++ * #define REG_FIELD_D GENMASK(31, 16) -++ * -++ * Get: -++ * a = FIELD_GET(REG_FIELD_A, reg); -++ * b = FIELD_GET(REG_FIELD_B, reg); -++ * -++ * Set: -++ * reg = FIELD_PREP(REG_FIELD_A, 1) | -++ * FIELD_PREP(REG_FIELD_B, 0) | -++ * FIELD_PREP(REG_FIELD_C, c) | -++ * FIELD_PREP(REG_FIELD_D, 0x40); -++ * -++ * Modify: -++ * reg &= ~REG_FIELD_C; -++ * reg |= FIELD_PREP(REG_FIELD_C, c); -++ */ -++ -++#define __bf_shf(x) (__builtin_ffsll(x) - 1) -++ -++#define __BF_FIELD_CHECK(_mask, _reg, _val, _pfx) \ -++ ({ \ -++ BUILD_BUG_ON_MSG(!__builtin_constant_p(_mask), \ -++ _pfx "mask is not constant"); \ -++ BUILD_BUG_ON_MSG(!(_mask), _pfx "mask is zero"); \ -++ BUILD_BUG_ON_MSG(__builtin_constant_p(_val) ? \ -++ ~((_mask) >> __bf_shf(_mask)) & (_val) : 0, \ -++ _pfx "value too large for the field"); \ -++ BUILD_BUG_ON_MSG((_mask) > (typeof(_reg))~0ull, \ -++ _pfx "type of reg too small for mask"); \ -++ __BUILD_BUG_ON_NOT_POWER_OF_2((_mask) + \ -++ (1ULL << __bf_shf(_mask))); \ -++ }) -++ -++/** -++ * FIELD_PREP() - prepare a bitfield element -++ * @_mask: shifted mask defining the field's length and position -++ * @_val: value to put in the field -++ * -++ * FIELD_PREP() masks and shifts up the value. The result should -++ * be combined with other fields of the bitfield using logical OR. -++ */ -++#define FIELD_PREP(_mask, _val) \ -++ ({ \ -++ __BF_FIELD_CHECK(_mask, 0ULL, _val, "FIELD_PREP: "); \ -++ ((typeof(_mask))(_val) << __bf_shf(_mask)) & (_mask); \ -++ }) -++ -++/** -++ * FIELD_GET() - extract a bitfield element -++ * @_mask: shifted mask defining the field's length and position -++ * @_reg: 32bit value of entire bitfield -++ * -++ * FIELD_GET() extracts the field specified by @_mask from the -++ * bitfield passed in as @_reg by masking and shifting it down. -++ */ -++#define FIELD_GET(_mask, _reg) \ -++ ({ \ -++ __BF_FIELD_CHECK(_mask, _reg, 0U, "FIELD_GET: "); \ -++ (typeof(_mask))(((_reg) & (_mask)) >> __bf_shf(_mask)); \ -++ }) -++ -++#endif -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-fix-using-sta-drv_priv-before-initializing-it.patch b/package/kernel/mac80211/patches/320-ath9k-fix-using-sta-drv_priv-before-initializing-it.patch -new file mode 100644 -index 0000000..aaa6706 ---- /dev/null -+++ b/package/kernel/mac80211/patches/320-ath9k-fix-using-sta-drv_priv-before-initializing-it.patch -@@ -0,0 +1,33 @@ -+From: Felix Fietkau -+Date: Tue, 2 Aug 2016 13:00:01 +0200 -+Subject: [PATCH] ath9k: fix using sta->drv_priv before initializing it -+ -+A station pointer can be passed to the driver on tx, before it has been -+marked as associated. Since ath9k_sta_state was initializing the entry -+too late, it resulted in some spurious crashes. -+ -+Fixes: df3c6eb34da5 ("ath9k: Use sta_state() callback") -+Cc: stable@vger.kernel.org -+Signed-off-by: Felix Fietkau -+--- -+ -+--- a/drivers/net/wireless/ath/ath9k/main.c -++++ b/drivers/net/wireless/ath/ath9k/main.c -+@@ -1563,13 +1563,13 @@ static int ath9k_sta_state(struct ieee80 -+ struct ath_common *common = ath9k_hw_common(sc->sc_ah); -+ int ret = 0; -+ -+- if (old_state == IEEE80211_STA_AUTH && -+- new_state == IEEE80211_STA_ASSOC) { -++ if (old_state == IEEE80211_STA_NOTEXIST && -++ new_state == IEEE80211_STA_NONE) { -+ ret = ath9k_sta_add(hw, vif, sta); -+ ath_dbg(common, CONFIG, -+ "Add station: %pM\n", sta->addr); -+- } else if (old_state == IEEE80211_STA_ASSOC && -+- new_state == IEEE80211_STA_AUTH) { -++ } else if (old_state == IEEE80211_STA_NONE && -++ new_state == IEEE80211_STA_NOTEXIST) { -+ ret = ath9k_sta_remove(hw, vif, sta); -+ ath_dbg(common, CONFIG, -+ "Remove station: %pM\n", sta->addr); -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-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/331-mac80211-End-the-MPSP-even-if-EOSP-frame-was-not-rec.patch b/package/kernel/mac80211/patches/331-mac80211-End-the-MPSP-even-if-EOSP-frame-was-not-rec.patch -new file mode 100644 -index 0000000..5d8a8fb ---- /dev/null -+++ b/package/kernel/mac80211/patches/331-mac80211-End-the-MPSP-even-if-EOSP-frame-was-not-rec.patch -@@ -0,0 +1,42 @@ -+From: Masashi Honma -+Date: Wed, 13 Jul 2016 16:04:35 +0900 -+Subject: [PATCH] mac80211: End the MPSP even if EOSP frame was not received -+ -+The mesh STA sends QoS frame with EOSP (end of service period) -+subfiled=1 to end the MPSP(mesh peer service period). Previously, if -+the frame was not acked by peer, the mesh STA did not end the MPSP. -+This patch ends the MPSP even if the QoS frame was no acked. -+ -+Signed-off-by: Masashi Honma -+--- -+ -+--- a/net/mac80211/status.c -++++ b/net/mac80211/status.c -+@@ -784,6 +784,13 @@ void ieee80211_tx_status(struct ieee8021 -+ clear_sta_flag(sta, WLAN_STA_SP); -+ -+ acked = !!(info->flags & IEEE80211_TX_STAT_ACK); -++ -++ /* mesh Peer Service Period support */ -++ if (ieee80211_vif_is_mesh(&sta->sdata->vif) && -++ ieee80211_is_data_qos(fc)) -++ ieee80211_mpsp_trigger_process( -++ ieee80211_get_qos_ctl(hdr), sta, true, acked); -++ -+ if (!acked && test_sta_flag(sta, WLAN_STA_PS_STA)) { -+ /* -+ * The STA is in power save mode, so assume -+@@ -794,13 +801,6 @@ void ieee80211_tx_status(struct ieee8021 -+ return; -+ } -+ -+- /* mesh Peer Service Period support */ -+- if (ieee80211_vif_is_mesh(&sta->sdata->vif) && -+- ieee80211_is_data_qos(fc)) -+- ieee80211_mpsp_trigger_process( -+- ieee80211_get_qos_ctl(hdr), -+- sta, true, acked); -+- -+ if (ieee80211_hw_check(&local->hw, HAS_RATE_CONTROL) && -+ (ieee80211_is_data(hdr->frame_control)) && -+ (rates_idx != -1)) -diff --git a/package/kernel/mac80211/patches/332-ath10k-implement-NAPI-support.patch b/package/kernel/mac80211/patches/332-ath10k-implement-NAPI-support.patch -new file mode 100644 -index 0000000..c6cc145 ---- /dev/null -+++ b/package/kernel/mac80211/patches/332-ath10k-implement-NAPI-support.patch -@@ -0,0 +1,642 @@ -+From: Rajkumar Manoharan -+Date: Thu, 21 Jul 2016 11:50:00 +0530 -+Subject: [PATCH] ath10k: implement NAPI support -+ -+Add NAPI support for rx and tx completion. NAPI poll is scheduled -+from interrupt handler. The design is as below -+ -+ - on interrupt -+ - schedule napi and mask interrupts -+ - on poll -+ - process all pipes (no actual Tx/Rx) -+ - process Rx within budget -+ - if quota exceeds budget reschedule napi poll by returning budget -+ - process Tx completions and update budget if necessary -+ - process Tx fetch indications (pull-push) -+ - push any other pending Tx (if possible) -+ - before resched or napi completion replenish htt rx ring buffer -+ - if work done < budget, complete napi poll and unmask interrupts -+ -+This change also get rid of two tasklets (intr_tq and txrx_compl_task). -+ -+Measured peak throughput with NAPI on IPQ4019 platform in controlled -+environment. No noticeable reduction in throughput is seen and also -+observed improvements in CPU usage. Approx. 15% CPU usage got reduced -+in UDP uplink case. -+ -+DL: AP DUT Tx -+UL: AP DUT Rx -+ -+IPQ4019 (avg. cpu usage %) -+======== -+ TOT +NAPI -+ =========== ============= -+TCP DL 644 Mbps (42%) 645 Mbps (36%) -+TCP UL 673 Mbps (30%) 675 Mbps (26%) -+UDP DL 682 Mbps (49%) 680 Mbps (49%) -+UDP UL 720 Mbps (28%) 717 Mbps (11%) -+ -+Signed-off-by: Rajkumar Manoharan -+--- -+ -+--- a/drivers/net/wireless/ath/ath10k/ahb.c -++++ b/drivers/net/wireless/ath/ath10k/ahb.c -+@@ -462,13 +462,13 @@ static void ath10k_ahb_halt_chip(struct -+ static irqreturn_t ath10k_ahb_interrupt_handler(int irq, void *arg) -+ { -+ struct ath10k *ar = arg; -+- struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); -+ -+ if (!ath10k_pci_irq_pending(ar)) -+ return IRQ_NONE; -+ -+ ath10k_pci_disable_and_clear_legacy_irq(ar); -+- tasklet_schedule(&ar_pci->intr_tq); -++ ath10k_pci_irq_msi_fw_mask(ar); -++ napi_schedule(&ar->napi); -+ -+ return IRQ_HANDLED; -+ } -+@@ -831,7 +831,7 @@ static int ath10k_ahb_probe(struct platf -+ goto err_resource_deinit; -+ } -+ -+- ath10k_pci_init_irq_tasklets(ar); -++ ath10k_pci_init_napi(ar); -+ -+ ret = ath10k_ahb_request_irq_legacy(ar); -+ if (ret) -+--- a/drivers/net/wireless/ath/ath10k/core.c -++++ b/drivers/net/wireless/ath/ath10k/core.c -+@@ -2226,6 +2226,8 @@ struct ath10k *ath10k_core_create(size_t -+ INIT_WORK(&ar->register_work, ath10k_core_register_work); -+ INIT_WORK(&ar->restart_work, ath10k_core_restart); -+ -++ init_dummy_netdev(&ar->napi_dev); -++ -+ ret = ath10k_debug_create(ar); -+ if (ret) -+ goto err_free_aux_wq; -+--- a/drivers/net/wireless/ath/ath10k/core.h -++++ b/drivers/net/wireless/ath/ath10k/core.h -+@@ -65,6 +65,10 @@ -+ #define ATH10K_KEEPALIVE_MAX_IDLE 3895 -+ #define ATH10K_KEEPALIVE_MAX_UNRESPONSIVE 3900 -+ -++/* NAPI poll budget */ -++#define ATH10K_NAPI_BUDGET 64 -++#define ATH10K_NAPI_QUOTA_LIMIT 60 -++ -+ struct ath10k; -+ -+ enum ath10k_bus { -+@@ -933,6 +937,10 @@ struct ath10k { -+ struct ath10k_thermal thermal; -+ struct ath10k_wow wow; -+ -++ /* NAPI */ -++ struct net_device napi_dev; -++ struct napi_struct napi; -++ -+ /* must be last */ -+ u8 drv_priv[0] __aligned(sizeof(void *)); -+ }; -+--- a/drivers/net/wireless/ath/ath10k/htt.h -++++ b/drivers/net/wireless/ath/ath10k/htt.h -+@@ -1666,7 +1666,6 @@ struct ath10k_htt { -+ -+ /* This is used to group tx/rx completions separately and process them -+ * in batches to reduce cache stalls */ -+- struct tasklet_struct txrx_compl_task; -+ struct sk_buff_head rx_compl_q; -+ struct sk_buff_head rx_in_ord_compl_q; -+ struct sk_buff_head tx_fetch_ind_q; -+@@ -1799,5 +1798,6 @@ int ath10k_htt_tx(struct ath10k_htt *htt -+ struct sk_buff *msdu); -+ void ath10k_htt_rx_pktlog_completion_handler(struct ath10k *ar, -+ struct sk_buff *skb); -++int ath10k_htt_txrx_compl_task(struct ath10k *ar, int budget); -+ -+ #endif -+--- a/drivers/net/wireless/ath/ath10k/htt_rx.c -++++ b/drivers/net/wireless/ath/ath10k/htt_rx.c -+@@ -34,7 +34,6 @@ -+ #define HTT_RX_RING_REFILL_RESCHED_MS 5 -+ -+ static int ath10k_htt_rx_get_csum_state(struct sk_buff *skb); -+-static void ath10k_htt_txrx_compl_task(unsigned long ptr); -+ -+ static struct sk_buff * -+ ath10k_htt_rx_find_skb_paddr(struct ath10k *ar, u32 paddr) -+@@ -226,7 +225,6 @@ int ath10k_htt_rx_ring_refill(struct ath -+ void ath10k_htt_rx_free(struct ath10k_htt *htt) -+ { -+ del_timer_sync(&htt->rx_ring.refill_retry_timer); -+- tasklet_kill(&htt->txrx_compl_task); -+ -+ skb_queue_purge(&htt->rx_compl_q); -+ skb_queue_purge(&htt->rx_in_ord_compl_q); -+@@ -520,9 +518,6 @@ int ath10k_htt_rx_alloc(struct ath10k_ht -+ skb_queue_head_init(&htt->tx_fetch_ind_q); -+ atomic_set(&htt->num_mpdus_ready, 0); -+ -+- tasklet_init(&htt->txrx_compl_task, ath10k_htt_txrx_compl_task, -+- (unsigned long)htt); -+- -+ ath10k_dbg(ar, ATH10K_DBG_BOOT, "htt rx ring size %d fill_level %d\n", -+ htt->rx_ring.size, htt->rx_ring.fill_level); -+ return 0; -+@@ -958,7 +953,7 @@ static void ath10k_process_rx(struct ath -+ trace_ath10k_rx_hdr(ar, skb->data, skb->len); -+ trace_ath10k_rx_payload(ar, skb->data, skb->len); -+ -+- ieee80211_rx(ar->hw, skb); -++ ieee80211_rx_napi(ar->hw, NULL, skb, &ar->napi); -+ } -+ -+ static int ath10k_htt_rx_nwifi_hdrlen(struct ath10k *ar, -+@@ -1527,7 +1522,7 @@ static int ath10k_htt_rx_handle_amsdu(st -+ struct ath10k *ar = htt->ar; -+ struct ieee80211_rx_status *rx_status = &htt->rx_status; -+ struct sk_buff_head amsdu; -+- int ret; -++ int ret, num_msdus; -+ -+ __skb_queue_head_init(&amsdu); -+ -+@@ -1549,13 +1544,14 @@ static int ath10k_htt_rx_handle_amsdu(st -+ return ret; -+ } -+ -++ num_msdus = skb_queue_len(&amsdu); -+ 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); -+ -+- return 0; -++ return num_msdus; -+ } -+ -+ static void ath10k_htt_rx_proc_rx_ind(struct ath10k_htt *htt, -+@@ -1579,15 +1575,6 @@ static void ath10k_htt_rx_proc_rx_ind(st -+ mpdu_count += mpdu_ranges[i].mpdu_count; -+ -+ atomic_add(mpdu_count, &htt->num_mpdus_ready); -+- -+- tasklet_schedule(&htt->txrx_compl_task); -+-} -+- -+-static void ath10k_htt_rx_frag_handler(struct ath10k_htt *htt) -+-{ -+- atomic_inc(&htt->num_mpdus_ready); -+- -+- tasklet_schedule(&htt->txrx_compl_task); -+ } -+ -+ static void ath10k_htt_rx_tx_compl_ind(struct ath10k *ar, -+@@ -1772,14 +1759,15 @@ static void ath10k_htt_rx_h_rx_offload_p -+ RX_FLAG_MMIC_STRIPPED; -+ } -+ -+-static void ath10k_htt_rx_h_rx_offload(struct ath10k *ar, -+- struct sk_buff_head *list) -++static int ath10k_htt_rx_h_rx_offload(struct ath10k *ar, -++ struct sk_buff_head *list) -+ { -+ struct ath10k_htt *htt = &ar->htt; -+ struct ieee80211_rx_status *status = &htt->rx_status; -+ struct htt_rx_offload_msdu *rx; -+ struct sk_buff *msdu; -+ size_t offset; -++ int num_msdu = 0; -+ -+ while ((msdu = __skb_dequeue(list))) { -+ /* Offloaded frames don't have Rx descriptor. Instead they have -+@@ -1819,10 +1807,12 @@ static void ath10k_htt_rx_h_rx_offload(s -+ ath10k_htt_rx_h_rx_offload_prot(status, msdu); -+ ath10k_htt_rx_h_channel(ar, status, NULL, rx->vdev_id); -+ ath10k_process_rx(ar, status, msdu); -++ num_msdu++; -+ } -++ return num_msdu; -+ } -+ -+-static void ath10k_htt_rx_in_ord_ind(struct ath10k *ar, struct sk_buff *skb) -++static int ath10k_htt_rx_in_ord_ind(struct ath10k *ar, struct sk_buff *skb) -+ { -+ struct ath10k_htt *htt = &ar->htt; -+ struct htt_resp *resp = (void *)skb->data; -+@@ -1835,12 +1825,12 @@ static void ath10k_htt_rx_in_ord_ind(str -+ u8 tid; -+ bool offload; -+ bool frag; -+- int ret; -++ int ret, num_msdus = 0; -+ -+ lockdep_assert_held(&htt->rx_ring.lock); -+ -+ if (htt->rx_confused) -+- return; -++ return -EIO; -+ -+ skb_pull(skb, sizeof(resp->hdr)); -+ skb_pull(skb, sizeof(resp->rx_in_ord_ind)); -+@@ -1859,7 +1849,7 @@ static void ath10k_htt_rx_in_ord_ind(str -+ -+ if (skb->len < msdu_count * sizeof(*resp->rx_in_ord_ind.msdu_descs)) { -+ ath10k_warn(ar, "dropping invalid in order rx indication\n"); -+- return; -++ return -EINVAL; -+ } -+ -+ /* The event can deliver more than 1 A-MSDU. Each A-MSDU is later -+@@ -1870,14 +1860,14 @@ static void ath10k_htt_rx_in_ord_ind(str -+ if (ret < 0) { -+ ath10k_warn(ar, "failed to pop paddr list: %d\n", ret); -+ htt->rx_confused = true; -+- return; -++ return -EIO; -+ } -+ -+ /* Offloaded frames are very different and need to be handled -+ * separately. -+ */ -+ if (offload) -+- ath10k_htt_rx_h_rx_offload(ar, &list); -++ num_msdus = ath10k_htt_rx_h_rx_offload(ar, &list); -+ -+ while (!skb_queue_empty(&list)) { -+ __skb_queue_head_init(&amsdu); -+@@ -1890,6 +1880,7 @@ static void ath10k_htt_rx_in_ord_ind(str -+ * better to report something than nothing though. This -+ * should still give an idea about rx rate to the user. -+ */ -++ num_msdus += skb_queue_len(&amsdu); -+ ath10k_htt_rx_h_ppdu(ar, &amsdu, status, vdev_id); -+ ath10k_htt_rx_h_filter(ar, &amsdu, status); -+ ath10k_htt_rx_h_mpdu(ar, &amsdu, status); -+@@ -1902,9 +1893,10 @@ static void ath10k_htt_rx_in_ord_ind(str -+ ath10k_warn(ar, "failed to extract amsdu: %d\n", ret); -+ htt->rx_confused = true; -+ __skb_queue_purge(&list); -+- return; -++ return -EIO; -+ } -+ } -++ return num_msdus; -+ } -+ -+ static void ath10k_htt_rx_tx_fetch_resp_id_confirm(struct ath10k *ar, -+@@ -2267,7 +2259,6 @@ bool ath10k_htt_t2h_msg_handler(struct a -+ } -+ case HTT_T2H_MSG_TYPE_TX_COMPL_IND: -+ ath10k_htt_rx_tx_compl_ind(htt->ar, skb); -+- tasklet_schedule(&htt->txrx_compl_task); -+ break; -+ case HTT_T2H_MSG_TYPE_SEC_IND: { -+ struct ath10k *ar = htt->ar; -+@@ -2284,7 +2275,7 @@ bool ath10k_htt_t2h_msg_handler(struct a -+ case HTT_T2H_MSG_TYPE_RX_FRAG_IND: { -+ ath10k_dbg_dump(ar, ATH10K_DBG_HTT_DUMP, NULL, "htt event: ", -+ skb->data, skb->len); -+- ath10k_htt_rx_frag_handler(htt); -++ atomic_inc(&htt->num_mpdus_ready); -+ break; -+ } -+ case HTT_T2H_MSG_TYPE_TEST: -+@@ -2322,8 +2313,7 @@ bool ath10k_htt_t2h_msg_handler(struct a -+ break; -+ } -+ case HTT_T2H_MSG_TYPE_RX_IN_ORD_PADDR_IND: { -+- skb_queue_tail(&htt->rx_in_ord_compl_q, skb); -+- tasklet_schedule(&htt->txrx_compl_task); -++ __skb_queue_tail(&htt->rx_in_ord_compl_q, skb); -+ return false; -+ } -+ case HTT_T2H_MSG_TYPE_TX_CREDIT_UPDATE_IND: -+@@ -2349,7 +2339,6 @@ bool ath10k_htt_t2h_msg_handler(struct a -+ break; -+ } -+ skb_queue_tail(&htt->tx_fetch_ind_q, tx_fetch_ind); -+- tasklet_schedule(&htt->txrx_compl_task); -+ break; -+ } -+ case HTT_T2H_MSG_TYPE_TX_FETCH_CONFIRM: -+@@ -2378,27 +2367,77 @@ void ath10k_htt_rx_pktlog_completion_han -+ } -+ EXPORT_SYMBOL(ath10k_htt_rx_pktlog_completion_handler); -+ -+-static void ath10k_htt_txrx_compl_task(unsigned long ptr) -++int ath10k_htt_txrx_compl_task(struct ath10k *ar, int budget) -+ { -+- struct ath10k_htt *htt = (struct ath10k_htt *)ptr; -+- struct ath10k *ar = htt->ar; -++ struct ath10k_htt *htt = &ar->htt; -+ struct htt_tx_done tx_done = {}; -+- struct sk_buff_head rx_ind_q; -+ struct sk_buff_head tx_ind_q; -+ struct sk_buff *skb; -+ unsigned long flags; -+- int num_mpdus; -++ int quota = 0, done, num_rx_msdus; -++ bool resched_napi = false; -+ -+- __skb_queue_head_init(&rx_ind_q); -+ __skb_queue_head_init(&tx_ind_q); -+ -+- spin_lock_irqsave(&htt->rx_in_ord_compl_q.lock, flags); -+- skb_queue_splice_init(&htt->rx_in_ord_compl_q, &rx_ind_q); -+- spin_unlock_irqrestore(&htt->rx_in_ord_compl_q.lock, flags); -++ /* Since in-ord-ind can deliver more than 1 A-MSDU in single event, -++ * process it first to utilize full available quota. -++ */ -++ while (quota < budget) { -++ if (skb_queue_empty(&htt->rx_in_ord_compl_q)) -++ break; -+ -+- spin_lock_irqsave(&htt->tx_fetch_ind_q.lock, flags); -+- skb_queue_splice_init(&htt->tx_fetch_ind_q, &tx_ind_q); -+- spin_unlock_irqrestore(&htt->tx_fetch_ind_q.lock, flags); -++ skb = __skb_dequeue(&htt->rx_in_ord_compl_q); -++ if (!skb) { -++ resched_napi = true; -++ goto exit; -++ } -++ -++ spin_lock_bh(&htt->rx_ring.lock); -++ num_rx_msdus = ath10k_htt_rx_in_ord_ind(ar, skb); -++ spin_unlock_bh(&htt->rx_ring.lock); -++ if (num_rx_msdus < 0) { -++ resched_napi = true; -++ goto exit; -++ } -++ -++ dev_kfree_skb_any(skb); -++ if (num_rx_msdus > 0) -++ quota += num_rx_msdus; -++ -++ if ((quota > ATH10K_NAPI_QUOTA_LIMIT) && -++ !skb_queue_empty(&htt->rx_in_ord_compl_q)) { -++ resched_napi = true; -++ goto exit; -++ } -++ } -++ -++ while (quota < budget) { -++ /* no more data to receive */ -++ if (!atomic_read(&htt->num_mpdus_ready)) -++ break; -++ -++ num_rx_msdus = ath10k_htt_rx_handle_amsdu(htt); -++ if (num_rx_msdus < 0) { -++ resched_napi = true; -++ goto exit; -++ } -++ -++ quota += num_rx_msdus; -++ atomic_dec(&htt->num_mpdus_ready); -++ if ((quota > ATH10K_NAPI_QUOTA_LIMIT) && -++ atomic_read(&htt->num_mpdus_ready)) { -++ resched_napi = true; -++ goto exit; -++ } -++ } -++ -++ /* From NAPI documentation: -++ * The napi poll() function may also process TX completions, in which -++ * case if it processes the entire TX ring then it should count that -++ * work as the rest of the budget. -++ */ -++ if ((quota < budget) && !kfifo_is_empty(&htt->txdone_fifo)) -++ quota = budget; -+ -+ /* kfifo_get: called only within txrx_tasklet so it's neatly serialized. -+ * From kfifo_get() documentation: -+@@ -2408,27 +2447,22 @@ static void ath10k_htt_txrx_compl_task(u -+ while (kfifo_get(&htt->txdone_fifo, &tx_done)) -+ ath10k_txrx_tx_unref(htt, &tx_done); -+ -++ spin_lock_irqsave(&htt->tx_fetch_ind_q.lock, flags); -++ skb_queue_splice_init(&htt->tx_fetch_ind_q, &tx_ind_q); -++ spin_unlock_irqrestore(&htt->tx_fetch_ind_q.lock, flags); -++ -+ while ((skb = __skb_dequeue(&tx_ind_q))) { -+ ath10k_htt_rx_tx_fetch_ind(ar, skb); -+ dev_kfree_skb_any(skb); -+ } -+ -+- num_mpdus = atomic_read(&htt->num_mpdus_ready); -+- -+- while (num_mpdus) { -+- if (ath10k_htt_rx_handle_amsdu(htt)) -+- break; -+- -+- num_mpdus--; -+- atomic_dec(&htt->num_mpdus_ready); -+- } -+- -+- while ((skb = __skb_dequeue(&rx_ind_q))) { -+- spin_lock_bh(&htt->rx_ring.lock); -+- ath10k_htt_rx_in_ord_ind(ar, skb); -+- spin_unlock_bh(&htt->rx_ring.lock); -+- dev_kfree_skb_any(skb); -+- } -+- -++exit: -+ ath10k_htt_rx_msdu_buff_replenish(htt); -++ /* In case of rx failure or more data to read, report budget -++ * to reschedule NAPI poll -++ */ -++ done = resched_napi ? budget : quota; -++ -++ return done; -+ } -++EXPORT_SYMBOL(ath10k_htt_txrx_compl_task); -+--- a/drivers/net/wireless/ath/ath10k/htt_tx.c -++++ b/drivers/net/wireless/ath/ath10k/htt_tx.c -+@@ -388,8 +388,6 @@ 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); -+ -+--- a/drivers/net/wireless/ath/ath10k/pci.c -++++ b/drivers/net/wireless/ath/ath10k/pci.c -+@@ -1502,12 +1502,10 @@ void ath10k_pci_hif_send_complete_check( -+ ath10k_ce_per_engine_service(ar, pipe); -+ } -+ -+-void ath10k_pci_kill_tasklet(struct ath10k *ar) -++static void ath10k_pci_rx_retry_sync(struct ath10k *ar) -+ { -+ struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); -+ -+- tasklet_kill(&ar_pci->intr_tq); -+- -+ del_timer_sync(&ar_pci->rx_post_retry); -+ } -+ -+@@ -1566,7 +1564,7 @@ void ath10k_pci_hif_get_default_pipe(str -+ ul_pipe, dl_pipe); -+ } -+ -+-static void ath10k_pci_irq_msi_fw_mask(struct ath10k *ar) -++void ath10k_pci_irq_msi_fw_mask(struct ath10k *ar) -+ { -+ u32 val; -+ -+@@ -1747,7 +1745,7 @@ void ath10k_pci_ce_deinit(struct ath10k -+ -+ void ath10k_pci_flush(struct ath10k *ar) -+ { -+- ath10k_pci_kill_tasklet(ar); -++ ath10k_pci_rx_retry_sync(ar); -+ ath10k_pci_buffer_cleanup(ar); -+ } -+ -+@@ -2754,35 +2752,53 @@ static irqreturn_t ath10k_pci_interrupt_ -+ return IRQ_NONE; -+ } -+ -+- if (ar_pci->oper_irq_mode == ATH10K_PCI_IRQ_LEGACY) { -+- if (!ath10k_pci_irq_pending(ar)) -+- return IRQ_NONE; -+- -+- ath10k_pci_disable_and_clear_legacy_irq(ar); -+- } -++ if ((ar_pci->oper_irq_mode == ATH10K_PCI_IRQ_LEGACY) && -++ !ath10k_pci_irq_pending(ar)) -++ return IRQ_NONE; -+ -+- tasklet_schedule(&ar_pci->intr_tq); -++ ath10k_pci_disable_and_clear_legacy_irq(ar); -++ ath10k_pci_irq_msi_fw_mask(ar); -++ napi_schedule(&ar->napi); -+ -+ return IRQ_HANDLED; -+ } -+ -+-static void ath10k_pci_tasklet(unsigned long data) -++static int ath10k_pci_napi_poll(struct napi_struct *ctx, int budget) -+ { -+- struct ath10k *ar = (struct ath10k *)data; -+- struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); -++ struct ath10k *ar = container_of(ctx, struct ath10k, napi); -++ int done = 0; -+ -+ if (ath10k_pci_has_fw_crashed(ar)) { -+- ath10k_pci_irq_disable(ar); -+ ath10k_pci_fw_crashed_clear(ar); -+ ath10k_pci_fw_crashed_dump(ar); -+- return; -++ napi_complete(ctx); -++ return done; -+ } -+ -+ ath10k_ce_per_engine_service_any(ar); -+ -+- /* Re-enable legacy irq that was disabled in the irq handler */ -+- if (ar_pci->oper_irq_mode == ATH10K_PCI_IRQ_LEGACY) -++ done = ath10k_htt_txrx_compl_task(ar, budget); -++ -++ if (done < budget) { -++ napi_complete(ctx); -++ /* In case of MSI, it is possible that interrupts are received -++ * while NAPI poll is inprogress. So pending interrupts that are -++ * received after processing all copy engine pipes by NAPI poll -++ * will not be handled again. This is causing failure to -++ * complete boot sequence in x86 platform. So before enabling -++ * interrupts safer to check for pending interrupts for -++ * immediate servicing. -++ */ -++ if (CE_INTERRUPT_SUMMARY(ar)) { -++ napi_reschedule(&ar->napi); -++ goto out; -++ } -+ ath10k_pci_enable_legacy_irq(ar); -++ ath10k_pci_irq_msi_fw_unmask(ar); -++ } -++ -++out: -++ return done; -+ } -+ -+ static int ath10k_pci_request_irq_msi(struct ath10k *ar) -+@@ -2840,11 +2856,11 @@ static void ath10k_pci_free_irq(struct a -+ free_irq(ar_pci->pdev->irq, ar); -+ } -+ -+-void ath10k_pci_init_irq_tasklets(struct ath10k *ar) -++void ath10k_pci_init_napi(struct ath10k *ar) -+ { -+- struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); -+- -+- tasklet_init(&ar_pci->intr_tq, ath10k_pci_tasklet, (unsigned long)ar); -++ netif_napi_add(&ar->napi_dev, &ar->napi, ath10k_pci_napi_poll, -++ ATH10K_NAPI_BUDGET); -++ napi_enable(&ar->napi); -+ } -+ -+ static int ath10k_pci_init_irq(struct ath10k *ar) -+@@ -2852,7 +2868,7 @@ static int ath10k_pci_init_irq(struct at -+ struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); -+ int ret; -+ -+- ath10k_pci_init_irq_tasklets(ar); -++ ath10k_pci_init_napi(ar); -+ -+ if (ath10k_pci_irq_mode != ATH10K_PCI_IRQ_AUTO) -+ ath10k_info(ar, "limiting irq mode to: %d\n", -+@@ -3113,7 +3129,8 @@ int ath10k_pci_setup_resource(struct ath -+ -+ void ath10k_pci_release_resource(struct ath10k *ar) -+ { -+- ath10k_pci_kill_tasklet(ar); -++ ath10k_pci_rx_retry_sync(ar); -++ netif_napi_del(&ar->napi); -+ ath10k_pci_ce_deinit(ar); -+ ath10k_pci_free_pipes(ar); -+ } -+@@ -3274,7 +3291,7 @@ static int ath10k_pci_probe(struct pci_d -+ -+ err_free_irq: -+ ath10k_pci_free_irq(ar); -+- ath10k_pci_kill_tasklet(ar); -++ ath10k_pci_rx_retry_sync(ar); -+ -+ err_deinit_irq: -+ ath10k_pci_deinit_irq(ar); -+--- a/drivers/net/wireless/ath/ath10k/pci.h -++++ b/drivers/net/wireless/ath/ath10k/pci.h -+@@ -177,8 +177,6 @@ struct ath10k_pci { -+ /* Operating interrupt mode */ -+ enum ath10k_pci_irq_mode oper_irq_mode; -+ -+- struct tasklet_struct intr_tq; -+- -+ struct ath10k_pci_pipe pipe_info[CE_COUNT_MAX]; -+ -+ /* Copy Engine used for Diagnostic Accesses */ -+@@ -294,8 +292,7 @@ void ath10k_pci_free_pipes(struct ath10k -+ void ath10k_pci_free_pipes(struct ath10k *ar); -+ void ath10k_pci_rx_replenish_retry(unsigned long ptr); -+ void ath10k_pci_ce_deinit(struct ath10k *ar); -+-void ath10k_pci_init_irq_tasklets(struct ath10k *ar); -+-void ath10k_pci_kill_tasklet(struct ath10k *ar); -++void ath10k_pci_init_napi(struct ath10k *ar); -+ int ath10k_pci_init_pipes(struct ath10k *ar); -+ int ath10k_pci_init_config(struct ath10k *ar); -+ void ath10k_pci_rx_post(struct ath10k *ar); -+@@ -303,6 +300,7 @@ void ath10k_pci_flush(struct ath10k *ar) -+ void ath10k_pci_enable_legacy_irq(struct ath10k *ar); -+ bool ath10k_pci_irq_pending(struct ath10k *ar); -+ void ath10k_pci_disable_and_clear_legacy_irq(struct ath10k *ar); -++void ath10k_pci_irq_msi_fw_mask(struct ath10k *ar); -+ int ath10k_pci_wait_for_target_init(struct ath10k *ar); -+ int ath10k_pci_setup_resource(struct ath10k *ar); -+ void ath10k_pci_release_resource(struct ath10k *ar); -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-ath9k-fix-client-mode-beacon-configuration.patch b/package/kernel/mac80211/patches/333-ath9k-fix-client-mode-beacon-configuration.patch -new file mode 100644 -index 0000000..d008ceb ---- /dev/null -+++ b/package/kernel/mac80211/patches/333-ath9k-fix-client-mode-beacon-configuration.patch -@@ -0,0 +1,69 @@ -+From: Felix Fietkau -+Date: Tue, 26 Jul 2016 08:05:10 +0200 -+Subject: [PATCH] ath9k: fix client mode beacon configuration -+ -+For pure station mode, iter_data.primary_beacon_vif was used and passed -+to ath_beacon_config, but not set to the station vif. -+This was causing the following warning: -+ -+[ 100.310919] ------------[ cut here ]------------ -+[ 100.315683] WARNING: CPU: 0 PID: 7 at compat-wireless-2016-06-20/drivers/net/wireless/ath/ath9k/beacon.c:642 ath9k_calculate_summary_state+0x250/0x60c [ath9k]() -+[ 100.402028] CPU: 0 PID: 7 Comm: kworker/u2:1 Tainted: G W 4.4.15 #5 -+[ 100.409676] Workqueue: phy0 ieee80211_ibss_leave [mac80211] -+[ 100.415351] Stack : 8736e98c 870b4b20 87a25b54 800a6800 8782a080 80400d63 8039b96c 00000007 -+[ 100.415351] 803c5edc 87875914 80400000 800a47cc 87a25b54 800a6800 803a0fd8 80400000 -+[ 100.415351] 00000003 87875914 80400000 80094ae0 87a25b54 8787594c 00000000 801ef308 -+[ 100.415351] 803ffe70 801ef300 87193d58 87b3a400 87b3ad00 70687930 00000000 00000000 -+[ 100.415351] 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 -+[ 100.415351] ... -+[ 100.451703] Call Trace: -+[ 100.454235] [<800a6800>] vprintk_default+0x24/0x30 -+[ 100.459110] [<800a47cc>] printk+0x2c/0x38 -+[ 100.463190] [<800a6800>] vprintk_default+0x24/0x30 -+[ 100.468072] [<80094ae0>] print_worker_info+0x148/0x174 -+[ 100.473378] [<801ef308>] serial8250_console_putchar+0x0/0x44 -+[ 100.479122] [<801ef300>] wait_for_xmitr+0xc4/0xcc -+[ 100.484014] [<87193d58>] ieee80211_ibss_leave+0xb90/0x1900 [mac80211] -+[ 100.490590] [<80081604>] warn_slowpath_common+0xa0/0xd0 -+[ 100.495922] [<801a359c>] dump_stack+0x14/0x28 -+[ 100.500350] [<80071a00>] show_stack+0x50/0x84 -+[ 100.504784] [<80081604>] warn_slowpath_common+0xa0/0xd0 -+[ 100.510106] [<87024c60>] ath9k_calculate_summary_state+0x250/0x60c [ath9k] -+[ 100.517105] [<800816b8>] warn_slowpath_null+0x18/0x24 -+[ 100.522256] [<87024c60>] ath9k_calculate_summary_state+0x250/0x60c [ath9k] -+[ 100.529273] [<87025418>] ath9k_set_txpower+0x148/0x498 [ath9k] -+[ 100.535302] [<871d2c64>] cleanup_module+0xa74/0xd4c [mac80211] -+[ 100.541237] [<801ef308>] serial8250_console_putchar+0x0/0x44 -+[ 100.547042] [<800a5d18>] wake_up_klogd+0x54/0x68 -+[ 100.551730] [<800a6650>] vprintk_emit+0x404/0x43c -+[ 100.556623] [<871b9db8>] ieee80211_sta_rx_notify+0x258/0x32c [mac80211] -+[ 100.563475] [<871ba6a4>] ieee80211_sta_rx_queued_mgmt+0x63c/0x734 [mac80211] -+[ 100.570693] [<871aa49c>] ieee80211_tx_prepare_skb+0x210/0x230 [mac80211] -+[ 100.577609] [<800af5d4>] mod_timer+0x15c/0x190 -+[ 100.582220] [<871ba8b8>] ieee80211_sta_work+0xfc/0xe1c [mac80211] -+[ 100.588539] [<871940b4>] ieee80211_ibss_leave+0xeec/0x1900 [mac80211] -+[ 100.595122] [<8009ec84>] dequeue_task_fair+0x44/0x130 -+[ 100.600281] [<80092a34>] process_one_work+0x1f8/0x334 -+[ 100.605454] [<80093830>] worker_thread+0x2b4/0x408 -+[ 100.610317] [<8009357c>] worker_thread+0x0/0x408 -+[ 100.615019] [<8009357c>] worker_thread+0x0/0x408 -+[ 100.619705] [<80097b68>] kthread+0xdc/0xe8 -+[ 100.623886] [<80097a8c>] kthread+0x0/0xe8 -+[ 100.627961] [<80060878>] ret_from_kernel_thread+0x14/0x1c -+[ 100.633448] -+[ 100.634956] ---[ end trace aafbe57e9ae6862f ]--- -+ -+Fixes: cfda2d8e2314 ("ath9k: Fix beacon configuration for addition/removal of interfaces") -+Signed-off-by: Felix Fietkau -+--- -+ -+--- a/drivers/net/wireless/ath/ath9k/main.c -++++ b/drivers/net/wireless/ath/ath9k/main.c -+@@ -1154,6 +1154,7 @@ void ath9k_calculate_summary_state(struc -+ bool changed = (iter_data.primary_sta != ctx->primary_sta); -+ -+ if (iter_data.primary_sta) { -++ iter_data.primary_beacon_vif = iter_data.primary_sta; -+ iter_data.beacons = true; -+ ath9k_set_assoc_state(sc, iter_data.primary_sta, -+ changed); -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-purging-multicast-PS-buffer-queue.patch b/package/kernel/mac80211/patches/334-mac80211-fix-purging-multicast-PS-buffer-queue.patch -new file mode 100644 -index 0000000..dfcc6e4 ---- /dev/null -+++ b/package/kernel/mac80211/patches/334-mac80211-fix-purging-multicast-PS-buffer-queue.patch -@@ -0,0 +1,54 @@ -+From: Felix Fietkau -+Date: Tue, 2 Aug 2016 11:11:13 +0200 -+Subject: [PATCH] mac80211: fix purging multicast PS buffer queue -+ -+The code currently assumes that buffered multicast PS frames don't have -+a pending ACK frame for tx status reporting. -+However, hostapd sends a broadcast deauth frame on teardown for which tx -+status is requested. This can lead to the "Have pending ack frames" -+warning on module reload. -+Fix this by using ieee80211_free_txskb/ieee80211_purge_tx_queue. -+ -+Signed-off-by: Felix Fietkau -+--- -+ -+--- a/net/mac80211/cfg.c -++++ b/net/mac80211/cfg.c -+@@ -868,7 +868,7 @@ static int ieee80211_stop_ap(struct wiph -+ -+ /* free all potentially still buffered bcast frames */ -+ local->total_ps_buffered -= skb_queue_len(&sdata->u.ap.ps.bc_buf); -+- skb_queue_purge(&sdata->u.ap.ps.bc_buf); -++ ieee80211_purge_tx_queue(&local->hw, &sdata->u.ap.ps.bc_buf); -+ -+ mutex_lock(&local->mtx); -+ ieee80211_vif_copy_chanctx_to_vlans(sdata, true); -+--- a/net/mac80211/tx.c -++++ b/net/mac80211/tx.c -+@@ -368,7 +368,7 @@ static void purge_old_ps_buffers(struct -+ skb = skb_dequeue(&ps->bc_buf); -+ if (skb) { -+ purged++; -+- dev_kfree_skb(skb); -++ ieee80211_free_txskb(&local->hw, skb); -+ } -+ total += skb_queue_len(&ps->bc_buf); -+ } -+@@ -451,7 +451,7 @@ ieee80211_tx_h_multicast_ps_buf(struct i -+ if (skb_queue_len(&ps->bc_buf) >= AP_MAX_BC_BUFFER) { -+ ps_dbg(tx->sdata, -+ "BC TX buffer full - dropping the oldest frame\n"); -+- dev_kfree_skb(skb_dequeue(&ps->bc_buf)); -++ ieee80211_free_txskb(&tx->local->hw, skb_dequeue(&ps->bc_buf)); -+ } else -+ tx->local->total_ps_buffered++; -+ -+@@ -4276,7 +4276,7 @@ ieee80211_get_buffered_bc(struct ieee802 -+ sdata = IEEE80211_DEV_TO_SUB_IF(skb->dev); -+ if (!ieee80211_tx_prepare(sdata, &tx, NULL, skb)) -+ break; -+- dev_kfree_skb_any(skb); -++ ieee80211_free_txskb(hw, skb); -+ } -+ -+ info = IEEE80211_SKB_CB(skb); -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-ath9k-use-ieee80211_tx_status_noskb-where-possible.patch b/package/kernel/mac80211/patches/335-ath9k-use-ieee80211_tx_status_noskb-where-possible.patch -new file mode 100644 -index 0000000..dbb5b90 ---- /dev/null -+++ b/package/kernel/mac80211/patches/335-ath9k-use-ieee80211_tx_status_noskb-where-possible.patch -@@ -0,0 +1,305 @@ -+From: Felix Fietkau -+Date: Tue, 2 Aug 2016 12:12:18 +0200 -+Subject: [PATCH] ath9k: use ieee80211_tx_status_noskb where possible -+ -+It removes the need for undoing the padding changes to skb->data and it -+improves performance by eliminating one tx status lookup per MPDU in the -+status path. It is also useful for preparing a follow-up fix to better -+handle powersave filtering. -+ -+Signed-off-by: Felix Fietkau -+--- -+ -+--- a/drivers/net/wireless/ath/ath9k/xmit.c -++++ b/drivers/net/wireless/ath/ath9k/xmit.c -+@@ -50,9 +50,11 @@ static u16 bits_per_symbol[][2] = { -+ static void ath_tx_send_normal(struct ath_softc *sc, struct ath_txq *txq, -+ struct ath_atx_tid *tid, struct sk_buff *skb); -+ static void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb, -+- int tx_flags, struct ath_txq *txq); -++ int tx_flags, struct ath_txq *txq, -++ struct ieee80211_sta *sta); -+ static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf, -+ struct ath_txq *txq, struct list_head *bf_q, -++ struct ieee80211_sta *sta, -+ struct ath_tx_status *ts, int txok); -+ static void ath_tx_txqaddbuf(struct ath_softc *sc, struct ath_txq *txq, -+ struct list_head *head, bool internal); -+@@ -77,6 +79,22 @@ enum { -+ /* Aggregation logic */ -+ /*********************/ -+ -++static void ath_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb) -++{ -++ struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); -++ struct ieee80211_sta *sta = info->status.status_driver_data[0]; -++ -++ if (info->flags & IEEE80211_TX_CTL_REQ_TX_STATUS) { -++ ieee80211_tx_status(hw, skb); -++ return; -++ } -++ -++ if (sta) -++ ieee80211_tx_status_noskb(hw, sta, info); -++ -++ dev_kfree_skb(skb); -++} -++ -+ void ath_txq_lock(struct ath_softc *sc, struct ath_txq *txq) -+ __acquires(&txq->axq_lock) -+ { -+@@ -92,6 +110,7 @@ void ath_txq_unlock(struct ath_softc *sc -+ void ath_txq_unlock_complete(struct ath_softc *sc, struct ath_txq *txq) -+ __releases(&txq->axq_lock) -+ { -++ struct ieee80211_hw *hw = sc->hw; -+ struct sk_buff_head q; -+ struct sk_buff *skb; -+ -+@@ -100,7 +119,7 @@ void ath_txq_unlock_complete(struct ath_ -+ spin_unlock_bh(&txq->axq_lock); -+ -+ while ((skb = __skb_dequeue(&q))) -+- ieee80211_tx_status(sc->hw, skb); -++ ath_tx_status(hw, skb); -+ } -+ -+ static void ath_tx_queue_tid(struct ath_softc *sc, struct ath_txq *txq, -+@@ -268,7 +287,7 @@ static void ath_tx_flush_tid(struct ath_ -+ } -+ -+ list_add_tail(&bf->list, &bf_head); -+- ath_tx_complete_buf(sc, bf, txq, &bf_head, &ts, 0); -++ ath_tx_complete_buf(sc, bf, txq, &bf_head, NULL, &ts, 0); -+ } -+ -+ if (sendbar) { -+@@ -333,12 +352,12 @@ static void ath_tid_drain(struct ath_sof -+ bf = fi->bf; -+ -+ if (!bf) { -+- ath_tx_complete(sc, skb, ATH_TX_ERROR, txq); -++ ath_tx_complete(sc, skb, ATH_TX_ERROR, txq, NULL); -+ continue; -+ } -+ -+ list_add_tail(&bf->list, &bf_head); -+- ath_tx_complete_buf(sc, bf, txq, &bf_head, &ts, 0); -++ ath_tx_complete_buf(sc, bf, txq, &bf_head, NULL, &ts, 0); -+ } -+ } -+ -+@@ -441,12 +460,11 @@ static void ath_tx_count_frames(struct a -+ -+ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq, -+ struct ath_buf *bf, struct list_head *bf_q, -++ struct ieee80211_sta *sta, -+ struct ath_tx_status *ts, int txok) -+ { -+ struct ath_node *an = NULL; -+ struct sk_buff *skb; -+- struct ieee80211_sta *sta; -+- struct ieee80211_hw *hw = sc->hw; -+ struct ieee80211_hdr *hdr; -+ struct ieee80211_tx_info *tx_info; -+ struct ath_atx_tid *tid = NULL; -+@@ -475,12 +493,7 @@ static void ath_tx_complete_aggr(struct -+ for (i = 0; i < ts->ts_rateindex; i++) -+ retries += rates[i].count; -+ -+- rcu_read_lock(); -+- -+- sta = ieee80211_find_sta_by_ifaddr(hw, hdr->addr1, hdr->addr2); -+ if (!sta) { -+- rcu_read_unlock(); -+- -+ INIT_LIST_HEAD(&bf_head); -+ while (bf) { -+ bf_next = bf->bf_next; -+@@ -488,7 +501,7 @@ static void ath_tx_complete_aggr(struct -+ if (!bf->bf_state.stale || bf_next != NULL) -+ list_move_tail(&bf->list, &bf_head); -+ -+- ath_tx_complete_buf(sc, bf, txq, &bf_head, ts, 0); -++ ath_tx_complete_buf(sc, bf, txq, &bf_head, NULL, ts, 0); -+ -+ bf = bf_next; -+ } -+@@ -598,7 +611,7 @@ static void ath_tx_complete_aggr(struct -+ ts); -+ } -+ -+- ath_tx_complete_buf(sc, bf, txq, &bf_head, ts, -++ ath_tx_complete_buf(sc, bf, txq, &bf_head, sta, ts, -+ !txfail); -+ } else { -+ if (tx_info->flags & IEEE80211_TX_STATUS_EOSP) { -+@@ -619,7 +632,8 @@ static void ath_tx_complete_aggr(struct -+ ath_tx_update_baw(sc, tid, seqno); -+ -+ ath_tx_complete_buf(sc, bf, txq, -+- &bf_head, ts, 0); -++ &bf_head, NULL, ts, -++ 0); -+ bar_index = max_t(int, bar_index, -+ ATH_BA_INDEX(seq_first, seqno)); -+ break; -+@@ -663,8 +677,6 @@ static void ath_tx_complete_aggr(struct -+ ath_txq_lock(sc, txq); -+ } -+ -+- rcu_read_unlock(); -+- -+ if (needreset) -+ ath9k_queue_reset(sc, RESET_TYPE_TX_ERROR); -+ } -+@@ -679,7 +691,10 @@ static void ath_tx_process_buffer(struct -+ struct ath_tx_status *ts, struct ath_buf *bf, -+ struct list_head *bf_head) -+ { -++ struct ieee80211_hw *hw = sc->hw; -+ struct ieee80211_tx_info *info; -++ struct ieee80211_sta *sta; -++ struct ieee80211_hdr *hdr; -+ bool txok, flush; -+ -+ txok = !(ts->ts_status & ATH9K_TXERR_MASK); -+@@ -692,6 +707,10 @@ static void ath_tx_process_buffer(struct -+ -+ ts->duration = ath9k_hw_get_duration(sc->sc_ah, bf->bf_desc, -+ ts->ts_rateindex); -++ -++ hdr = (struct ieee80211_hdr *) bf->bf_mpdu->data; -++ sta = ieee80211_find_sta_by_ifaddr(hw, hdr->addr1, hdr->addr2); -++ -+ if (!bf_isampdu(bf)) { -+ if (!flush) { -+ info = IEEE80211_SKB_CB(bf->bf_mpdu); -+@@ -700,9 +719,9 @@ static void ath_tx_process_buffer(struct -+ ath_tx_rc_status(sc, bf, ts, 1, txok ? 0 : 1, txok); -+ ath_dynack_sample_tx_ts(sc->sc_ah, bf->bf_mpdu, ts); -+ } -+- ath_tx_complete_buf(sc, bf, txq, bf_head, ts, txok); -++ ath_tx_complete_buf(sc, bf, txq, bf_head, sta, ts, txok); -+ } else -+- ath_tx_complete_aggr(sc, txq, bf, bf_head, ts, txok); -++ ath_tx_complete_aggr(sc, txq, bf, bf_head, sta, ts, txok); -+ -+ if (!flush) -+ ath_txq_schedule(sc, txq); -+@@ -938,7 +957,7 @@ ath_tx_get_tid_subframe(struct ath_softc -+ 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); -++ ath_tx_complete_buf(sc, bf, txq, &bf_head, NULL, &ts, 0); -+ continue; -+ } -+ -+@@ -1847,6 +1866,7 @@ static void ath_drain_txq_list(struct at -+ */ -+ void ath_draintxq(struct ath_softc *sc, struct ath_txq *txq) -+ { -++ rcu_read_lock(); -+ ath_txq_lock(sc, txq); -+ -+ if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) { -+@@ -1865,6 +1885,7 @@ void ath_draintxq(struct ath_softc *sc, -+ ath_drain_txq_list(sc, txq, &txq->axq_q); -+ -+ ath_txq_unlock_complete(sc, txq); -++ rcu_read_unlock(); -+ } -+ -+ bool ath_drain_all_txq(struct ath_softc *sc) -+@@ -2487,7 +2508,8 @@ void ath_tx_cabq(struct ieee80211_hw *hw -+ /*****************/ -+ -+ static void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb, -+- int tx_flags, struct ath_txq *txq) -++ int tx_flags, struct ath_txq *txq, -++ struct ieee80211_sta *sta) -+ { -+ struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); -+ struct ath_common *common = ath9k_hw_common(sc->sc_ah); -+@@ -2507,15 +2529,17 @@ static void ath_tx_complete(struct ath_s -+ tx_info->flags |= IEEE80211_TX_STAT_ACK; -+ } -+ -+- padpos = ieee80211_hdrlen(hdr->frame_control); -+- padsize = padpos & 3; -+- if (padsize && skb->len>padpos+padsize) { -+- /* -+- * Remove MAC header padding before giving the frame back to -+- * mac80211. -+- */ -+- memmove(skb->data + padsize, skb->data, padpos); -+- skb_pull(skb, padsize); -++ if (tx_info->flags & IEEE80211_TX_CTL_REQ_TX_STATUS) { -++ padpos = ieee80211_hdrlen(hdr->frame_control); -++ padsize = padpos & 3; -++ if (padsize && skb->len>padpos+padsize) { -++ /* -++ * Remove MAC header padding before giving the frame back to -++ * mac80211. -++ */ -++ memmove(skb->data + padsize, skb->data, padpos); -++ skb_pull(skb, padsize); -++ } -+ } -+ -+ spin_lock_irqsave(&sc->sc_pm_lock, flags); -+@@ -2530,12 +2554,14 @@ static void ath_tx_complete(struct ath_s -+ } -+ spin_unlock_irqrestore(&sc->sc_pm_lock, flags); -+ -+- __skb_queue_tail(&txq->complete_q, skb); -+ ath_txq_skb_done(sc, txq, skb); -++ tx_info->status.status_driver_data[0] = sta; -++ __skb_queue_tail(&txq->complete_q, skb); -+ } -+ -+ static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf, -+ struct ath_txq *txq, struct list_head *bf_q, -++ struct ieee80211_sta *sta, -+ struct ath_tx_status *ts, int txok) -+ { -+ struct sk_buff *skb = bf->bf_mpdu; -+@@ -2563,7 +2589,7 @@ static void ath_tx_complete_buf(struct a -+ complete(&sc->paprd_complete); -+ } else { -+ ath_debug_stat_tx(sc, bf, ts, txq, tx_flags); -+- ath_tx_complete(sc, skb, tx_flags, txq); -++ ath_tx_complete(sc, skb, tx_flags, txq, sta); -+ } -+ skip_tx_complete: -+ /* At this point, skb (bf->bf_mpdu) is consumed...make sure we don't -+@@ -2715,10 +2741,12 @@ void ath_tx_tasklet(struct ath_softc *sc -+ u32 qcumask = ((1 << ATH9K_NUM_TX_QUEUES) - 1) & ah->intr_txqs; -+ int i; -+ -++ rcu_read_lock(); -+ for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) { -+ if (ATH_TXQ_SETUP(sc, i) && (qcumask & (1 << i))) -+ ath_tx_processq(sc, &sc->tx.txq[i]); -+ } -++ rcu_read_unlock(); -+ } -+ -+ void ath_tx_edma_tasklet(struct ath_softc *sc) -+@@ -2732,6 +2760,7 @@ void ath_tx_edma_tasklet(struct ath_soft -+ struct list_head *fifo_list; -+ int status; -+ -++ rcu_read_lock(); -+ for (;;) { -+ if (test_bit(ATH_OP_HW_RESET, &common->op_flags)) -+ break; -+@@ -2802,6 +2831,7 @@ void ath_tx_edma_tasklet(struct ath_soft -+ ath_tx_process_buffer(sc, txq, &ts, bf, &bf_head); -+ ath_txq_unlock_complete(sc, txq); -+ } -++ 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-ath9k-improve-powersave-filter-handling.patch b/package/kernel/mac80211/patches/336-ath9k-improve-powersave-filter-handling.patch -new file mode 100644 -index 0000000..67a6c63 ---- /dev/null -+++ b/package/kernel/mac80211/patches/336-ath9k-improve-powersave-filter-handling.patch -@@ -0,0 +1,70 @@ -+From: Felix Fietkau -+Date: Tue, 2 Aug 2016 12:13:35 +0200 -+Subject: [PATCH] ath9k: improve powersave filter handling -+ -+For non-aggregated frames, ath9k was leaving handling of powersave -+filtered packets to mac80211. This can be too slow if the intermediate -+queue is already filled with packets and mac80211 does not immediately -+send a new packet via drv_tx(). -+ -+Improve response time with filtered frames by triggering clearing the -+powersave filter internally. -+ -+Signed-off-by: Felix Fietkau -+--- -+ -+--- a/drivers/net/wireless/ath/ath9k/xmit.c -++++ b/drivers/net/wireless/ath/ath9k/xmit.c -+@@ -461,13 +461,13 @@ static void ath_tx_count_frames(struct a -+ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq, -+ struct ath_buf *bf, struct list_head *bf_q, -+ struct ieee80211_sta *sta, -++ struct ath_atx_tid *tid, -+ struct ath_tx_status *ts, int txok) -+ { -+ struct ath_node *an = NULL; -+ struct sk_buff *skb; -+ struct ieee80211_hdr *hdr; -+ struct ieee80211_tx_info *tx_info; -+- struct ath_atx_tid *tid = NULL; -+ struct ath_buf *bf_next, *bf_last = bf->bf_lastbf; -+ struct list_head bf_head; -+ struct sk_buff_head bf_pending; -+@@ -509,7 +509,6 @@ static void ath_tx_complete_aggr(struct -+ } -+ -+ an = (struct ath_node *)sta->drv_priv; -+- tid = ath_get_skb_tid(sc, an, skb); -+ seq_first = tid->seq_start; -+ isba = ts->ts_flags & ATH9K_TX_BA; -+ -+@@ -695,6 +694,7 @@ static void ath_tx_process_buffer(struct -+ struct ieee80211_tx_info *info; -+ struct ieee80211_sta *sta; -+ struct ieee80211_hdr *hdr; -++ struct ath_atx_tid *tid = NULL; -+ bool txok, flush; -+ -+ txok = !(ts->ts_status & ATH9K_TXERR_MASK); -+@@ -710,6 +710,12 @@ static void ath_tx_process_buffer(struct -+ -+ hdr = (struct ieee80211_hdr *) bf->bf_mpdu->data; -+ sta = ieee80211_find_sta_by_ifaddr(hw, hdr->addr1, hdr->addr2); -++ if (sta) { -++ struct ath_node *an = (struct ath_node *)sta->drv_priv; -++ tid = ath_get_skb_tid(sc, an, bf->bf_mpdu); -++ if (ts->ts_status & (ATH9K_TXERR_FILT | ATH9K_TXERR_XRETRY)) -++ tid->clear_ps_filter = true; -++ } -+ -+ if (!bf_isampdu(bf)) { -+ if (!flush) { -+@@ -721,7 +727,7 @@ static void ath_tx_process_buffer(struct -+ } -+ ath_tx_complete_buf(sc, bf, txq, bf_head, sta, ts, txok); -+ } else -+- ath_tx_complete_aggr(sc, txq, bf, bf_head, sta, ts, txok); -++ ath_tx_complete_aggr(sc, txq, bf, bf_head, sta, tid, ts, txok); -+ -+ if (!flush) -+ ath_txq_schedule(sc, txq); -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-ath9k-Switch-to-using-mac80211-intermediate-software.patch b/package/kernel/mac80211/patches/337-ath9k-Switch-to-using-mac80211-intermediate-software.patch -new file mode 100644 -index 0000000..adfd6df ---- /dev/null -+++ b/package/kernel/mac80211/patches/337-ath9k-Switch-to-using-mac80211-intermediate-software.patch -@@ -0,0 +1,951 @@ -+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,7 @@ 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_AN_2_TID(_an, _tidno) ath_node_to_tid(_an, _tidno) -+ -+ #define IS_HT_RATE(rate) (rate & 0x80) -+ #define IS_CCK_RATE(rate) ((rate >= 0x18) && (rate <= 0x1e)) -+@@ -164,7 +163,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 +230,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 +244,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 +273,6 @@ struct ath_tx_control { -+ struct ath_node *an; -+ struct ieee80211_sta *sta; -+ u8 paprd; -+- bool force_channel; -+ }; -+ -+ -+@@ -293,7 +289,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]; -+ }; -+ -+@@ -421,6 +416,22 @@ struct ath_offchannel { -+ int duration; -+ }; -+ -++static inline struct ath_atx_tid * -++ath_node_to_tid(struct ath_node *an, u8 tidno) -++{ -++ struct ieee80211_sta *sta = an->sta; -++ struct ieee80211_vif *vif = an->vif; -++ struct ieee80211_txq *txq; -++ -++ BUG_ON(!vif); -++ if (sta) -++ txq = sta->txq[tidno % ARRAY_SIZE(sta->txq)]; -++ else -++ txq = vif->txq; -++ -++ return (struct ath_atx_tid *) txq->drv_priv; -++} -++ -+ #define case_rtn_string(val) case val: return #val -+ -+ #define ath_for_each_chanctx(_sc, _ctx) \ -+@@ -575,7 +586,6 @@ void ath_tx_edma_tasklet(struct ath_soft -+ int ath_tx_aggr_start(struct ath_softc *sc, struct ieee80211_sta *sta, -+ u16 tid, u16 *ssn); -+ void ath_tx_aggr_stop(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid); -+-void ath_tx_aggr_resume(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid); -+ -+ void ath_tx_aggr_wakeup(struct ath_softc *sc, struct ath_node *an); -+ void ath_tx_aggr_sleep(struct ieee80211_sta *sta, struct ath_softc *sc, -+@@ -585,6 +595,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_node_to_tid(an, 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 -+@@ -1897,9 +1897,11 @@ static int ath9k_ampdu_action(struct iee -+ bool flush = false; -+ int ret = 0; -+ struct ieee80211_sta *sta = params->sta; -++ struct ath_node *an = (struct ath_node *)sta->drv_priv; -+ enum ieee80211_ampdu_mlme_action action = params->action; -+ u16 tid = params->tid; -+ u16 *ssn = ¶ms->ssn; -++ struct ath_atx_tid *atid; -+ -+ mutex_lock(&sc->mutex); -+ -+@@ -1932,9 +1934,9 @@ static int ath9k_ampdu_action(struct iee -+ ath9k_ps_restore(sc); -+ break; -+ case IEEE80211_AMPDU_TX_OPERATIONAL: -+- ath9k_ps_wakeup(sc); -+- ath_tx_aggr_resume(sc, sta, tid); -+- ath9k_ps_restore(sc); -++ atid = ath_node_to_tid(an, tid); -++ atid->baw_size = IEEE80211_MIN_AMPDU_BUF << -++ sta->ht_cap.ampdu_factor; -+ break; -+ default: -+ ath_err(ath9k_hw_common(sc->sc_ah), "Unknown AMPDU action\n"); -+@@ -2696,4 +2698,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 -+@@ -67,6 +67,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, -+@@ -137,6 +139,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); -+@@ -179,7 +201,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; -+ -+@@ -190,14 +211,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 * -+@@ -207,9 +220,48 @@ 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 ieee80211_txq *txq = container_of((void*)tid, struct ieee80211_txq, drv_priv); -++ 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, txq); -++ 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) -+@@ -218,46 +270,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; -+@@ -898,20 +915,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; -+ -+@@ -923,7 +936,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; -+@@ -952,8 +964,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 = {}; -+@@ -961,7 +984,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, NULL, &ts, 0); -+ continue; -+@@ -973,11 +995,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; -+@@ -987,12 +1008,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); -+ -+@@ -1001,12 +1023,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 */ -+@@ -1028,20 +1050,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; -+ -+@@ -1052,9 +1072,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 -+ } -+ -+@@ -1431,18 +1449,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; -+@@ -1451,13 +1466,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); -+@@ -1468,34 +1485,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; -+@@ -1538,9 +1554,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; -+@@ -1565,7 +1578,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); -+ } -+ -+@@ -1575,14 +1587,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_node_to_tid(an, tidno); -+ txq = tid->txq; -+ -+ ath_txq_lock(sc, txq); -+@@ -1592,13 +1602,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); -+ } -+ } -+ -+@@ -1611,49 +1620,20 @@ 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_node_to_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); -+ } -+ } -+ -+-void ath_tx_aggr_resume(struct ath_softc *sc, struct ieee80211_sta *sta, -+- u16 tidno) -+-{ -+- struct ath_common *common = ath9k_hw_common(sc->sc_ah); -+- struct ath_atx_tid *tid; -+- struct ath_node *an; -+- struct ath_txq *txq; -+- -+- ath_dbg(common, XMIT, "%s called\n", __func__); -+- -+- an = (struct ath_node *)sta->drv_priv; -+- tid = ATH_AN_2_TID(an, tidno); -+- txq = tid->txq; -+- -+- ath_txq_lock(sc, txq); -+- -+- 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); -+-} -+- -+ void ath9k_release_buffered_frames(struct ieee80211_hw *hw, -+ struct ieee80211_sta *sta, -+ u16 tids, int nframes, -+@@ -1666,7 +1646,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; -+ -+@@ -1681,11 +1660,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)) { -+@@ -1700,7 +1678,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); -+@@ -1929,13 +1907,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); -+ } -+ -+@@ -2334,16 +2306,14 @@ int ath_tx_start(struct ieee80211_hw *hw -+ struct ath_softc *sc = hw->priv; -+ struct ath_txq *txq = txctl->txq; -+ struct ath_atx_tid *tid = NULL; -++ struct ath_node *an = 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); -+@@ -2358,63 +2328,18 @@ int ath_tx_start(struct ieee80211_hw *hw -+ -+ q = skb_get_queue_mapping(skb); -+ -+- 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); -++ if (ps_resp) -+ 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); -++ if (txctl->sta) { -++ an = (struct ath_node *) sta->drv_priv; -++ tid = ath_get_skb_tid(sc, an, skb); -++ } -+ -+- ath_txq_schedule(sc, txq); -+- goto out; -++ ath_txq_lock(sc, txq); -++ if (txq == sc->tx.txq_map[q]) { -++ fi->txq = q; -++ ++txq->pending_frames; -+ } -+ -+ bf = ath_tx_setup_buffer(sc, txq, tid, skb); -+@@ -2907,9 +2832,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_node_to_tid(an, tidno); -+ tid->an = an; -+ tid->tidno = tidno; -+ tid->seq_start = tid->seq_next = 0; -+@@ -2917,11 +2841,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 */ -+ } -+ } -+ -+@@ -2931,9 +2858,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_node_to_tid(an, tidno); -+ txq = tid->txq; -+ -+ ath_txq_lock(sc, txq); -+@@ -2945,6 +2871,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/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/338-mac80211-fix-tim-recalculation-after-PS-response.patch b/package/kernel/mac80211/patches/338-mac80211-fix-tim-recalculation-after-PS-response.patch -new file mode 100644 -index 0000000..6c0852e ---- /dev/null -+++ b/package/kernel/mac80211/patches/338-mac80211-fix-tim-recalculation-after-PS-response.patch -@@ -0,0 +1,31 @@ -+From: Felix Fietkau -+Date: Fri, 26 Aug 2016 21:57:16 +0200 -+Subject: [PATCH] mac80211: fix tim recalculation after PS response -+ -+Handle the case where the mac80211 intermediate queues are empty and the -+driver has buffered frames -+ -+Fixes: ba8c3d6f16a1 ("mac80211: add an intermediate software queue implementation") -+Signed-off-by: Felix Fietkau -+--- -+ -+--- a/net/mac80211/sta_info.c -++++ b/net/mac80211/sta_info.c -+@@ -1616,7 +1616,6 @@ ieee80211_sta_ps_deliver_response(struct -+ -+ sta_info_recalc_tim(sta); -+ } else { -+- unsigned long tids = sta->txq_buffered_tids & driver_release_tids; -+ int tid; -+ -+ /* -+@@ -1648,7 +1647,8 @@ ieee80211_sta_ps_deliver_response(struct -+ for (tid = 0; tid < ARRAY_SIZE(sta->sta.txq); tid++) { -+ struct txq_info *txqi = to_txq_info(sta->sta.txq[tid]); -+ -+- if (!(tids & BIT(tid)) || txqi->tin.backlog_packets) -++ if (!(driver_release_tids & BIT(tid)) || -++ txqi->tin.backlog_packets) -+ continue; -+ -+ sta_info_recalc_tim(sta); -diff --git a/package/kernel/mac80211/patches/339-ath9k-fix-moredata-bit-in-PS-buffered-frame-release.patch b/package/kernel/mac80211/patches/339-ath9k-fix-moredata-bit-in-PS-buffered-frame-release.patch -new file mode 100644 -index 0000000..49b37e4 ---- /dev/null -+++ b/package/kernel/mac80211/patches/339-ath9k-fix-moredata-bit-in-PS-buffered-frame-release.patch -@@ -0,0 +1,49 @@ -+From: Felix Fietkau -+Date: Sun, 28 Aug 2016 13:13:01 +0200 -+Subject: [PATCH] ath9k: fix moredata bit in PS buffered frame release -+ -+Signed-off-by: Felix Fietkau -+--- -+ -+--- a/drivers/net/wireless/ath/ath9k/xmit.c -++++ b/drivers/net/wireless/ath/ath9k/xmit.c -+@@ -1634,6 +1634,21 @@ void ath_tx_aggr_wakeup(struct ath_softc -+ } -+ } -+ -++static void -++ath9k_set_moredata(struct ath_softc *sc, struct ath_buf *bf, bool val) -++{ -++ struct ieee80211_hdr *hdr; -++ u16 mask = cpu_to_le16(IEEE80211_FCTL_MOREDATA); -++ u16 mask_val = mask * val; -++ -++ hdr = (struct ieee80211_hdr *) bf->bf_mpdu->data; -++ if ((hdr->frame_control & mask) != mask_val) { -++ hdr->frame_control = (hdr->frame_control & ~mask) | mask_val; -++ dma_sync_single_for_device(sc->dev, bf->bf_buf_addr, -++ sizeof(*hdr), DMA_TO_DEVICE); -++ } -++} -++ -+ void ath9k_release_buffered_frames(struct ieee80211_hw *hw, -+ struct ieee80211_sta *sta, -+ u16 tids, int nframes, -+@@ -1664,6 +1679,7 @@ void ath9k_release_buffered_frames(struc -+ if (!bf) -+ break; -+ -++ ath9k_set_moredata(sc, bf, true); -+ list_add_tail(&bf->list, &bf_q); -+ ath_set_rates(tid->an->vif, tid->an->sta, bf, true); -+ if (bf_isampdu(bf)) { -+@@ -1687,6 +1703,9 @@ void ath9k_release_buffered_frames(struc -+ if (list_empty(&bf_q)) -+ return; -+ -++ if (!more_data) -++ ath9k_set_moredata(sc, bf_tail, false); -++ -+ info = IEEE80211_SKB_CB(bf_tail->bf_mpdu); -+ info->flags |= IEEE80211_TX_STATUS_EOSP; -+ -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-ath9k-clear-potentially-stale-EOSP-status-bit-in-int.patch b/package/kernel/mac80211/patches/340-ath9k-clear-potentially-stale-EOSP-status-bit-in-int.patch -new file mode 100644 -index 0000000..929da25 ---- /dev/null -+++ b/package/kernel/mac80211/patches/340-ath9k-clear-potentially-stale-EOSP-status-bit-in-int.patch -@@ -0,0 +1,22 @@ -+From: Felix Fietkau -+Date: Sun, 28 Aug 2016 13:13:42 +0200 -+Subject: [PATCH] ath9k: clear potentially stale EOSP status bit in -+ intermediate queues -+ -+Prevents spurious ieee80211_sta_eosp calls. -+ -+Signed-off-by: Felix Fietkau -+--- -+ -+--- a/drivers/net/wireless/ath/ath9k/xmit.c -++++ b/drivers/net/wireless/ath/ath9k/xmit.c -+@@ -945,7 +945,8 @@ ath_tx_get_tid_subframe(struct ath_softc -+ bf->bf_lastbf = bf; -+ -+ tx_info = IEEE80211_SKB_CB(skb); -+- tx_info->flags &= ~IEEE80211_TX_CTL_CLEAR_PS_FILT; -++ tx_info->flags &= ~(IEEE80211_TX_CTL_CLEAR_PS_FILT | -++ IEEE80211_TX_STATUS_EOSP); -+ -+ /* -+ * No aggregation session is running, but there may be frames -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-ath9k-release-PS-buffered-frames-as-A-MPDU-if-enable.patch b/package/kernel/mac80211/patches/341-ath9k-release-PS-buffered-frames-as-A-MPDU-if-enable.patch -new file mode 100644 -index 0000000..1cc1667 ---- /dev/null -+++ b/package/kernel/mac80211/patches/341-ath9k-release-PS-buffered-frames-as-A-MPDU-if-enable.patch -@@ -0,0 +1,40 @@ -+From: Felix Fietkau -+Date: Sun, 28 Aug 2016 13:15:10 +0200 -+Subject: [PATCH] ath9k: release PS buffered frames as A-MPDU if enabled -+ -+Signed-off-by: Felix Fietkau -+--- -+ -+--- a/drivers/net/wireless/ath/ath9k/xmit.c -++++ b/drivers/net/wireless/ath/ath9k/xmit.c -+@@ -1660,10 +1660,11 @@ void ath9k_release_buffered_frames(struc -+ struct ath_node *an = (struct ath_node *)sta->drv_priv; -+ struct ath_txq *txq = sc->tx.uapsdq; -+ struct ieee80211_tx_info *info; -++ struct ath_frame_info *fi; -+ struct list_head bf_q; -+ struct ath_buf *bf_tail = NULL, *bf; -+ int sent = 0; -+- int i; -++ int n, i; -+ -+ INIT_LIST_HEAD(&bf_q); -+ for (i = 0; tids && nframes; i++, tids >>= 1) { -+@@ -1683,10 +1684,15 @@ void ath9k_release_buffered_frames(struc -+ ath9k_set_moredata(sc, bf, true); -+ list_add_tail(&bf->list, &bf_q); -+ ath_set_rates(tid->an->vif, tid->an->sta, bf, true); -+- if (bf_isampdu(bf)) { -++ if (bf_isampdu(bf)) -+ ath_tx_addto_baw(sc, tid, bf); -+- bf->bf_state.bf_type &= ~BUF_AGGR; -++ if (bf_isaggr(bf)) { -++ fi = get_frame_info(bf->bf_mpdu); -++ n = ath_compute_num_delims(sc, tid, bf, -++ fi->framelen, true); -++ bf->bf_state.ndelim = n; -+ } -++ -+ if (bf_tail) -+ bf_tail->bf_next = bf; -+ -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-ath9k-report-tx-status-on-EOSP.patch b/package/kernel/mac80211/patches/342-ath9k-report-tx-status-on-EOSP.patch -new file mode 100644 -index 0000000..80a3074 ---- /dev/null -+++ b/package/kernel/mac80211/patches/342-ath9k-report-tx-status-on-EOSP.patch -@@ -0,0 +1,19 @@ -+From: Felix Fietkau -+Date: Sun, 28 Aug 2016 13:23:27 +0200 -+Subject: [PATCH] ath9k: report tx status on EOSP -+ -+Signed-off-by: Felix Fietkau -+--- -+ -+--- a/drivers/net/wireless/ath/ath9k/xmit.c -++++ b/drivers/net/wireless/ath/ath9k/xmit.c -+@@ -86,7 +86,8 @@ static void ath_tx_status(struct ieee802 -+ struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); -+ struct ieee80211_sta *sta = info->status.status_driver_data[0]; -+ -+- if (info->flags & IEEE80211_TX_CTL_REQ_TX_STATUS) { -++ if (info->flags & (IEEE80211_TX_CTL_REQ_TX_STATUS | -++ IEEE80211_TX_STATUS_EOSP)) { -+ ieee80211_tx_status(hw, skb); -+ return; -+ } -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-ath9k-fix-block-ack-window-tracking-issues.patch b/package/kernel/mac80211/patches/343-ath9k-fix-block-ack-window-tracking-issues.patch -new file mode 100644 -index 0000000..007a8d7d ---- /dev/null -+++ b/package/kernel/mac80211/patches/343-ath9k-fix-block-ack-window-tracking-issues.patch -@@ -0,0 +1,111 @@ -+From: Felix Fietkau -+Date: Tue, 30 Aug 2016 12:44:08 +0200 -+Subject: [PATCH] ath9k: fix block-ack window tracking issues -+ -+Ensure that a buffer gets tracked as part of the block-ack window as -+soon as it's dequeued from the tid for the first time. Ensure that -+double calls to ath_tx_addto_baw (e.g. on retransmission) don't cause -+any issues. -+ -+Signed-off-by: Felix Fietkau -+--- -+ -+--- a/drivers/net/wireless/ath/ath9k/xmit.c -++++ b/drivers/net/wireless/ath/ath9k/xmit.c -+@@ -62,7 +62,7 @@ static void ath_tx_rc_status(struct ath_ -+ struct ath_tx_status *ts, int nframes, int nbad, -+ int txok); -+ static void ath_tx_update_baw(struct ath_softc *sc, struct ath_atx_tid *tid, -+- int seqno); -++ struct ath_buf *bf); -+ static struct ath_buf *ath_tx_setup_buffer(struct ath_softc *sc, -+ struct ath_txq *txq, -+ struct ath_atx_tid *tid, -+@@ -300,7 +300,7 @@ static void ath_tx_flush_tid(struct ath_ -+ } -+ -+ if (fi->baw_tracked) { -+- ath_tx_update_baw(sc, tid, bf->bf_state.seqno); -++ ath_tx_update_baw(sc, tid, bf); -+ sendbar = true; -+ } -+ -+@@ -316,10 +316,15 @@ static void ath_tx_flush_tid(struct ath_ -+ } -+ -+ static void ath_tx_update_baw(struct ath_softc *sc, struct ath_atx_tid *tid, -+- int seqno) -++ struct ath_buf *bf) -+ { -++ struct ath_frame_info *fi = get_frame_info(bf->bf_mpdu); -++ u16 seqno = bf->bf_state.seqno; -+ int index, cindex; -+ -++ if (!fi->baw_tracked) -++ return; -++ -+ index = ATH_BA_INDEX(tid->seq_start, seqno); -+ cindex = (tid->baw_head + index) & (ATH_TID_MAX_BUFS - 1); -+ -+@@ -340,6 +345,9 @@ static void ath_tx_addto_baw(struct ath_ -+ u16 seqno = bf->bf_state.seqno; -+ int index, cindex; -+ -++ if (fi->baw_tracked) -++ return; -++ -+ index = ATH_BA_INDEX(tid->seq_start, seqno); -+ cindex = (tid->baw_head + index) & (ATH_TID_MAX_BUFS - 1); -+ __set_bit(cindex, tid->tx_buf); -+@@ -616,7 +624,7 @@ static void ath_tx_complete_aggr(struct -+ * complete the acked-ones/xretried ones; update -+ * block-ack window -+ */ -+- ath_tx_update_baw(sc, tid, seqno); -++ ath_tx_update_baw(sc, tid, bf); -+ -+ if (rc_update && (acked_cnt == 1 || txfail_cnt == 1)) { -+ memcpy(tx_info->control.rates, rates, sizeof(rates)); -+@@ -646,7 +654,7 @@ static void ath_tx_complete_aggr(struct -+ * run out of tx buf. -+ */ -+ if (!tbf) { -+- ath_tx_update_baw(sc, tid, seqno); -++ ath_tx_update_baw(sc, tid, bf); -+ -+ ath_tx_complete_buf(sc, bf, txq, -+ &bf_head, NULL, ts, -+@@ -986,11 +994,14 @@ ath_tx_get_tid_subframe(struct ath_softc -+ -+ INIT_LIST_HEAD(&bf_head); -+ list_add(&bf->list, &bf_head); -+- ath_tx_update_baw(sc, tid, seqno); -++ ath_tx_update_baw(sc, tid, bf); -+ ath_tx_complete_buf(sc, bf, txq, &bf_head, NULL, &ts, 0); -+ continue; -+ } -+ -++ if (bf_isampdu(bf)) -++ ath_tx_addto_baw(sc, tid, bf); -++ -+ return bf; -+ } -+ -+@@ -1048,8 +1059,6 @@ ath_tx_form_aggr(struct ath_softc *sc, s -+ bf->bf_next = NULL; -+ -+ /* link buffers of this frame to the aggregate */ -+- if (!fi->baw_tracked) -+- ath_tx_addto_baw(sc, tid, bf); -+ bf->bf_state.ndelim = ndelim; -+ -+ list_add_tail(&bf->list, bf_q); -+@@ -1685,8 +1694,6 @@ void ath9k_release_buffered_frames(struc -+ ath9k_set_moredata(sc, bf, true); -+ list_add_tail(&bf->list, &bf_q); -+ ath_set_rates(tid->an->vif, tid->an->sta, bf, true); -+- if (bf_isampdu(bf)) -+- ath_tx_addto_baw(sc, tid, bf); -+ if (bf_isaggr(bf)) { -+ fi = get_frame_info(bf->bf_mpdu); -+ n = ath_compute_num_delims(sc, tid, bf, -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-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-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 c529ff2..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 --@@ -40,7 +40,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-mac80211-send-delBA-on-unexpected-BlockAck-data-fram.patch b/package/kernel/mac80211/patches/344-mac80211-send-delBA-on-unexpected-BlockAck-data-fram.patch -new file mode 100644 -index 0000000..3bbca22 ---- /dev/null -+++ b/package/kernel/mac80211/patches/344-mac80211-send-delBA-on-unexpected-BlockAck-data-fram.patch -@@ -0,0 +1,64 @@ -+From: Johannes Berg -+Date: Mon, 29 Aug 2016 23:25:18 +0300 -+Subject: [PATCH] mac80211: send delBA on unexpected BlockAck data frames -+ -+When we receive data frames with ACK policy BlockAck, send -+delBA as requested by the 802.11 spec. Since this would be -+happening for every frame inside an A-MPDU if it's really -+received outside a session, limit it to a single attempt. -+ -+Signed-off-by: Johannes Berg -+--- -+ -+--- a/net/mac80211/agg-rx.c -++++ b/net/mac80211/agg-rx.c -+@@ -388,8 +388,10 @@ void __ieee80211_start_rx_ba_session(str -+ } -+ -+ end: -+- if (status == WLAN_STATUS_SUCCESS) -++ if (status == WLAN_STATUS_SUCCESS) { -+ __set_bit(tid, sta->ampdu_mlme.agg_session_valid); -++ __clear_bit(tid, sta->ampdu_mlme.unexpected_agg); -++ } -+ mutex_unlock(&sta->ampdu_mlme.mtx); -+ -+ end_no_lock: -+--- a/net/mac80211/rx.c -++++ b/net/mac80211/rx.c -+@@ -1072,8 +1072,15 @@ static void ieee80211_rx_reorder_ampdu(s -+ tid = *ieee80211_get_qos_ctl(hdr) & IEEE80211_QOS_CTL_TID_MASK; -+ -+ tid_agg_rx = rcu_dereference(sta->ampdu_mlme.tid_rx[tid]); -+- if (!tid_agg_rx) -++ if (!tid_agg_rx) { -++ if (ack_policy == IEEE80211_QOS_CTL_ACK_POLICY_BLOCKACK && -++ !test_bit(tid, rx->sta->ampdu_mlme.agg_session_valid) && -++ !test_and_set_bit(tid, rx->sta->ampdu_mlme.unexpected_agg)) -++ ieee80211_send_delba(rx->sdata, rx->sta->sta.addr, tid, -++ WLAN_BACK_RECIPIENT, -++ WLAN_REASON_QSTA_REQUIRE_SETUP); -+ goto dont_reorder; -++ } -+ -+ /* qos null data frames are excluded */ -+ if (unlikely(hdr->frame_control & cpu_to_le16(IEEE80211_STYPE_NULLFUNC))) -+--- a/net/mac80211/sta_info.h -++++ b/net/mac80211/sta_info.h -+@@ -230,6 +230,8 @@ struct tid_ampdu_rx { -+ * @tid_rx_stop_requested: bitmap indicating which BA sessions per TID the -+ * driver requested to close until the work for it runs -+ * @agg_session_valid: bitmap indicating which TID has a rx BA session open on -++ * @unexpected_agg: bitmap indicating which TID already sent a delBA due to -++ * unexpected aggregation related frames outside a session -+ * @work: work struct for starting/stopping aggregation -+ * @tid_tx: aggregation info for Tx per TID -+ * @tid_start_tx: sessions where start was requested -+@@ -244,6 +246,7 @@ struct sta_ampdu_mlme { -+ unsigned long tid_rx_timer_expired[BITS_TO_LONGS(IEEE80211_NUM_TIDS)]; -+ unsigned long tid_rx_stop_requested[BITS_TO_LONGS(IEEE80211_NUM_TIDS)]; -+ unsigned long agg_session_valid[BITS_TO_LONGS(IEEE80211_NUM_TIDS)]; -++ unsigned long unexpected_agg[BITS_TO_LONGS(IEEE80211_NUM_TIDS)]; -+ /* tx */ -+ struct work_struct work; -+ struct tid_ampdu_tx __rcu *tid_tx[IEEE80211_NUM_TIDS]; -diff --git a/package/kernel/mac80211/patches/345-brcmfmac-insert-default-boardrev-in-nvram-data-if-mi.patch b/package/kernel/mac80211/patches/345-brcmfmac-insert-default-boardrev-in-nvram-data-if-mi.patch -deleted file mode 100644 -index f293401..0000000 ---- a/package/kernel/mac80211/patches/345-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/345-mac80211-send-delBA-on-unexpected-BlockAck-Request.patch b/package/kernel/mac80211/patches/345-mac80211-send-delBA-on-unexpected-BlockAck-Request.patch -new file mode 100644 -index 0000000..c3d3118 ---- /dev/null -+++ b/package/kernel/mac80211/patches/345-mac80211-send-delBA-on-unexpected-BlockAck-Request.patch -@@ -0,0 +1,26 @@ -+From: Johannes Berg -+Date: Mon, 29 Aug 2016 23:25:19 +0300 -+Subject: [PATCH] mac80211: send delBA on unexpected BlockAck Request -+ -+If we don't have a BA session, send delBA, as requested by the -+IEEE 802.11 spec. Apply the same limit of sending such a delBA -+only once as in the previous patch. -+ -+Signed-off-by: Johannes Berg -+--- -+ -+--- a/net/mac80211/rx.c -++++ b/net/mac80211/rx.c -+@@ -2537,6 +2537,12 @@ ieee80211_rx_h_ctrl(struct ieee80211_rx_ -+ -+ tid = le16_to_cpu(bar_data.control) >> 12; -+ -++ if (!test_bit(tid, rx->sta->ampdu_mlme.agg_session_valid) && -++ !test_and_set_bit(tid, rx->sta->ampdu_mlme.unexpected_agg)) -++ ieee80211_send_delba(rx->sdata, rx->sta->sta.addr, tid, -++ WLAN_BACK_RECIPIENT, -++ WLAN_REASON_QSTA_REQUIRE_SETUP); -++ -+ tid_agg_rx = rcu_dereference(rx->sta->ampdu_mlme.tid_rx[tid]); -+ if (!tid_agg_rx) -+ return RX_DROP_MONITOR; -diff --git a/package/kernel/mac80211/patches/346-mac80211-fix-sequence-number-assignment-for-PS-respo.patch b/package/kernel/mac80211/patches/346-mac80211-fix-sequence-number-assignment-for-PS-respo.patch -new file mode 100644 -index 0000000..a82d12f ---- /dev/null -+++ b/package/kernel/mac80211/patches/346-mac80211-fix-sequence-number-assignment-for-PS-respo.patch -@@ -0,0 +1,107 @@ -+From: Felix Fietkau -+Date: Sun, 4 Sep 2016 17:46:24 +0200 -+Subject: [PATCH] mac80211: fix sequence number assignment for PS response -+ frames -+ -+When using intermediate queues, sequence number allocation is deferred -+until dequeue. This doesn't work for PS response frames, which bypass -+those queues. -+ -+Signed-off-by: Felix Fietkau -+--- -+ -+--- a/net/mac80211/tx.c -++++ b/net/mac80211/tx.c -+@@ -792,6 +792,36 @@ static __le16 ieee80211_tx_next_seq(stru -+ return ret; -+ } -+ -++static struct txq_info *ieee80211_get_txq(struct ieee80211_local *local, -++ struct ieee80211_vif *vif, -++ struct ieee80211_sta *pubsta, -++ struct sk_buff *skb) -++{ -++ struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; -++ struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); -++ struct ieee80211_txq *txq = NULL; -++ -++ if ((info->flags & IEEE80211_TX_CTL_SEND_AFTER_DTIM) || -++ (info->control.flags & IEEE80211_TX_CTRL_PS_RESPONSE)) -++ return NULL; -++ -++ if (!ieee80211_is_data(hdr->frame_control)) -++ return NULL; -++ -++ if (pubsta) { -++ u8 tid = skb->priority & IEEE80211_QOS_CTL_TID_MASK; -++ -++ txq = pubsta->txq[tid]; -++ } else if (vif) { -++ txq = vif->txq; -++ } -++ -++ if (!txq) -++ return NULL; -++ -++ return to_txq_info(txq); -++} -++ -+ static ieee80211_tx_result debug_noinline -+ ieee80211_tx_h_sequence(struct ieee80211_tx_data *tx) -+ { -+@@ -849,7 +879,8 @@ ieee80211_tx_h_sequence(struct ieee80211 -+ tid = *qc & IEEE80211_QOS_CTL_TID_MASK; -+ tx->sta->tx_stats.msdu[tid]++; -+ -+- if (!tx->sta->sta.txq[0]) -++ if (!ieee80211_get_txq(tx->local, info->control.vif, &tx->sta->sta, -++ tx->skb)) -+ hdr->seq_ctrl = ieee80211_tx_next_seq(tx->sta, tid); -+ -+ return TX_CONTINUE; -+@@ -1238,36 +1269,6 @@ ieee80211_tx_prepare(struct ieee80211_su -+ return TX_CONTINUE; -+ } -+ -+-static struct txq_info *ieee80211_get_txq(struct ieee80211_local *local, -+- struct ieee80211_vif *vif, -+- struct ieee80211_sta *pubsta, -+- struct sk_buff *skb) -+-{ -+- struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; -+- struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); -+- struct ieee80211_txq *txq = NULL; -+- -+- if ((info->flags & IEEE80211_TX_CTL_SEND_AFTER_DTIM) || -+- (info->control.flags & IEEE80211_TX_CTRL_PS_RESPONSE)) -+- return NULL; -+- -+- if (!ieee80211_is_data(hdr->frame_control)) -+- return NULL; -+- -+- if (pubsta) { -+- u8 tid = skb->priority & IEEE80211_QOS_CTL_TID_MASK; -+- -+- txq = pubsta->txq[tid]; -+- } else if (vif) { -+- txq = vif->txq; -+- } -+- -+- if (!txq) -+- return NULL; -+- -+- return to_txq_info(txq); -+-} -+- -+ static void ieee80211_set_skb_enqueue_time(struct sk_buff *skb) -+ { -+ IEEE80211_SKB_CB(skb)->control.enqueue_time = codel_get_time(); -+@@ -3265,7 +3266,7 @@ static bool ieee80211_xmit_fast(struct i -+ -+ if (hdr->frame_control & cpu_to_le16(IEEE80211_STYPE_QOS_DATA)) { -+ *ieee80211_get_qos_ctl(hdr) = tid; -+- if (!sta->sta.txq[0]) -++ if (!ieee80211_get_txq(local, &sdata->vif, &sta->sta, skb)) -+ hdr->seq_ctrl = ieee80211_tx_next_seq(sta, tid); -+ } else { -+ info->flags |= IEEE80211_TX_CTL_ASSIGN_SEQ; -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..69147f6 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 -+@@ -827,6 +827,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 -+@@ -963,6 +966,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 { -+@@ -1015,9 +1025,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..6edef09 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 -+@@ -1067,6 +1075,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..1330dfe ---- /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" -+@@ -973,6 +974,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; -+@@ -1027,6 +1036,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..f86b015 ---- /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 -+@@ -1038,6 +1038,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-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 00181f6..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 --@@ -1332,6 +1332,7 @@ static int __init brcmfmac_module_init(v -- #endif -- 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 4295b4b..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 --@@ -615,9 +615,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(-EEXIST); --+ } --+ -- 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/kernel/mwlwifi/Makefile b/package/kernel/mwlwifi/Makefile -index 091928d..b36486d 100644 ---- a/package/kernel/mwlwifi/Makefile -+++ b/package/kernel/mwlwifi/Makefile -@@ -8,7 +8,7 @@ - include $(TOPDIR)/rules.mk - - PKG_NAME:=mwlwifi --PKG_VERSION:=10.3.0.16-20160105 -+PKG_VERSION:=10.3.0.18-20160823-1 - PKG_RELEASE=1 - - PKG_LICENSE:=ISC -@@ -17,7 +17,7 @@ PKG_LICENSE_FILES:= - PKG_SOURCE_URL:=https://github.com/kaloz/mwlwifi - PKG_SOURCE_PROTO:=git - PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION) --PKG_SOURCE_VERSION:=99d3879cc72f2a25d44fb4bee96fd84eca028b04 -+PKG_SOURCE_VERSION:=af606563453c819fac156faf2b15b9caef844329 - PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)-$(PKG_SOURCE_VERSION).tar.xz - - PKG_MAINTAINER:=Imre Kaloz -@@ -29,7 +29,7 @@ include $(INCLUDE_DIR)/package.mk - define KernelPackage/mwlwifi - SUBMENU:=Wireless Drivers - TITLE:=Marvell 88W8864 wireless driver -- DEPENDS:=+kmod-mac80211 +@DRIVER_11N_SUPPORT @PCI_SUPPORT @TARGET_mvebu -+ DEPENDS:=+kmod-mac80211 +@DRIVER_11N_SUPPORT +@DRIVER_11W_SUPPORT @PCI_SUPPORT @TARGET_mvebu - FILES:=$(PKG_BUILD_DIR)/mwlwifi.ko - AUTOLOAD:=$(call AutoLoad,50,mac80211 mwlwifi) - endef -diff --git a/package/kernel/mwlwifi/patches/100-drop_old_api.patch b/package/kernel/mwlwifi/patches/100-drop_old_api.patch -deleted file mode 100644 -index d2e149e..0000000 ---- a/package/kernel/mwlwifi/patches/100-drop_old_api.patch -+++ /dev/null -@@ -1,92 +0,0 @@ ----- a/main.c --+++ b/main.c --@@ -418,11 +418,7 @@ static void mwl_set_ht_caps(struct mwl_p -- band->ht_cap.cap |= IEEE80211_HT_CAP_SGI_20; -- band->ht_cap.cap |= IEEE80211_HT_CAP_SGI_40; -- ---#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 2, 0) --- hw->flags |= IEEE80211_HW_AMPDU_AGGREGATION; ---#else -- ieee80211_hw_set(hw, AMPDU_AGGREGATION); ---#endif -- band->ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K; -- band->ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_4; -- --@@ -524,29 +520,16 @@ static int mwl_wl_init(struct mwl_priv * -- hw->queues = SYSADPT_TX_WMM_QUEUES; -- -- /* Set rssi values to dBm */ ---#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 2, 0) --- hw->flags |= IEEE80211_HW_SIGNAL_DBM | IEEE80211_HW_HAS_RATE_CONTROL; ---#else -- ieee80211_hw_set(hw, SIGNAL_DBM); -- ieee80211_hw_set(hw, HAS_RATE_CONTROL); ---#endif -- -- /* Ask mac80211 not to trigger PS mode -- * based on PM bit of incoming frames. -- */ ---#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 2, 0) --- hw->flags |= IEEE80211_HW_AP_LINK_PS; ---#else -- ieee80211_hw_set(hw, AP_LINK_PS); ---#endif -- ---#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 2, 0) --- hw->flags |= IEEE80211_HW_SUPPORTS_PER_STA_GTK | --- IEEE80211_HW_MFP_CAPABLE; ---#else -- ieee80211_hw_set(hw, SUPPORTS_PER_STA_GTK); -- ieee80211_hw_set(hw, MFP_CAPABLE); ---#endif -- -- hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN; -- ----- a/dev.h --+++ b/dev.h --@@ -484,10 +484,6 @@ static inline struct mwl_sta *mwl_dev_ge -- return (struct mwl_sta *)&sta->drv_priv; -- } -- ---#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 14, 0) ---#define ether_addr_copy(dst, src) memcpy(dst, src, ETH_ALEN) ---#endif --- -- /* Defined in mac80211.c. */ -- extern const struct ieee80211_ops mwl_mac80211_ops; -- ----- a/mac80211.c --+++ b/mac80211.c --@@ -572,19 +572,11 @@ static int mwl_mac80211_get_survey(struc -- return 0; -- } -- ---#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 3, 0) ---static int mwl_mac80211_ampdu_action(struct ieee80211_hw *hw, --- struct ieee80211_vif *vif, --- enum ieee80211_ampdu_mlme_action action, --- struct ieee80211_sta *sta, --- u16 tid, u16 *ssn, u8 buf_size) ---#else -- static int mwl_mac80211_ampdu_action(struct ieee80211_hw *hw, -- struct ieee80211_vif *vif, -- enum ieee80211_ampdu_mlme_action action, -- struct ieee80211_sta *sta, -- u16 tid, u16 *ssn, u8 buf_size, bool amsdu) ---#endif -- { -- int rc = 0; -- struct mwl_priv *priv = hw->priv; ----- a/rx.c --+++ b/rx.c --@@ -232,10 +232,8 @@ static inline void mwl_rx_prepare_status -- status->flag |= RX_FLAG_VHT; -- if (bw == RX_RATE_INFO_HT40) -- status->flag |= RX_FLAG_40MHZ; ---#if LINUX_VERSION_CODE > KERNEL_VERSION(3, 18, 0) -- if (bw == RX_RATE_INFO_HT80) -- status->vht_flag |= RX_VHT_FLAG_80MHZ; ---#endif -- if (gi == RX_RATE_INFO_SHORT_INTERVAL) -- status->flag |= RX_FLAG_SHORT_GI; -- status->vht_nss = (nss + 1); -diff --git a/package/kernel/mwlwifi/patches/110-api_sync.patch b/package/kernel/mwlwifi/patches/110-api_sync.patch -deleted file mode 100644 -index ed3e06a..0000000 ---- a/package/kernel/mwlwifi/patches/110-api_sync.patch -+++ /dev/null -@@ -1,19 +0,0 @@ ----- a/mac80211.c --+++ b/mac80211.c --@@ -597,10 +597,13 @@ static int mwl_mac80211_get_survey(struc -- -- static int mwl_mac80211_ampdu_action(struct ieee80211_hw *hw, -- struct ieee80211_vif *vif, --- enum ieee80211_ampdu_mlme_action action, --- struct ieee80211_sta *sta, --- u16 tid, u16 *ssn, u8 buf_size, bool amsdu) --+ struct ieee80211_ampdu_params *params) -- { --+ enum ieee80211_ampdu_mlme_action action = params->action; --+ struct ieee80211_sta *sta = params->sta; --+ u16 tid = params->tid; --+ u16 *ssn = ¶ms->ssn; --+ u8 buf_size = params->buf_size; -- int rc = 0; -- struct mwl_priv *priv = hw->priv; -- struct mwl_ampdu_stream *stream; -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 <