diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 824362d7..1c827fb2 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -46,24 +46,8 @@ fix some bug, detail in the remaining commit message exactly how it could be
triggered and what you did to fix it. If in question, have a glance at the
existing commit messages to get the idea.
-Squash commits
---------------
-Most changes are trivial enough to fit in one single commit in order to not
-clutter the history. While developing a new feature, you are free to use
-multiple commits, but if your feature is to be merged, reduce the number of
-commits to a minimum. Even huge feature introductions like the 802.11s mesh
-(commit [2a93c58]) fit into a single commit.
-
-If you developed your change in multiple smaller commits, you can easily
-[squash] those before opening the pull request. While discussing, it is okay to
-do your changes using `git commit --amend` and force-push them to your head of
-the pull request. This way, your change always consists of only one commit and
-can be merged in the instant everybody is content with the whole thing.
-
[packages]: http://gluon.readthedocs.org/en/latest/user/site.html#packages
[#gluon]: https://webirc.hackint.org/#gluon
[mailing list]: mailto:gluon@luebeck.freifunk.net
[list of rejected features]: https://github.com/freifunk-gluon/gluon/issues?q=label%3Arejected
-[2a93c58]: https://github.com/freifunk-gluon/gluon/commit/2a93c580428d10724116b0d2d1238e2745715a14
-[squash]: https://www.git-scm.com/book/en/v2/Git-Tools-Rewriting-History#Squashing-Commits
diff --git a/Makefile b/Makefile
index 90ea36f3..5c02c752 100644
--- a/Makefile
+++ b/Makefile
@@ -152,17 +152,21 @@ 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
@@ -447,6 +451,15 @@ image: FORCE
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) && \
diff --git a/README.md b/README.md
index 72113cb0..3ef1f420 100644
--- a/README.md
+++ b/README.md
@@ -12,11 +12,14 @@ Before opening an issue, make sure to check whether any existing issues
(open or closed) match. If you're suggesting a new feature, drop by on IRC or
our mailinglist to discuss it first.
+We maintain a [Roadmap](https://github.com/freifunk-gluon/gluon/wiki/Roadmap) for
+the future development of Gluon.
+
## Use a release!
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.4 && make update`.
+and switch to one by running `git checkout v2016.1.5 && 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.
diff --git a/contrib/lsupgrade.sh b/contrib/lsupgrade.sh
index 7fe11299..eca7a852 100755
--- a/contrib/lsupgrade.sh
+++ b/contrib/lsupgrade.sh
@@ -2,10 +2,11 @@
# Script to list all upgrade scripts in a clear manner
# Limitations:
-# * Does only show scripts of packages whose `files' directory represent the whole image filesystem (which are all Gluon packages)
+# * Does only show scripts of packages whose `files'/`luasrc' directories represent the whole image filesystem (which are all Gluon packages)
-SUFFIX=files/lib/gluon/upgrade
+SUFFIX1=files/lib/gluon/upgrade
+SUFFIX2=luasrc/lib/gluon/upgrade
shopt -s nullglob
@@ -35,8 +36,11 @@ find ./package packages -name Makefile | while read makefile; do
dirname="$(dirname "$dir" | cut -d/ -f 3-)"
package="$(basename "$dir")"
- for file in "${SUFFIX}"/*; do
- echo "${GREEN}$(basename "${file}")${RESET}" "(${BLUE}${repo}${RESET}/${dirname}${dirname:+/}${RED}${package}${RESET}/${SUFFIX})"
+ for file in "${SUFFIX1}"/*; do
+ echo "${GREEN}$(basename "${file}")${RESET}" "(${BLUE}${repo}${RESET}/${dirname}${dirname:+/}${RED}${package}${RESET}/${SUFFIX1})"
+ done
+ for file in "${SUFFIX2}"/*; do
+ echo "${GREEN}$(basename "${file}")${RESET}" "(${BLUE}${repo}${RESET}/${dirname}${dirname:+/}${RED}${package}${RESET}/${SUFFIX2})"
done
popd >/dev/null
done | sort
diff --git a/docs/dev/hardware.rst b/docs/dev/hardware.rst
index 3bd62a3d..b7f7c174 100644
--- a/docs/dev/hardware.rst
+++ b/docs/dev/hardware.rst
@@ -51,7 +51,7 @@ may be defined arbitrarily.
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/core/initial/001-sysconfig``
+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).
@@ -62,9 +62,10 @@ required for adding a new target:
Adjust packages
'''''''''''''''
-One package that definitely needs adjustments for every new target added is ``lua-platform-info``. Just
-start with a copy of an existing platform info script, adjust it for the new target, and add the new target
-to the list of supported targets in the package Makefile.
+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
+there is nothing to adjust). Then add the new target to the DEPENDS variable in the ``libplatforminfo`` package Makefile.
On many targets, Gluon's network setup scripts (mainly in the packages ``gluon-core`` and ``gluon-mesh-batman-adv-core``)
won't run correctly without some adjustments, so better double check that everything is fine there (and the files
diff --git a/docs/dev/i18n.rst b/docs/dev/i18n.rst
index b51bfdee..fb7710ca 100644
--- a/docs/dev/i18n.rst
+++ b/docs/dev/i18n.rst
@@ -5,7 +5,10 @@ General guidelines
------------------
* All config mode packages must be fully translatable, with complete English and German texts.
-* All new expert mode packages be fully translatable. English texts are required, German texts recommended.
+* All new expert mode packages must be fully translatable. English texts are required.
+* German translations are recommended. Other supported languages, especially French, are
+ nice-to-have, but not required. If you don't know a language well, rather leave the translation
+ blank, so it is obvious that there is no proper translation yet.
* Existing expert mode packages should be made translatable as soon as possible.
* The "message IDs" (which are the arguments to the ``translate`` function) should be the
English texts.
@@ -38,7 +41,7 @@ The entries in the template can be reordered after the generation if desirable.
translations like "Cancel" are already available in the LuCI base translation file (see
``packages/luci/po/templates/base.pot``) and can be removed from the template.
-In addition, some additions to the Makefile must be made. Instead of OpenWrt's default package.mk,
+In addition, some additions to the Makefile must be made. Instead of OpenWrt's default ``package.mk``,
the Gluon version ``$(GLUONDIR)/include/package.mk`` must be used. The i18n files must be installed
and PKG_CONFIG_DEPENDS must be added::
@@ -73,7 +76,7 @@ The translation file can be updated to a new template version using the ``msgmer
msgmerge -U de.po gluon-config-mode-geo-location.pot
After the merge, the translation file should be checked for "fuzzy matched" entries where
-the original English texts have changed. All entries from the the translation file should be
+the original English texts have changed. All entries from the translation file should be
translated in the ``.po`` file (or removed from it, so the original English texts are displayed
instead).
@@ -84,5 +87,6 @@ A list of all languages supported by LuCI can be found in the ``packages/luci/lu
Gluon's dependencies have been downloaded using ``make update``. Adding translations for these
languages is straightforward using the ``msginit`` command.
-For other languages, support must be added tu LuCI first, which constitutes completely translating
-the ``base.pot``. Please contact the upstream LuCI maintainers if you'd like to do this.
+For other languages, support must be added to LuCI first, which constitutes completely translating
+the ``base.pot``. Please contact the upstream LuCI maintainers at https://github.com/openwrt/luci/
+if you'd like to do this.
diff --git a/docs/dev/mac_addresses.rst b/docs/dev/mac_addresses.rst
new file mode 100644
index 00000000..b221a302
--- /dev/null
+++ b/docs/dev/mac_addresses.rst
@@ -0,0 +1,18 @@
+MAC addresses
+=============
+
+Many devices don't have enough unique MAC addresses assigned by the vendor
+(in batman-adv, each mesh interface needs an own MAC address that must be unique
+mesh-wide).
+
+Gluon tries to solve this issue by using a hash of the primary MAC address as a
+45 bit MAC address prefix. The resulting 8 addresses are used as follows:
+
+* 0: client0; WAN
+* 1: mesh0
+* 2: ibss0
+* 3: wan_radio0 (private WLAN); batman-adv primary address
+* 4: client1; LAN
+* 5: mesh1
+* 6: ibss1
+* 7: wan_radio1 (private WLAN); mesh VPN
diff --git a/docs/features/autoupdater.rst b/docs/features/autoupdater.rst
index 873f6097..8c4ca73f 100644
--- a/docs/features/autoupdater.rst
+++ b/docs/features/autoupdater.rst
@@ -70,5 +70,11 @@ These commands can be used on a node:
# Force update check, even when the updater is disabled
autoupdater -f
+
+::
+
+ # If fallback is true the updater will perform an update only if
+ # the timespan given by the priority and another 24h have passed
+ autoupdater --fallback
diff --git a/docs/features/wired-mesh.rst b/docs/features/wired-mesh.rst
index 77c7d6b3..b9996335 100644
--- a/docs/features/wired-mesh.rst
+++ b/docs/features/wired-mesh.rst
@@ -19,7 +19,7 @@ Configuration
~~~~~~~~~~~~~
Both Mesh-on-WAN and Mesh-on-LAN can be configured on the "Network" page
-of the *Expert Mode* (if the package ``gluon-luci-portconfig`` is installed).
+of the *Advanced settings* (if the package ``gluon-luci-portconfig`` is installed).
It is also possible to enable Mesh-on-WAN and Mesh-on-LAN by default by
adding ``mesh_on_wan = true`` and ``mesh_on_lan = true`` to ``site.conf``.
@@ -61,5 +61,5 @@ It may be disabled by running::
uci commit
Please note that this configuration has changed in Gluon v2016.1. Using
-the old commands on v2016.1 will break the corresponding Expert Mode
-settings.
+the old commands on v2016.1 will break the corresponding options in the
+*Advanced settings*.
diff --git a/docs/index.rst b/docs/index.rst
index 028c65b8..a32c3c1a 100644
--- a/docs/index.rst
+++ b/docs/index.rst
@@ -43,6 +43,7 @@ Developer Documentation
dev/configmode
dev/wan
dev/i18n
+ dev/mac_addresses
Packages
--------
@@ -54,6 +55,10 @@ Packages
package/gluon-config-mode-geo-location
package/gluon-ebtables-filter-multicast
package/gluon-ebtables-filter-ra-dhcp
+<<<<<<< HEAD
+=======
+ package/gluon-ebtables-segment-mld
+>>>>>>> gluon-next-node: mark local-node ip6 as deprecated
package/gluon-next-node
Releases
@@ -62,6 +67,7 @@ Releases
.. toctree::
:maxdepth: 1
+ releases/v2016.1.5
releases/v2016.1.4
releases/v2016.1.3
releases/v2016.1.2
@@ -90,6 +96,9 @@ ar71xx-generic
- AP121
- AP121U
- Hornet-UB
+ - Tube2H
+ - N2
+ - N5
* Allnet
@@ -108,7 +117,7 @@ ar71xx-generic
* D-Link
- - DIR-505 (A1)
+ - DIR-505 (A1, A2)
- DIR-615 (C1)
- DIR-825 (B1)
@@ -131,6 +140,16 @@ ar71xx-generic
- Omega
+* OpenMesh
+
+ - MR600 (v1, v2)
+ - MR900 (v1, v2)
+ - OM2P (v1, v2)
+ - OM2P-HS (v1, v2, v3)
+ - OM2P-LC
+ - OM5P
+ - OM5P-AN
+
* TP-Link
- CPE210 (v1.0, v1.1)
@@ -172,11 +191,13 @@ ar71xx-generic
- Air Gateway
- Air Router
- Bullet M
+ - Loco M
+ - Loco M XW
- Nanostation M
- Nanostation M XW
- - Loco M XW
- Picostation M
- Rocket M
+ - Rocket M XW
- UniFi AP
- UniFi AP Pro
- UniFi AP Outdoor
diff --git a/docs/package/gluon-config-mode-contact-info.rst b/docs/package/gluon-config-mode-contact-info.rst
new file mode 100644
index 00000000..a38cc0a5
--- /dev/null
+++ b/docs/package/gluon-config-mode-contact-info.rst
@@ -0,0 +1,28 @@
+gluon-config-mode-contact-info
+==============================
+
+This package allows the user to provide contact information within config mode to be
+distributed in the mesh. You can define whether the owner contact field is
+obligatory or not in your site.conf.
+
+site.conf
+---------
+
+config_mode.owner.obligatory : this whole section is optional
+ - ``true`` field is obligatory: gluon-node-info.@owner[0].contact may not be empty
+ - ``false`` field is optional: gluon-node-info.@owner[0].contact may be empty
+ - defaults to ``false``
+
+# example:
+
+ config_mode = {
+ geo_location = {
+ show_altitude = true,
+ },
+ owner = {
+ obligatory = true
+ },
+ },
+
+
+
\ No newline at end of file
diff --git a/docs/package/gluon-ebtables-segment-mld.rst b/docs/package/gluon-ebtables-segment-mld.rst
new file mode 100644
index 00000000..7e197ece
--- /dev/null
+++ b/docs/package/gluon-ebtables-segment-mld.rst
@@ -0,0 +1,16 @@
+gluon-ebtables-segment-mld
+==========================
+
+These filters drop IGMP/MLD packets before they enter the mesh and
+filter any IGMP/MLD packets coming from the mesh.
+
+IGMP/MLD have the concept of a local, elected Querier. For more
+decentralization and increased robustness, the idea of this package is
+to split the IGMP/MLD domain a querier is responsible for, allowing to
+have a querier per node. The split IGMP/MLD domain will also reduce
+overhead for this packet type, increasing scalability.
+
+Beware of the consequences of using this package though: You might need
+to explicitly, manually mark ports on snooping switches leading towards
+your mesh node as multicast router ports for now (Multicast Router
+Discovery, MRD, not implemented yet).
diff --git a/docs/releases/v2016.1.5.rst b/docs/releases/v2016.1.5.rst
new file mode 100644
index 00000000..e5ee1a00
--- /dev/null
+++ b/docs/releases/v2016.1.5.rst
@@ -0,0 +1,66 @@
+Gluon 2016.1.5
+==============
+
+Added hardware support
+~~~~~~~~~~~~~~~~~~~~~~
+
+ar71xx-generic
+^^^^^^^^^^^^^^
+
+* OpenMesh
+
+ - MR600 (v1, v2)
+ - MR900 (v1, v2)
+ - OM2P (v1, v2)
+ - OM2P-HS (v1, v2)
+ - OM2P-LC
+ - OM5P
+ - OM5P-AN
+
+* Ubiquiti
+
+ - Rocket M XW
+
+* TP-LINK
+
+ - TL-WR841N/ND v11
+
+Bugfixes
+~~~~~~~~
+
+* build: fix race condition caused by using certain make targets (like *clean*, *images* or *package/\**)
+ with parallel build options without doing a full build before
+* build: fix package dependency issue causing "recursive dependency" warning
+
+ This dependency issue could lead to broken configurations and reportedly caused failed builds in some cases
+ when additional (site-specific) packages were used.
+* build: Gluon will now build correctly with GCC 6 as host compiler
+* Fix configuration of batman-adv when VLANs are used on top of IBSS interfaces (regression due to netifd update in :doc:`v2016.1.4`)
+* Add back missing ath10k firmware (regression due to mac80211 update in :doc:`v2016.1.4`)
+* Gluon can now be used on all supported Ubiquiti AirMAX devices without downgrading to AirOS 5.5.x before
+
+ :doc:`v2016.1.1` added support for most Ubiquiti AirMAX devices with AirOS 5.6.x without downgrading AirOS,
+ but left some devices (at least some PicoStations and Bullets) with unwritable flash. This issue has been
+ resolved (`#687 `_).
+* Add upgrade script to automatically remove whitespace from configured geolocation
+
+ The new respondd implementation included in :doc:`v2016.1` is stricter about the number format than the
+ old one and doesn't accept trailing whitespace (so one or both coordinates are missing from the output).
+
+ The Config Mode has been fixed to strip whitespace from numeric fields in new configurations since :doc:`v2016.1.1`.
+ This still left old configurations, which are now fixed by this script.
+
+Known Issues
+~~~~~~~~~~~~
+
+* Default TX power on many Ubiquiti devices is too high, correct offsets are unknown (`#94 `_)
+
+ Reducing the TX power in the Expert Mode 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/site-example/i18n/de.po b/docs/site-example/i18n/de.po
index 69cf1dd8..30f5c838 100644
--- a/docs/site-example/i18n/de.po
+++ b/docs/site-example/i18n/de.po
@@ -22,11 +22,11 @@ msgstr ""
"er auf den Servern des Entenhausener Freifunk-Projektes eingetragen wurde, "
"kann sich dein Knoten mit dem Entenhausener Mesh-VPN verbinden. Bitte "
"schicke dazu diesen Schlüssel und den Namen deines Knotens "
-"(<%=hostname%>) an "
+"(<%=escape(hostname)%>) an "
"keys@entenhausen.freifunk.net."
"
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. "
-"To register, send the key together with your node's name (<%=hostname%>) to "
+"To register, send the key together with your node's name (<%=escape(hostname)%>) to "
"keys@entenhausen.freifunk.net."
"
"
diff --git a/docs/site-example/i18n/fr.po b/docs/site-example/i18n/fr.po
index 30e21c50..1462fdbf 100644
--- a/docs/site-example/i18n/fr.po
+++ b/docs/site-example/i18n/fr.po
@@ -22,11 +22,11 @@ msgstr ""
"entrée sur les serveurs de votre groupe de Freifunk votre nœud pourra se connecter "
"sur les serveur Mesh-VPN de votre groupe Freifunk. Veuillez envoyer la clé avec le "
"nom de votre nœud "
-"(<%=hostname%>) à "
+"(<%=escape(hostname)%>) à "
"keys@entenhausen.freifunk.net."
""
"
"
diff --git a/docs/site-example/site.conf b/docs/site-example/site.conf
index 45719b94..6dee6df2 100644
--- a/docs/site-example/site.conf
+++ b/docs/site-example/site.conf
@@ -35,6 +35,14 @@
-- Wireless channel.
channel = 1,
+ -- List of supported wifi rates (optional)
+ -- Example removes 802.11b compatibility for better performance
+ supported_rates = {6000, 9000, 12000, 18000, 24000, 36000, 48000, 54000},
+
+ -- List of basic wifi rates (optional, required if supported_rates is set)
+ -- Example removes 802.11b compatibility for better performance
+ basic_rate = {6000, 9000, 18000, 36000, 54000},
+
-- ESSID used for client network.
ap = {
ssid = 'entenhausen.freifunk.net',
@@ -184,10 +192,15 @@
-- skip = true,
-- },
- -- Show/hide the altitude field
-- config_mode = {
- -- geo_location = {
- -- show_altitude = false,
- -- },
+ -- Show/hide the altitude field
+ -- geo_location = {
+ -- show_altitude = false,
+ -- },
+ -- define if the contact field is obligatory (optional)
+ -- owner = {
+ -- obligatory = true
+ -- },
-- },
+
}
diff --git a/docs/site-example/site.mk b/docs/site-example/site.mk
index de8a562a..9f729890 100644
--- a/docs/site-example/site.mk
+++ b/docs/site-example/site.mk
@@ -52,5 +52,8 @@ GLUON_RELEASE ?= $(DEFAULT_GLUON_RELEASE)
# Default priority for updates.
GLUON_PRIORITY ?= 0
+# Region code required for some images; supported values: us eu
+GLUON_REGION ?= eu
+
# Languages to include
GLUON_LANGS ?= en de
diff --git a/docs/user/getting_started.rst b/docs/user/getting_started.rst
index 6c614d70..c7519cf0 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.4*. Always get Gluon using git and don't try to download it
+e.g. *v2016.1.5*. 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
@@ -42,7 +42,7 @@ 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.4*.
+version you'd like to checkout, e.g. *v2016.1.5*.
::
@@ -130,7 +130,7 @@ not support IPv6.
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 repositoy containing all kernel modules provided by OpenWrt/Gluon
+but also an opkg repository containing all kernel modules provided by OpenWrt/Gluon
for the kernel of the generated images.
Signing keys
diff --git a/docs/user/site.rst b/docs/user/site.rst
index 7f56150d..9349a1a5 100644
--- a/docs/user/site.rst
+++ b/docs/user/site.rst
@@ -98,6 +98,12 @@ wifi24 \: optional
This will only affect new installations.
Upgrades will not changed 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.
+ If ``supported_rates`` is set, ``basic_rate`` is required, because ``basic_rate``
+ has to be a subset of ``supported_rates``.
+ The example below disables 802.11b rates.
+
``ap`` requires a single parameter, a string, named ``ssid`` which sets the
interface's ESSID.
@@ -112,6 +118,8 @@ wifi24 \: optional
wifi24 = {
channel = 11,
+ supported_rates = {6000, 9000, 12000, 18000, 24000, 36000, 48000, 54000},
+ basic_rate = {6000, 9000, 18000, 36000, 54000},
ap = {
ssid = 'entenhausen.freifunk.net',
},
@@ -229,8 +237,14 @@ mesh_on_wan \: optional
mesh_on_lan \: optional
Enables the mesh on the LAN port (``true`` or ``false``).
+poe_passthrough \: optional
+ Enable PoE passthrough by default on hardware with such a feature.
+
autoupdater \: package
Configuration for the autoupdater feature of Gluon.
+
+ The mirrors are checked in random order until the manifest could be downloaded
+ successfully or all mirrors have been tried.
::
autoupdater = {
@@ -320,6 +334,10 @@ GLUON_PRIORITY
The default priority for the generated manifests (see the autoupdater documentation
for more information).
+GLUON_REGION
+ Region code to build into images where necessary. Valid values are the empty string,
+ ``us`` and ``eu``.
+
GLUON_LANGS
List of languages (as two-letter-codes) to be included in the web interface. Should always contain
``en``.
@@ -355,6 +373,41 @@ utilities are installed.
Depending on the context, you might be able to use comments like
```` as translations to effectively hide the text.
+Site modules
+------------
+
+The file ``modules`` in the site repository is completely optional and can be used
+to supply additional package feeds from which packages are built. The git repositories
+specified here are retrieved in addition to the default feeds when ``make update``
+it called.
+
+This file's format is very similar to the toplevel ``modules`` file of the Gluon
+tree, with the important different that the list of feeds must be assigned to
+the variable ``GLUON_SITE_FEEDS``. Multiple feed names must be separated by spaces,
+for example::
+
+ GLUON_SITE_FEEDS='foo bar'
+
+The feed names may only contain alphanumerical characters, underscores and slashes.
+For each of the feeds, the following variables are used to specify how to update
+the feed:
+
+PACKAGES_${feed}_REPO
+ The URL of the git repository to clone (usually ``git://`` or ``http(s)://``)
+
+PACKAGES_${feed}_COMMIT
+ The commit ID of the repository to use
+
+PACKAGES_${feed}_BRANCH
+ Optional: The branch of the repository the given commit ID can be found in.
+ Defaults to the default branch of the repository (usually ``master``)
+
+These variables are always all uppercase, so for an entry ``foo`` in GLUON_SITE_FEEDS,
+the corresponding configuration variables would be ``PACKAGES_FOO_REPO``,
+``PACKAGES_FOO_COMMIT`` and ``PACKAGES_FOO_BRANCH``. Slashes in feed names are
+replaced by underscores to get valid shell variable identifiers.
+
+
Examples
--------
@@ -394,23 +447,35 @@ site-repos in the wild
This is a non-exhaustive list of site-repos from various communities:
* `site-ffa `_ (Altdorf, Landshut & Umgebung)
+* `site-ffac `_ (Regio Aachen)
* `site-ffbs `_ (Braunschweig)
* `site-ffhb `_ (Bremen)
* `site-ffda `_ (Darmstadt)
+* `site-ffeh `_ (Ehingen)
+* `site-fffl `_ (Flensburg)
* `site-ffgoe `_ (Göttingen)
+* `site-ffgt-rhw `_ (Guetersloh)
* `site-ffhh `_ (Hamburg)
* `site-ffho `_ (Hochstift)
* `site-ffhgw `_ (Greifswald)
+* `site-ffka `_ (Karlsruhe)
+* `site-ffki `_ (Kiel)
+* `site-fflz `_ (Lausitz)
* `site-ffl `_ (Leipzig)
* `site-ffhl `_ (Lübeck)
+* `site-fflg `_ (Lüneburg)
* `site-ffmd `_ (Magdeburg)
* `site-ffmwu `_ (Mainz, Wiesbaden & Umgebung)
* `site-ffmyk `_ (Mayen-Koblenz)
+* `site-ffmo `_ (Moers)
+* `site-ffmg `_ (Mönchengladbach)
* `site-ffm `_ (München)
+* `site-ffhmue `_ (Münden)
* `site-ffms `_ (Münsterland)
-* `site-ffnw `_ (Nordwest)
-* `site-ffka `_ (Karlsruhe)
-* `site-ffrl `_ (Rheinland)
-* `site-ffrg `_ (Ruhrgebiet)
+* `site-neuss `_ (Neuss)
+* `site-ffniers `_ (Niersufer)
+* `site-ffnw `_ (Nordwest)
+* `site-ffrgb `_ (Regensburg)
+* `site-ffruhr `_ (Ruhrgebiet, Multi-Communities)
* `site-ffs `_ (Stuttgart)
* `site-fftr `_ (Trier)
diff --git a/include/gluon.mk b/include/gluon.mk
index d49dc13f..ef0f5311 100644
--- a/include/gluon.mk
+++ b/include/gluon.mk
@@ -75,7 +75,7 @@ GLUON_TARGET_$$(gluon_target)_BOARD := $(1)
GLUON_TARGET_$$(gluon_target)_SUBTARGET := $(2)
endef
-GLUON_DEFAULT_PACKAGES := gluon-core kmod-ipv6 firewall ip6tables -uboot-envtools -wpad-mini hostapd-mini
+GLUON_DEFAULT_PACKAGES := gluon-core firewall ip6tables -uboot-envtools -wpad-mini hostapd-mini
override DEFAULT_PACKAGES.router :=
diff --git a/include/package.mk b/include/package.mk
index 76e109e2..9d35ad3c 100644
--- a/include/package.mk
+++ b/include/package.mk
@@ -1,3 +1,6 @@
+# Dependencies for LuaSrcDiet
+PKG_BUILD_DEPENDS += luci-base/host lua/host
+
include $(INCLUDE_DIR)/package.mk
# Annoyingly, make's shell function replaces all newlines with spaces, so we have to do some escaping work. Yuck.
@@ -33,3 +36,16 @@ define GluonInstallI18N
fi; \
done
endef
+
+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; \
+ done
+endef
diff --git a/modules b/modules
index 2a52cdf1..b5c42e11 100644
--- a/modules
+++ b/modules
@@ -1,18 +1,19 @@
GLUON_FEEDS='openwrt gluon routing luci'
-OPENWRT_REPO=git://git.openwrt.org/15.05/openwrt.git
-OPENWRT_COMMIT=eadf19c0b43d2f75f196ea8d875a08c7c348530c
+OPENWRT_REPO=git://github.com/openwrt/openwrt.git
+OPENWRT_COMMIT=e663db7bb1797740c4a29ac0fc96eda1b88f9e6e
+OPENWRT_BRANCH=chaos_calmer
PACKAGES_OPENWRT_REPO=git://github.com/openwrt/packages.git
-PACKAGES_OPENWRT_COMMIT=9622fe984bba3a4547f48bc507ebaba7637eb2b0
+PACKAGES_OPENWRT_COMMIT=73776792f7d58e982be9e5819450d4875b273159
PACKAGES_OPENWRT_BRANCH=for-15.05
PACKAGES_GLUON_REPO=git://github.com/freifunk-gluon/packages.git
-PACKAGES_GLUON_COMMIT=087eef9e684fdef066e63c8f64dddfbfd02141a5
+PACKAGES_GLUON_COMMIT=c24cdae83049e22ad35a3908a7d48c7fdc6dad7d
PACKAGES_ROUTING_REPO=git://github.com/openwrt-routing/packages.git
-PACKAGES_ROUTING_COMMIT=2a8338559de5c4b077cde7a83f43f4700a17d5cc
+PACKAGES_ROUTING_COMMIT=a4eae82c155079a4372e4b910ec733f77288b717
PACKAGES_LUCI_REPO=git://github.com/openwrt/luci.git
-PACKAGES_LUCI_COMMIT=cdcdfd2594634804ab09dc8105e46116edce0cd6
+PACKAGES_LUCI_COMMIT=70a4d43cc895b7d728b4fc201f2b6fd9f4b8aaec
PACKAGES_LUCI_BRANCH=for-15.05
diff --git a/package/gluon-alfred/Makefile b/package/gluon-alfred/Makefile
index ca3ae327..f38b0dbe 100644
--- a/package/gluon-alfred/Makefile
+++ b/package/gluon-alfred/Makefile
@@ -6,7 +6,8 @@ PKG_RELEASE:=1
PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME)
-include $(INCLUDE_DIR)/package.mk
+include $(GLUONDIR)/include/package.mk
+
define Package/gluon-alfred
SECTION:=gluon
@@ -23,10 +24,12 @@ define Build/Configure
endef
define Build/Compile
+ $(call GluonSrcDiet,./luasrc,$(PKG_BUILD_DIR)/luadest/)
endef
define Package/gluon-alfred/install
$(CP) ./files/* $(1)/
+ $(CP) $(PKG_BUILD_DIR)/luadest/* $(1)/
endef
$(eval $(call BuildPackage,gluon-alfred))
diff --git a/package/gluon-alfred/files/lib/gluon/upgrade/500-enable-alfred b/package/gluon-alfred/luasrc/lib/gluon/upgrade/500-enable-alfred
similarity index 100%
rename from package/gluon-alfred/files/lib/gluon/upgrade/500-enable-alfred
rename to package/gluon-alfred/luasrc/lib/gluon/upgrade/500-enable-alfred
diff --git a/package/gluon-authorized-keys/Makefile b/package/gluon-authorized-keys/Makefile
index 6ef90da3..83eaf04f 100644
--- a/package/gluon-authorized-keys/Makefile
+++ b/package/gluon-authorized-keys/Makefile
@@ -7,6 +7,7 @@ PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME)
include $(GLUONDIR)/include/package.mk
+
define Package/gluon-authorized-keys
SECTION:=gluon
CATEGORY:=Gluon
@@ -22,10 +23,11 @@ define Build/Configure
endef
define Build/Compile
+ $(call GluonSrcDiet,./luasrc,$(PKG_BUILD_DIR)/luadest/)
endef
define Package/gluon-authorized-keys/install
- $(CP) ./files/* $(1)/
+ $(CP) $(PKG_BUILD_DIR)/luadest/* $(1)/
endef
define Package/gluon-authorized-keys/postinst
diff --git a/package/gluon-authorized-keys/files/lib/gluon/upgrade/100-authorized-keys b/package/gluon-authorized-keys/luasrc/lib/gluon/upgrade/100-authorized-keys
similarity index 100%
rename from package/gluon-authorized-keys/files/lib/gluon/upgrade/100-authorized-keys
rename to package/gluon-authorized-keys/luasrc/lib/gluon/upgrade/100-authorized-keys
diff --git a/package/gluon-autoupdater/Makefile b/package/gluon-autoupdater/Makefile
index 40120fa9..baae06ba 100644
--- a/package/gluon-autoupdater/Makefile
+++ b/package/gluon-autoupdater/Makefile
@@ -9,6 +9,7 @@ PKG_BUILD_DEPENDS := respondd
include $(GLUONDIR)/include/package.mk
+
define Package/gluon-autoupdater
SECTION:=gluon
CATEGORY:=Gluon
@@ -21,8 +22,14 @@ define Build/Prepare
$(CP) ./src/* $(PKG_BUILD_DIR)/
endef
+define Build/Compile
+ $(call Build/Compile/Default)
+ $(call GluonSrcDiet,./luasrc,$(PKG_BUILD_DIR)/luadest/)
+endef
+
define Package/gluon-autoupdater/install
$(CP) ./files/* $(1)/
+ $(CP) $(PKG_BUILD_DIR)/luadest/* $(1)/
$(INSTALL_DIR) $(1)/lib/gluon/respondd
$(CP) $(PKG_BUILD_DIR)/respondd.so $(1)/lib/gluon/respondd/autoupdater.so
diff --git a/package/gluon-autoupdater/files/lib/gluon/upgrade/500-autoupdater b/package/gluon-autoupdater/luasrc/lib/gluon/upgrade/500-autoupdater
similarity index 100%
rename from package/gluon-autoupdater/files/lib/gluon/upgrade/500-autoupdater
rename to package/gluon-autoupdater/luasrc/lib/gluon/upgrade/500-autoupdater
diff --git a/package/gluon-client-bridge/Makefile b/package/gluon-client-bridge/Makefile
index 6bbfed64..cbd62a38 100644
--- a/package/gluon-client-bridge/Makefile
+++ b/package/gluon-client-bridge/Makefile
@@ -7,6 +7,7 @@ PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME)
include $(GLUONDIR)/include/package.mk
+
define Package/gluon-client-bridge
SECTION:=gluon
CATEGORY:=Gluon
@@ -22,10 +23,11 @@ define Build/Configure
endef
define Build/Compile
+ $(call GluonSrcDiet,./luasrc,$(PKG_BUILD_DIR)/luadest/)
endef
define Package/gluon-client-bridge/install
- $(CP) ./files/* $(1)/
+ $(CP) $(PKG_BUILD_DIR)/luadest/* $(1)/
endef
define Package/gluon-client-bridge/postinst
diff --git a/package/gluon-client-bridge/files/lib/gluon/upgrade/300-gluon-client-bridge-network b/package/gluon-client-bridge/luasrc/lib/gluon/upgrade/300-gluon-client-bridge-network
similarity index 55%
rename from package/gluon-client-bridge/files/lib/gluon/upgrade/300-gluon-client-bridge-network
rename to package/gluon-client-bridge/luasrc/lib/gluon/upgrade/300-gluon-client-bridge-network
index 4a897f74..f5ab8582 100755
--- a/package/gluon-client-bridge/files/lib/gluon/upgrade/300-gluon-client-bridge-network
+++ b/package/gluon-client-bridge/luasrc/lib/gluon/upgrade/300-gluon-client-bridge-network
@@ -1,16 +1,16 @@
#!/usr/bin/lua
local sysconfig = require 'gluon.sysconfig'
+
+local lutil = require 'luci.util'
local uci = require('luci.model.uci').cursor()
-if not uci:get('network', 'client') then
- uci:section('network', 'interface', 'client',
- {
- type = 'bridge',
- }
- )
-end
+uci:section('network', 'interface', 'client',
+ {
+ type = 'bridge',
+ }
+)
local ifname = uci:get('network', 'client', 'ifname')
@@ -21,6 +21,13 @@ if type(ifname) == 'string' then
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
+end
+
+
uci:set('network', 'client', 'macaddr', sysconfig.primary_mac)
uci:save('network')
diff --git a/package/gluon-client-bridge/files/lib/gluon/upgrade/320-gluon-client-bridge-wireless b/package/gluon-client-bridge/luasrc/lib/gluon/upgrade/320-gluon-client-bridge-wireless
similarity index 66%
rename from package/gluon-client-bridge/files/lib/gluon/upgrade/320-gluon-client-bridge-wireless
rename to package/gluon-client-bridge/luasrc/lib/gluon/upgrade/320-gluon-client-bridge-wireless
index 6fc8a72a..6c25f995 100755
--- a/package/gluon-client-bridge/files/lib/gluon/upgrade/320-gluon-client-bridge-wireless
+++ b/package/gluon-client-bridge/luasrc/lib/gluon/upgrade/320-gluon-client-bridge-wireless
@@ -21,21 +21,26 @@ local function configure_client(config, radio, index, suffix)
uci:delete('wireless', name)
- macaddr = util.generate_mac(3*index)
-
- if config and macaddr then
- uci:section('wireless', 'wifi-iface', name,
- {
- device = radio,
- network = 'client',
- mode = 'ap',
- ssid = config.ssid,
- macaddr = macaddr,
- ifname = suffix and 'client' .. suffix,
- disabled = disabled,
- }
- )
+ if not config then
+ return
end
+
+ local macaddr = util.get_wlan_mac(radio, index, 1)
+ if not macaddr then
+ return
+ end
+
+ uci:section('wireless', 'wifi-iface', name,
+ {
+ device = radio,
+ network = 'client',
+ mode = 'ap',
+ ssid = config.ssid,
+ macaddr = macaddr,
+ ifname = suffix and 'client' .. suffix,
+ disabled = disabled,
+ }
+ )
end
local function configure_radio(radio, index, config)
diff --git a/package/gluon-config-mode-autoupdater/Makefile b/package/gluon-config-mode-autoupdater/Makefile
index 4303940b..ab5d1adc 100644
--- a/package/gluon-config-mode-autoupdater/Makefile
+++ b/package/gluon-config-mode-autoupdater/Makefile
@@ -30,10 +30,11 @@ endef
define Build/Compile
$(call GluonBuildI18N,gluon-config-mode-autoupdater,i18n)
+ $(call GluonSrcDiet,./luasrc,$(PKG_BUILD_DIR)/luadest/)
endef
define Package/gluon-config-mode-autoupdater/install
- $(CP) ./files/* $(1)/
+ $(CP) $(PKG_BUILD_DIR)/luadest/* $(1)/
$(call GluonInstallI18N,gluon-config-mode-autoupdater,$(1))
endef
diff --git a/package/gluon-config-mode-autoupdater/files/lib/gluon/config-mode/wizard/0050-autoupdater-info.lua b/package/gluon-config-mode-autoupdater/luasrc/lib/gluon/config-mode/wizard/0050-autoupdater-info.lua
similarity index 100%
rename from package/gluon-config-mode-autoupdater/files/lib/gluon/config-mode/wizard/0050-autoupdater-info.lua
rename to package/gluon-config-mode-autoupdater/luasrc/lib/gluon/config-mode/wizard/0050-autoupdater-info.lua
diff --git a/package/gluon-config-mode-contact-info/Makefile b/package/gluon-config-mode-contact-info/Makefile
index ff9cb57f..3ac8a0b3 100644
--- a/package/gluon-config-mode-contact-info/Makefile
+++ b/package/gluon-config-mode-contact-info/Makefile
@@ -13,10 +13,15 @@ PKG_CONFIG_DEPENDS += $(GLUON_I18N_CONFIG)
define Package/gluon-config-mode-contact-info
SECTION:=gluon
CATEGORY:=Gluon
- TITLE:=Set a custom string that will be distributed in the mesh.
+ TITLE:=Allows the user to provide contact information to be distributed in the mesh
DEPENDS:=gluon-config-mode-core-virtual +gluon-node-info
endef
+define Package/gluon-config-mode-contact-info/description
+ Allows the user to provide contact information to be distributed in the mesh.
+ Can be made obligatory in site.conf
+endef
+
define Build/Prepare
mkdir -p $(PKG_BUILD_DIR)
endef
@@ -26,11 +31,17 @@ endef
define Build/Compile
$(call GluonBuildI18N,gluon-config-mode-contact-info,i18n)
+ $(call GluonSrcDiet,./luasrc,$(PKG_BUILD_DIR)/luadest/)
endef
define Package/gluon-config-mode-contact-info/install
- $(CP) ./files/* $(1)/
+ $(CP) $(PKG_BUILD_DIR)/luadest/* $(1)/
$(call GluonInstallI18N,gluon-config-mode-contact-info,$(1))
endef
+define Package/gluon-config-mode-contact-info/postinst
+#!/bin/sh
+$(call GluonCheckSite,check_site.lua)
+endef
+
$(eval $(call BuildPackage,gluon-config-mode-contact-info))
diff --git a/package/gluon-config-mode-contact-info/check_site.lua b/package/gluon-config-mode-contact-info/check_site.lua
new file mode 100644
index 00000000..fe818616
--- /dev/null
+++ b/package/gluon-config-mode-contact-info/check_site.lua
@@ -0,0 +1,3 @@
+if need_table('config_mode', nil, false) and need_table('config_mode.owner', nil, false) then
+ need_boolean('config_mode.owner.obligatory', false)
+end
diff --git a/package/gluon-config-mode-contact-info/i18n/de.po b/package/gluon-config-mode-contact-info/i18n/de.po
index 719246f4..35f0ee95 100644
--- a/package/gluon-config-mode-contact-info/i18n/de.po
+++ b/package/gluon-config-mode-contact-info/i18n/de.po
@@ -14,13 +14,13 @@ msgid "Contact info"
msgstr "Kontakt"
msgid ""
-"You can provide your contact information here to allow others to contact "
-"you. Please note that this information will be visible publicly on "
+"Please provide your contact information here to allow others to contact "
+"you. Note that this information will be visible publicly on "
"the internet together with your node's coordinates."
msgstr ""
-"Hier kannst du einen öffentlichen Hinweis hinterlegen, um anderen "
-"zu ermöglichen, Kontakt mit dir aufzunehmen. Bitte beachte, dass "
-"dieser Hinweis auch öffentlich im Internet, zusammen mit den Koordinaten "
+"Bitte hinterlege hier einen Hinweis, um anderen zu ermöglichen, "
+"Kontakt mit dir aufzunehmen. Beachte, dass dieser Hinweis auch "
+"öffentlich im Internet, zusammen mit den Koordinaten "
"deines Knotens, einsehbar sein wird."
msgid "e.g. E-mail or phone number"
diff --git a/package/gluon-config-mode-contact-info/i18n/fr.po b/package/gluon-config-mode-contact-info/i18n/fr.po
index 779e15fe..624b1864 100644
--- a/package/gluon-config-mode-contact-info/i18n/fr.po
+++ b/package/gluon-config-mode-contact-info/i18n/fr.po
@@ -14,11 +14,12 @@ msgid "Contact info"
msgstr "Informations de Contact"
msgid ""
-"You can provide your contact information here to allow others to contact "
-"you. Please note that this information will be visible publicly on "
+"Please provide your contact information here to allow others to contact "
+"you. Note that this information will be visible publicly on "
"the internet together with your node's coordinates."
msgstr ""
-"Ici vous pouvez donner des informations publiques pour permettre aux autres de vous contacter. "
+"S'il vous plaît entrez ici des informations publiques pour "
+"permettre aux autres de vous contacter. "
"Ces informations seront affichées en ligne, avec les coordonnées du nœud."
msgid "e.g. E-mail or phone number"
diff --git a/package/gluon-config-mode-contact-info/i18n/gluon-config-mode-contact-info.pot b/package/gluon-config-mode-contact-info/i18n/gluon-config-mode-contact-info.pot
index 63939a83..9dcaf9ec 100644
--- a/package/gluon-config-mode-contact-info/i18n/gluon-config-mode-contact-info.pot
+++ b/package/gluon-config-mode-contact-info/i18n/gluon-config-mode-contact-info.pot
@@ -5,8 +5,8 @@ msgid "Contact info"
msgstr ""
msgid ""
-"You can provide your contact information here to allow others to contact "
-"you. Please note that this information will be visible publicly on "
+"Please provide your contact information here to allow others to contact "
+"you. Note that this information will be visible publicly on "
"the internet together with your node's coordinates."
msgstr ""
diff --git a/package/gluon-config-mode-contact-info/files/lib/gluon/config-mode/wizard/0500-contact-info.lua b/package/gluon-config-mode-contact-info/luasrc/lib/gluon/config-mode/wizard/0500-contact-info.lua
similarity index 81%
rename from package/gluon-config-mode-contact-info/files/lib/gluon/config-mode/wizard/0500-contact-info.lua
rename to package/gluon-config-mode-contact-info/luasrc/lib/gluon/config-mode/wizard/0500-contact-info.lua
index a2182f95..46ff4567 100644
--- a/package/gluon-config-mode-contact-info/files/lib/gluon/config-mode/wizard/0500-contact-info.lua
+++ b/package/gluon-config-mode-contact-info/luasrc/lib/gluon/config-mode/wizard/0500-contact-info.lua
@@ -1,13 +1,14 @@
local cbi = require "luci.cbi"
local i18n = require "luci.i18n"
local uci = luci.model.uci.cursor()
+local site = require 'gluon.site_config'
local M = {}
function M.section(form)
local s = form:section(cbi.SimpleSection, nil, i18n.translate(
- 'You can provide your contact information here to '
- .. 'allow others to contact you. Please note that '
+ 'Please provide your contact information here to '
+ .. 'allow others to contact you. Note that '
.. 'this information will be visible publicly '
.. 'on the internet together with your node\'s coordinates.'
)
@@ -15,7 +16,7 @@ function M.section(form)
local o = s:option(cbi.Value, "_contact", i18n.translate("Contact info"))
o.default = uci:get_first("gluon-node-info", "owner", "contact", "")
- o.rmempty = true
+ o.rmempty = not ((site.config_mode or {}).owner or {}).obligatory
o.datatype = "string"
o.description = i18n.translate("e.g. E-mail or phone number")
o.maxlen = 140
diff --git a/package/gluon-config-mode-core/Makefile b/package/gluon-config-mode-core/Makefile
index 5d700f7f..52a4f0e1 100644
--- a/package/gluon-config-mode-core/Makefile
+++ b/package/gluon-config-mode-core/Makefile
@@ -17,7 +17,7 @@ define Package/gluon-config-mode-core
SECTION:=gluon
CATEGORY:=Gluon
TITLE:=Luci based config mode for user friendly setup of new mesh nodes
- DEPENDS:=gluon-setup-mode-virtual +gluon-luci-theme +gluon-lock-password $(GLUON_I18N_PACKAGES)
+ DEPENDS:=gluon-setup-mode-virtual +gluon-luci-theme +gluon-lock-password +pretty-hostname $(GLUON_I18N_PACKAGES)
PROVIDES:=gluon-config-mode-core-virtual
endef
@@ -30,10 +30,12 @@ endef
define Build/Compile
$(call GluonBuildI18N,gluon-config-mode-core,i18n)
+ $(call GluonSrcDiet,./luasrc,$(PKG_BUILD_DIR)/luadest/)
endef
define Package/gluon-config-mode-core/install
$(CP) ./files/* $(1)/
+ $(CP) $(PKG_BUILD_DIR)/luadest/* $(1)/
$(call GluonInstallI18N,gluon-config-mode-core,$(1))
endef
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 d2210eca..b4aca92e 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
@@ -1,4 +1,5 @@
<%-
+ local gluon_luci = require 'gluon.luci'
local sysconfig = require 'gluon.sysconfig'
local i18n = require 'luci.i18n'
local template = require 'luci.template'
@@ -6,7 +7,12 @@
<% if not self.embedded then %>
diff --git a/package/gluon-config-mode-core/files/usr/lib/lua/luci/view/gluon/config-mode/reboot.htm b/package/gluon-config-mode-core/files/usr/lib/lua/luci/view/gluon/config-mode/reboot.htm
index e8f32d99..25ad20bf 100644
--- a/package/gluon-config-mode-core/files/usr/lib/lua/luci/view/gluon/config-mode/reboot.htm
+++ b/package/gluon-config-mode-core/files/usr/lib/lua/luci/view/gluon/config-mode/reboot.htm
@@ -3,7 +3,7 @@
- <%=hostname%> is rebooting
+ <%=escape(hostname)%> is rebooting
diff --git a/package/gluon-config-mode-core/files/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
similarity index 100%
rename from package/gluon-config-mode-core/files/lib/gluon/config-mode/reboot/0900-msg-reboot.lua
rename to package/gluon-config-mode-core/luasrc/lib/gluon/config-mode/reboot/0900-msg-reboot.lua
diff --git a/package/gluon-config-mode-core/files/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
similarity index 61%
rename from package/gluon-config-mode-core/files/usr/lib/lua/luci/controller/gluon-config-mode/index.lua
rename to package/gluon-config-mode-core/luasrc/usr/lib/lua/luci/controller/gluon-config-mode/index.lua
index 39ba00a9..0a6a5495 100644
--- a/package/gluon-config-mode-core/files/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
@@ -48,43 +48,46 @@ function action_reboot()
uci:save("gluon-setup-mode")
uci:commit("gluon-setup-mode")
- if nixio.fork() ~= 0 then
- local fs = require "nixio.fs"
- local util = require "nixio.util"
+ local gluon_luci = require "gluon.luci"
+ local fs = require "nixio.fs"
+ local util = require "nixio.util"
+ local pretty_hostname = require "pretty_hostname"
- local parts_dir = "/lib/gluon/config-mode/reboot/"
- local files = util.consume(fs.dir(parts_dir))
+ local parts_dir = "/lib/gluon/config-mode/reboot/"
+ local files = util.consume(fs.dir(parts_dir))
- table.sort(files)
+ table.sort(files)
- local parts = {}
+ local parts = {}
- for _, entry in ipairs(files) do
- if entry:sub(1, 1) ~= '.' then
- local f = dofile(parts_dir .. '/' .. entry)
- if f ~= nil then
- table.insert(parts, f)
- end
+ for _, entry in ipairs(files) do
+ if entry:sub(1, 1) ~= '.' then
+ local f = dofile(parts_dir .. '/' .. entry)
+ if f ~= nil then
+ table.insert(parts, f)
end
end
+ end
- local hostname = uci:get_first("system", "system", "hostname")
+ local hostname = pretty_hostname.get(uci)
- luci.template.render("gluon/config-mode/reboot", { parts=parts
- , hostname=hostname
- })
- else
- debug.setfenv(io.stdout, debug.getfenv(io.open '/dev/null'))
- io.stdout:close()
+ luci.template.render("gluon/config-mode/reboot",
+ {
+ parts = parts,
+ hostname = hostname,
+ escape = gluon_luci.escape,
+ urlescape = gluon_luci.urlescape,
+ }
+ )
+
+ if nixio.fork() == 0 then
+ -- Replace stdout with /dev/null
+ nixio.dup(nixio.open('/dev/null', 'w'), nixio.stdout)
-- Sleep a little so the browser can fetch everything required to
-- display the reboot page, then reboot the device.
- nixio.nanosleep(2)
+ nixio.nanosleep(1)
- -- Run reboot with popen so it gets its own std filehandles.
- io.popen("reboot")
-
- -- Prevent any further execution in this child.
- os.exit()
+ nixio.execp("reboot")
end
end
diff --git a/package/gluon-config-mode-core/files/usr/lib/lua/luci/model/cbi/gluon-config-mode/wizard.lua b/package/gluon-config-mode-core/luasrc/usr/lib/lua/luci/model/cbi/gluon-config-mode/wizard.lua
similarity index 100%
rename from package/gluon-config-mode-core/files/usr/lib/lua/luci/model/cbi/gluon-config-mode/wizard.lua
rename to package/gluon-config-mode-core/luasrc/usr/lib/lua/luci/model/cbi/gluon-config-mode/wizard.lua
diff --git a/package/gluon-config-mode-geo-location/Makefile b/package/gluon-config-mode-geo-location/Makefile
index 03812e54..aa16ad06 100644
--- a/package/gluon-config-mode-geo-location/Makefile
+++ b/package/gluon-config-mode-geo-location/Makefile
@@ -26,10 +26,11 @@ endef
define Build/Compile
$(call GluonBuildI18N,gluon-config-mode-geo-location,i18n)
+ $(call GluonSrcDiet,./luasrc,$(PKG_BUILD_DIR)/luadest/)
endef
define Package/gluon-config-mode-geo-location/install
- $(CP) ./files/* $(1)/
+ $(CP) $(PKG_BUILD_DIR)/luadest/* $(1)/
$(call GluonInstallI18N,gluon-config-mode-geo-location,$(1))
endef
diff --git a/package/gluon-config-mode-geo-location/files/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
similarity index 100%
rename from package/gluon-config-mode-geo-location/files/lib/gluon/config-mode/wizard/0400-geo-location.lua
rename to package/gluon-config-mode-geo-location/luasrc/lib/gluon/config-mode/wizard/0400-geo-location.lua
diff --git a/package/gluon-config-mode-hostname/Makefile b/package/gluon-config-mode-hostname/Makefile
index 803f018f..6e30466d 100644
--- a/package/gluon-config-mode-hostname/Makefile
+++ b/package/gluon-config-mode-hostname/Makefile
@@ -26,10 +26,11 @@ endef
define Build/Compile
$(call GluonBuildI18N,gluon-config-mode-hostname,i18n)
+ $(call GluonSrcDiet,./luasrc,$(PKG_BUILD_DIR)/luadest/)
endef
define Package/gluon-config-mode-hostname/install
- $(CP) ./files/* $(1)/
+ $(CP) $(PKG_BUILD_DIR)/luadest/* $(1)/
$(call GluonInstallI18N,gluon-config-mode-hostname,$(1))
endef
diff --git a/package/gluon-config-mode-hostname/files/lib/gluon/config-mode/wizard/0100-hostname.lua b/package/gluon-config-mode-hostname/luasrc/lib/gluon/config-mode/wizard/0100-hostname.lua
similarity index 65%
rename from package/gluon-config-mode-hostname/files/lib/gluon/config-mode/wizard/0100-hostname.lua
rename to package/gluon-config-mode-hostname/luasrc/lib/gluon/config-mode/wizard/0100-hostname.lua
index cf8bbf89..2ffde723 100644
--- a/package/gluon-config-mode-hostname/files/lib/gluon/config-mode/wizard/0100-hostname.lua
+++ b/package/gluon-config-mode-hostname/luasrc/lib/gluon/config-mode/wizard/0100-hostname.lua
@@ -1,5 +1,6 @@
local cbi = require "luci.cbi"
local i18n = require "luci.i18n"
+local pretty_hostname = require "pretty_hostname"
local uci = luci.model.uci.cursor()
local M = {}
@@ -7,14 +8,12 @@ local M = {}
function M.section(form)
local s = form:section(cbi.SimpleSection, nil, nil)
local o = s:option(cbi.Value, "_hostname", i18n.translate("Node name"))
- o.value = uci:get_first("system", "system", "hostname")
+ o.value = pretty_hostname.get(uci)
o.rmempty = false
- o.datatype = "hostname"
end
function M.handle(data)
- uci:set("system", uci:get_first("system", "system"), "hostname", data._hostname)
- uci:save("system")
+ pretty_hostname.set(uci, data._hostname)
uci:commit("system")
end
diff --git a/package/gluon-config-mode-mesh-vpn/Makefile b/package/gluon-config-mode-mesh-vpn/Makefile
index 35d53ea7..ec819a9c 100644
--- a/package/gluon-config-mode-mesh-vpn/Makefile
+++ b/package/gluon-config-mode-mesh-vpn/Makefile
@@ -26,10 +26,11 @@ endef
define Build/Compile
$(call GluonBuildI18N,gluon-config-mode-mesh-vpn,i18n)
+ $(call GluonSrcDiet,./luasrc,$(PKG_BUILD_DIR)/luadest/)
endef
define Package/gluon-config-mode-mesh-vpn/install
- $(CP) ./files/* $(1)/
+ $(CP) $(PKG_BUILD_DIR)/luadest/* $(1)/
$(call GluonInstallI18N,gluon-config-mode-mesh-vpn,$(1))
endef
diff --git a/package/gluon-config-mode-mesh-vpn/files/lib/gluon/config-mode/reboot/0100-mesh-vpn.lua b/package/gluon-config-mode-mesh-vpn/luasrc/lib/gluon/config-mode/reboot/0100-mesh-vpn.lua
similarity index 56%
rename from package/gluon-config-mode-mesh-vpn/files/lib/gluon/config-mode/reboot/0100-mesh-vpn.lua
rename to package/gluon-config-mode-mesh-vpn/luasrc/lib/gluon/config-mode/reboot/0100-mesh-vpn.lua
index c6e06975..07b6d228 100644
--- a/package/gluon-config-mode-mesh-vpn/files/lib/gluon/config-mode/reboot/0100-mesh-vpn.lua
+++ b/package/gluon-config-mode-mesh-vpn/luasrc/lib/gluon/config-mode/reboot/0100-mesh-vpn.lua
@@ -6,21 +6,28 @@ if meshvpn_enabled ~= "1" then
else
local i18n = require "luci.i18n"
local util = require "luci.util"
+
+ local gluon_luci = require 'gluon.luci'
local site = require 'gluon.site_config'
local sysconfig = require 'gluon.sysconfig'
+ local pretty_hostname = require 'pretty_hostname'
+
local pubkey = util.trim(util.exec("/etc/init.d/fastd show_key " .. "mesh_vpn"))
- local hostname = uci:get_first("system", "system", "hostname")
+ local hostname = pretty_hostname.get(uci)
local contact = uci:get_first("gluon-node-info", "owner", "contact")
local msg = i18n.translate('gluon-config-mode:pubkey')
return function ()
- luci.template.render_string(msg, { pubkey=pubkey
- , hostname=hostname
- , site=site
- , sysconfig=sysconfig
- , contact=contact
- })
- end
+ luci.template.render_string(msg, {
+ pubkey = pubkey,
+ hostname = hostname,
+ site = site,
+ sysconfig = sysconfig,
+ contact = contact,
+ escape = gluon_luci.escape,
+ urlescape = gluon_luci.urlescape,
+ })
+ end
end
diff --git a/package/gluon-config-mode-mesh-vpn/files/lib/gluon/config-mode/wizard/0300-mesh-vpn.lua b/package/gluon-config-mode-mesh-vpn/luasrc/lib/gluon/config-mode/wizard/0300-mesh-vpn.lua
similarity index 100%
rename from package/gluon-config-mode-mesh-vpn/files/lib/gluon/config-mode/wizard/0300-mesh-vpn.lua
rename to package/gluon-config-mode-mesh-vpn/luasrc/lib/gluon/config-mode/wizard/0300-mesh-vpn.lua
diff --git a/package/gluon-core/Makefile b/package/gluon-core/Makefile
index 725fb737..2b9cfb47 100644
--- a/package/gluon-core/Makefile
+++ b/package/gluon-core/Makefile
@@ -8,14 +8,14 @@ PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME)
include $(GLUONDIR)/include/package.mk
+
define Package/gluon-core
SECTION:=gluon
CATEGORY:=Gluon
TITLE:=Base files of Gluon
- DEPENDS:=+gluon-site +libgluonutil +lua-platform-info +lua-hash +luci-base +luci-lib-jsonc +odhcp6c +firewall
+ DEPENDS:=+gluon-site +libgluonutil +lua-platform-info +lua-hash +luci-base +luci-lib-jsonc +odhcp6c +firewall +pretty-hostname
endef
-
define Package/gluon-core/description
Gluon community wifi mesh firmware framework: core
endef
@@ -28,10 +28,12 @@ define Build/Configure
endef
define Build/Compile
+ $(call GluonSrcDiet,./luasrc,$(PKG_BUILD_DIR)/luadest/)
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
diff --git a/package/gluon-core/check_site.lua b/package/gluon-core/check_site.lua
index 1647d778..3586149e 100644
--- a/package/gluon-core/check_site.lua
+++ b/package/gluon-core/check_site.lua
@@ -28,5 +28,15 @@ for _, config in ipairs({'wifi24', 'wifi5'}) do
need_string('regdom') -- regdom is only required when wifi24 or wifi5 is configured
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
end
+
+need_boolean('poe_passthrough', false)
diff --git a/package/gluon-core/files/lib/gluon/core/mesh/setup.d/.keep b/package/gluon-core/files/lib/gluon/core/mesh/setup.d/.keep
new file mode 100644
index 00000000..e69de29b
diff --git a/package/gluon-core/files/lib/gluon/core/mesh/teardown.d/.keep b/package/gluon-core/files/lib/gluon/core/mesh/teardown.d/.keep
new file mode 100644
index 00000000..e69de29b
diff --git a/package/gluon-core/files/lib/gluon/upgrade/200-wireless b/package/gluon-core/files/lib/gluon/upgrade/200-wireless
deleted file mode 100755
index 5a4ec0a4..00000000
--- a/package/gluon-core/files/lib/gluon/upgrade/200-wireless
+++ /dev/null
@@ -1,35 +0,0 @@
-#!/usr/bin/lua
-
-local util = require 'gluon.util'
-local uci = require('luci.model.uci').cursor()
-local site = require 'gluon.site_config'
-local sysconfig = require 'gluon.sysconfig'
-
--- Initial
-if not sysconfig.gluon_version then
- uci:delete_all('wireless', 'wifi-iface')
-end
-
-local function get_channel(radio, config)
- if uci:get_first('gluon-core', 'wireless', 'preserve_channels') then
- return uci:get('wireless', radio, 'channel') or config.channel
- else
- return config.channel
- end
-end
-
-local function configure_radio(radio, index, config)
- if config then
- local channel = get_channel(radio, config)
-
- uci:delete('wireless', radio, 'disabled')
-
- uci:set('wireless', radio, 'channel', channel)
- uci:set('wireless', radio, 'htmode', 'HT20')
- uci:set('wireless', radio, 'country', site.regdom)
- end
-end
-
-util.iterate_radios(configure_radio)
-
-uci:save('wireless')
diff --git a/package/gluon-core/files/lib/netifd/proto/gluon_mesh.sh b/package/gluon-core/files/lib/netifd/proto/gluon_mesh.sh
new file mode 100755
index 00000000..aaa24c84
--- /dev/null
+++ b/package/gluon-core/files/lib/netifd/proto/gluon_mesh.sh
@@ -0,0 +1,39 @@
+#!/bin/sh
+
+. /lib/functions.sh
+. ../netifd-proto.sh
+init_proto "$@"
+
+proto_gluon_mesh_init_config() {
+ proto_config_add_boolean fixed_mtu
+ proto_config_add_boolean transitive
+}
+
+proto_gluon_mesh_setup() {
+ export CONFIG="$1"
+ export IFNAME="$2"
+
+ local fixed_mtu transitive
+ json_get_vars fixed_mtu transitive
+
+ export FIXED_MTU="$fixed_mtu"
+ export TRANSITIVE="$transitive"
+
+ for script in /lib/gluon/core/mesh/setup.d/*; do
+ [ ! -x "$script" ] || "$script"
+ done
+
+ proto_init_update "$IFNAME" 1
+ proto_send_update "$CONFIG"
+}
+
+proto_gluon_mesh_teardown() {
+ export CONFIG="$1"
+ export IFNAME="$2"
+
+ for script in /lib/gluon/core/mesh/teardown.d/*; do
+ [ ! -x "$script" ] || "$script"
+ done
+}
+
+add_protocol gluon_mesh
diff --git a/package/gluon-core/files/usr/lib/lua/gluon/util.lua b/package/gluon-core/files/usr/lib/lua/gluon/util.lua
deleted file mode 100644
index 72b6220d..00000000
--- a/package/gluon-core/files/usr/lib/lua/gluon/util.lua
+++ /dev/null
@@ -1,129 +0,0 @@
--- 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()
-
- for line in io.lines(input) do
- if line:sub(1, l) ~= prefix then
- f:write(line, '\n')
- end
- end
-
- return f
-end
-
-
-local function escape_args(ret, arg0, ...)
- if not arg0 then
- return ret
- end
-
- return escape_args(ret .. "'" .. string.gsub(arg0, "'", "'\\''") .. "' ", ...)
-end
-
-
-local os = os
-local string = string
-local tonumber = tonumber
-local ipairs = ipairs
-local table = table
-
-local nixio = require 'nixio'
-local hash = require 'hash'
-local sysconfig = require 'gluon.sysconfig'
-local site = require 'gluon.site_config'
-local uci = require('luci.model.uci').cursor()
-
-
-module 'gluon.util'
-
-function 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)
-end
-
-function readline(fd)
- local line = fd:read('*l')
- fd:close()
- return line
-end
-
-function lock(file)
- exec('lock', file)
-end
-
-function unlock(file)
- exec('lock', '-u', file)
-end
-
-function node_id()
- return string.gsub(sysconfig.primary_mac, ':', '')
-end
-
--- Generates a (hopefully) unique MAC address
--- The parameter defines the ID to add to the mac addr
---
--- IDs defined so far:
--- 0: client0; mesh-vpn
--- 1: mesh0
--- 2: ibss0
--- 3: client1; mesh-on-wan
--- 4: mesh1
--- 5: ibss1
--- 6: mesh-on-lan
--- 7: unused
-function generate_mac(i)
- 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)')
-
- 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
-
- -- It's necessary that the first 45 bits of the mac do
- -- not vary on a single hardware interface, since some chips are using
- -- a hardware mac filter. (e.g 'ramips-rt305x')
-
- 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)
-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 = {}
-
- 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')
-
- 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-core/files/lib/gluon/upgrade/001-upgrade b/package/gluon-core/luasrc/lib/gluon/upgrade/001-upgrade
similarity index 100%
rename from package/gluon-core/files/lib/gluon/upgrade/001-upgrade
rename to package/gluon-core/luasrc/lib/gluon/upgrade/001-upgrade
diff --git a/package/gluon-core/files/lib/gluon/upgrade/010-primary-mac b/package/gluon-core/luasrc/lib/gluon/upgrade/010-primary-mac
similarity index 53%
rename from package/gluon-core/files/lib/gluon/upgrade/010-primary-mac
rename to package/gluon-core/luasrc/lib/gluon/upgrade/010-primary-mac
index a913db90..c4f44065 100755
--- a/package/gluon-core/files/lib/gluon/upgrade/010-primary-mac
+++ b/package/gluon-core/luasrc/lib/gluon/upgrade/010-primary-mac
@@ -18,13 +18,26 @@ local try_files = {
'/sys/class/net/eth0/address'
}
-if not util.contains({'x86', 'brcm2708'}, platform.get_target()) then
+if not (
+ util.contains({'x86', 'brcm2708'}, platform.get_target()) or
+ platform.match('ar71xx', 'mikrotik')
+) then
table.insert(try_files, 1, '/sys/class/ieee80211/phy0/macaddress')
end
if platform.match('ar71xx', 'generic', {'tl-wdr3600', 'tl-wdr4300'}) then
table.insert(try_files, 1, '/sys/class/ieee80211/phy1/macaddress')
-elseif platform.match('ar71xx', 'generic', {'unifi-outdoor-plus', 'carambola2'}) then
+elseif platform.match('ramips', 'mt7621', {'dir-860l-b1'}) then
+ table.insert(try_files, 1, '/sys/class/ieee80211/phy1/macaddress')
+elseif platform.match('ar71xx', 'generic', {'unifi-outdoor-plus', 'carambola2',
+ 'mr600', 'mr600v2',
+ 'mr900', 'mr900v2',
+ 'mr1750', 'mr1750v2',
+ 'om2p', 'om2pv2',
+ 'om2p-hs', 'om2p-hsv2', 'om2p-hsv3',
+ 'om2p-lc',
+ 'om5p', 'om5p-an',
+ 'om5p-ac', 'om5p-acv2'}) then
table.insert(try_files, 1, '/sys/class/net/eth0/address')
elseif platform.match('ar71xx', 'generic', {'archer-c5', 'archer-c7'}) then
table.insert(try_files, 1, '/sys/class/net/eth1/address')
diff --git a/package/gluon-core/files/lib/gluon/upgrade/020-interfaces b/package/gluon-core/luasrc/lib/gluon/upgrade/020-interfaces
similarity index 91%
rename from package/gluon-core/files/lib/gluon/upgrade/020-interfaces
rename to package/gluon-core/luasrc/lib/gluon/upgrade/020-interfaces
index 1818ad00..34e1c8bb 100755
--- a/package/gluon-core/files/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'}) then
+ if platform.match('ar71xx', 'generic', {'cpe510', '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/files/lib/gluon/upgrade/030-system b/package/gluon-core/luasrc/lib/gluon/upgrade/030-system
similarity index 74%
rename from package/gluon-core/files/lib/gluon/upgrade/030-system
rename to package/gluon-core/luasrc/lib/gluon/upgrade/030-system
index 0086a5dc..90ad1ba5 100755
--- a/package/gluon-core/files/lib/gluon/upgrade/030-system
+++ b/package/gluon-core/luasrc/lib/gluon/upgrade/030-system
@@ -1,5 +1,6 @@
#!/usr/bin/lua
+local pretty_hostname = require 'pretty_hostname'
local sysconfig = require 'gluon.sysconfig'
-- Initial
@@ -10,7 +11,7 @@ if not sysconfig.gluon_version then
local system = uci:get_first('system', 'system')
- uci:set('system', system, 'hostname', (site.hostname_prefix or '') .. util.node_id())
+ pretty_hostname.set(uci, (site.hostname_prefix or '') .. util.node_id())
uci:set('system', system, 'timezone', site.timezone)
uci:save('system')
diff --git a/package/gluon-core/files/lib/gluon/upgrade/110-network b/package/gluon-core/luasrc/lib/gluon/upgrade/110-network
similarity index 95%
rename from package/gluon-core/files/lib/gluon/upgrade/110-network
rename to package/gluon-core/luasrc/lib/gluon/upgrade/110-network
index bf87d47f..c61b81d1 100755
--- a/package/gluon-core/files/lib/gluon/upgrade/110-network
+++ b/package/gluon-core/luasrc/lib/gluon/upgrade/110-network
@@ -9,11 +9,12 @@ uci:section('network', 'interface', 'wan',
{
ifname = sysconfig.wan_ifname,
type = 'bridge',
- igmp_snooping = 0,
+ multicast_querier = 0,
peerdns = 0,
auto = 1,
}
)
+uci:delete('network', 'wan', 'igmp_snooping')
if not uci:get('network', 'wan', 'proto') then
uci:set('network', 'wan', 'proto', 'dhcp')
diff --git a/package/gluon-core/files/lib/gluon/upgrade/120-ntp-servers b/package/gluon-core/luasrc/lib/gluon/upgrade/120-ntp-servers
similarity index 100%
rename from package/gluon-core/files/lib/gluon/upgrade/120-ntp-servers
rename to package/gluon-core/luasrc/lib/gluon/upgrade/120-ntp-servers
diff --git a/package/gluon-core/files/lib/gluon/upgrade/130-reboot-on-oom b/package/gluon-core/luasrc/lib/gluon/upgrade/130-reboot-on-oom
similarity index 100%
rename from package/gluon-core/files/lib/gluon/upgrade/130-reboot-on-oom
rename to package/gluon-core/luasrc/lib/gluon/upgrade/130-reboot-on-oom
diff --git a/package/gluon-core/files/lib/gluon/upgrade/140-firewall-rules b/package/gluon-core/luasrc/lib/gluon/upgrade/140-firewall-rules
similarity index 100%
rename from package/gluon-core/files/lib/gluon/upgrade/140-firewall-rules
rename to package/gluon-core/luasrc/lib/gluon/upgrade/140-firewall-rules
diff --git a/package/gluon-core/luasrc/lib/gluon/upgrade/150-poe-passthrough b/package/gluon-core/luasrc/lib/gluon/upgrade/150-poe-passthrough
new file mode 100755
index 00000000..81e6740b
--- /dev/null
+++ b/package/gluon-core/luasrc/lib/gluon/upgrade/150-poe-passthrough
@@ -0,0 +1,13 @@
+#!/usr/bin/lua
+
+local sysconfig = require 'gluon.sysconfig'
+local site = require 'gluon.site_config'
+
+if (not sysconfig.gluon_version) and (site.poe_passthrough == true) then
+ local uci = require('luci.model.uci').cursor()
+
+ if uci:get('system', 'gpio_switch_poe_passthrough') then
+ uci:set('system', 'gpio_switch_poe_passthrough', 'value', 1)
+ uci:save('system')
+ end
+end
diff --git a/package/gluon-core/luasrc/lib/gluon/upgrade/200-wireless b/package/gluon-core/luasrc/lib/gluon/upgrade/200-wireless
new file mode 100755
index 00000000..6e809572
--- /dev/null
+++ b/package/gluon-core/luasrc/lib/gluon/upgrade/200-wireless
@@ -0,0 +1,213 @@
+#!/usr/bin/lua
+
+local util = require 'gluon.util'
+local site = require 'gluon.site_config'
+local sysconfig = require 'gluon.sysconfig'
+
+local uci = require('luci.model.uci').cursor()
+
+-- Initial
+if not sysconfig.gluon_version then
+ uci:delete_all('wireless', 'wifi-iface')
+end
+
+local function get_channel(radio, config)
+ if uci:get_first('gluon-core', 'wireless', 'preserve_channels') then
+ return uci:get('wireless', radio, 'channel') or config.channel
+ else
+ return config.channel
+ end
+end
+
+local function is_disabled(name)
+ if uci:get('wireless', name) then
+ return uci:get_bool('wireless', name, 'disabled')
+ end
+end
+
+-- Returns the first argument that is not nil; don't call without any non-nil arguments!
+local function first_non_nil(first, ...)
+ if first ~= nil then
+ return first
+ else
+ return first_non_nil(...)
+ end
+end
+
+
+local function configure_ibss(config, radio, index, suffix, disabled)
+ local name = 'ibss_' .. radio
+
+ uci:delete('network', name)
+ uci:delete('network', name .. '_vlan')
+ uci:delete('wireless', name)
+
+ if not config then
+ return
+ end
+
+ local macaddr = util.get_wlan_mac(radio, index, 3)
+ if not macaddr then
+ return
+ end
+
+ if config.vlan then
+ uci:section('network', 'interface', name,
+ {
+ proto = 'none',
+ }
+ )
+
+ uci:section('network', 'interface', name .. '_vlan',
+ {
+ ifname = '@' .. name .. '.' .. config.vlan,
+ proto = 'gluon_mesh',
+ }
+ )
+ else
+ uci:section('network', 'interface', name,
+ {
+ proto = 'gluon_mesh',
+ }
+ )
+ end
+
+ uci:section('wireless', 'wifi-iface', name,
+ {
+ device = radio,
+ network = name,
+ mode = 'adhoc',
+ ssid = config.ssid,
+ bssid = config.bssid,
+ macaddr = macaddr,
+ mcast_rate = config.mcast_rate,
+ ifname = suffix and 'ibss' .. suffix,
+ disabled = disabled and 1 or 0,
+ }
+ )
+end
+
+local function configure_mesh(config, radio, index, suffix, disabled)
+ local name = 'mesh_' .. radio
+ local macfilter = uci:get('wireless', name, 'macfilter')
+ local maclist = uci:get('wireless', name, 'maclist')
+
+ uci:delete('network', name)
+ uci:delete('wireless', name)
+
+ if not config then
+ return
+ end
+
+ local macaddr = util.get_wlan_mac(radio, index, 2)
+ if not macaddr then
+ return
+ end
+
+ uci:section('network', 'interface', name,
+ {
+ proto = 'gluon_mesh',
+ }
+ )
+
+ uci:section('wireless', 'wifi-iface', name,
+ {
+ device = radio,
+ network = name,
+ mode = 'mesh',
+ mesh_id = config.id,
+ mesh_fwding = 0,
+ macaddr = macaddr,
+ mcast_rate = config.mcast_rate,
+ ifname = suffix and 'mesh' .. suffix,
+ disabled = disabled and 1 or 0,
+ macfilter = macfilter,
+ maclist = maclist,
+ }
+ )
+end
+
+local function fixup_wan(radio, index)
+ local name = 'wan_' .. radio
+
+ if not uci:get('wireless', name) then
+ return
+ end
+
+ local macaddr = util.get_wlan_mac(radio, index, 4)
+ if not macaddr then
+ return
+ end
+
+ uci:set('wireless', name, 'macaddr', macaddr)
+end
+
+local function configure_radio(radio, index, config)
+ if not config then
+ return
+ end
+
+ local suffix = radio:match('^radio(%d+)$')
+ if not suffix then
+ return
+ end
+
+ local channel = get_channel(radio, config)
+
+ uci:delete('wireless', radio, 'disabled')
+
+ uci:set('wireless', radio, 'channel', channel)
+ uci:set('wireless', radio, 'htmode', 'HT20')
+ uci:set('wireless', radio, 'country', site.regdom)
+
+ if config.supported_rates then
+ uci:set_list('wireless', radio, 'supported_rates', config.supported_rates)
+ else
+ uci:delete('wireless', radio, 'supported_rates')
+ end
+
+ if config.basic_rate then
+ uci:set_list('wireless', radio, 'basic_rate', config.basic_rate)
+ else
+ uci:delete('wireless', radio, 'basic_rate')
+ end
+
+
+ local ibss_disabled = is_disabled('ibss_' .. radio)
+ local mesh_disabled = is_disabled('mesh_' .. radio)
+
+ configure_ibss(config.ibss, radio, index, suffix,
+ first_non_nil(
+ ibss_disabled,
+ mesh_disabled,
+ (config.ibss or {}).disabled, -- will be nil if config.ibss or config.ibss.disabled is unset
+ false
+ )
+ )
+ configure_mesh(config.mesh, radio, index, suffix,
+ first_non_nil(
+ mesh_disabled,
+ ibss_disabled,
+ (config.mesh or {}).disabled, -- will be nil if config.mesh or config.mesh.disabled is unset
+ false
+ )
+ )
+
+ fixup_wan(radio, index)
+end
+
+util.iterate_radios(configure_radio)
+
+
+if uci:get('system', 'rssid_wlan0') then
+ if uci:get('wireless', 'mesh_radio0') then
+ uci:set('system', 'rssid_wlan0', 'dev', 'mesh0')
+ else
+ uci:set('system', 'rssid_wlan0', 'dev', 'ibss0')
+ end
+
+ uci:save('system')
+end
+
+uci:save('wireless')
+uci:save('network')
diff --git a/package/gluon-core/luasrc/lib/gluon/upgrade/210-interface-wan b/package/gluon-core/luasrc/lib/gluon/upgrade/210-interface-wan
new file mode 100755
index 00000000..0c780f07
--- /dev/null
+++ b/package/gluon-core/luasrc/lib/gluon/upgrade/210-interface-wan
@@ -0,0 +1,16 @@
+#!/usr/bin/lua
+
+local site = require 'gluon.site_config'
+local uci = require('luci.model.uci').cursor()
+
+if not uci:get('network', 'mesh_wan') then
+ uci:section('network', 'interface', 'mesh_wan', {
+ ifname = 'br-wan',
+ proto = 'gluon_mesh',
+ transitive = 1,
+ fixed_mtu = 1,
+ auto = site.mesh_on_wan and 1 or 0,
+ })
+end
+
+uci:save('network')
diff --git a/package/gluon-mesh-batman-adv-core/files/lib/gluon/upgrade/340-gluon-mesh-batman-adv-core-mesh-on-lan b/package/gluon-core/luasrc/lib/gluon/upgrade/220-interface-lan
similarity index 83%
rename from package/gluon-mesh-batman-adv-core/files/lib/gluon/upgrade/340-gluon-mesh-batman-adv-core-mesh-on-lan
rename to package/gluon-core/luasrc/lib/gluon/upgrade/220-interface-lan
index 99ca4213..21759aa9 100755
--- a/package/gluon-mesh-batman-adv-core/files/lib/gluon/upgrade/340-gluon-mesh-batman-adv-core-mesh-on-lan
+++ b/package/gluon-core/luasrc/lib/gluon/upgrade/220-interface-lan
@@ -12,13 +12,12 @@ if not sysconfig.lan_ifname then
end
uci:section('network', 'interface', 'mesh_lan', {
- ifname = sysconfig.lan_ifname,
- type = 'bridge',
+ ifname = sysconfig.lan_ifname,
+ type = 'bridge',
igmp_snooping = 0,
- proto = 'batadv',
- mesh = 'bat0',
- mesh_no_rebroadcast = '1',
- macaddr = util.generate_mac(6),
+ proto = 'gluon_mesh',
+ transitive = 1,
+ fixed_mtu = 1,
})
if uci:get('network', 'mesh_lan', 'auto') == nil then
diff --git a/package/gluon-core/files/lib/gluon/upgrade/500-opkg b/package/gluon-core/luasrc/lib/gluon/upgrade/500-opkg
similarity index 100%
rename from package/gluon-core/files/lib/gluon/upgrade/500-opkg
rename to package/gluon-core/luasrc/lib/gluon/upgrade/500-opkg
diff --git a/package/gluon-core/luasrc/lib/gluon/upgrade/800-migrate-batadv b/package/gluon-core/luasrc/lib/gluon/upgrade/800-migrate-batadv
new file mode 100755
index 00000000..7843e6a1
--- /dev/null
+++ b/package/gluon-core/luasrc/lib/gluon/upgrade/800-migrate-batadv
@@ -0,0 +1,24 @@
+#!/usr/bin/lua
+
+local uci = require('luci.model.uci').cursor()
+
+local function migrate_iface(iface)
+ if iface.proto ~= 'batadv' or iface.mesh ~= 'bat0' then
+ return
+ end
+
+ local s = iface['.name']
+
+ uci:set('network', s, 'proto', 'gluon_mesh')
+ uci:set('network', s, 'fixed_mtu', '1')
+
+ if iface.mesh_no_rebroadcast then
+ uci:set('network', s, 'transitive', iface.mesh_no_rebroadcast)
+ end
+
+ uci:delete('network', s, 'mesh')
+ uci:delete('network', s, 'mesh_no_rebroadcast')
+end
+
+uci:foreach('network', 'interface', migrate_iface)
+uci:save('network')
diff --git a/package/gluon-core/files/lib/gluon/upgrade/999-version b/package/gluon-core/luasrc/lib/gluon/upgrade/999-version
similarity index 100%
rename from package/gluon-core/files/lib/gluon/upgrade/999-version
rename to package/gluon-core/luasrc/lib/gluon/upgrade/999-version
diff --git a/package/gluon-core/files/usr/lib/lua/gluon/platform.lua b/package/gluon-core/luasrc/usr/lib/lua/gluon/platform.lua
similarity index 86%
rename from package/gluon-core/files/usr/lib/lua/gluon/platform.lua
rename to package/gluon-core/luasrc/usr/lib/lua/gluon/platform.lua
index 3d56f081..6483ad2e 100644
--- a/package/gluon-core/files/usr/lib/lua/gluon/platform.lua
+++ b/package/gluon-core/luasrc/usr/lib/lua/gluon/platform.lua
@@ -21,7 +21,7 @@ function match(target, subtarget, boards)
return false
end
- if not util.contains(boards, get_board_name()) then
+ if boards and not util.contains(boards, get_board_name()) then
return false
end
diff --git a/package/gluon-core/files/usr/lib/lua/gluon/site_config.lua b/package/gluon-core/luasrc/usr/lib/lua/gluon/site_config.lua
similarity index 100%
rename from package/gluon-core/files/usr/lib/lua/gluon/site_config.lua
rename to package/gluon-core/luasrc/usr/lib/lua/gluon/site_config.lua
diff --git a/package/gluon-core/files/usr/lib/lua/gluon/sysconfig.lua b/package/gluon-core/luasrc/usr/lib/lua/gluon/sysconfig.lua
similarity index 100%
rename from package/gluon-core/files/usr/lib/lua/gluon/sysconfig.lua
rename to package/gluon-core/luasrc/usr/lib/lua/gluon/sysconfig.lua
diff --git a/package/gluon-core/files/usr/lib/lua/gluon/sysctl.lua b/package/gluon-core/luasrc/usr/lib/lua/gluon/sysctl.lua
similarity index 100%
rename from package/gluon-core/files/usr/lib/lua/gluon/sysctl.lua
rename to package/gluon-core/luasrc/usr/lib/lua/gluon/sysctl.lua
diff --git a/package/gluon-core/files/usr/lib/lua/gluon/users.lua b/package/gluon-core/luasrc/usr/lib/lua/gluon/users.lua
similarity index 100%
rename from package/gluon-core/files/usr/lib/lua/gluon/users.lua
rename to package/gluon-core/luasrc/usr/lib/lua/gluon/users.lua
diff --git a/package/gluon-core/luasrc/usr/lib/lua/gluon/util.lua b/package/gluon-core/luasrc/usr/lib/lua/gluon/util.lua
new file mode 100644
index 00000000..0ae50b4d
--- /dev/null
+++ b/package/gluon-core/luasrc/usr/lib/lua/gluon/util.lua
@@ -0,0 +1,195 @@
+-- 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()
+
+ for line in io.lines(input) do
+ if line:sub(1, l) ~= prefix then
+ f:write(line, '\n')
+ end
+ end
+
+ return f
+end
+
+
+local function escape_args(ret, arg0, ...)
+ if not arg0 then
+ return ret
+ end
+
+ return escape_args(ret .. "'" .. string.gsub(arg0, "'", "'\\''") .. "' ", ...)
+end
+
+
+local io = io
+local os = os
+local string = string
+local tonumber = tonumber
+local ipairs = ipairs
+local table = table
+
+local nixio = require 'nixio'
+local hash = require 'hash'
+local sysconfig = require 'gluon.sysconfig'
+local site = require 'gluon.site_config'
+local uci = require('luci.model.uci').cursor()
+local lutil = require 'luci.util'
+local fs = require 'nixio.fs'
+
+
+module 'gluon.util'
+
+function 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)
+end
+
+function readline(fd)
+ local line = fd:read('*l')
+ fd:close()
+ return line
+end
+
+function lock(file)
+ exec('lock', file)
+end
+
+function unlock(file)
+ exec('lock', '-u', file)
+end
+
+function node_id()
+ return string.gsub(sysconfig.primary_mac, ':', '')
+end
+
+
+local function find_phy_by_path(path)
+ 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
+end
+
+local function find_phy(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
+end
+
+local function get_addresses(radio)
+ local phy = find_phy(radio)
+ if not phy then
+ return function() end
+ end
+
+ return io.lines('/sys/class/ieee80211/' .. phy .. '/addresses')
+end
+
+-- Generates a (hopefully) unique MAC address
+-- The parameter defines the ID to add to the MAC address
+--
+-- IDs defined so far:
+-- 0: client0; WAN
+-- 1: mesh0
+-- 2: ibss0
+-- 3: wan_radio0 (private WLAN); batman-adv primary address
+-- 4: client1; LAN
+-- 5: mesh1
+-- 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)
+
+ 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 = 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')
+
+ 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)
+end
+
+local function get_wlan_mac_from_driver(radio, vif)
+ 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
+
+ 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
+
+ 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 = {}
+
+ 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')
+
+ 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-ebtables-filter-multicast/Makefile b/package/gluon-ebtables-filter-multicast/Makefile
index 93b7f9a5..2b622902 100644
--- a/package/gluon-ebtables-filter-multicast/Makefile
+++ b/package/gluon-ebtables-filter-multicast/Makefile
@@ -8,6 +8,7 @@ PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME)
include $(INCLUDE_DIR)/package.mk
+
define Package/gluon-ebtables-filter-multicast
SECTION:=gluon
CATEGORY:=Gluon
diff --git a/package/gluon-ebtables-filter-multicast/files/lib/gluon/ebtables/100-mcast-chain b/package/gluon-ebtables-filter-multicast/files/lib/gluon/ebtables/100-mcast-chain
deleted file mode 100644
index ec0013a3..00000000
--- a/package/gluon-ebtables-filter-multicast/files/lib/gluon/ebtables/100-mcast-chain
+++ /dev/null
@@ -1 +0,0 @@
-chain('MULTICAST_OUT', 'DROP')
diff --git a/package/gluon-ebtables-filter-multicast/files/lib/gluon/ebtables/110-mcast-allow-icmpv6 b/package/gluon-ebtables-filter-multicast/files/lib/gluon/ebtables/110-mcast-allow-icmpv6
index 8d3b7ec2..0058ed86 100644
--- a/package/gluon-ebtables-filter-multicast/files/lib/gluon/ebtables/110-mcast-allow-icmpv6
+++ b/package/gluon-ebtables-filter-multicast/files/lib/gluon/ebtables/110-mcast-allow-icmpv6
@@ -1,5 +1,3 @@
-rule 'MULTICAST_OUT -p IPv6 --ip6-protocol ipv6-icmp --ip6-icmp-type echo-request -j DROP'
-rule 'MULTICAST_OUT -p IPv6 --ip6-protocol ipv6-icmp --ip6-icmp-type 139 -j DROP'
-rule 'MULTICAST_OUT -p IPv6 --ip6-protocol ipv6-icmp -j RETURN'
-
-rule 'MULTICAST_OUT -p IPv6 --ip6-protocol 0 -j RETURN' -- hop-by-hop
+rule 'MULTICAST_OUT_ICMPV6 -p IPv6 --ip6-protocol ipv6-icmp --ip6-icmp-type echo-request -j RETURN'
+rule 'MULTICAST_OUT_ICMPV6 -p IPv6 --ip6-protocol ipv6-icmp --ip6-icmp-type 139 -j RETURN' -- ICMP Node Information Query
+rule 'MULTICAST_OUT_ICMPV6 -j ACCEPT'
diff --git a/package/gluon-ebtables-filter-multicast/files/lib/gluon/ebtables/300-mcast b/package/gluon-ebtables-filter-multicast/files/lib/gluon/ebtables/300-mcast
deleted file mode 100644
index c52f122f..00000000
--- a/package/gluon-ebtables-filter-multicast/files/lib/gluon/ebtables/300-mcast
+++ /dev/null
@@ -1,2 +0,0 @@
-rule 'FORWARD --logical-out br-client -o bat0 -d Multicast -j MULTICAST_OUT'
-rule 'OUTPUT --logical-out br-client -o bat0 -d Multicast -j MULTICAST_OUT'
diff --git a/package/gluon-ebtables-filter-multicast/files/lib/gluon/ebtables/355-mcast-drop b/package/gluon-ebtables-filter-multicast/files/lib/gluon/ebtables/355-mcast-drop
new file mode 100644
index 00000000..46ac01a5
--- /dev/null
+++ b/package/gluon-ebtables-filter-multicast/files/lib/gluon/ebtables/355-mcast-drop
@@ -0,0 +1 @@
+rule ('MULTICAST_OUT -j DROP')
diff --git a/package/gluon-ebtables-filter-ra-dhcp/Makefile b/package/gluon-ebtables-filter-ra-dhcp/Makefile
index ea6a737d..acec081f 100644
--- a/package/gluon-ebtables-filter-ra-dhcp/Makefile
+++ b/package/gluon-ebtables-filter-ra-dhcp/Makefile
@@ -8,6 +8,7 @@ PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME)
include $(INCLUDE_DIR)/package.mk
+
define Package/gluon-ebtables-filter-ra-dhcp
SECTION:=gluon
CATEGORY:=Gluon
diff --git a/package/gluon-ebtables-segment-mld/Makefile b/package/gluon-ebtables-segment-mld/Makefile
new file mode 100644
index 00000000..e3aacde1
--- /dev/null
+++ b/package/gluon-ebtables-segment-mld/Makefile
@@ -0,0 +1,51 @@
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=gluon-ebtables-segment-mld
+PKG_VERSION:=1
+PKG_RELEASE:=1
+
+PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME)
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/gluon-ebtables-segment-mld
+ SECTION:=gluon
+ CATEGORY:=Gluon
+ TITLE:=Ebtables filters for IGMP/MLD packets
+ DEPENDS:=+gluon-core +gluon-ebtables
+endef
+
+define Package/gluon-ebtables-segment-mld/description
+ Gluon community wifi mesh firmware framework: Ebtables filters for
+ IGMP/MLD packets
+
+ These filters drop IGMP/MLD packets before they enter the mesh and
+ filter any IGMP/MLD packets coming from the mesh.
+
+ IGMP/MLD have the concept of a local, elected Querier. For more
+ decentralization and increased robustness, the idea of this package is
+ to split the IGMP/MLD domain a querier is responsible for, allowing to
+ have a querier per node. The split IGMP/MLD domain will also reduce
+ overhead for this packet type, increasing scalability.
+
+ Beware of the consequences of using this package though: You might need
+ to explicitly, manually mark ports on snooping switches leading towards
+ your mesh node as multicast router ports for now (Multicast Router
+ Discovery, MRD, not implemented yet).
+endef
+
+define Build/Prepare
+ mkdir -p $(PKG_BUILD_DIR)
+endef
+
+define Build/Configure
+endef
+
+define Build/Compile
+endef
+
+define Package/gluon-ebtables-segment-mld/install
+ $(CP) ./files/* $(1)/
+endef
+
+$(eval $(call BuildPackage,gluon-ebtables-segment-mld))
diff --git a/package/gluon-ebtables-segment-mld/files/lib/gluon/ebtables/100-mcast-in-chain b/package/gluon-ebtables-segment-mld/files/lib/gluon/ebtables/100-mcast-in-chain
new file mode 100644
index 00000000..69d6bf18
--- /dev/null
+++ b/package/gluon-ebtables-segment-mld/files/lib/gluon/ebtables/100-mcast-in-chain
@@ -0,0 +1,2 @@
+chain('MULTICAST_IN', 'RETURN', 'nat')
+chain('MULTICAST_IN_ICMPV6', 'RETURN', 'nat')
diff --git a/package/gluon-ebtables-segment-mld/files/lib/gluon/ebtables/101-mcast-in-rule b/package/gluon-ebtables-segment-mld/files/lib/gluon/ebtables/101-mcast-in-rule
new file mode 100644
index 00000000..4eef2e7e
--- /dev/null
+++ b/package/gluon-ebtables-segment-mld/files/lib/gluon/ebtables/101-mcast-in-rule
@@ -0,0 +1,2 @@
+rule ('PREROUTING -d Multicast --logical-in br-client -i bat0 -j MULTICAST_IN', 'nat')
+rule ('MULTICAST_IN -p IPv6 --ip6-protocol ipv6-icmp -j MULTICAST_IN_ICMPV6', 'nat')
diff --git a/package/gluon-ebtables-segment-mld/files/lib/gluon/ebtables/105-mcast-drop-igmp b/package/gluon-ebtables-segment-mld/files/lib/gluon/ebtables/105-mcast-drop-igmp
new file mode 100644
index 00000000..08052721
--- /dev/null
+++ b/package/gluon-ebtables-segment-mld/files/lib/gluon/ebtables/105-mcast-drop-igmp
@@ -0,0 +1,2 @@
+rule('MULTICAST_OUT -p IPv4 --ip-protocol igmp -j DROP')
+rule('MULTICAST_IN -p IPv4 --ip-protocol igmp -j DROP', 'nat')
diff --git a/package/gluon-ebtables-segment-mld/files/lib/gluon/ebtables/105-mcast-drop-mld b/package/gluon-ebtables-segment-mld/files/lib/gluon/ebtables/105-mcast-drop-mld
new file mode 100644
index 00000000..b6090c22
--- /dev/null
+++ b/package/gluon-ebtables-segment-mld/files/lib/gluon/ebtables/105-mcast-drop-mld
@@ -0,0 +1,9 @@
+rule('MULTICAST_OUT_ICMPV6 -p IPv6 --ip6-protocol ipv6-icmp --ip6-icmp-type 130 -j DROP') -- MLD Query
+rule('MULTICAST_OUT_ICMPV6 -p IPv6 --ip6-protocol ipv6-icmp --ip6-icmp-type 131 -j DROP') -- MLDv1 Report
+rule('MULTICAST_OUT_ICMPV6 -p IPv6 --ip6-protocol ipv6-icmp --ip6-icmp-type 132 -j DROP') -- MLDv1 Done
+rule('MULTICAST_OUT_ICMPV6 -p IPv6 --ip6-protocol ipv6-icmp --ip6-icmp-type 143 -j DROP') -- MLDv2 Report
+
+rule('MULTICAST_IN_ICMPV6 -p IPv6 --ip6-protocol ipv6-icmp --ip6-icmp-type 130 -j DROP', 'nat') -- MLD Query
+rule('MULTICAST_IN_ICMPV6 -p IPv6 --ip6-protocol ipv6-icmp --ip6-icmp-type 131 -j DROP', 'nat') -- MLDv1 Report
+rule('MULTICAST_IN_ICMPV6 -p IPv6 --ip6-protocol ipv6-icmp --ip6-icmp-type 132 -j DROP', 'nat') -- MLDv1 Done
+rule('MULTICAST_IN_ICMPV6 -p IPv6 --ip6-protocol ipv6-icmp --ip6-icmp-type 143 -j DROP', 'nat') -- MLDv2 Report
diff --git a/package/gluon-ebtables/Makefile b/package/gluon-ebtables/Makefile
index 39c654c1..43185c73 100644
--- a/package/gluon-ebtables/Makefile
+++ b/package/gluon-ebtables/Makefile
@@ -8,6 +8,7 @@ PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME)
include $(INCLUDE_DIR)/package.mk
+
define Package/gluon-ebtables
SECTION:=gluon
CATEGORY:=Gluon
diff --git a/package/gluon-ebtables/files/etc/init.d/gluon-ebtables b/package/gluon-ebtables/files/etc/init.d/gluon-ebtables
index 5a770452..e6bffe96 100755
--- a/package/gluon-ebtables/files/etc/init.d/gluon-ebtables
+++ b/package/gluon-ebtables/files/etc/init.d/gluon-ebtables
@@ -24,12 +24,15 @@ exec_file() {
local file="$1"
/usr/bin/lua -e "
- function rule(command)
+ function rule(command, table)
+ table = table or 'filter'
os.execute($EBTABLES_RULE)
end
- function chain(name, policy)
+ function chain(name, policy, table)
+ table = table or 'filter'
os.execute($EBTABLES_CHAIN)
end
+
" "$file"
}
@@ -48,8 +51,8 @@ exec_all() {
start() {
(
- export EBTABLES_RULE='"ebtables -A " .. command'
- export EBTABLES_CHAIN='"ebtables -N " .. name .. " -P " .. policy'
+ export EBTABLES_RULE='"ebtables -t " .. table .. " -A " .. command'
+ export EBTABLES_CHAIN='"ebtables -t " .. table .. " -N " .. name .. " -P " .. policy'
if [ -z "$1" ]; then
exec_all ''
@@ -61,8 +64,8 @@ start() {
stop() {
(
- export EBTABLES_RULE='"ebtables -D " .. command'
- export EBTABLES_CHAIN='"ebtables -X " .. name'
+ export EBTABLES_RULE='"ebtables -t " .. table .. " -D " .. command'
+ export EBTABLES_CHAIN='"ebtables -t " .. table .. " -X " .. name'
if [ -z "$1" ]; then
exec_all '-r'
diff --git a/package/gluon-ebtables/files/lib/gluon/ebtables/100-dir-chain b/package/gluon-ebtables/files/lib/gluon/ebtables/100-dir-chain
index 31c19c53..e6bf98e3 100644
--- a/package/gluon-ebtables/files/lib/gluon/ebtables/100-dir-chain
+++ b/package/gluon-ebtables/files/lib/gluon/ebtables/100-dir-chain
@@ -1,2 +1,5 @@
chain('IN_ONLY', 'RETURN')
chain('OUT_ONLY', 'RETURN')
+
+chain('MULTICAST_OUT', 'RETURN')
+chain('MULTICAST_OUT_ICMPV6', 'RETURN')
diff --git a/package/gluon-ebtables/files/lib/gluon/ebtables/350-mcast-dir-rules b/package/gluon-ebtables/files/lib/gluon/ebtables/350-mcast-dir-rules
new file mode 100644
index 00000000..01609068
--- /dev/null
+++ b/package/gluon-ebtables/files/lib/gluon/ebtables/350-mcast-dir-rules
@@ -0,0 +1,4 @@
+rule 'OUTPUT -d Multicast --logical-out br-client -o bat0 -j MULTICAST_OUT'
+rule 'FORWARD -d Multicast --logical-out br-client -o bat0 -j MULTICAST_OUT'
+
+rule 'MULTICAST_OUT -p IPv6 --ip6-protocol ipv6-icmp -j MULTICAST_OUT_ICMPV6'
diff --git a/package/gluon-legacy/Makefile b/package/gluon-legacy/Makefile
index 7320fba6..1cb2e5f4 100644
--- a/package/gluon-legacy/Makefile
+++ b/package/gluon-legacy/Makefile
@@ -7,6 +7,7 @@ PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME)
include $(GLUONDIR)/include/package.mk
+
define Package/gluon-legacy
SECTION:=gluon
CATEGORY:=Gluon
@@ -26,10 +27,11 @@ define Build/Configure
endef
define Build/Compile
+ $(call GluonSrcDiet,./luasrc,$(PKG_BUILD_DIR)/luadest/)
endef
define Package/gluon-legacy/install
- $(CP) ./files/* $(1)/
+ $(CP) $(PKG_BUILD_DIR)/luadest/* $(1)/
endef
define Package/gluon-legacy/postinst
diff --git a/package/gluon-legacy/files/lib/gluon/upgrade/000-legacy b/package/gluon-legacy/luasrc/lib/gluon/upgrade/000-legacy
similarity index 100%
rename from package/gluon-legacy/files/lib/gluon/upgrade/000-legacy
rename to package/gluon-legacy/luasrc/lib/gluon/upgrade/000-legacy
diff --git a/package/gluon-legacy/files/lib/gluon/upgrade/019-legacy-interfaces b/package/gluon-legacy/luasrc/lib/gluon/upgrade/019-legacy-interfaces
similarity index 100%
rename from package/gluon-legacy/files/lib/gluon/upgrade/019-legacy-interfaces
rename to package/gluon-legacy/luasrc/lib/gluon/upgrade/019-legacy-interfaces
diff --git a/package/gluon-legacy/files/lib/gluon/upgrade/210-legacy-wireless b/package/gluon-legacy/luasrc/lib/gluon/upgrade/210-legacy-wireless
similarity index 100%
rename from package/gluon-legacy/files/lib/gluon/upgrade/210-legacy-wireless
rename to package/gluon-legacy/luasrc/lib/gluon/upgrade/210-legacy-wireless
diff --git a/package/gluon-legacy/files/lib/gluon/upgrade/290-legacy-setup-mode b/package/gluon-legacy/luasrc/lib/gluon/upgrade/290-legacy-setup-mode
similarity index 100%
rename from package/gluon-legacy/files/lib/gluon/upgrade/290-legacy-setup-mode
rename to package/gluon-legacy/luasrc/lib/gluon/upgrade/290-legacy-setup-mode
diff --git a/package/gluon-legacy/files/lib/gluon/upgrade/290-legacy-simple-tc b/package/gluon-legacy/luasrc/lib/gluon/upgrade/290-legacy-simple-tc
similarity index 100%
rename from package/gluon-legacy/files/lib/gluon/upgrade/290-legacy-simple-tc
rename to package/gluon-legacy/luasrc/lib/gluon/upgrade/290-legacy-simple-tc
diff --git a/package/gluon-legacy/files/lib/gluon/upgrade/390-legacy-mesh-vpn-fastd b/package/gluon-legacy/luasrc/lib/gluon/upgrade/390-legacy-mesh-vpn-fastd
similarity index 100%
rename from package/gluon-legacy/files/lib/gluon/upgrade/390-legacy-mesh-vpn-fastd
rename to package/gluon-legacy/luasrc/lib/gluon/upgrade/390-legacy-mesh-vpn-fastd
diff --git a/package/gluon-legacy/files/lib/gluon/upgrade/990-legacy-late b/package/gluon-legacy/luasrc/lib/gluon/upgrade/990-legacy-late
similarity index 100%
rename from package/gluon-legacy/files/lib/gluon/upgrade/990-legacy-late
rename to package/gluon-legacy/luasrc/lib/gluon/upgrade/990-legacy-late
diff --git a/package/gluon-lock-password/Makefile b/package/gluon-lock-password/Makefile
index d0e99373..0583f96c 100644
--- a/package/gluon-lock-password/Makefile
+++ b/package/gluon-lock-password/Makefile
@@ -8,6 +8,7 @@ PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME)
include $(INCLUDE_DIR)/package.mk
+
define Package/gluon-lock-password
SECTION:=gluon
CATEGORY:=Gluon
diff --git a/package/gluon-luci-admin/Makefile b/package/gluon-luci-admin/Makefile
index 3e20d179..7b5f632a 100644
--- a/package/gluon-luci-admin/Makefile
+++ b/package/gluon-luci-admin/Makefile
@@ -13,11 +13,12 @@ include $(GLUONDIR)/include/package.mk
PKG_CONFIG_DEPENDS += $(GLUON_I18N_CONFIG)
+
define Package/gluon-luci-admin
SECTION:=gluon
CATEGORY:=Gluon
TITLE:=Luci based simple administration interface for mesh nodes
- DEPENDS:=gluon-config-mode-core-virtual
+ DEPENDS:=gluon-config-mode-core-virtual +pretty-hostname
endef
define Build/Prepare
@@ -29,10 +30,12 @@ endef
define Build/Compile
$(call GluonBuildI18N,gluon-luci-admin,i18n)
+ $(call GluonSrcDiet,./luasrc,$(PKG_BUILD_DIR)/luadest/)
endef
define Package/gluon-luci-admin/install
$(CP) ./files/* $(1)/
+ $(CP) $(PKG_BUILD_DIR)/luadest/* $(1)/
$(call GluonInstallI18N,gluon-luci-admin,$(1))
endef
diff --git a/package/gluon-luci-admin/files/usr/lib/lua/luci/view/admin/info.htm b/package/gluon-luci-admin/files/usr/lib/lua/luci/view/admin/info.htm
index da403c1b..03f3f2ca 100644
--- a/package/gluon-luci-admin/files/usr/lib/lua/luci/view/admin/info.htm
+++ b/package/gluon-luci-admin/files/usr/lib/lua/luci/view/admin/info.htm
@@ -1,45 +1,47 @@
<%-
- local fs = require 'nixio.fs'
- local uci = require('luci.model.uci').cursor()
- local util = require 'luci.util'
- local i18n = require 'luci.i18n'
+ local fs = require 'nixio.fs'
+ local uci = require('luci.model.uci').cursor()
+ local util = require 'luci.util'
+ local i18n = require 'luci.i18n'
+ local pretty_hostname = require 'pretty_hostname'
- local site = require 'gluon.site_config'
- local sysconfig = require 'gluon.sysconfig'
- local platform = require 'gluon.platform'
+ local gluon_luci = require "gluon.luci"
+ local site = require 'gluon.site_config'
+ local sysconfig = require 'gluon.sysconfig'
+ local platform = require 'gluon.platform'
- local keys = {
- hostname = i18n.translate('Hostname'),
- primary_mac = i18n.translate('MAC address'),
- model = i18n.translate('Hardware model'),
- version = i18n.translate('Gluon version'),
- release = i18n.translate('Firmware release'),
- site = i18n.translate('Site'),
- pubkey = i18n.translate('Public VPN key'),
- }
+ local keys = {
+ hostname = i18n.translate('Hostname'),
+ primary_mac = i18n.translate('MAC address'),
+ model = i18n.translate('Hardware model'),
+ version = i18n.translate('Gluon version'),
+ release = i18n.translate('Firmware release'),
+ site = i18n.translate('Site'),
+ pubkey = i18n.translate('Public VPN key'),
+ }
- local values = {
- hostname = uci:get_first('system', 'system', 'hostname'),
- primary_mac = sysconfig.primary_mac,
- model = platform.get_model(),
- version = util.trim(fs.readfile('/lib/gluon/gluon-version')),
- release = util.trim(fs.readfile('/lib/gluon/release')),
- site = site.site_name,
- pubkey = 'n/a',
- }
+ local values = {
+ hostname = pretty_hostname.get(uci),
+ primary_mac = sysconfig.primary_mac,
+ model = platform.get_model(),
+ version = util.trim(fs.readfile('/lib/gluon/gluon-version')),
+ release = util.trim(fs.readfile('/lib/gluon/release')),
+ site = site.site_name,
+ pubkey = 'n/a',
+ }
- local meshvpn_enabled = uci:get("fastd", "mesh_vpn", "enabled", "0")
- if meshvpn_enabled == "1" then
- local pubkey = util.trim(util.exec('/etc/init.d/fastd show_key mesh_vpn'))
- if pubkey ~= '' then
- values.pubkey = pubkey
- end
- end
+ local meshvpn_enabled = uci:get("fastd", "mesh_vpn", "enabled", "0")
+ if meshvpn_enabled == "1" then
+ local pubkey = util.trim(util.exec('/etc/init.d/fastd show_key mesh_vpn'))
+ if pubkey ~= '' then
+ values.pubkey = pubkey
+ end
+ end
-%>
<%:Information%>
<% for _, key in ipairs({'hostname', 'primary_mac', 'model', 'version', 'release', 'site', 'pubkey'}) do %>
-
<%=keys[key]%>
<%=values[key] or 'n/a'%>
+
<%=keys[key]%>
<%=gluon_luci.escape(values[key] or 'n/a')%>
<% end %>
diff --git a/package/gluon-luci-admin/i18n/de.po b/package/gluon-luci-admin/i18n/de.po
index ec109ae0..e2a371d8 100644
--- a/package/gluon-luci-admin/i18n/de.po
+++ b/package/gluon-luci-admin/i18n/de.po
@@ -26,8 +26,8 @@ msgstr "Fortfahren"
msgid "Don't switch off the device in any circumstance!"
msgstr "Unterbrich auf keinen Fall die Stromversorgung!"
-msgid "Expert Mode"
-msgstr "Expert Mode"
+msgid "Advanced settings"
+msgstr "Erweiterte Einstellungen"
msgid "Firmware image"
msgstr "Firmware-Datei"
diff --git a/package/gluon-luci-admin/i18n/fr.po b/package/gluon-luci-admin/i18n/fr.po
index 23eeb7ff..0a876a35 100644
--- a/package/gluon-luci-admin/i18n/fr.po
+++ b/package/gluon-luci-admin/i18n/fr.po
@@ -1,12 +1,12 @@
msgid ""
msgstr ""
-"Content-Type: text/plain; charset=UTF-8\n"
"Project-Id-Version: PACKAGE VERSION\n"
"PO-Revision-Date: 2015-08-19 20:20+0100\n"
"Last-Translator: Bernot Tobias \n"
"Language-Team: French\n"
"Language: fr\n"
"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
@@ -15,10 +15,11 @@ msgid ""
"secure password you don't use anywhere else.
If you set an empty "
"password, login via password will be disabled. This is the default."
msgstr ""
-"Alternativement, vous pouvez mettre un mot de passe pour accéder à votre nœud, "
-"Penseiz à choisir un mot de passe sûr, que vous n'utilisez nulle part ailleurs. "
-"
Si vous n'entrez pas de mot de passe, la connexion par mot de passe "
-"sera désactivée. La connexion par mot de passe est désactivée par défaut."
+"Alternativement, vous pouvez mettre un mot de passe pour accéder à votre "
+"nœud, Penseiz à choisir un mot de passe sûr, que vous n'utilisez nulle part "
+"ailleurs.
Si vous n'entrez pas de mot de passe, la connexion "
+"par mot de passe sera désactivée. La connexion par mot de passe est "
+"désactivée par défaut."
msgid "Continue"
msgstr "Continuer"
@@ -26,8 +27,8 @@ msgstr "Continuer"
msgid "Don't switch off the device in any circumstance!"
msgstr "N'interrompez en aucun cas l'alimentation!"
-msgid "Expert Mode"
-msgstr "Mode Expert"
+msgid "Advanced settings"
+msgstr "Paramètres avancés"
msgid "Firmware image"
msgstr "Fichier image"
@@ -88,8 +89,8 @@ msgid ""
"The upgrade will take a few minutes. When it is finished, your node will "
"reboot automatically."
msgstr ""
-"La mise à jour va prendre quelques minutes. Quand elle sera finie, "
-"votre nœud va redémarrer automatiquement."
+"La mise à jour va prendre quelques minutes. Quand elle sera finie, votre "
+"nœud va redémarrer automatiquement."
msgid "Unable to change the password."
msgstr "Le mot de passe n'a pas pu être changé."
diff --git a/package/gluon-luci-admin/i18n/gluon-luci-admin.pot b/package/gluon-luci-admin/i18n/gluon-luci-admin.pot
index 197b6367..d8a0adb0 100644
--- a/package/gluon-luci-admin/i18n/gluon-luci-admin.pot
+++ b/package/gluon-luci-admin/i18n/gluon-luci-admin.pot
@@ -13,7 +13,7 @@ msgstr ""
msgid "Don't switch off the device in any circumstance!"
msgstr ""
-msgid "Expert Mode"
+msgid "Advanced settings"
msgstr ""
msgid "Firmware image"
diff --git a/package/gluon-luci-admin/files/usr/lib/lua/luci/controller/admin/index.lua b/package/gluon-luci-admin/luasrc/usr/lib/lua/luci/controller/admin/index.lua
similarity index 92%
rename from package/gluon-luci-admin/files/usr/lib/lua/luci/controller/admin/index.lua
rename to package/gluon-luci-admin/luasrc/usr/lib/lua/luci/controller/admin/index.lua
index 55c0a248..6598c83a 100644
--- a/package/gluon-luci-admin/files/usr/lib/lua/luci/controller/admin/index.lua
+++ b/package/gluon-luci-admin/luasrc/usr/lib/lua/luci/controller/admin/index.lua
@@ -29,7 +29,7 @@ function index()
root.index = true
end
- local page = entry({"admin"}, alias("admin", "index"), _("Expert Mode"), 10)
+ local page = entry({"admin"}, alias("admin", "index"), _("Advanced settings"), 10)
page.sysauth = "root"
page.sysauth_authenticator = function() return "root" end
page.index = true
diff --git a/package/gluon-luci-admin/files/usr/lib/lua/luci/controller/admin/upgrade.lua b/package/gluon-luci-admin/luasrc/usr/lib/lua/luci/controller/admin/upgrade.lua
similarity index 97%
rename from package/gluon-luci-admin/files/usr/lib/lua/luci/controller/admin/upgrade.lua
rename to package/gluon-luci-admin/luasrc/usr/lib/lua/luci/controller/admin/upgrade.lua
index 29aecb95..2365f02c 100644
--- a/package/gluon-luci-admin/files/usr/lib/lua/luci/controller/admin/upgrade.lua
+++ b/package/gluon-luci-admin/luasrc/usr/lib/lua/luci/controller/admin/upgrade.lua
@@ -101,9 +101,7 @@ end
function image_supported(tmpfile)
-- XXX: yay...
return ( 0 == os.execute(
- ". /lib/functions.sh; " ..
- "include /lib/upgrade; " ..
- "platform_check_image %q >/dev/null"
+ "/sbin/sysupgrade -T %q >/dev/null"
% tmpfile
) )
end
diff --git a/package/gluon-luci-admin/files/usr/lib/lua/luci/model/cbi/admin/info.lua b/package/gluon-luci-admin/luasrc/usr/lib/lua/luci/model/cbi/admin/info.lua
similarity index 100%
rename from package/gluon-luci-admin/files/usr/lib/lua/luci/model/cbi/admin/info.lua
rename to package/gluon-luci-admin/luasrc/usr/lib/lua/luci/model/cbi/admin/info.lua
diff --git a/package/gluon-luci-admin/files/usr/lib/lua/luci/model/cbi/admin/remote.lua b/package/gluon-luci-admin/luasrc/usr/lib/lua/luci/model/cbi/admin/remote.lua
similarity index 100%
rename from package/gluon-luci-admin/files/usr/lib/lua/luci/model/cbi/admin/remote.lua
rename to package/gluon-luci-admin/luasrc/usr/lib/lua/luci/model/cbi/admin/remote.lua
diff --git a/package/gluon-luci-autoupdater/Makefile b/package/gluon-luci-autoupdater/Makefile
index 650c4692..908a0879 100644
--- a/package/gluon-luci-autoupdater/Makefile
+++ b/package/gluon-luci-autoupdater/Makefile
@@ -13,6 +13,7 @@ include $(GLUONDIR)/include/package.mk
PKG_CONFIG_DEPENDS += $(GLUON_I18N_CONFIG)
+
define Package/gluon-luci-autoupdater
SECTION:=gluon
CATEGORY:=Gluon
@@ -29,10 +30,11 @@ endef
define Build/Compile
$(call GluonBuildI18N,gluon-luci-autoupdater,i18n)
+ $(call GluonSrcDiet,./luasrc,$(PKG_BUILD_DIR)/luadest/)
endef
define Package/gluon-luci-autoupdater/install
- $(CP) ./files/* $(1)/
+ $(CP) $(PKG_BUILD_DIR)/luadest/* $(1)/
$(call GluonInstallI18N,gluon-luci-autoupdater,$(1))
endef
diff --git a/package/gluon-luci-autoupdater/files/usr/lib/lua/luci/controller/admin/autoupdater.lua b/package/gluon-luci-autoupdater/luasrc/usr/lib/lua/luci/controller/admin/autoupdater.lua
similarity index 100%
rename from package/gluon-luci-autoupdater/files/usr/lib/lua/luci/controller/admin/autoupdater.lua
rename to package/gluon-luci-autoupdater/luasrc/usr/lib/lua/luci/controller/admin/autoupdater.lua
diff --git a/package/gluon-luci-autoupdater/files/usr/lib/lua/luci/model/cbi/admin/autoupdater.lua b/package/gluon-luci-autoupdater/luasrc/usr/lib/lua/luci/model/cbi/admin/autoupdater.lua
similarity index 100%
rename from package/gluon-luci-autoupdater/files/usr/lib/lua/luci/model/cbi/admin/autoupdater.lua
rename to package/gluon-luci-autoupdater/luasrc/usr/lib/lua/luci/model/cbi/admin/autoupdater.lua
diff --git a/package/gluon-luci-mesh-vpn-fastd/Makefile b/package/gluon-luci-mesh-vpn-fastd/Makefile
index 1be12ccc..b6b7ce4f 100644
--- a/package/gluon-luci-mesh-vpn-fastd/Makefile
+++ b/package/gluon-luci-mesh-vpn-fastd/Makefile
@@ -10,6 +10,7 @@ include $(GLUONDIR)/include/package.mk
PKG_CONFIG_DEPENDS += $(GLUON_I18N_CONFIG)
+
define Package/gluon-luci-mesh-vpn-fastd
SECTION:=gluon
CATEGORY:=Gluon
@@ -26,10 +27,12 @@ endef
define Build/Compile
$(call GluonBuildI18N,gluon-mesh-vpn-fastd,i18n)
+ $(call GluonSrcDiet,./luasrc,$(PKG_BUILD_DIR)/luadest/)
endef
define Package/gluon-luci-mesh-vpn-fastd/install
$(CP) ./files/* $(1)/
+ $(CP) $(PKG_BUILD_DIR)/luadest/* $(1)/
$(call GluonInstallI18N,gluon-mesh-vpn-fastd,$(1))
endef
diff --git a/package/gluon-luci-mesh-vpn-fastd/files/usr/lib/lua/luci/controller/admin/mesh_vpn_fastd.lua b/package/gluon-luci-mesh-vpn-fastd/luasrc/usr/lib/lua/luci/controller/admin/mesh_vpn_fastd.lua
similarity index 100%
rename from package/gluon-luci-mesh-vpn-fastd/files/usr/lib/lua/luci/controller/admin/mesh_vpn_fastd.lua
rename to package/gluon-luci-mesh-vpn-fastd/luasrc/usr/lib/lua/luci/controller/admin/mesh_vpn_fastd.lua
diff --git a/package/gluon-luci-mesh-vpn-fastd/files/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
similarity index 100%
rename from package/gluon-luci-mesh-vpn-fastd/files/usr/lib/lua/luci/model/cbi/admin/mesh_vpn_fastd.lua
rename to package/gluon-luci-mesh-vpn-fastd/luasrc/usr/lib/lua/luci/model/cbi/admin/mesh_vpn_fastd.lua
diff --git a/package/gluon-luci-node-role/Makefile b/package/gluon-luci-node-role/Makefile
index ded7bd3f..2c862610 100644
--- a/package/gluon-luci-node-role/Makefile
+++ b/package/gluon-luci-node-role/Makefile
@@ -10,6 +10,7 @@ include $(GLUONDIR)/include/package.mk
PKG_CONFIG_DEPENDS += $(GLUON_I18N_CONFIG)
+
define Package/gluon-luci-node-role
SECTION:=gluon
CATEGORY:=Gluon
@@ -26,10 +27,11 @@ endef
define Build/Compile
$(call GluonBuildI18N,gluon-luci-node-role,i18n)
+ $(call GluonSrcDiet,./luasrc,$(PKG_BUILD_DIR)/luadest/)
endef
define Package/gluon-luci-node-role/install
- $(CP) ./files/* $(1)/
+ $(CP) $(PKG_BUILD_DIR)/luadest/* $(1)/
$(call GluonInstallI18N,gluon-luci-node-role,$(1))
endef
diff --git a/package/gluon-luci-node-role/files/usr/lib/lua/luci/controller/admin/noderole.lua b/package/gluon-luci-node-role/luasrc/usr/lib/lua/luci/controller/admin/noderole.lua
similarity index 100%
rename from package/gluon-luci-node-role/files/usr/lib/lua/luci/controller/admin/noderole.lua
rename to package/gluon-luci-node-role/luasrc/usr/lib/lua/luci/controller/admin/noderole.lua
diff --git a/package/gluon-luci-node-role/files/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
similarity index 100%
rename from package/gluon-luci-node-role/files/usr/lib/lua/luci/model/cbi/admin/noderole.lua
rename to package/gluon-luci-node-role/luasrc/usr/lib/lua/luci/model/cbi/admin/noderole.lua
diff --git a/package/gluon-luci-portconfig/Makefile b/package/gluon-luci-portconfig/Makefile
index 007c5fea..d4590864 100644
--- a/package/gluon-luci-portconfig/Makefile
+++ b/package/gluon-luci-portconfig/Makefile
@@ -13,11 +13,12 @@ include $(GLUONDIR)/include/package.mk
PKG_CONFIG_DEPENDS += $(GLUON_I18N_CONFIG)
+
define Package/gluon-luci-portconfig
SECTION:=gluon
CATEGORY:=Gluon
TITLE:=Luci module for advanced ethernet port configuration
- DEPENDS:=+gluon-luci-admin +gluon-mesh-batman-adv
+ DEPENDS:=+gluon-luci-admin +gluon-client-bridge
endef
define Build/Prepare
@@ -29,10 +30,11 @@ endef
define Build/Compile
$(call GluonBuildI18N,gluon-luci-portconfig,i18n)
+ $(call GluonSrcDiet,./luasrc,$(PKG_BUILD_DIR)/luadest/)
endef
define Package/gluon-luci-portconfig/install
- $(CP) ./files/* $(1)/
+ $(CP) $(PKG_BUILD_DIR)/luadest/* $(1)/
$(call GluonInstallI18N,gluon-luci-portconfig,$(1))
endef
diff --git a/package/gluon-luci-portconfig/i18n/de.po b/package/gluon-luci-portconfig/i18n/de.po
index 2197fdbe..a94e7d41 100644
--- a/package/gluon-luci-portconfig/i18n/de.po
+++ b/package/gluon-luci-portconfig/i18n/de.po
@@ -1,12 +1,12 @@
msgid ""
msgstr ""
-"Content-Type: text/plain; charset=UTF-8\n"
"Project-Id-Version: PACKAGE VERSION\n"
"PO-Revision-Date: 2015-05-04 02:08+0200\n"
"Last-Translator: \n"
"Language-Team: German\n"
"Language: de\n"
"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
@@ -16,12 +16,15 @@ msgstr "Automatisch (DHCP)"
msgid "Automatic (RA/DHCPv6)"
msgstr "Automatisch (RA/DHCPv6)"
-msgid "Enable meshing on the WAN interface"
-msgstr "Mesh auf dem WAN-Port aktivieren"
+msgid "Enable PoE passthrough"
+msgstr "PoE-Passthrough aktivieren"
msgid "Enable meshing on the LAN interface"
msgstr "Mesh auf dem LAN-Port aktivieren"
+msgid "Enable meshing on the WAN interface"
+msgstr "Mesh auf dem WAN-Port aktivieren"
+
msgid "Static"
msgstr "Statisch"
diff --git a/package/gluon-luci-portconfig/i18n/fr.po b/package/gluon-luci-portconfig/i18n/fr.po
index b5f7405d..3ec59395 100644
--- a/package/gluon-luci-portconfig/i18n/fr.po
+++ b/package/gluon-luci-portconfig/i18n/fr.po
@@ -1,28 +1,30 @@
msgid ""
msgstr ""
-"Content-Type: text/plain; charset=UTF-8\n"
"Project-Id-Version: PACKAGE VERSION\n"
"PO-Revision-Date: 2015-08-19 23:30+0100\n"
"Last-Translator:Tobias Bernot \n"
"Language-Team: French\n"
"Language: fr\n"
"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
-
msgid "Automatic (DHCP)"
msgstr "Automatique (DHCP)"
msgid "Automatic (RA/DHCPv6)"
msgstr "Automatique (RA/DHCPv6)"
-msgid "Enable meshing on the WAN interface"
-msgstr "Activer le réseau MESH sur les ports WAN"
+msgid "Enable PoE passthrough"
+msgstr ""
msgid "Enable meshing on the LAN interface"
msgstr "Activer le réseau MESH sur le port LAN"
+msgid "Enable meshing on the WAN interface"
+msgstr "Activer le réseau MESH sur les ports WAN"
+
msgid "Static"
msgstr "Statique"
diff --git a/package/gluon-luci-portconfig/i18n/gluon-luci-portconfig.pot b/package/gluon-luci-portconfig/i18n/gluon-luci-portconfig.pot
index 31ac71d3..5945016b 100644
--- a/package/gluon-luci-portconfig/i18n/gluon-luci-portconfig.pot
+++ b/package/gluon-luci-portconfig/i18n/gluon-luci-portconfig.pot
@@ -7,12 +7,15 @@ msgstr ""
msgid "Automatic (RA/DHCPv6)"
msgstr ""
-msgid "Enable meshing on the WAN interface"
+msgid "Enable PoE passthrough"
msgstr ""
msgid "Enable meshing on the LAN interface"
msgstr ""
+msgid "Enable meshing on the WAN interface"
+msgstr ""
+
msgid "Static"
msgstr ""
diff --git a/package/gluon-luci-portconfig/files/usr/lib/lua/luci/controller/admin/portconfig.lua b/package/gluon-luci-portconfig/luasrc/usr/lib/lua/luci/controller/admin/portconfig.lua
similarity index 100%
rename from package/gluon-luci-portconfig/files/usr/lib/lua/luci/controller/admin/portconfig.lua
rename to package/gluon-luci-portconfig/luasrc/usr/lib/lua/luci/controller/admin/portconfig.lua
diff --git a/package/gluon-luci-portconfig/files/usr/lib/lua/luci/model/cbi/admin/portconfig.lua b/package/gluon-luci-portconfig/luasrc/usr/lib/lua/luci/model/cbi/admin/portconfig.lua
similarity index 89%
rename from package/gluon-luci-portconfig/files/usr/lib/lua/luci/model/cbi/admin/portconfig.lua
rename to package/gluon-luci-portconfig/luasrc/usr/lib/lua/luci/model/cbi/admin/portconfig.lua
index 994f3077..2e40577a 100644
--- a/package/gluon-luci-portconfig/files/usr/lib/lua/luci/model/cbi/admin/portconfig.lua
+++ b/package/gluon-luci-portconfig/luasrc/usr/lib/lua/luci/model/cbi/admin/portconfig.lua
@@ -94,6 +94,13 @@ if sysconfig.lan_ifname then
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
+end
+
function f.handle(self, state, data)
if state == FORM_VALID then
@@ -137,6 +144,12 @@ function f.handle(self, state, data)
uci:save("network")
uci:commit("network")
+ 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
+
if dns then
if #data.dns > 0 then
uci:set("gluon-wan-dnsmasq", dns, "server", data.dns)
diff --git a/package/gluon-luci-private-wifi/Makefile b/package/gluon-luci-private-wifi/Makefile
index 604929dd..34608900 100644
--- a/package/gluon-luci-private-wifi/Makefile
+++ b/package/gluon-luci-private-wifi/Makefile
@@ -10,6 +10,7 @@ include $(GLUONDIR)/include/package.mk
PKG_CONFIG_DEPENDS += $(GLUON_I18N_CONFIG)
+
define Package/gluon-luci-private-wifi
SECTION:=gluon
CATEGORY:=Gluon
@@ -26,10 +27,11 @@ endef
define Build/Compile
$(call GluonBuildI18N,gluon-luci-private-wifi,i18n)
+ $(call GluonSrcDiet,./luasrc,$(PKG_BUILD_DIR)/luadest/)
endef
define Package/gluon-luci-private-wifi/install
- $(CP) ./files/* $(1)/
+ $(CP) $(PKG_BUILD_DIR)/luadest/* $(1)/
$(call GluonInstallI18N,gluon-luci-private-wifi,$(1))
endef
diff --git a/package/gluon-luci-private-wifi/files/usr/lib/lua/luci/controller/admin/privatewifi.lua b/package/gluon-luci-private-wifi/luasrc/usr/lib/lua/luci/controller/admin/privatewifi.lua
similarity index 100%
rename from package/gluon-luci-private-wifi/files/usr/lib/lua/luci/controller/admin/privatewifi.lua
rename to package/gluon-luci-private-wifi/luasrc/usr/lib/lua/luci/controller/admin/privatewifi.lua
diff --git a/package/gluon-luci-private-wifi/files/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
similarity index 67%
rename from package/gluon-luci-private-wifi/files/usr/lib/lua/luci/model/cbi/admin/privatewifi.lua
rename to package/gluon-luci-private-wifi/luasrc/usr/lib/lua/luci/model/cbi/admin/privatewifi.lua
index 788ff430..46a1a9d7 100644
--- a/package/gluon-luci-private-wifi/files/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
@@ -1,10 +1,11 @@
-local f, s, o, ssid
local uci = luci.model.uci.cursor()
-local config = 'wireless'
+local util = require 'gluon.util'
+
+local f, s, o, ssid
-- where to read the configuration from
local primary_iface = 'wan_radio0'
-local ssid = uci:get(config, primary_iface, "ssid")
+local ssid = uci:get('wireless', primary_iface, "ssid")
f = SimpleForm("wifi", translate("Private WLAN"))
f.template = "admin/expertmode"
@@ -17,46 +18,50 @@ s = f:section(SimpleSection, nil, translate(
))
o = s:option(Flag, "enabled", translate("Enabled"))
-o.default = (ssid and not uci:get_bool(config, primary_iface, "disabled")) and o.enabled or o.disabled
+o.default = (ssid and not uci:get_bool('wireless', primary_iface, "disabled")) and o.enabled or o.disabled
o.rmempty = false
o = s:option(Value, "ssid", translate("Name (SSID)"))
o:depends("enabled", '1')
+o.datatype = "maxlength(32)"
o.default = ssid
o = s:option(Value, "key", translate("Key"), translate("8-63 characters"))
o:depends("enabled", '1')
o.datatype = "wpakey"
-o.default = uci:get(config, primary_iface, "key")
+o.default = uci:get('wireless', primary_iface, "key")
function f.handle(self, state, data)
if state == FORM_VALID then
- uci:foreach(config, "wifi-device",
- function(s)
- local device = s['.name']
- local name = "wan_" .. device
+ util.iterate_radios(
+ function(radio, index)
+ local name = "wan_" .. radio
if data.enabled == '1' then
+ local macaddr = util.get_wlan_mac(radio, index, 4)
+
-- set up WAN wifi-iface
- uci:section(config, "wifi-iface", name,
+ uci:section('wireless', "wifi-iface", name,
{
- device = device,
+ device = radio,
network = "wan",
mode = 'ap',
encryption = 'psk2',
ssid = data.ssid,
key = data.key,
+ macaddr = macaddr,
disabled = 0,
}
)
else
-- disable WAN wifi-iface
- uci:set(config, name, "disabled", 1)
+ uci:set('wireless', name, "disabled", 1)
end
- end)
+ end
+ )
- uci:save(config)
- uci:commit(config)
+ uci:save('wireless')
+ uci:commit('wireless')
end
end
diff --git a/package/gluon-luci-theme/Makefile b/package/gluon-luci-theme/Makefile
index 4fc947c4..6e65db3c 100644
--- a/package/gluon-luci-theme/Makefile
+++ b/package/gluon-luci-theme/Makefile
@@ -9,13 +9,14 @@ PKG_RELEASE:=1
PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME)
-include $(INCLUDE_DIR)/package.mk
+include $(GLUONDIR)/include/package.mk
+
define Package/gluon-luci-theme
SECTION:=gluon
CATEGORY:=Gluon
TITLE:=Luci theme for Gluon
- DEPENDS:=
+ DEPENDS:=+pretty-hostname
endef
define Package/gluon-luci-theme/description
@@ -30,10 +31,12 @@ define Build/Configure
endef
define Build/Compile
+ $(call GluonSrcDiet,./luasrc,$(PKG_BUILD_DIR)/luadest/)
endef
define Package/gluon-luci-theme/install
$(CP) ./files/* $(1)/
+ $(CP) $(PKG_BUILD_DIR)/luadest/* $(1)/
endef
$(eval $(call BuildPackage,gluon-luci-theme))
diff --git a/package/gluon-luci-theme/files/usr/lib/lua/luci/view/themes/gluon/header.htm b/package/gluon-luci-theme/files/usr/lib/lua/luci/view/themes/gluon/header.htm
index 2fe1004b..7e894603 100644
--- a/package/gluon-luci-theme/files/usr/lib/lua/luci/view/themes/gluon/header.htm
+++ b/package/gluon-luci-theme/files/usr/lib/lua/luci/view/themes/gluon/header.htm
@@ -16,9 +16,12 @@ $Id$
local sys = require "luci.sys"
local http = require "luci.http"
local disp = require "luci.dispatcher"
+ local uci = require("luci.model.uci").cursor()
local fs = require "nixio.fs"
+ local gluon_luci = require "gluon.luci"
+ local pretty_hostname = require "pretty_hostname"
- local hostname = sys.hostname()
+ local hostname = pretty_hostname.get(uci)
local release = fs.readfile("/lib/gluon/release")
local request = disp.context.path
@@ -110,15 +113,15 @@ $Id$
<% end -%>
-<%=striptags( hostname .. ( (node and node.title) and ' - ' .. translate(node.title) or '')) %> - LuCI
+<%=gluon_luci.escape( hostname .. ( (node and node.title) and ' - ' .. translate(node.title) or '')) %> - LuCI
- <%=hostname%>
+ <%=gluon_luci.escape(hostname)%>
<% if release then %>
- / <%=release%>
+ / <%=gluon_luci.escape(release)%>
<% end %>
| <%:Auto Refresh%>:
diff --git a/package/gluon-luci-theme/luasrc/usr/lib/lua/gluon/luci.lua b/package/gluon-luci-theme/luasrc/usr/lib/lua/gluon/luci.lua
new file mode 100644
index 00000000..6d027827
--- /dev/null
+++ b/package/gluon-luci-theme/luasrc/usr/lib/lua/gluon/luci.lua
@@ -0,0 +1,28 @@
+-- Config mode utility functions
+
+local string = string
+
+module 'gluon.luci'
+
+function escape(s)
+ return (string.gsub(s, '[<>&"]', {
+ ['<'] = '<',
+ ['>'] = '>',
+ ['&'] = '&',
+ ['"'] = '"',
+ }))
+end
+
+function urlescape(s)
+ return (string.gsub(s, '[^a-zA-Z0-9%-_%.~]',
+ function(c)
+ local ret = ''
+
+ for i = 1, string.len(c) do
+ ret = ret .. string.format('%%%02X', string.byte(c, i, i))
+ end
+
+ return ret
+ end
+ ))
+end
diff --git a/package/gluon-luci-wifi-config/Makefile b/package/gluon-luci-wifi-config/Makefile
index 462eab9f..0f0d90f2 100644
--- a/package/gluon-luci-wifi-config/Makefile
+++ b/package/gluon-luci-wifi-config/Makefile
@@ -10,6 +10,7 @@ include $(GLUONDIR)/include/package.mk
PKG_CONFIG_DEPENDS += $(GLUON_I18N_CONFIG)
+
define Package/gluon-luci-wifi-config
SECTION:=gluon
CATEGORY:=Gluon
@@ -26,10 +27,11 @@ endef
define Build/Compile
$(call GluonBuildI18N,gluon-luci-wifi-config,i18n)
+ $(call GluonSrcDiet,./luasrc,$(PKG_BUILD_DIR)/luadest/)
endef
define Package/gluon-luci-wifi-config/install
- $(CP) ./files/* $(1)/
+ $(CP) $(PKG_BUILD_DIR)/luadest/* $(1)/
$(call GluonInstallI18N,gluon-luci-wifi-config,$(1))
endef
diff --git a/package/gluon-luci-wifi-config/files/usr/lib/lua/luci/controller/admin/wifi-config.lua b/package/gluon-luci-wifi-config/luasrc/usr/lib/lua/luci/controller/admin/wifi-config.lua
similarity index 100%
rename from package/gluon-luci-wifi-config/files/usr/lib/lua/luci/controller/admin/wifi-config.lua
rename to package/gluon-luci-wifi-config/luasrc/usr/lib/lua/luci/controller/admin/wifi-config.lua
diff --git a/package/gluon-luci-wifi-config/files/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
similarity index 99%
rename from package/gluon-luci-wifi-config/files/usr/lib/lua/luci/model/cbi/admin/wifi-config.lua
rename to package/gluon-luci-wifi-config/luasrc/usr/lib/lua/luci/model/cbi/admin/wifi-config.lua
index 060fb22b..efff8657 100644
--- a/package/gluon-luci-wifi-config/files/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
@@ -98,7 +98,7 @@ for _, radio in ipairs(radios) do
if config.path then
phy = find_phy_by_path(config.path)
elseif config.macaddr then
- phy = find_phy_by_path(config.macaddr)
+ phy = find_phy_by_macaddr(config.macaddr)
end
if phy then
diff --git a/package/gluon-mesh-babel/Makefile b/package/gluon-mesh-babel/Makefile
index b7dd2b06..73693877 100644
--- a/package/gluon-mesh-babel/Makefile
+++ b/package/gluon-mesh-babel/Makefile
@@ -4,7 +4,7 @@ PKG_NAME:=gluon-mesh-babel
PKG_VERSION:=1
PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME)
-
+PROVIDES := gluon-radvd-provider
include $(GLUONDIR)/include/package.mk
define Package/gluon-mesh-babel
@@ -12,6 +12,7 @@ define Package/gluon-mesh-babel
CATEGORY:=Gluon
TITLE:=Babel mesh
DEPENDS:=+gluon-core +babeld
+ PROVIDES:=gluon-mesh-provider gluon-mesh-babel
endef
define Build/Prepare
diff --git a/package/gluon-mesh-babel/files/etc/init.d/gluon-mesh-babel b/package/gluon-mesh-babel/files/etc/init.d/gluon-mesh-babel
new file mode 100755
index 00000000..271ebc41
--- /dev/null
+++ b/package/gluon-mesh-babel/files/etc/init.d/gluon-mesh-babel
@@ -0,0 +1,38 @@
+#!/bin/sh /etc/rc.common
+
+. $IPKG_INSTROOT/lib/functions/network.sh
+
+START=70
+
+pidfile='/var/run/babeld.pid'
+CONFIGFILE='/var/etc/gluon-babel.conf'
+EXTRA_COMMANDS="status"
+EXTRA_HELP=" status Dump Babel's table to the log file."
+
+start() {
+ mkdir -p /var/lib
+ mkdir -p /var/etc
+
+ /lib/gluon/gluon-mesh-babel/mkconfig "$CONFIGFILE"
+ /usr/sbin/babeld -D -I "$pidfile" -c "$CONFIGFILE"
+ # Wait for the pidfile to appear
+ for i in 1 2
+ do
+ [ -f "$pidfile" ] || sleep 1
+ done
+ [ -f "$pidfile" ] || (echo "Failed to start babeld"; exit 42)
+}
+
+stop() {
+ [ -f "$pidfile" ] && kill $(cat $pidfile)
+ # avoid race-condition on restart: wait for
+ # babeld to die for real.
+ [ -f "$pidfile" ] && sleep 1
+ [ -f "$pidfile" ] && sleep 1
+ [ -f "$pidfile" ] && sleep 1
+ [ -f "$pidfile" ] && exit 42
+}
+
+status() {
+ [ -f "$pidfile" ] && kill -USR1 $(cat $pidfile)
+}
diff --git a/package/gluon-mesh-babel/files/lib/gluon/gluon-mesh-babel/mkconfig b/package/gluon-mesh-babel/files/lib/gluon/gluon-mesh-babel/mkconfig
new file mode 100755
index 00000000..26ddf2c2
--- /dev/null
+++ b/package/gluon-mesh-babel/files/lib/gluon/gluon-mesh-babel/mkconfig
@@ -0,0 +1,25 @@
+#!/usr/bin/lua
+
+local site = require 'gluon.site_config'
+local gmesh = require 'gluon.mesh'
+
+--local interfaces='/lib/gluon/core/mesh_interfaces'
+local babelconf=arg[1]
+
+file = io.open(babelconf, "w")
+file:write("ipv6-subtrees true\n")
+file:write("export-table 10\n")
+file:write("import-table 255\n")
+file:write("import-table 11\n")
+
+for interface, _ in pairs(gmesh.interfaces()) do
+ file:write("interface " .. interface .. "\n")
+end
+
+file:write(" redistribute ip " .. site.prefix6 .. " eq 128 allow\n")
+file:write(" redistribute ip " .. site.babel_mesh.prefix .. " eq 128 allow\n")
+file:write(" redistribute local deny\n")
+file:write(" redistribute ip ::/0 eq 0 allow\n")
+file:close()
+
+
diff --git a/package/gluon-mesh-babel/files/lib/gluon/radvd/arguments b/package/gluon-mesh-babel/files/lib/gluon/radvd/arguments
new file mode 100755
index 00000000..c1bdad3c
--- /dev/null
+++ b/package/gluon-mesh-babel/files/lib/gluon/radvd/arguments
@@ -0,0 +1,3 @@
+#!/usr/bin/lua
+local site = require "gluon.site_config"
+print("-i local-node --default-lifetime 900 -a " .. site.prefix6)
diff --git a/package/gluon-mesh-babel/files/lib/gluon/upgrade/330-gluon-mesh-babel-interfaces b/package/gluon-mesh-babel/files/lib/gluon/upgrade/330-gluon-mesh-babel-interfaces
index 28cbe5df..b620da63 100755
--- a/package/gluon-mesh-babel/files/lib/gluon/upgrade/330-gluon-mesh-babel-interfaces
+++ b/package/gluon-mesh-babel/files/lib/gluon/upgrade/330-gluon-mesh-babel-interfaces
@@ -2,22 +2,15 @@
local uci = require('luci.model.uci').cursor()
local site = require 'gluon.site_config'
+--local gmesh = require 'gluon.mesh'
+-- TODO: do we need settings for more interfaces in the firewall?
if site.mesh_on_wan then
- uci:section('babeld', 'interface', 'mesh_wan',
- {
- ifname = 'br-wan',
- }
- )
-
uci:add_to_set('firewall', 'mesh_babel', 'network', 'wan')
end
-
uci:add_to_set('firewall', 'mesh_babel', 'network', 'client')
uci:add_to_set('firewall', 'mesh_babel', 'network', 'local_node4')
uci:add_to_set('firewall', 'mesh_babel', 'network', 'local_node6')
-uci:save('babeld')
uci:save('firewall')
-uci:commit('babeld')
uci:commit('firewall')
diff --git a/package/gluon-mesh-batman-adv-14/Makefile b/package/gluon-mesh-batman-adv-14/Makefile
index be65cafa..aa53e85f 100644
--- a/package/gluon-mesh-batman-adv-14/Makefile
+++ b/package/gluon-mesh-batman-adv-14/Makefile
@@ -7,6 +7,7 @@ PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME)
include $(GLUONDIR)/include/package.mk
+
define Package/gluon-mesh-batman-adv-14
SECTION:=gluon
CATEGORY:=Gluon
diff --git a/package/gluon-mesh-batman-adv-14/files/lib/gluon/core/mesh/setup.d/30-gluon-mesh-batman-adv-14 b/package/gluon-mesh-batman-adv-14/files/lib/gluon/core/mesh/setup.d/30-gluon-mesh-batman-adv-14
new file mode 100755
index 00000000..8be4037a
--- /dev/null
+++ b/package/gluon-mesh-batman-adv-14/files/lib/gluon/core/mesh/setup.d/30-gluon-mesh-batman-adv-14
@@ -0,0 +1,3 @@
+#!/bin/sh
+
+exec /lib/gluon/mesh-batman-adv-core/config_mesh_interface setup 1528
diff --git a/package/gluon-mesh-batman-adv-14/files/lib/gluon/core/mesh/teardown.d/70-gluon-mesh-batman-adv-14 b/package/gluon-mesh-batman-adv-14/files/lib/gluon/core/mesh/teardown.d/70-gluon-mesh-batman-adv-14
new file mode 100755
index 00000000..494a4f9c
--- /dev/null
+++ b/package/gluon-mesh-batman-adv-14/files/lib/gluon/core/mesh/teardown.d/70-gluon-mesh-batman-adv-14
@@ -0,0 +1,3 @@
+#!/bin/sh
+
+exec /lib/gluon/mesh-batman-adv-core/config_mesh_interface teardown
diff --git a/package/gluon-mesh-batman-adv-14/files/lib/gluon/upgrade/350-gluon-mesh-batman-adv-14 b/package/gluon-mesh-batman-adv-14/files/lib/gluon/upgrade/350-gluon-mesh-batman-adv-14
deleted file mode 100755
index 30e2682b..00000000
--- a/package/gluon-mesh-batman-adv-14/files/lib/gluon/upgrade/350-gluon-mesh-batman-adv-14
+++ /dev/null
@@ -1,47 +0,0 @@
-#!/usr/bin/lua
-
-local site = require 'gluon.site_config'
-
-local uci = require('luci.model.uci').cursor()
-
-
-local function configure_mtu(radio, config, mtu)
- if config.ibss then
- local network = 'ibss_' .. radio
-
- if config.ibss.vlan then
- uci:set('network', network, 'mtu', mtu + 4)
- uci:set('network', network .. '_vlan', 'mtu', mtu)
- else
- uci:set('network', network, 'mtu', mtu)
- end
- end
-
- if config.mesh then
- uci:set('network', 'mesh_' .. radio, 'mtu', mtu)
- end
-end
-
-
-local radios = {}
-
-uci:foreach('wireless', 'wifi-device',
- function(s)
- table.insert(radios, s['.name'])
- end
-)
-
-local mtu = 1528
-
-for _, radio in ipairs(radios) do
- local hwmode = uci:get('wireless', radio, 'hwmode')
-
- if hwmode == '11g' or hwmode == '11ng' then
- configure_mtu(radio, site.wifi24, mtu)
- elseif hwmode == '11a' or hwmode == '11na' then
- configure_mtu(radio, site.wifi5, mtu)
- end
-end
-
-
-uci:save('network')
diff --git a/package/gluon-mesh-batman-adv-15/Makefile b/package/gluon-mesh-batman-adv-15/Makefile
index 14a39a61..d64fea88 100644
--- a/package/gluon-mesh-batman-adv-15/Makefile
+++ b/package/gluon-mesh-batman-adv-15/Makefile
@@ -7,6 +7,7 @@ PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME)
include $(GLUONDIR)/include/package.mk
+
define Package/gluon-mesh-batman-adv-15
SECTION:=gluon
CATEGORY:=Gluon
diff --git a/package/gluon-mesh-batman-adv-15/files/lib/gluon/core/mesh/setup.d/30-gluon-mesh-batman-adv-15 b/package/gluon-mesh-batman-adv-15/files/lib/gluon/core/mesh/setup.d/30-gluon-mesh-batman-adv-15
new file mode 100755
index 00000000..a9b67cb0
--- /dev/null
+++ b/package/gluon-mesh-batman-adv-15/files/lib/gluon/core/mesh/setup.d/30-gluon-mesh-batman-adv-15
@@ -0,0 +1,3 @@
+#!/bin/sh
+
+exec /lib/gluon/mesh-batman-adv-core/config_mesh_interface setup 1532
diff --git a/package/gluon-mesh-batman-adv-15/files/lib/gluon/core/mesh/teardown.d/70-gluon-mesh-batman-adv-15 b/package/gluon-mesh-batman-adv-15/files/lib/gluon/core/mesh/teardown.d/70-gluon-mesh-batman-adv-15
new file mode 100755
index 00000000..494a4f9c
--- /dev/null
+++ b/package/gluon-mesh-batman-adv-15/files/lib/gluon/core/mesh/teardown.d/70-gluon-mesh-batman-adv-15
@@ -0,0 +1,3 @@
+#!/bin/sh
+
+exec /lib/gluon/mesh-batman-adv-core/config_mesh_interface teardown
diff --git a/package/gluon-mesh-batman-adv-15/files/lib/gluon/upgrade/350-gluon-mesh-batman-adv-15 b/package/gluon-mesh-batman-adv-15/files/lib/gluon/upgrade/350-gluon-mesh-batman-adv-15
deleted file mode 100755
index 7148d42c..00000000
--- a/package/gluon-mesh-batman-adv-15/files/lib/gluon/upgrade/350-gluon-mesh-batman-adv-15
+++ /dev/null
@@ -1,47 +0,0 @@
-#!/usr/bin/lua
-
-local site = require 'gluon.site_config'
-
-local uci = require('luci.model.uci').cursor()
-
-
-local function configure_mtu(radio, config, mtu)
- if config.ibss then
- local network = 'ibss_' .. radio
-
- if config.ibss.vlan then
- uci:set('network', network, 'mtu', mtu + 4)
- uci:set('network', network .. '_vlan', 'mtu', mtu)
- else
- uci:set('network', network, 'mtu', mtu)
- end
- end
-
- if config.mesh then
- uci:set('network', 'mesh_' .. radio, 'mtu', mtu)
- end
-end
-
-
-local radios = {}
-
-uci:foreach('wireless', 'wifi-device',
- function(s)
- table.insert(radios, s['.name'])
- end
-)
-
-local mtu = 1532
-
-for _, radio in ipairs(radios) do
- local hwmode = uci:get('wireless', radio, 'hwmode')
-
- if hwmode == '11g' or hwmode == '11ng' then
- configure_mtu(radio, site.wifi24, mtu)
- elseif hwmode == '11a' or hwmode == '11na' then
- configure_mtu(radio, site.wifi5, mtu)
- end
-end
-
-
-uci:save('network')
diff --git a/package/gluon-mesh-batman-adv-core/Makefile b/package/gluon-mesh-batman-adv-core/Makefile
index 7ae7c305..efcf1698 100644
--- a/package/gluon-mesh-batman-adv-core/Makefile
+++ b/package/gluon-mesh-batman-adv-core/Makefile
@@ -8,11 +8,12 @@ PKG_BUILD_DEPENDS := respondd
include $(GLUONDIR)/include/package.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
+ DEPENDS:=+gluon-core +libgluonutil +gluon-client-bridge +firewall +libiwinfo +kmod-dummy
endef
define Build/Prepare
@@ -20,9 +21,14 @@ define Build/Prepare
$(CP) ./src/* $(PKG_BUILD_DIR)/
endef
+define Build/Compile
+ $(call Build/Compile/Default)
+ $(call GluonSrcDiet,./luasrc,$(PKG_BUILD_DIR)/luadest/)
+endef
+
define Package/gluon-mesh-batman-adv-core/install
$(CP) ./files/* $(1)/
-
+ $(CP) $(PKG_BUILD_DIR)/luadest/* $(1)/
$(INSTALL_DIR) $(1)/lib/gluon/respondd
$(CP) $(PKG_BUILD_DIR)/respondd.so $(1)/lib/gluon/respondd/mesh-batman-adv-core.so
endef
diff --git a/package/gluon-mesh-batman-adv-core/check_site.lua b/package/gluon-mesh-batman-adv-core/check_site.lua
index 19774871..07bf9a0a 100644
--- a/package/gluon-mesh-batman-adv-core/check_site.lua
+++ b/package/gluon-mesh-batman-adv-core/check_site.lua
@@ -1,15 +1,18 @@
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
+
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_number(config .. '.ibss.mcast_rate', false)
+ 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_number(config .. '.mesh.mcast_rate', false)
+ need_one_of(config .. '.mesh.mcast_rate', rates, false)
need_boolean(config .. '.mesh.disabled', false)
end
end
diff --git a/package/gluon-mesh-batman-adv-core/files/lib/gluon/radvd/arguments b/package/gluon-mesh-batman-adv-core/files/lib/gluon/radvd/arguments
new file mode 100755
index 00000000..4062748a
--- /dev/null
+++ b/package/gluon-mesh-batman-adv-core/files/lib/gluon/radvd/arguments
@@ -0,0 +1,3 @@
+#!/usr/bin/lua
+local site = require "gluon.site_config"
+print("-i br-client -p " .. site.prefix6)
diff --git a/package/gluon-mesh-batman-adv-core/files/lib/gluon/upgrade/300-gluon-mesh-batman-adv-core-wan b/package/gluon-mesh-batman-adv-core/files/lib/gluon/upgrade/300-gluon-mesh-batman-adv-core-wan
deleted file mode 100755
index be96c012..00000000
--- a/package/gluon-mesh-batman-adv-core/files/lib/gluon/upgrade/300-gluon-mesh-batman-adv-core-wan
+++ /dev/null
@@ -1,10 +0,0 @@
-#!/usr/bin/lua
-
-local util = require 'gluon.util'
-local uci = require('luci.model.uci').cursor()
-
-
--- fix up duplicate mac addresses (for mesh-on-WAN)
-uci:set('network', 'wan', 'macaddr', util.generate_mac(3))
-uci:save('network')
-
diff --git a/package/gluon-mesh-batman-adv-core/files/lib/gluon/upgrade/320-gluon-mesh-batman-adv-core-wireless b/package/gluon-mesh-batman-adv-core/files/lib/gluon/upgrade/320-gluon-mesh-batman-adv-core-wireless
deleted file mode 100755
index 05462c6f..00000000
--- a/package/gluon-mesh-batman-adv-core/files/lib/gluon/upgrade/320-gluon-mesh-batman-adv-core-wireless
+++ /dev/null
@@ -1,137 +0,0 @@
-#!/usr/bin/lua
-
-local site = require 'gluon.site_config'
-local util = require 'gluon.util'
-
-local uci = require('luci.model.uci').cursor()
-
-
-local function is_disabled(name)
- if uci:get('wireless', name) then
- return uci:get_bool('wireless', name, 'disabled')
- end
-end
-
--- Returns the first argument that is not nil; don't call without any non-nil arguments!
-local function first_non_nil(first, ...)
- if first ~= nil then
- return first
- else
- return first_non_nil(...)
- end
-end
-
-
-local function configure_ibss(config, radio, index, suffix, disabled)
- local name = 'ibss_' .. radio
-
- uci:delete('network', name)
- uci:delete('network', name .. '_vlan')
- uci:delete('wireless', name)
-
- macaddr = util.generate_mac(3*index+2)
-
- if config and macaddr then
- if config.vlan then
- uci:section('network', 'interface', name,
- {
- proto = 'none',
- }
- )
-
- uci:section('network', 'interface', name .. '_vlan',
- {
- ifname = '@' .. name .. '.' .. config.vlan,
- proto = 'batadv',
- mesh = 'bat0',
- }
- )
- else
- uci:section('network', 'interface', name,
- {
- proto = 'batadv',
- mesh = 'bat0',
- }
- )
- end
-
- uci:section('wireless', 'wifi-iface', name,
- {
- device = radio,
- network = name,
- mode = 'adhoc',
- ssid = config.ssid,
- bssid = config.bssid,
- macaddr = macaddr,
- mcast_rate = config.mcast_rate,
- ifname = suffix and 'ibss' .. suffix,
- disabled = disabled and 1 or 0,
- }
- )
- end
-end
-
-local function configure_mesh(config, radio, index, suffix, disabled)
- local name = 'mesh_' .. radio
- local macfilter = uci:get('wireless', name, 'macfilter')
- local maclist = uci:get('wireless', name, 'maclist')
-
- uci:delete('network', name)
- uci:delete('wireless', name)
-
- macaddr = util.generate_mac(3*index+1)
-
- if config and macaddr then
- uci:section('network', 'interface', name,
- {
- proto = 'batadv',
- mesh = 'bat0',
- }
- )
-
- uci:section('wireless', 'wifi-iface', name,
- {
- device = radio,
- network = name,
- mode = 'mesh',
- mesh_id = config.id,
- mesh_fwding = 0,
- macaddr = macaddr,
- mcast_rate = config.mcast_rate,
- ifname = suffix and 'mesh' .. suffix,
- disabled = disabled and 1 or 0,
- macfilter = macfilter,
- maclist = maclist,
- }
- )
- end
-end
-
-local function configure_radio(radio, index, config)
- local suffix = radio:match('^radio(%d+)$')
-
- local ibss_disabled = is_disabled('ibss_' .. radio)
- local mesh_disabled = is_disabled('mesh_' .. radio)
-
- configure_ibss(config.ibss, radio, index, suffix,
- first_non_nil(
- ibss_disabled,
- mesh_disabled,
- (config.ibss or {}).disabled, -- will be nil if config.ibss or config.ibss.disabled is unset
- false
- )
- )
- configure_mesh(config.mesh, radio, index, suffix,
- first_non_nil(
- mesh_disabled,
- ibss_disabled,
- (config.mesh or {}).disabled, -- will be nil if config.mesh or config.mesh.disabled is unset
- false
- )
- )
-end
-
-util.iterate_radios(configure_radio)
-
-uci:save('wireless')
-uci:save('network')
diff --git a/package/gluon-mesh-batman-adv-core/files/lib/gluon/upgrade/330-gluon-mesh-batman-adv-core-mesh-on-wan b/package/gluon-mesh-batman-adv-core/files/lib/gluon/upgrade/330-gluon-mesh-batman-adv-core-mesh-on-wan
deleted file mode 100755
index 7a964ee2..00000000
--- a/package/gluon-mesh-batman-adv-core/files/lib/gluon/upgrade/330-gluon-mesh-batman-adv-core-mesh-on-wan
+++ /dev/null
@@ -1,18 +0,0 @@
-#!/usr/bin/lua
-
-local site = require 'gluon.site_config'
-local uci = require 'luci.model.uci'
-
-local c = uci.cursor()
-
-if not c:get('network', 'mesh_wan') then
- c:section('network', 'interface', 'mesh_wan',
- { ifname = 'br-wan'
- , proto = 'batadv'
- , mesh = 'bat0'
- , mesh_no_rebroadcast = '1'
- , auto = site.mesh_on_wan and 1 or 0
- })
-end
-
-c:save('network')
diff --git a/package/gluon-mesh-batman-adv-core/files/lib/gluon/upgrade/350-gluon-mesh-batman-adv-core-rssid b/package/gluon-mesh-batman-adv-core/files/lib/gluon/upgrade/350-gluon-mesh-batman-adv-core-rssid
deleted file mode 100755
index b6b16574..00000000
--- a/package/gluon-mesh-batman-adv-core/files/lib/gluon/upgrade/350-gluon-mesh-batman-adv-core-rssid
+++ /dev/null
@@ -1,13 +0,0 @@
-#!/usr/bin/lua
-
-local uci = require('luci.model.uci').cursor()
-
-if uci:get('system', 'rssid_wlan0') then
- if uci:get('wireless', 'mesh_radio0') then
- uci:set('system', 'rssid_wlan0', 'dev', 'mesh0')
- else
- uci:set('system', 'rssid_wlan0', 'dev', 'ibss0')
- end
-
- uci:save('system')
-end
diff --git a/package/gluon-mesh-batman-adv-core/files/usr/lib/autoupdater/abort.d/10start-network b/package/gluon-mesh-batman-adv-core/files/usr/lib/autoupdater/abort.d/10start-network
new file mode 100755
index 00000000..f04d55cc
--- /dev/null
+++ b/package/gluon-mesh-batman-adv-core/files/usr/lib/autoupdater/abort.d/10start-network
@@ -0,0 +1,5 @@
+#!/bin/sh
+
+. /lib/gluon/autoupdater/lib.sh
+
+pidof netifd >/dev/null || start_enabled network
diff --git a/package/gluon-mesh-batman-adv-core/files/usr/lib/autoupdater/upgrade.d/10stop-network b/package/gluon-mesh-batman-adv-core/files/usr/lib/autoupdater/upgrade.d/10stop-network
new file mode 100755
index 00000000..b02580a3
--- /dev/null
+++ b/package/gluon-mesh-batman-adv-core/files/usr/lib/autoupdater/upgrade.d/10stop-network
@@ -0,0 +1,8 @@
+#!/bin/sh
+
+. /lib/gluon/autoupdater/lib.sh
+
+wifi down
+sleep 1
+stop network
+ip link del bat0
diff --git a/package/gluon-mesh-batman-adv-core/luasrc/lib/gluon/mesh-batman-adv-core/config_mesh_interface b/package/gluon-mesh-batman-adv-core/luasrc/lib/gluon/mesh-batman-adv-core/config_mesh_interface
new file mode 100755
index 00000000..bb069497
--- /dev/null
+++ b/package/gluon-mesh-batman-adv-core/luasrc/lib/gluon/mesh-batman-adv-core/config_mesh_interface
@@ -0,0 +1,64 @@
+#!/usr/bin/lua
+
+local util = require 'gluon.util'
+local fs = require 'nixio.fs'
+
+
+local ifname = os.getenv('IFNAME')
+local cmd = arg[1]
+
+
+if cmd == 'setup' then
+
+ local fixed_mtu = tonumber(os.getenv('FIXED_MTU')) or 0
+ local transitive = tonumber(os.getenv('TRANSITIVE')) or 0
+
+ local mtu = tonumber(arg[2])
+
+ if os.execute('ip link show primary0 >/dev/null 2>&1') ~= 0 then
+ os.execute([[
+ ip link add primary0 type dummy
+ echo 1 > /proc/sys/net/ipv6/conf/primary0/disable_ipv6
+ ip link set primary0 address ]] .. util.generate_mac(3) .. [[ mtu ]] .. mtu .. [[ up
+ echo 'bat0' > /sys/class/net/primary0/batman_adv/mesh_iface
+ ]])
+ end
+
+ if fixed_mtu == 0 then
+ local lower = fs.glob('/sys/class/net/' .. ifname .. '/lower_*/wireless')()
+ if lower then
+ lower = lower:match('/lower_([^/]+)/wireless$')
+ util.exec('ip', 'link', 'set', 'dev', lower, 'mtu', tostring(mtu+4))
+ end
+
+ util.exec('ip', 'link', 'set', 'dev', ifname, 'mtu', tostring(mtu))
+ end
+
+ local file = assert(io.open('/sys/class/net/' .. ifname .. '/batman_adv/mesh_iface', 'w'))
+ file:write('bat0')
+ file:close()
+
+ file = assert(io.open('/sys/class/net/' .. ifname .. '/batman_adv/no_rebroadcast', 'w'))
+ file:write(tostring(transitive))
+ file:close()
+
+elseif cmd == 'teardown' then
+
+ local file = io.open('/sys/class/net/' .. ifname .. '/batman_adv/mesh_iface', 'w')
+ if file then
+ file:write('none')
+ file:close()
+ end
+
+ local other = false
+ for lower in fs.glob('/sys/class/net/bat0/lower_*') do
+ if lower ~= '/sys/class/net/bat0/lower_primary0' then
+ other = true
+ break
+ end
+ end
+
+ if not other then
+ os.execute('ip link del primary0')
+ end
+end
diff --git a/package/gluon-mesh-batman-adv-core/files/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
similarity index 83%
rename from package/gluon-mesh-batman-adv-core/files/lib/gluon/upgrade/310-gluon-mesh-batman-adv-core-mesh
rename to package/gluon-mesh-batman-adv-core/luasrc/lib/gluon/upgrade/310-gluon-mesh-batman-adv-core-mesh
index ade6af57..4710d47c 100755
--- a/package/gluon-mesh-batman-adv-core/files/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
@@ -5,7 +5,6 @@ local sysctl = require 'gluon.sysctl'
local site = require 'gluon.site_config'
local uci = require('luci.model.uci').cursor()
-local lutil = require 'luci.util'
local gw_sel_class
@@ -25,19 +24,12 @@ uci:section('batman-adv', 'mesh', 'bat0',
)
uci:save('batman-adv')
-if not uci:get('network', 'client', 'ifname') then
- uci:add_to_set('network', 'client', 'ifname', 'bat0')
- if sysconfig.lan_ifname and not site.mesh_on_lan then
- for _, lanif in ipairs(lutil.split(sysconfig.lan_ifname, ' ')) do
- uci:add_to_set('network', 'client', 'ifname', lanif)
- end
- end
-end
+uci:add_to_set('network', 'client', 'ifname', 'bat0')
uci:set('network', 'client', 'proto', 'dhcpv6')
uci:set('network', 'client', 'reqprefix', 'no')
-uci:set('network', 'client', 'igmp_snooping', 0)
+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)
@@ -51,9 +43,20 @@ uci:section('network', 'interface', '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
+
uci:save('network')
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/320-gluon-mesh-batman-adv-core-mac-addresses
new file mode 100755
index 00000000..38011107
--- /dev/null
+++ b/package/gluon-mesh-batman-adv-core/luasrc/lib/gluon/upgrade/320-gluon-mesh-batman-adv-core-mac-addresses
@@ -0,0 +1,10 @@
+#!/usr/bin/lua
+
+local util = require 'gluon.util'
+local uci = require('luci.model.uci').cursor()
+
+
+-- fix up potentially duplicate MAC addresses (for meshing)
+uci:set('network', 'wan', 'macaddr', util.generate_mac(0))
+uci:set('network', 'mesh_lan', 'macaddr', util.generate_mac(4))
+uci:save('network')
diff --git a/package/gluon-mesh-batman-adv-core/src/respondd.c b/package/gluon-mesh-batman-adv-core/src/respondd.c
index f0085457..f21eb62e 100644
--- a/package/gluon-mesh-batman-adv-core/src/respondd.c
+++ b/package/gluon-mesh-batman-adv-core/src/respondd.c
@@ -212,11 +212,13 @@ static void add_gateway(struct json_object *obj) {
while (getline(&line, &len, f) >= 0) {
char addr[18];
+ char nexthop[18];
- if (sscanf(line, "=> %17[0-9a-fA-F:]", addr) != 1)
+ 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;
}
@@ -501,7 +503,9 @@ static struct json_object * get_batadv(void) {
struct json_object *obj = json_object_new_object();
json_object_object_add(obj, "tq", json_object_new_int(tq));
- json_object_object_add(obj, "lastseen", json_object_new_double(lastseen));
+ 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);
}
diff --git a/package/gluon-mesh-vpn-fastd/Makefile b/package/gluon-mesh-vpn-fastd/Makefile
index 0875e485..4d75116e 100644
--- a/package/gluon-mesh-vpn-fastd/Makefile
+++ b/package/gluon-mesh-vpn-fastd/Makefile
@@ -8,11 +8,12 @@ PKG_BUILD_DEPENDS := respondd
include $(GLUONDIR)/include/package.mk
+
define Package/gluon-mesh-vpn-fastd
SECTION:=gluon
CATEGORY:=Gluon
TITLE:=Support for connecting batman-adv meshes via fastd
- DEPENDS:=+gluon-core +libgluonutil gluon-mesh-batman-adv +gluon-wan-dnsmasq +fastd +iptables-mod-extra +simple-tc
+ DEPENDS:=+gluon-core +libgluonutil gluon-mesh-batman-adv +gluon-wan-dnsmasq +fastd +iptables +iptables-mod-extra +simple-tc
endef
define Build/Prepare
@@ -20,9 +21,14 @@ define Build/Prepare
$(CP) ./src/* $(PKG_BUILD_DIR)/
endef
+define Build/Compile
+ $(call Build/Compile/Default)
+ $(call GluonSrcDiet,./luasrc,$(PKG_BUILD_DIR)/luadest/)
+endef
+
define Package/gluon-mesh-vpn-fastd/install
$(CP) ./files/* $(1)/
-
+ $(CP) $(PKG_BUILD_DIR)/luadest/* $(1)/
$(INSTALL_DIR) $(1)/lib/gluon/respondd
$(CP) $(PKG_BUILD_DIR)/respondd.so $(1)/lib/gluon/respondd/mesh-vpn-fastd.so
endef
diff --git a/package/gluon-mesh-vpn-fastd/files/lib/gluon/upgrade/400-mesh-vpn-fastd b/package/gluon-mesh-vpn-fastd/luasrc/lib/gluon/upgrade/400-mesh-vpn-fastd
similarity index 95%
rename from package/gluon-mesh-vpn-fastd/files/lib/gluon/upgrade/400-mesh-vpn-fastd
rename to package/gluon-mesh-vpn-fastd/luasrc/lib/gluon/upgrade/400-mesh-vpn-fastd
index 77f2e6f2..74ab4a41 100755
--- a/package/gluon-mesh-vpn-fastd/files/lib/gluon/upgrade/400-mesh-vpn-fastd
+++ b/package/gluon-mesh-vpn-fastd/luasrc/lib/gluon/upgrade/400-mesh-vpn-fastd
@@ -122,13 +122,13 @@ uci:save('fastd')
uci:section('network', 'interface', 'mesh_vpn',
- {
- ifname = 'mesh-vpn',
- proto = 'batadv',
- mesh = 'bat0',
- mesh_no_rebroadcast = 1,
- macaddr = util.generate_mac(0),
- }
+ {
+ ifname = 'mesh-vpn',
+ proto = 'gluon_mesh',
+ transitive = 1,
+ fixed_mtu = 1,
+ macaddr = util.generate_mac(7),
+ }
)
uci:save('network')
diff --git a/package/gluon-mesh-vpn-fastd/files/lib/gluon/upgrade/410-mesh-vpn-fastd-generate-secret b/package/gluon-mesh-vpn-fastd/luasrc/lib/gluon/upgrade/410-mesh-vpn-fastd-generate-secret
similarity index 100%
rename from package/gluon-mesh-vpn-fastd/files/lib/gluon/upgrade/410-mesh-vpn-fastd-generate-secret
rename to package/gluon-mesh-vpn-fastd/luasrc/lib/gluon/upgrade/410-mesh-vpn-fastd-generate-secret
diff --git a/package/gluon-mesh-vpn-fastd/files/lib/gluon/upgrade/420-mesh-vpn-fastd-simple-tc b/package/gluon-mesh-vpn-fastd/luasrc/lib/gluon/upgrade/420-mesh-vpn-fastd-simple-tc
similarity index 100%
rename from package/gluon-mesh-vpn-fastd/files/lib/gluon/upgrade/420-mesh-vpn-fastd-simple-tc
rename to package/gluon-mesh-vpn-fastd/luasrc/lib/gluon/upgrade/420-mesh-vpn-fastd-simple-tc
diff --git a/package/gluon-mesh-vpn-fastd/src/respondd.c b/package/gluon-mesh-vpn-fastd/src/respondd.c
index 3045c77a..7354783a 100644
--- a/package/gluon-mesh-vpn-fastd/src/respondd.c
+++ b/package/gluon-mesh-vpn-fastd/src/respondd.c
@@ -192,7 +192,9 @@ static bool get_peer_connection(struct json_object **ret, struct json_object *co
int64_t established_time = json_object_get_int64(established);
*ret = json_object_new_object();
- json_object_object_add(*ret, "established", json_object_new_double(established_time/1000.0));
+ struct json_object *jso = json_object_new_double(established_time/1000.0);
+ json_object_set_serializer(jso, json_object_double_to_json_string, "%.3f", NULL);
+ json_object_object_add(*ret, "established", jso);
}
else {
*ret = NULL;
diff --git a/package/gluon-neighbour-info/Makefile b/package/gluon-neighbour-info/Makefile
index 63586920..498abc4f 100644
--- a/package/gluon-neighbour-info/Makefile
+++ b/package/gluon-neighbour-info/Makefile
@@ -6,7 +6,8 @@ PKG_RELEASE:=1
PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME)
-include $(INCLUDE_DIR)/package.mk
+include $(GLUONDIR)/include/package.mk
+
define Package/gluon-neighbour-info
SECTION:=gluon
@@ -29,11 +30,11 @@ endef
define Build/Compile
CFLAGS="$(TARGET_CFLAGS)" CPPFLAGS="$(TARGET_CPPFLAGS)" $(MAKE) -C $(PKG_BUILD_DIR) $(TARGET_CONFIGURE_OPTS)
+ $(call GluonSrcDiet,./luasrc,$(PKG_BUILD_DIR)/luadest/)
endef
define Package/gluon-neighbour-info/install
- $(CP) ./files/* $(1)/
-
+ $(CP) $(PKG_BUILD_DIR)/luadest/* $(1)/
$(INSTALL_DIR) $(1)/usr/bin
$(INSTALL_BIN) $(PKG_BUILD_DIR)/gluon-neighbour-info $(1)/usr/bin/
endef
diff --git a/package/gluon-neighbour-info/files/lib/gluon/upgrade/400-neighbour-info-firewall b/package/gluon-neighbour-info/luasrc/lib/gluon/upgrade/400-neighbour-info-firewall
similarity index 100%
rename from package/gluon-neighbour-info/files/lib/gluon/upgrade/400-neighbour-info-firewall
rename to package/gluon-neighbour-info/luasrc/lib/gluon/upgrade/400-neighbour-info-firewall
diff --git a/package/gluon-neighbour-info/src/gluon-neighbour-info.c b/package/gluon-neighbour-info/src/gluon-neighbour-info.c
index c1dd162a..808a1b12 100644
--- a/package/gluon-neighbour-info/src/gluon-neighbour-info.c
+++ b/package/gluon-neighbour-info/src/gluon-neighbour-info.c
@@ -38,7 +38,7 @@
void usage() {
puts("Usage: gluon-neighbour-info [-h] [-s] [-l] [-c ] [-t ] -d -p -i -r ");
puts(" -p UDP port");
- puts(" -d multicast group, e.g. ff02:0:0:0:0:0:2:1001");
+ puts(" -d destination address (unicast ip6 or multicast group, e.g. ff02:0:0:0:0:0:2:1001)");
puts(" -i interface, e.g. eth0 ");
puts(" -r request, e.g. nodeinfo");
puts(" -t timeout in seconds (default: 3)");
@@ -145,7 +145,6 @@ int main(int argc, char **argv) {
}
client_addr.sin6_family = AF_INET6;
- client_addr.sin6_addr = in6addr_any;
opterr = 0;
@@ -206,10 +205,20 @@ int main(int argc, char **argv) {
}
if (request_string == NULL) {
- fprintf(stderr, "No request string supplied");
+ fprintf(stderr, "No request string supplied\n");
exit(EXIT_FAILURE);
}
+ if (client_addr.sin6_port == htons(0)) {
+ fprintf(stderr, "No port supplied\n");
+ exit(EXIT_FAILURE);
+ }
+
+ if (IN6_IS_ADDR_UNSPECIFIED(&client_addr.sin6_addr)) {
+ fprintf(stderr, "No destination address supplied\n");
+ exit(EXIT_FAILURE);
+ }
+
if (sse) {
fputs("Content-Type: text/event-stream\n\n", stdout);
fflush(stdout);
diff --git a/package/gluon-next-node/Makefile b/package/gluon-next-node/Makefile
index c08890b9..be47ebe6 100644
--- a/package/gluon-next-node/Makefile
+++ b/package/gluon-next-node/Makefile
@@ -7,6 +7,7 @@ PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME)
include $(GLUONDIR)/include/package.mk
+
define Package/gluon-next-node
SECTION:=gluon
CATEGORY:=Gluon
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
index 6dac30ad..df1ea6fb 100755
--- a/package/gluon-next-node/files/lib/gluon/upgrade/400-next-node
+++ b/package/gluon-next-node/files/lib/gluon/upgrade/400-next-node
@@ -38,6 +38,14 @@ c:section('network', 'interface', 'local_node6',
}
)
+c:section('network', 'interface', 'local_node6',
+ {
+ ifname = 'local-node',
+ proto = 'static_deprecated',
+ ip6addr = site.next_node.ip6,
+ }
+)
+
c:save('network')
c:delete('firewall', 'local_node')
diff --git a/package/gluon-node-info/Makefile b/package/gluon-node-info/Makefile
index a5ac8ddc..8dd31553 100644
--- a/package/gluon-node-info/Makefile
+++ b/package/gluon-node-info/Makefile
@@ -9,6 +9,7 @@ PKG_BUILD_DEPENDS := respondd
include $(GLUONDIR)/include/package.mk
+
define Package/gluon-node-info
SECTION:=gluon
CATEGORY:=Gluon
diff --git a/package/gluon-node-info/src/respondd.c b/package/gluon-node-info/src/respondd.c
index dfbfd3f8..3b0e07dc 100644
--- a/package/gluon-node-info/src/respondd.c
+++ b/package/gluon-node-info/src/respondd.c
@@ -64,7 +64,15 @@ static struct json_object * get_number(struct uci_context *ctx, struct uci_secti
if (*end)
return NULL;
- return json_object_new_double(d);
+ struct json_object *jso = json_object_new_double(d);
+ json_object_set_serializer(jso, json_object_double_to_json_string, "%.8f", NULL);
+ return jso;
+}
+
+static void maybe_add_number(struct uci_context *ctx, struct uci_section *s, const char *name, struct json_object *parent) {
+ struct json_object *jso = get_number(ctx, s, name);
+ if (jso)
+ json_object_object_add(parent, name, jso);
}
static struct json_object * get_location(struct uci_context *ctx, struct uci_package *p) {
@@ -78,17 +86,9 @@ static struct json_object * get_location(struct uci_context *ctx, struct uci_pac
struct json_object *ret = json_object_new_object();
- struct json_object *latitude = get_number(ctx, s, "latitude");
- if (latitude)
- json_object_object_add(ret, "latitude", latitude);
-
- struct json_object *longitude = get_number(ctx, s, "longitude");
- if (longitude)
- json_object_object_add(ret, "longitude", longitude);
-
- struct json_object *altitude = get_number(ctx, s, "altitude");
- if (altitude)
- json_object_object_add(ret, "altitude", altitude);
+ maybe_add_number(ctx, s, "latitude", ret);
+ maybe_add_number(ctx, s, "longitude", ret);
+ maybe_add_number(ctx, s, "altitude", ret);
return ret;
}
diff --git a/package/gluon-radvd/Makefile b/package/gluon-radvd/Makefile
index 08448362..e44b80c5 100644
--- a/package/gluon-radvd/Makefile
+++ b/package/gluon-radvd/Makefile
@@ -5,7 +5,8 @@ PKG_VERSION:=4
PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME)
-include $(INCLUDE_DIR)/package.mk
+include $(GLUONDIR)/include/package.mk
+
define Package/gluon-radvd
SECTION:=gluon
@@ -26,10 +27,12 @@ define Build/Configure
endef
define Build/Compile
+ $(call GluonSrcDiet,./luasrc,$(PKG_BUILD_DIR)/luadest/)
endef
define Package/gluon-radvd/install
$(CP) ./files/* $(1)/
+ $(CP) $(PKG_BUILD_DIR)/luadest/* $(1)/
endef
$(eval $(call BuildPackage,gluon-radvd))
diff --git a/package/gluon-radvd/files/etc/init.d/gluon-radvd b/package/gluon-radvd/files/etc/init.d/gluon-radvd
index 98cf7a36..feef0399 100755
--- a/package/gluon-radvd/files/etc/init.d/gluon-radvd
+++ b/package/gluon-radvd/files/etc/init.d/gluon-radvd
@@ -1,5 +1,6 @@
#!/bin/sh /etc/rc.common
+USE_PROCD=1
START=50
SERVICE_WRITE_PID=1
@@ -7,7 +8,7 @@ SERVICE_DAEMONIZE=1
start() {
- service_start /usr/sbin/uradvd -i local-node -a $(lua -e 'print(require("gluon.site_config").prefix6)') --default-lifetime 900
+ service_start /usr/sbin/uradvd -i local-node -a $(lua -e 'print(require("gluon.site_config").prefix6)')
}
stop() {
diff --git a/package/gluon-radvd/files/lib/gluon/upgrade/500-radvd-remove-user b/package/gluon-radvd/luasrc/lib/gluon/upgrade/500-radvd-remove-user
similarity index 100%
rename from package/gluon-radvd/files/lib/gluon/upgrade/500-radvd-remove-user
rename to package/gluon-radvd/luasrc/lib/gluon/upgrade/500-radvd-remove-user
diff --git a/package/gluon-respondd/Makefile b/package/gluon-respondd/Makefile
index df9f257e..c6cc71e4 100644
--- a/package/gluon-respondd/Makefile
+++ b/package/gluon-respondd/Makefile
@@ -5,13 +5,14 @@ PKG_VERSION:=1
PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME)
-include $(INCLUDE_DIR)/package.mk
+include $(GLUONDIR)/include/package.mk
+
define Package/gluon-respondd
SECTION:=gluon
CATEGORY:=Gluon
TITLE:=Provides node information to the network
- DEPENDS:=+gluon-core +libplatforminfo +libgluonutil +respondd
+ DEPENDS:=+gluon-core +libplatforminfo +libgluonutil +libuci +respondd
endef
define Build/Prepare
@@ -19,9 +20,14 @@ define Build/Prepare
$(CP) ./src/* $(PKG_BUILD_DIR)/
endef
+define Build/Compile
+ $(call Build/Compile/Default)
+ $(call GluonSrcDiet,./luasrc,$(PKG_BUILD_DIR)/luadest/)
+endef
+
define Package/gluon-respondd/install
$(CP) ./files/* $(1)/
-
+ $(CP) $(PKG_BUILD_DIR)/luadest/* $(1)/
$(INSTALL_DIR) $(1)/lib/gluon/respondd
$(CP) $(PKG_BUILD_DIR)/respondd.so $(1)/lib/gluon/respondd/respondd.so
endef
diff --git a/package/gluon-respondd/files/lib/gluon/upgrade/400-respondd-firewall b/package/gluon-respondd/luasrc/lib/gluon/upgrade/400-respondd-firewall
similarity index 100%
rename from package/gluon-respondd/files/lib/gluon/upgrade/400-respondd-firewall
rename to package/gluon-respondd/luasrc/lib/gluon/upgrade/400-respondd-firewall
diff --git a/package/gluon-respondd/src/Makefile b/package/gluon-respondd/src/Makefile
index eddbe260..f26b59a2 100644
--- a/package/gluon-respondd/src/Makefile
+++ b/package/gluon-respondd/src/Makefile
@@ -3,4 +3,4 @@ all: respondd.so
CFLAGS += -Wall
respondd.so: respondd.c
- $(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) -shared -fPIC -D_GNU_SOURCE -o $@ $^ $(LDLIBS) -lgluonutil -lplatforminfo
+ $(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) -shared -fPIC -D_GNU_SOURCE -o $@ $^ $(LDLIBS) -lgluonutil -lplatforminfo -luci
diff --git a/package/gluon-respondd/src/respondd.c b/package/gluon-respondd/src/respondd.c
index 85006d6f..2b7a18f9 100644
--- a/package/gluon-respondd/src/respondd.c
+++ b/package/gluon-respondd/src/respondd.c
@@ -29,12 +29,12 @@
#include
#include
#include
+#include
#include
#include
#include
-#include
#include
@@ -67,12 +67,29 @@ static struct json_object * get_site_code(void) {
}
static struct json_object * get_hostname(void) {
- struct utsname utsname;
+ struct json_object *ret = NULL;
- if (uname(&utsname))
- return NULL;
+ struct uci_context *ctx = uci_alloc_context();
+ ctx->flags &= ~UCI_FLAG_STRICT;
- return gluonutil_wrap_string(utsname.nodename);
+ char section[] = "system.@system[0]";
+ struct uci_ptr ptr;
+ if (uci_lookup_ptr(ctx, &ptr, section, true))
+ goto error;
+
+ struct uci_section *s = ptr.s;
+
+ const char *hostname = uci_lookup_option_string(ctx, s, "pretty_hostname");
+
+ if (!hostname)
+ hostname = uci_lookup_option_string(ctx, s, "hostname");
+
+ ret = gluonutil_wrap_string(hostname);
+
+error:
+ uci_free_context(ctx);
+
+ return ret;
}
static struct json_object * respondd_provider_nodeinfo(void) {
@@ -107,13 +124,18 @@ static struct json_object * respondd_provider_nodeinfo(void) {
static void add_uptime(struct json_object *obj) {
FILE *f = fopen("/proc/uptime", "r");
+ struct json_object* jso;
if (!f)
return;
double uptime, idletime;
if (fscanf(f, "%lf %lf", &uptime, &idletime) == 2) {
- json_object_object_add(obj, "uptime", json_object_new_double(uptime));
- json_object_object_add(obj, "idletime", json_object_new_double(idletime));
+ jso = json_object_new_double(uptime);
+ json_object_set_serializer(jso, json_object_double_to_json_string, "%.2f", NULL);
+ json_object_object_add(obj, "uptime", jso);
+ jso = json_object_new_double(idletime);
+ json_object_set_serializer(jso, json_object_double_to_json_string, "%.2f", NULL);
+ json_object_object_add(obj, "idletime", jso);
}
fclose(f);
@@ -127,7 +149,9 @@ static void add_loadavg(struct json_object *obj) {
double loadavg;
unsigned proc_running, proc_total;
if (fscanf(f, "%lf %*f %*f %u/%u", &loadavg, &proc_running, &proc_total) == 3) {
- json_object_object_add(obj, "loadavg", json_object_new_double(loadavg));
+ struct json_object *jso = json_object_new_double(loadavg);
+ json_object_set_serializer(jso, json_object_double_to_json_string, "%.2f", NULL);
+ json_object_object_add(obj, "loadavg", jso);
struct json_object *processes = json_object_new_object();
json_object_object_add(processes, "running", json_object_new_int(proc_running));
@@ -176,7 +200,9 @@ static struct json_object * get_rootfs_usage(void) {
if (statfs("/", &s))
return NULL;
- return json_object_new_double(1 - (double)s.f_bfree / s.f_blocks);
+ struct json_object *jso = json_object_new_double(1 - (double)s.f_bfree / s.f_blocks);
+ json_object_set_serializer(jso, json_object_double_to_json_string, "%.4f", NULL);
+ return jso;
}
static struct json_object * respondd_provider_statistics(void) {
diff --git a/package/gluon-setup-mode/Makefile b/package/gluon-setup-mode/Makefile
index 55370abe..ea9722c0 100644
--- a/package/gluon-setup-mode/Makefile
+++ b/package/gluon-setup-mode/Makefile
@@ -10,6 +10,7 @@ PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME)
include $(GLUONDIR)/include/package.mk
+
define Package/gluon-setup-mode
SECTION:=gluon
CATEGORY:=Gluon
@@ -30,10 +31,12 @@ define Build/Configure
endef
define Build/Compile
+ $(call GluonSrcDiet,./luasrc,$(PKG_BUILD_DIR)/luadest/)
endef
define Package/gluon-setup-mode/install
$(CP) ./files/* $(1)/
+ $(CP) $(PKG_BUILD_DIR)/luadest/* $(1)/
endef
define Package/gluon-setup-mode/postinst
diff --git a/package/gluon-setup-mode/files/lib/gluon/upgrade/320-setup-ifname b/package/gluon-setup-mode/files/lib/gluon/upgrade/320-setup-ifname
deleted file mode 100755
index 3c4a8afe..00000000
--- a/package/gluon-setup-mode/files/lib/gluon/upgrade/320-setup-ifname
+++ /dev/null
@@ -1,18 +0,0 @@
-#!/usr/bin/lua
-
-local platform = require 'gluon.platform'
-local sysconfig = require 'gluon.sysconfig'
-
-
-if sysconfig.setup_ifname then
- os.exit(0)
-end
-
-if platform.match('ar71xx', 'generic', {'cpe510', 'nanostation-m', 'nanostation-m-xw', 'unifi-outdoor-plus'}) then
- sysconfig.setup_ifname = sysconfig.config_ifname or sysconfig.wan_ifname or sysconfig.lan_ifname
-else
- sysconfig.setup_ifname = sysconfig.config_ifname or sysconfig.lan_ifname or sysconfig.wan_ifname
-end
-
--- Remove the old sysconfig setting
-sysconfig.config_ifname = nil
diff --git a/package/gluon-setup-mode/files/lib/gluon/setup-mode/www/cgi-bin/luci b/package/gluon-setup-mode/luasrc/lib/gluon/setup-mode/www/cgi-bin/luci
similarity index 100%
rename from package/gluon-setup-mode/files/lib/gluon/setup-mode/www/cgi-bin/luci
rename to package/gluon-setup-mode/luasrc/lib/gluon/setup-mode/www/cgi-bin/luci
diff --git a/package/gluon-setup-mode/files/lib/gluon/upgrade/300-setup-mode b/package/gluon-setup-mode/luasrc/lib/gluon/upgrade/300-setup-mode
similarity index 100%
rename from package/gluon-setup-mode/files/lib/gluon/upgrade/300-setup-mode
rename to package/gluon-setup-mode/luasrc/lib/gluon/upgrade/300-setup-mode
diff --git a/package/gluon-setup-mode/files/lib/gluon/upgrade/310-setup-mode-migrate b/package/gluon-setup-mode/luasrc/lib/gluon/upgrade/310-setup-mode-migrate
similarity index 89%
rename from package/gluon-setup-mode/files/lib/gluon/upgrade/310-setup-mode-migrate
rename to package/gluon-setup-mode/luasrc/lib/gluon/upgrade/310-setup-mode-migrate
index 3b5165c4..8526dd29 100755
--- a/package/gluon-setup-mode/files/lib/gluon/upgrade/310-setup-mode-migrate
+++ b/package/gluon-setup-mode/luasrc/lib/gluon/upgrade/310-setup-mode-migrate
@@ -1,6 +1,5 @@
#!/usr/bin/lua
-local site = require 'gluon.site_config'
local uci = require 'luci.model.uci'
local c = uci.cursor()
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
new file mode 100755
index 00000000..3dba79a9
--- /dev/null
+++ b/package/gluon-setup-mode/luasrc/lib/gluon/upgrade/320-setup-ifname
@@ -0,0 +1,21 @@
+#!/usr/bin/lua
+
+local platform = require 'gluon.platform'
+local sysconfig = require 'gluon.sysconfig'
+
+
+if sysconfig.setup_ifname then
+ os.exit(0)
+end
+
+if
+ platform.match('ar71xx', 'generic', {'cpe510', '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
+else
+ sysconfig.setup_ifname = sysconfig.config_ifname or sysconfig.lan_ifname or sysconfig.wan_ifname
+end
+
+-- Remove the old sysconfig setting
+sysconfig.config_ifname = nil
diff --git a/package/gluon-status-page-api/Makefile b/package/gluon-status-page-api/Makefile
index 174e2e85..ddad2cab 100644
--- a/package/gluon-status-page-api/Makefile
+++ b/package/gluon-status-page-api/Makefile
@@ -7,7 +7,8 @@ PKG_RELEASE:=1
PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)
PKG_BUILD_DEPENDS := respondd
-include $(INCLUDE_DIR)/package.mk
+include $(GLUONDIR)/include/package.mk
+
define Package/gluon-status-page-api
SECTION:=gluon
@@ -21,6 +22,11 @@ define Build/Prepare
$(CP) ./src/* $(PKG_BUILD_DIR)/
endef
+define Build/Compile
+ $(call Build/Compile/Default)
+ $(call GluonSrcDiet,./luasrc,$(PKG_BUILD_DIR)/luadest/)
+endef
+
define Package/gluon-status-page-api/install
$(INSTALL_DIR) $(1)/lib/gluon/status-page/providers
$(INSTALL_BIN) $(PKG_BUILD_DIR)/neighbours-batadv $(1)/lib/gluon/status-page/providers/
@@ -30,6 +36,7 @@ define Package/gluon-status-page-api/install
$(CP) $(PKG_BUILD_DIR)/respondd.so $(1)/lib/gluon/respondd/status-page-api.so
$(CP) ./files/* $(1)/
+ $(CP) $(PKG_BUILD_DIR)/luadest/* $(1)/
endef
$(eval $(call BuildPackage,gluon-status-page-api))
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 a11fac9b..ce1bf06e 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
@@ -1,6 +1,6 @@
#!/bin/sh
-uci batch <<-EOF
+uci -q batch <<-EOF
delete uhttpd.main.listen_http
add_list uhttpd.main.listen_http=0.0.0.0:80
add_list uhttpd.main.listen_http=[::]:80
diff --git a/package/gluon-status-page-api/files/lib/gluon/status-page/www/cgi-bin/interfaces b/package/gluon-status-page-api/luasrc/lib/gluon/status-page/www/cgi-bin/interfaces
similarity index 100%
rename from package/gluon-status-page-api/files/lib/gluon/status-page/www/cgi-bin/interfaces
rename to package/gluon-status-page-api/luasrc/lib/gluon/status-page/www/cgi-bin/interfaces
diff --git a/package/gluon-status-page/Makefile b/package/gluon-status-page/Makefile
index 460764d0..ef6618d2 100644
--- a/package/gluon-status-page/Makefile
+++ b/package/gluon-status-page/Makefile
@@ -9,6 +9,7 @@ PKG_BUILD_DEPENDS:=node/host
include $(INCLUDE_DIR)/package.mk
+
define Download/rjs
FILE:=r.js
URL:=http://requirejs.org/docs/release/2.1.10
diff --git a/package/gluon-status-page/src/css/animation.css b/package/gluon-status-page/src/css/animation.css
index ac5a9562..e6edbf3c 100644
--- a/package/gluon-status-page/src/css/animation.css
+++ b/package/gluon-status-page/src/css/animation.css
@@ -2,84 +2,11 @@
Animation example, for spinners
*/
.animate-spin {
- -moz-animation: spin 2s infinite linear;
- -o-animation: spin 2s infinite linear;
- -webkit-animation: spin 2s infinite linear;
- animation: spin 2s infinite linear;
+ animation: spin 2s linear infinite;
display: inline-block;
}
-@-moz-keyframes spin {
- 0% {
- -moz-transform: rotate(0deg);
- -o-transform: rotate(0deg);
- -webkit-transform: rotate(0deg);
- transform: rotate(0deg);
- }
-
- 100% {
- -moz-transform: rotate(359deg);
- -o-transform: rotate(359deg);
- -webkit-transform: rotate(359deg);
- transform: rotate(359deg);
- }
-}
-@-webkit-keyframes spin {
- 0% {
- -moz-transform: rotate(0deg);
- -o-transform: rotate(0deg);
- -webkit-transform: rotate(0deg);
- transform: rotate(0deg);
- }
-
- 100% {
- -moz-transform: rotate(359deg);
- -o-transform: rotate(359deg);
- -webkit-transform: rotate(359deg);
- transform: rotate(359deg);
- }
-}
-@-o-keyframes spin {
- 0% {
- -moz-transform: rotate(0deg);
- -o-transform: rotate(0deg);
- -webkit-transform: rotate(0deg);
- transform: rotate(0deg);
- }
-
- 100% {
- -moz-transform: rotate(359deg);
- -o-transform: rotate(359deg);
- -webkit-transform: rotate(359deg);
- transform: rotate(359deg);
- }
-}
-@-ms-keyframes spin {
- 0% {
- -moz-transform: rotate(0deg);
- -o-transform: rotate(0deg);
- -webkit-transform: rotate(0deg);
- transform: rotate(0deg);
- }
-
- 100% {
- -moz-transform: rotate(359deg);
- -o-transform: rotate(359deg);
- -webkit-transform: rotate(359deg);
- transform: rotate(359deg);
- }
-}
@keyframes spin {
- 0% {
- -moz-transform: rotate(0deg);
- -o-transform: rotate(0deg);
- -webkit-transform: rotate(0deg);
- transform: rotate(0deg);
- }
-
100% {
- -moz-transform: rotate(359deg);
- -o-transform: rotate(359deg);
- -webkit-transform: rotate(359deg);
- transform: rotate(359deg);
+ transform: rotate(360deg);
}
}
diff --git a/package/gluon-status-page/src/css/menu.css b/package/gluon-status-page/src/css/menu.css
index c865c648..b29e4a41 100644
--- a/package/gluon-status-page/src/css/menu.css
+++ b/package/gluon-status-page/src/css/menu.css
@@ -21,20 +21,10 @@
max-height: 80vh;
transform-origin: top left;
- -webkit-animation: new-menu-animation .08s ease-out forwards;
- -moz-animation: new-menu-animation .08s ease-out forwards;
+ animation: new-menu-animation .08s ease-out forwards;
}
-@-webkit-keyframes new-menu-animation {
- from {
- transform: scaleY(0);
- }
- to {
- transform: scaleY(1);
- }
-}
-
-@-moz-keyframes new-menu-animation {
+@keyframes new-menu-animation {
from {
transform: scaleY(0);
}
diff --git a/package/gluon-wan-dnsmasq/Makefile b/package/gluon-wan-dnsmasq/Makefile
index 3722210f..c672902d 100644
--- a/package/gluon-wan-dnsmasq/Makefile
+++ b/package/gluon-wan-dnsmasq/Makefile
@@ -5,7 +5,8 @@ PKG_VERSION:=1
PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME)
-include $(INCLUDE_DIR)/package.mk
+include $(GLUONDIR)/include/package.mk
+
define Package/gluon-wan-dnsmasq
SECTION:=gluon
@@ -26,10 +27,12 @@ define Build/Configure
endef
define Build/Compile
+ $(call GluonSrcDiet,./luasrc,$(PKG_BUILD_DIR)/luadest/)
endef
define Package/gluon-wan-dnsmasq/install
$(CP) ./files/* $(1)/
+ $(CP) $(PKG_BUILD_DIR)/luadest/* $(1)/
endef
$(eval $(call BuildPackage,gluon-wan-dnsmasq))
diff --git a/package/gluon-wan-dnsmasq/files/lib/gluon/wan-dnsmasq/update.lua b/package/gluon-wan-dnsmasq/luasrc/lib/gluon/wan-dnsmasq/update.lua
similarity index 76%
rename from package/gluon-wan-dnsmasq/files/lib/gluon/wan-dnsmasq/update.lua
rename to package/gluon-wan-dnsmasq/luasrc/lib/gluon/wan-dnsmasq/update.lua
index 88a86507..cceb7225 100755
--- a/package/gluon-wan-dnsmasq/files/lib/gluon/wan-dnsmasq/update.lua
+++ b/package/gluon-wan-dnsmasq/luasrc/lib/gluon/wan-dnsmasq/update.lua
@@ -12,14 +12,20 @@ local fs = require 'nixio.fs'
local new_servers = ''
-local function append_servers(servers)
+local function handle_interface(status)
+ local ifname = status.device
+ local servers = status.inactive['dns-server']
+
for _, server in ipairs(servers) do
+ if server:match('^fe80:') then
+ server = server .. '%' .. ifname
+ end
new_servers = new_servers .. 'nameserver ' .. server .. '\n'
end
end
local function append_interface_servers(iface)
- append_servers(ubus:call('network.interface.' .. iface, 'status', {}).inactive['dns-server'])
+ handle_interface(ubus:call('network.interface.' .. iface, 'status', {}))
end
diff --git a/package/libgluonutil/Makefile b/package/libgluonutil/Makefile
index 762c25f4..bebeb2b3 100644
--- a/package/libgluonutil/Makefile
+++ b/package/libgluonutil/Makefile
@@ -8,9 +8,10 @@ PKG_LICENSE:=BSD-2-Clause
PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME)
-include $(INCLUDE_DIR)/package.mk
+include $(GLUONDIR)/include/package.mk
include $(INCLUDE_DIR)/cmake.mk
+
define Package/libgluonutil
SECTION:=libs
CATEGORY:=Libraries
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
new file mode 100644
index 00000000..81d95a9a
--- /dev/null
+++ b/patches/openwrt/0006-ar71xx-define-wmac-reset-function-for-QCA955x.patch
@@ -0,0 +1,85 @@
+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/0006-ath10k-firmware-add-Candela-Technologies-firmware-for-QCA988X.patch b/patches/openwrt/0006-ath10k-firmware-add-Candela-Technologies-firmware-for-QCA988X.patch
deleted file mode 100644
index 5baf2712..00000000
--- a/patches/openwrt/0006-ath10k-firmware-add-Candela-Technologies-firmware-for-QCA988X.patch
+++ /dev/null
@@ -1,72 +0,0 @@
-From: Matthias Schiffer
-Date: Tue, 9 Feb 2016 18:22:29 +0100
-Subject: ath10k-firmware: add Candela Technologies firmware for QCA988X
-
-diff --git a/package/firmware/ath10k-firmware/Makefile b/package/firmware/ath10k-firmware/Makefile
-index b03d644..7d4d449 100644
---- a/package/firmware/ath10k-firmware/Makefile
-+++ b/package/firmware/ath10k-firmware/Makefile
-@@ -44,6 +44,26 @@ define Download/ath10k-firmware-qca988x
- endef
- $(eval $(call Download,ath10k-firmware-qca988x))
-
-+
-+define Package/ath10k-firmware-qca988x-ct
-+$(Package/ath10k-firmware-default)
-+ TITLE:=ath10k firmware for QCA988x devices (Candela Technologies version)
-+ CONFLICTS:=ath10k-firmware-qca988x
-+endef
-+
-+QCA988X_CT_FIRMWARE_FILE:=firmware-5-ct-full-community.bin
-+
-+define Download/ath10k-firmware-qca988x-ct
-+ # See http://www.candelatech.com/ath10k.php
-+ #URL:=http://www.candelatech.com/downloads/ath10k-10-2/
-+ # Update to beta version (will switch back to official URL after v2 release)
-+ URL:=https://home.universe-factory.net/neoraider/
-+ FILE:=$(QCA988X_CT_FIRMWARE_FILE)
-+ MD5SUM:=9aa205cfd6b98e695ca8e9ae6d1bcb6b
-+endef
-+$(eval $(call Download,ath10k-firmware-qca988x-ct))
-+
-+
- define Package/ath10k-firmware-qca99x0
- $(Package/ath10k-firmware-default)
- TITLE:=ath10k firmware for QCA99x0 devices
-@@ -79,6 +99,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_CT_FIRMWARE_FILE) \
-+ $(1)/lib/firmware/ath10k/QCA988X/hw2.0/firmware-5.bin
-+endef
-+
- define Package/ath10k-firmware-qca6174/install
- $(INSTALL_DIR) $(1)/lib/firmware/ath10k
- $(CP) $(PKG_BUILD_DIR)/QCA6174 $(1)/lib/firmware/ath10k/
-@@ -98,5 +128,6 @@ define Package/ath10k-firmware-qca99x0/install
- endef
-
- $(eval $(call BuildPackage,ath10k-firmware-qca988x))
-+$(eval $(call BuildPackage,ath10k-firmware-qca988x-ct))
- $(eval $(call BuildPackage,ath10k-firmware-qca99x0))
- $(eval $(call BuildPackage,ath10k-firmware-qca6174))
-diff --git a/package/kernel/mac80211/Makefile b/package/kernel/mac80211/Makefile
-index 30da1cf..cd8d670 100644
---- a/package/kernel/mac80211/Makefile
-+++ b/package/kernel/mac80211/Makefile
-@@ -247,7 +247,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
diff --git a/patches/openwrt/0007-mac80211-ath10k-allow-simultaneous-AP-IBSS.patch b/patches/openwrt/0007-mac80211-ath10k-allow-simultaneous-AP-IBSS.patch
deleted file mode 100644
index 7586d3a2..00000000
--- a/patches/openwrt/0007-mac80211-ath10k-allow-simultaneous-AP-IBSS.patch
+++ /dev/null
@@ -1,42 +0,0 @@
-From: Matthias Schiffer
-Date: Wed, 20 May 2015 23:10:36 +0200
-Subject: mac80211: ath10k: allow simultaneous AP+IBSS
-
-diff --git a/package/kernel/mac80211/patches/950-ath10k_AP_IBSS.patch b/package/kernel/mac80211/patches/950-ath10k_AP_IBSS.patch
-new file mode 100644
-index 0000000..33b3110
---- /dev/null
-+++ b/package/kernel/mac80211/patches/950-ath10k_AP_IBSS.patch
-@@ -0,0 +1,32 @@
-+--- a/drivers/net/wireless/ath/ath10k/mac.c
-++++ b/drivers/net/wireless/ath/ath10k/mac.c
-+@@ -5264,6 +5264,10 @@ static const struct ieee80211_iface_limi
-+ .max = 7,
-+ .types = BIT(NL80211_IFTYPE_AP)
-+ },
-++ {
-++ .max = 1,
-++ .types = BIT(NL80211_IFTYPE_ADHOC)
-++ },
-+ };
-+
-+ static const struct ieee80211_iface_limit ath10k_10x_if_limits[] = {
-+@@ -5271,6 +5275,10 @@ static const struct ieee80211_iface_limi
-+ .max = 8,
-+ .types = BIT(NL80211_IFTYPE_AP)
-+ },
-++ {
-++ .max = 1,
-++ .types = BIT(NL80211_IFTYPE_ADHOC)
-++ },
-+ };
-+
-+ static const struct ieee80211_iface_combination ath10k_if_comb[] = {
-+@@ -5575,6 +5583,7 @@ int ath10k_mac_register(struct ath10k *a
-+ ar->hw->wiphy->iface_combinations = ath10k_10x_if_comb;
-+ ar->hw->wiphy->n_iface_combinations =
-+ ARRAY_SIZE(ath10k_10x_if_comb);
-++ ar->hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_ADHOC);
-+ break;
-+ case ATH10K_FW_WMI_OP_VERSION_UNSET:
-+ case ATH10K_FW_WMI_OP_VERSION_MAX:
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
new file mode 100644
index 00000000..4858efde
--- /dev/null
+++ b/patches/openwrt/0007-mac80211-hostapd-iw-.-update-to-LEDE-42f559ed70897a7b74dd3e6293b42e6d2e511eaa.patch
@@ -0,0 +1,19251 @@
+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