From bca916dd5515eb6ee782da25b550c8b7521f7223 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Mon, 27 Apr 2015 22:00:38 +0200 Subject: [PATCH 01/62] gluon-core: disable multicast snooping on the WAN bridge This seems to mitigate weird bridge forwarding issues. --- package/gluon-core/files/lib/gluon/upgrade/110-network | 1 + 1 file changed, 1 insertion(+) diff --git a/package/gluon-core/files/lib/gluon/upgrade/110-network b/package/gluon-core/files/lib/gluon/upgrade/110-network index 1fd78f3c..07961788 100755 --- a/package/gluon-core/files/lib/gluon/upgrade/110-network +++ b/package/gluon-core/files/lib/gluon/upgrade/110-network @@ -9,6 +9,7 @@ uci:section('network', 'interface', 'wan', { ifname = sysconfig.wan_ifname, type = 'bridge', + igmp_snooping = 0, peerdns = 0, auto = 1, } From 55d95f16b3630abc2b273fc8069f1a2213d8a1f1 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Tue, 28 Apr 2015 01:11:53 +0200 Subject: [PATCH 02/62] docs: various user/site fixes --- docs/user/site.rst | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/docs/user/site.rst b/docs/user/site.rst index fdd107b1..b15d9d72 100644 --- a/docs/user/site.rst +++ b/docs/user/site.rst @@ -67,21 +67,19 @@ wifi24 ``htmode``, the adhoc ssid ``mesh_ssid`` used between devices, the adhoc bssid ``mesh_bssid`` and the adhoc multicast rate ``mesh_mcast_rate``. Optionally ``mesh_vlan`` can be used to setup VLAN on top of the 802.11 - ad-hoc interface. The options``mesh_disabled`` and ``client_disabled`` + ad-hoc interface. The options ``mesh_disabled`` and ``client_disabled`` are optional, too. They allow to disable the SSID by default, e.g. for preconfigured node. This only affects first configuraton. Combined in an dictionary, e.g.: :: wifi24 = { - ssid = 'http://kiel.freifunk.net/', + ssid = 'entenhausen.freifunk.net', channel = 11, htmode = 'HT40-', mesh_ssid = 'ff:ff:ff:ee:ba:be', mesh_bssid = 'ff:ff:ff:ee:ba:be', mesh_mcast_rate = 12000, - client_disabled = true, - mesh_disabled = false, }, wifi5 @@ -94,7 +92,7 @@ next_node : package next_node = { ip4 = '10.23.42.1', ip6 = 'fdca:ffee:babe:1::1', - mac = 'ca:ff:ee:ba:be' + mac = 'ca:ff:ee:ba:be:00' } @@ -103,12 +101,12 @@ fastd_mesh_vpn :: fastd_mesh_vpn = { - methods = {'salsa2012+gmac'}, + methods = {'salsa2012+umac'}, mtu = 1426, backbone = { limit = 2, peers = { - ffki_rz = { + peer1 = { key = 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX', remotes = {'ipv4 "vpn1.entenhausen.freifunk.net" port 10000'}, }, From 472087a7b189f8972090eaf809e3055baf116440 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Tue, 28 Apr 2015 04:51:32 +0200 Subject: [PATCH 03/62] contrib/lsupgrade.sh: fix path output --- contrib/lsupgrade.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/contrib/lsupgrade.sh b/contrib/lsupgrade.sh index 57485616..7fe11299 100755 --- a/contrib/lsupgrade.sh +++ b/contrib/lsupgrade.sh @@ -26,7 +26,7 @@ fi pushd "$(dirname "$0")/.." >/dev/null -find package packages -name Makefile | while read makefile; do +find ./package packages -name Makefile | while read makefile; do dir="$(dirname "$makefile")" pushd "$dir" >/dev/null @@ -36,7 +36,7 @@ find package packages -name Makefile | while read makefile; do package="$(basename "$dir")" for file in "${SUFFIX}"/*; do - echo "${GREEN}$(basename "${file}")${RESET}" "(${BLUE}${repo}${RESET}/${dirname}/${RED}${package}${RESET}/${SUFFIX})" + echo "${GREEN}$(basename "${file}")${RESET}" "(${BLUE}${repo}${RESET}/${dirname}${dirname:+/}${RED}${package}${RESET}/${SUFFIX})" done popd >/dev/null done | sort From 6bcd9b92d494f29de0d5d2bc41643d2d35ffc530 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Tue, 28 Apr 2015 05:25:56 +0200 Subject: [PATCH 04/62] gluon-announced: allow announced queries on WAN (if mesh-on-wan is enabled) --- .../lib/gluon/upgrade/400-announced-firewall | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100755 package/gluon-announced/files/lib/gluon/upgrade/400-announced-firewall diff --git a/package/gluon-announced/files/lib/gluon/upgrade/400-announced-firewall b/package/gluon-announced/files/lib/gluon/upgrade/400-announced-firewall new file mode 100755 index 00000000..77acb1b9 --- /dev/null +++ b/package/gluon-announced/files/lib/gluon/upgrade/400-announced-firewall @@ -0,0 +1,18 @@ +#!/usr/bin/lua + +local uci = require('luci.model.uci').cursor() + +-- Allow announced port on WAN to allow resolving neighbours over mesh-on-wan +uci:section('firewall', 'rule', 'wan_announced', + { + name = 'wan_announced', + src = 'wan', + src_ip = 'fe80::/64', + dest_port = '1001', + proto = 'udp', + target = 'ACCEPT', + } +) + +uci:save('firewall') +uci:commit('firewall') From e0a1bf5f9a08c76349b243b2d4009073d6036baa Mon Sep 17 00:00:00 2001 From: do9xe Date: Thu, 23 Apr 2015 18:35:50 +0200 Subject: [PATCH 05/62] add the package gluon-luci-wifi-config --- package/gluon-luci-wifi-config/Makefile | 32 +++++++ .../lua/luci/controller/admin/wifi-config.lua | 5 ++ .../lua/luci/model/cbi/admin/wifi-config.lua | 83 +++++++++++++++++++ 3 files changed, 120 insertions(+) create mode 100644 package/gluon-luci-wifi-config/Makefile create mode 100644 package/gluon-luci-wifi-config/files/usr/lib/lua/luci/controller/admin/wifi-config.lua create mode 100644 package/gluon-luci-wifi-config/files/usr/lib/lua/luci/model/cbi/admin/wifi-config.lua diff --git a/package/gluon-luci-wifi-config/Makefile b/package/gluon-luci-wifi-config/Makefile new file mode 100644 index 00000000..2dd03f09 --- /dev/null +++ b/package/gluon-luci-wifi-config/Makefile @@ -0,0 +1,32 @@ +include $(TOPDIR)/rules.mk + +PKG_NAME:=gluon-luci-wifi-config +PKG_VERSION:=0.1 +PKG_RELEASE:=1 + +PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME) + +include $(INCLUDE_DIR)/package.mk + +define Package/gluon-luci-wifi-config + SECTION:=gluon + CATEGORY:=Gluon + DEPENDS:=+gluon-luci-admin + TITLE:=UI for Wifi Settings +endef + +define Build/Prepare + mkdir -p $(PKG_BUILD_DIR) +endef + +define Build/Configure +endef + +define Build/Compile +endef + +define Package/gluon-luci-wifi-config/install + $(CP) ./files/* $(1)/ +endef + +$(eval $(call BuildPackage,gluon-luci-wifi-config)) diff --git a/package/gluon-luci-wifi-config/files/usr/lib/lua/luci/controller/admin/wifi-config.lua b/package/gluon-luci-wifi-config/files/usr/lib/lua/luci/controller/admin/wifi-config.lua new file mode 100644 index 00000000..3bcb0007 --- /dev/null +++ b/package/gluon-luci-wifi-config/files/usr/lib/lua/luci/controller/admin/wifi-config.lua @@ -0,0 +1,5 @@ +module("luci.controller.admin.wifi-config", package.seeall) + +function index() + entry({"admin", "wifi-config"}, cbi("admin/wifi-config"), "WLAN", 20) +end 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/files/usr/lib/lua/luci/model/cbi/admin/wifi-config.lua new file mode 100644 index 00000000..d6559b51 --- /dev/null +++ b/package/gluon-luci-wifi-config/files/usr/lib/lua/luci/model/cbi/admin/wifi-config.lua @@ -0,0 +1,83 @@ +local f, s, o +local uci = luci.model.uci.cursor() + +--set the heading, button and stuff +f = SimpleForm("wifi", "WLAN-Config") +f.reset = false +f.template = "admin/expertmode" +f.submit = "Speichern" + +-- text, which describes what the package does to the user +s = f:section(SimpleSection, nil, [[ +In diesem Abschnitt hast du die Möglichkeit die SSIDs des Client- und des +Mesh-Netzes zu deaktivieren. Bitte lass die SSID des Mesh-Netzes aktiviert, +damit sich auch andere Knoten über dich mit dem Freifunk verbinden können. +]]) + +local radios = {} + +-- look for wifi interfaces and add them to the array +uci:foreach('wireless', 'wifi-device', +function(s) + table.insert(radios, s['.name']) +end +) + +--add a client and mesh checkbox for each interface +for index, radio in ipairs(radios) do + --get the hwmode to seperate 2.4GHz and 5Ghz radios + local hwmode = uci:get('wireless', radio, 'hwmode') + local p + + if hwmode == '11g' or hwmode == '11ng' then --if 2.4GHz + + p = f:section(SimpleSection, "2,4GHz-WLAN", nil) + + elseif hwmode == '11a' or hwmode == '11na' then --if 5GHz + + p = f:section(SimpleSection, "5GHz-WLAN", nil) + + end + + if p then + --box for the clientnet + o = p:option(Flag, 'clientbox' .. index, "Client-Netz aktivieren") + o.default = (uci:get_bool('wireless', 'client_' .. radio, "disabled")) and o.disabled or o.enabled + o.rmempty = false + --box for the meshnet + o = p:option(Flag, 'meshbox' .. index, "Mesh-Netz aktivieren") + o.default = (uci:get_bool('wireless', 'mesh_' .. radio, "disabled")) and o.disabled or o.enabled + o.rmempty = false + end + +end + +--if the save-button is pushed +function f.handle(self, state, data) + if state == FORM_VALID then + + for index, radio in ipairs(radios) do + + local clientdisabled = 0 + local meshdisabled = 0 + -- get the data from the boxes and invert it + if data["clientbox"..index] == '0' then + clientdisabled = 1 + end + -- write the data to the config file + uci:set('wireless', 'client_' .. radio, "disabled", clientdisabled) + + if data["meshbox"..index] == '0' then + meshdisabled = 1 + end + + uci:set('wireless', 'mesh_' .. radio, "disabled", meshdisabled) + + end + + uci:save('wireless') + uci:commit('wireless') + end +end + +return f From 0c80e7863f1745bebcfb26192c5996a275526fa4 Mon Sep 17 00:00:00 2001 From: Kokel Date: Sun, 26 Apr 2015 17:34:05 +0200 Subject: [PATCH 06/62] gluon-luci-node-role: add translations --- package/gluon-luci-node-role/Makefile | 4 +++ .../lua/luci/controller/admin/noderole.lua | 2 +- .../lib/lua/luci/model/cbi/admin/noderole.lua | 15 +++++------ package/gluon-luci-node-role/i18n/de.po | 27 +++++++++++++++++++ .../i18n/gluon-luci-node-role.pot | 14 ++++++++++ 5 files changed, 53 insertions(+), 9 deletions(-) create mode 100644 package/gluon-luci-node-role/i18n/de.po create mode 100644 package/gluon-luci-node-role/i18n/gluon-luci-node-role.pot diff --git a/package/gluon-luci-node-role/Makefile b/package/gluon-luci-node-role/Makefile index 5e0fbb00..ded7bd3f 100644 --- a/package/gluon-luci-node-role/Makefile +++ b/package/gluon-luci-node-role/Makefile @@ -8,6 +8,8 @@ PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME) include $(GLUONDIR)/include/package.mk +PKG_CONFIG_DEPENDS += $(GLUON_I18N_CONFIG) + define Package/gluon-luci-node-role SECTION:=gluon CATEGORY:=Gluon @@ -23,10 +25,12 @@ define Build/Configure endef define Build/Compile + $(call GluonBuildI18N,gluon-luci-node-role,i18n) endef define Package/gluon-luci-node-role/install $(CP) ./files/* $(1)/ + $(call GluonInstallI18N,gluon-luci-node-role,$(1)) endef define Package/gluon-luci-node-role/postinst diff --git a/package/gluon-luci-node-role/files/usr/lib/lua/luci/controller/admin/noderole.lua b/package/gluon-luci-node-role/files/usr/lib/lua/luci/controller/admin/noderole.lua index dcde01f1..cfca1275 100644 --- a/package/gluon-luci-node-role/files/usr/lib/lua/luci/controller/admin/noderole.lua +++ b/package/gluon-luci-node-role/files/usr/lib/lua/luci/controller/admin/noderole.lua @@ -1,5 +1,5 @@ module("luci.controller.admin.noderole", package.seeall) function index() - entry({"admin", "noderole"}, cbi("admin/noderole"), "Verwendungszweck", 20) + entry({"admin", "noderole"}, cbi("admin/noderole"), "Node role", 20) end diff --git a/package/gluon-luci-node-role/files/usr/lib/lua/luci/model/cbi/admin/noderole.lua b/package/gluon-luci-node-role/files/usr/lib/lua/luci/model/cbi/admin/noderole.lua index 1d6d1798..48750508 100644 --- a/package/gluon-luci-node-role/files/usr/lib/lua/luci/model/cbi/admin/noderole.lua +++ b/package/gluon-luci-node-role/files/usr/lib/lua/luci/model/cbi/admin/noderole.lua @@ -1,23 +1,22 @@ local f, s, o local site = require 'gluon.site_config' +local i18n = require "luci.i18n" local uci = luci.model.uci.cursor() local config = 'gluon-node-info' -- where to read the configuration from local role = uci:get(config, uci:get_first(config, "system"), "role") -f = SimpleForm("role", "Verwendungszweck") +f = SimpleForm("role", i18n.translate("Node role")) f.reset = false f.template = "admin/expertmode" -f.submit = "Fertig" -s = f:section(SimpleSection, nil, [[ -Wenn dein Freifunk-Router eine besondere Rolle im Freifunk Netz einnimmt, kannst du diese hier angeben. -Bringe bitte zuvor in Erfahrung welche Auswirkungen die zur Verfügung stehenden Rollen im Freifunk-Netz haben. -Setze die Rolle nur, wenn du weißt was du machst. -]]) +s = f:section(SimpleSection, nil, i18n.translate( + "If this node has a special role within the freifunk network you can specify this role here. " + .. "Please find out about the available roles and their impact first. " + .. "Only change the role if you know what you are doing.")) -o = s:option(ListValue, "role", "Rolle") +o = s:option(ListValue, "role", i18n.translate("Role")) o.default = role o.rmempty = false for role, prettyname in pairs(site.roles.list) do diff --git a/package/gluon-luci-node-role/i18n/de.po b/package/gluon-luci-node-role/i18n/de.po new file mode 100644 index 00000000..e3037b26 --- /dev/null +++ b/package/gluon-luci-node-role/i18n/de.po @@ -0,0 +1,27 @@ +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"PO-Revision-Date: 2015-04-26 17:18+0200\n" +"Last-Translator: Tobias Hachmer \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" + +msgid "Node role" +msgstr "Verwendungszweck" + +msgid "Role" +msgstr "Rolle" + +msgid "" +"If this node has a special role within the freifunk network you can specify " +"this role here. Please find out about the available roles and their impact " +"first. Only change the role if you know what you are doing." +msgstr "" +"Wenn dein Freifunk-Knoten eine besondere Rolle im Freifunk Netz einnimmt, " +"kannst du diese hier angeben. Bringe bitte zuvor in Erfahrung, welche " +"Auswirkungen die zur Verfügung stehenden Rollen im Freifunk-Netz haben. " +"Setze die Rolle nur, wenn du weißt was du machst." diff --git a/package/gluon-luci-node-role/i18n/gluon-luci-node-role.pot b/package/gluon-luci-node-role/i18n/gluon-luci-node-role.pot new file mode 100644 index 00000000..acf6dd79 --- /dev/null +++ b/package/gluon-luci-node-role/i18n/gluon-luci-node-role.pot @@ -0,0 +1,14 @@ +msgid "" +msgstr "Content-Type: text/plain; charset=UTF-8" + +msgid "Node role" +msgstr "" + +msgid "Role" +msgstr "" + +msgid "" +"If this node has a special role within the freifunk network you can specify this role here. " +"Please find out about the available roles and their impact first. " +"Only change the role if you know what you are doing." +msgstr "" From 25d8b18f7ae007b654db9bd8747db34c24765361 Mon Sep 17 00:00:00 2001 From: kokel Date: Tue, 28 Apr 2015 06:43:11 +0200 Subject: [PATCH 07/62] gluon-luci-node-role: activate reset button --- .../files/usr/lib/lua/luci/model/cbi/admin/noderole.lua | 1 - 1 file changed, 1 deletion(-) diff --git a/package/gluon-luci-node-role/files/usr/lib/lua/luci/model/cbi/admin/noderole.lua b/package/gluon-luci-node-role/files/usr/lib/lua/luci/model/cbi/admin/noderole.lua index 48750508..d2ab51a7 100644 --- a/package/gluon-luci-node-role/files/usr/lib/lua/luci/model/cbi/admin/noderole.lua +++ b/package/gluon-luci-node-role/files/usr/lib/lua/luci/model/cbi/admin/noderole.lua @@ -8,7 +8,6 @@ local config = 'gluon-node-info' local role = uci:get(config, uci:get_first(config, "system"), "role") f = SimpleForm("role", i18n.translate("Node role")) -f.reset = false f.template = "admin/expertmode" s = f:section(SimpleSection, nil, i18n.translate( From db88166217f6ba4cd650874d83f42b5a01db83b6 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Wed, 29 Apr 2015 16:19:16 +0200 Subject: [PATCH 08/62] docs: mention site.mk changes in changelog --- docs/releases/v2015.1.rst | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/docs/releases/v2015.1.rst b/docs/releases/v2015.1.rst index 8ce3db0f..c52ef920 100644 --- a/docs/releases/v2015.1.rst +++ b/docs/releases/v2015.1.rst @@ -22,6 +22,12 @@ Site changes to keep the old behaviour, you have to append the hyphen to the ``hostname_prefix`` field of your ``site.conf``. +* ``site.mk`` + + - The packages ``gluon-setup-mode`` and ``gluon-config-mode-core`` must now be + added to ``GLUON_SITE_PACKAGES`` explicitly (to allow replacing them with + community-specific implementations). + Internals ~~~~~~~~~ From 531520032cdc9ab8b22b9c56d506fc9e9dd5c012 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Thu, 30 Apr 2015 03:40:04 +0200 Subject: [PATCH 09/62] mpc85xx: fix WDR4900 ethernet MAC address --- ...-from-patch-files-to-files-directory.patch | 1111 +++++++++++++++++ ...nfar-add-add-mtd-mac-address-support.patch | 168 +++ ...rnet-MAC-address-hack-with-DTS-entry.patch | 41 + 3 files changed, 1320 insertions(+) create mode 100644 patches/openwrt/0032-mpc85xx-move-newly-created-files-from-patch-files-to-files-directory.patch create mode 100644 patches/openwrt/0033-mpc85xx-gianfar-add-add-mtd-mac-address-support.patch create mode 100644 patches/openwrt/0034-mpc85xx-replace-WDR4900-uci-defaults-ethernet-MAC-address-hack-with-DTS-entry.patch diff --git a/patches/openwrt/0032-mpc85xx-move-newly-created-files-from-patch-files-to-files-directory.patch b/patches/openwrt/0032-mpc85xx-move-newly-created-files-from-patch-files-to-files-directory.patch new file mode 100644 index 00000000..656ffc27 --- /dev/null +++ b/patches/openwrt/0032-mpc85xx-move-newly-created-files-from-patch-files-to-files-directory.patch @@ -0,0 +1,1111 @@ +From: Matthias Schiffer +Date: Thu, 30 Apr 2015 03:21:01 +0200 +Subject: mpc85xx: move newly created files from patch files to files directory + +This will make these files much more maintainable. + +diff --git a/target/linux/mpc85xx/files/arch/powerpc/boot/cuboot-tl-wdr4900-v1.c b/target/linux/mpc85xx/files/arch/powerpc/boot/cuboot-tl-wdr4900-v1.c +new file mode 100644 +index 0000000..17459ef +--- /dev/null ++++ b/target/linux/mpc85xx/files/arch/powerpc/boot/cuboot-tl-wdr4900-v1.c +@@ -0,0 +1,168 @@ ++/* ++ * U-Boot compatibility wrapper for the TP-Link TL-WDR4900 v1 board ++ * ++ * Copyright (c) 2013 Gabor Juhos ++ * ++ * Based on: ++ * cuboot-85xx.c ++ * Author: Scott Wood ++ * Copyright (c) 2007 Freescale Semiconductor, Inc. ++ * ++ * simpleboot.c ++ * Authors: Scott Wood ++ * Grant Likely ++ * Copyright (c) 2007 Freescale Semiconductor, Inc. ++ * Copyright (c) 2008 Secret Lab Technologies Ltd. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License version 2 as published ++ * by the Free Software Foundation. ++ */ ++ ++#include "ops.h" ++#include "types.h" ++#include "io.h" ++#include "stdio.h" ++#include ++ ++BSS_STACK(4*1024); ++ ++static unsigned long bus_freq; ++static unsigned long int_freq; ++static u64 mem_size; ++static unsigned char enetaddr[6]; ++ ++static void process_boot_dtb(void *boot_dtb) ++{ ++ const u32 *na, *ns, *reg, *val32; ++ const char *path; ++ u64 memsize64; ++ int node, size, i; ++ ++ /* Make sure FDT blob is sane */ ++ if (fdt_check_header(boot_dtb) != 0) ++ fatal("Invalid device tree blob\n"); ++ ++ /* Find the #address-cells and #size-cells properties */ ++ node = fdt_path_offset(boot_dtb, "/"); ++ if (node < 0) ++ fatal("Cannot find root node\n"); ++ na = fdt_getprop(boot_dtb, node, "#address-cells", &size); ++ if (!na || (size != 4)) ++ fatal("Cannot find #address-cells property"); ++ ++ ns = fdt_getprop(boot_dtb, node, "#size-cells", &size); ++ if (!ns || (size != 4)) ++ fatal("Cannot find #size-cells property"); ++ ++ /* Find the memory range */ ++ node = fdt_node_offset_by_prop_value(boot_dtb, -1, "device_type", ++ "memory", sizeof("memory")); ++ if (node < 0) ++ fatal("Cannot find memory node\n"); ++ reg = fdt_getprop(boot_dtb, node, "reg", &size); ++ if (size < (*na+*ns) * sizeof(u32)) ++ fatal("cannot get memory range\n"); ++ ++ /* Only interested in memory based at 0 */ ++ for (i = 0; i < *na; i++) ++ if (*reg++ != 0) ++ fatal("Memory range is not based at address 0\n"); ++ ++ /* get the memsize and trucate it to under 4G on 32 bit machines */ ++ memsize64 = 0; ++ for (i = 0; i < *ns; i++) ++ memsize64 = (memsize64 << 32) | *reg++; ++ if (sizeof(void *) == 4 && memsize64 >= 0x100000000ULL) ++ memsize64 = 0xffffffff; ++ ++ mem_size = memsize64; ++ ++ /* get clock frequencies */ ++ node = fdt_node_offset_by_prop_value(boot_dtb, -1, "device_type", ++ "cpu", sizeof("cpu")); ++ if (!node) ++ fatal("Cannot find cpu node\n"); ++ ++ val32 = fdt_getprop(boot_dtb, node, "clock-frequency", &size); ++ if (!val32 || (size != 4)) ++ fatal("Cannot get clock frequency"); ++ ++ int_freq = *val32; ++ ++ val32 = fdt_getprop(boot_dtb, node, "bus-frequency", &size); ++ if (!val32 || (size != 4)) ++ fatal("Cannot get bus frequency"); ++ ++ bus_freq = *val32; ++ ++ path = fdt_get_alias(boot_dtb, "ethernet0"); ++ if (path) { ++ const void *p; ++ ++ node = fdt_path_offset(boot_dtb, path); ++ if (node < 0) ++ fatal("Cannot find ethernet0 node"); ++ ++ p = fdt_getprop(boot_dtb, node, "mac-address", &size); ++ if (!p || (size < 6)) { ++ printf("no mac-address property, finding local\n\r"); ++ p = fdt_getprop(boot_dtb, node, "local-mac-address", &size); ++ } ++ ++ if (!p || (size < 6)) ++ fatal("cannot get MAC addres"); ++ ++ memcpy(enetaddr, p, sizeof(enetaddr)); ++ } ++} ++ ++static void platform_fixups(void) ++{ ++ void *soc, *mpic; ++ ++ dt_fixup_memory(0, mem_size); ++ ++ dt_fixup_mac_address_by_alias("ethernet0", enetaddr); ++ dt_fixup_cpu_clocks(int_freq, bus_freq / 8, bus_freq); ++ ++ /* Unfortunately, the specific model number is encoded in the ++ * soc node name in existing dts files -- once that is fixed, ++ * this can do a simple path lookup. ++ */ ++ soc = find_node_by_devtype(NULL, "soc"); ++ if (soc) { ++ void *serial = NULL; ++ ++ setprop(soc, "bus-frequency", &bus_freq, sizeof(bus_freq)); ++ ++ while ((serial = find_node_by_devtype(serial, "serial"))) { ++ if (get_parent(serial) != soc) ++ continue; ++ ++ setprop(serial, "clock-frequency", &bus_freq, ++ sizeof(bus_freq)); ++ } ++ } ++ ++ mpic = find_node_by_compatible(NULL, "fsl,mpic"); ++ if (mpic) ++ setprop(mpic, "clock-frequency", &bus_freq, sizeof(bus_freq)); ++} ++ ++void platform_init(unsigned long r3, unsigned long r4, unsigned long r5, ++ unsigned long r6, unsigned long r7) ++{ ++ mem_size = 64 * 1024 * 1024; ++ ++ simple_alloc_init(_end, mem_size - (u32)_end - 1024*1024, 32, 64); ++ ++ fdt_init(_dtb_start); ++ serial_console_init(); ++ ++ printf("\n\r-- TL-WDR4900 v1 boot wrapper --\n\r"); ++ ++ process_boot_dtb((void *) r3); ++ ++ platform_ops.fixups = platform_fixups; ++} +diff --git a/target/linux/mpc85xx/files/arch/powerpc/boot/dts/tl-wdr4900-v1.dts b/target/linux/mpc85xx/files/arch/powerpc/boot/dts/tl-wdr4900-v1.dts +new file mode 100644 +index 0000000..49e516c +--- /dev/null ++++ b/target/linux/mpc85xx/files/arch/powerpc/boot/dts/tl-wdr4900-v1.dts +@@ -0,0 +1,212 @@ ++/* ++ * TP-Link TL-WDR4900 v1 Device Tree Source ++ * ++ * Copyright 2013 Gabor Juhos ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License as published by the ++ * Free Software Foundation; either version 2 of the License, or (at your ++ * option) any later version. ++ */ ++ ++/include/ "fsl/p1010si-pre.dtsi" ++ ++/ { ++ model = "TP-Link TL-WDR4900 v1"; ++ compatible = "tp-link,TL-WDR4900v1"; ++ ++ chosen { ++ bootargs = "console=ttyS0,115200"; ++/* ++ linux,stdout-path = "/soc@ffe00000/serial@4500"; ++*/ ++ }; ++ ++ aliases { ++ spi0 = &spi0; ++ }; ++ ++ memory { ++ device_type = "memory"; ++ }; ++ ++ soc: soc@ffe00000 { ++ ranges = <0x0 0x0 0xffe00000 0x100000>; ++ ++ spi0: spi@7000 { ++ flash@0 { ++ #address-cells = <1>; ++ #size-cells = <1>; ++ compatible = "spansion,s25fl129p1"; ++ reg = <0>; ++ spi-max-frequency = <25000000>; ++ ++ u-boot@0 { ++ reg = <0x0 0x0050000>; ++ label = "u-boot"; ++ read-only; ++ }; ++ ++ dtb@50000 { ++ reg = <0x00050000 0x00010000>; ++ label = "dtb"; ++ read-only; ++ }; ++ ++ kernel@60000 { ++ reg = <0x00060000 0x002a0000>; ++ label = "kernel"; ++ }; ++ ++ rootfs@300000 { ++ reg = <0x00300000 0x00ce0000>; ++ label = "rootfs"; ++ }; ++ ++ config@fe0000 { ++ reg = <0x00fe0000 0x00010000>; ++ label = "config"; ++ read-only; ++ }; ++ ++ caldata@ff0000 { ++ reg = <0x00ff0000 0x00010000>; ++ label = "caldata"; ++ read-only; ++ }; ++ ++ firmware@60000 { ++ reg = <0x00060000 0x00f80000>; ++ label = "firmware"; ++ }; ++ }; ++ }; ++ ++ gpio0: gpio-controller@f000 { ++ }; ++ ++ usb@22000 { ++ phy_type = "utmi"; ++ dr_mode = "host"; ++ }; ++ ++ mdio@24000 { ++ phy0: ethernet-phy@0 { ++ reg = <0x0>; ++ qca,ar8327-initvals = < ++ 0x00004 0x07600000 /* PAD0_MODE */ ++ 0x00008 0x00000000 /* PAD5_MODE */ ++ 0x0000c 0x01000000 /* PAD6_MODE */ ++ 0x00010 0x40000000 /* POWER_ON_STRIP */ ++ 0x00050 0xcf35cf35 /* LED_CTRL0 */ ++ 0x00054 0xcf35cf35 /* LED_CTRL1 */ ++ 0x00058 0xcf35cf35 /* LED_CTRL2 */ ++ 0x0005c 0x03ffff00 /* LED_CTRL3 */ ++ 0x0007c 0x0000007e /* PORT0_STATUS */ ++ >; ++ }; ++ }; ++ ++ mdio@25000 { ++ status = "disabled"; ++ }; ++ ++ mdio@26000 { ++ status = "disabled"; ++ }; ++ ++ enet0: ethernet@b0000 { ++ phy-handle = <&phy0>; ++ phy-connection-type = "rgmii-id"; ++ }; ++ ++ enet1: ethernet@b1000 { ++ status = "disabled"; ++ }; ++ ++ enet2: ethernet@b2000 { ++ status = "disabled"; ++ }; ++ ++ sdhc@2e000 { ++ status = "disabled"; ++ }; ++ ++ serial1: serial@4600 { ++ status = "disabled"; ++ }; ++ ++ can0: can@1c000 { ++ status = "disabled"; ++ }; ++ ++ can1: can@1d000 { ++ status = "disabled"; ++ }; ++ }; ++ ++ pci0: pcie@ffe09000 { ++ reg = <0 0xffe09000 0 0x1000>; ++ ranges = <0x2000000 0x0 0xa0000000 0 0xa0000000 0x0 0x20000000 ++ 0x1000000 0x0 0x00000000 0 0xffc10000 0x0 0x10000>; ++ pcie@0 { ++ ranges = <0x2000000 0x0 0xa0000000 ++ 0x2000000 0x0 0xa0000000 ++ 0x0 0x20000000 ++ ++ 0x1000000 0x0 0x0 ++ 0x1000000 0x0 0x0 ++ 0x0 0x100000>; ++ }; ++ }; ++ ++ pci1: pcie@ffe0a000 { ++ reg = <0 0xffe0a000 0 0x1000>; ++ ranges = <0x2000000 0x0 0x80000000 0 0x80000000 0x0 0x20000000 ++ 0x1000000 0x0 0x00000000 0 0xffc00000 0x0 0x10000>; ++ pcie@0 { ++ ranges = <0x2000000 0x0 0x80000000 ++ 0x2000000 0x0 0x80000000 ++ 0x0 0x20000000 ++ ++ 0x1000000 0x0 0x0 ++ 0x1000000 0x0 0x0 ++ 0x0 0x100000>; ++ }; ++ }; ++ ++ ifc: ifc@ffe1e000 { ++ status = "disabled"; ++ }; ++ ++ leds { ++ compatible = "gpio-leds"; ++ ++ system { ++ gpios = <&gpio0 2 1>; /* active low */ ++ label = "tp-link:blue:system"; ++ }; ++ ++ usb1 { ++ gpios = <&gpio0 3 1>; /* active low */ ++ label = "tp-link:green:usb1"; ++ }; ++ ++ usb2 { ++ gpios = <&gpio0 4 1>; /* active low */ ++ label = "tp-link:green:usb2"; ++ }; ++ }; ++ ++ buttons { ++ compatible = "gpio-keys"; ++ ++ reset { ++ label = "Reset button"; ++ gpios = <&gpio0 5 1>; /* active low */ ++ linux,code = <0x198>; /* KEY_RESTART */ ++ }; ++ }; ++}; ++ ++/include/ "fsl/p1010si-post.dtsi" +diff --git a/target/linux/mpc85xx/files/arch/powerpc/platforms/85xx/tl_wdr4900_v1.c b/target/linux/mpc85xx/files/arch/powerpc/platforms/85xx/tl_wdr4900_v1.c +new file mode 100644 +index 0000000..95afa4d +--- /dev/null ++++ b/target/linux/mpc85xx/files/arch/powerpc/platforms/85xx/tl_wdr4900_v1.c +@@ -0,0 +1,145 @@ ++/* ++ * TL-WDR4900 v1 board setup ++ * ++ * Copyright (c) 2013 Gabor Juhos ++ * ++ * Based on: ++ * p1010rdb.c: ++ * P1010RDB Board Setup ++ * Copyright 2011 Freescale Semiconductor Inc. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License as published by the ++ * Free Software Foundation; either version 2 of the License, or (at your ++ * option) any later version. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++ ++#include "mpc85xx.h" ++ ++void __init tl_wdr4900_v1_pic_init(void) ++{ ++ struct mpic *mpic = mpic_alloc(NULL, 0, MPIC_BIG_ENDIAN | ++ MPIC_SINGLE_DEST_CPU, ++ 0, 256, " OpenPIC "); ++ ++ BUG_ON(mpic == NULL); ++ ++ mpic_init(mpic); ++} ++ ++#ifdef CONFIG_PCI ++static struct gpio_led tl_wdr4900_v1_wmac_leds_gpio[] = { ++ { ++ .name = "tp-link:blue:wps", ++ .gpio = 1, ++ .active_low = 1, ++ }, ++}; ++ ++static struct ath9k_platform_data tl_wdr4900_v1_wmac0_data = { ++ .led_pin = 0, ++ .eeprom_name = "pci_wmac0.eeprom", ++ .leds = tl_wdr4900_v1_wmac_leds_gpio, ++ .num_leds = ARRAY_SIZE(tl_wdr4900_v1_wmac_leds_gpio), ++}; ++ ++static struct ath9k_platform_data tl_wdr4900_v1_wmac1_data = { ++ .led_pin = 0, ++ .eeprom_name = "pci_wmac1.eeprom", ++}; ++ ++static void tl_wdr4900_v1_pci_wmac_fixup(struct pci_dev *dev) ++{ ++ if (!machine_is(tl_wdr4900_v1)) ++ return; ++ ++ if (dev->bus->number == 1 && ++ PCI_SLOT(dev->devfn) == 0) { ++ dev->dev.platform_data = &tl_wdr4900_v1_wmac0_data; ++ return; ++ } ++ ++ if (dev->bus->number == 3 && ++ PCI_SLOT(dev->devfn) == 0 && ++ dev->device == 0xabcd) { ++ dev->dev.platform_data = &tl_wdr4900_v1_wmac1_data; ++ ++ /* ++ * The PCI header of the AR9381 chip is not programmed ++ * correctly by the bootloader and the device uses wrong ++ * data due to that. Replace the broken values with the ++ * correct ones. ++ */ ++ dev->device = 0x30; ++ dev->class = 0x028000; ++ ++ pr_info("pci %s: AR9381 fixup applied\n", pci_name(dev)); ++ } ++} ++ ++DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_ATHEROS, PCI_ANY_ID, ++ tl_wdr4900_v1_pci_wmac_fixup); ++#endif /* CONFIG_PCI */ ++ ++/* ++ * Setup the architecture ++ */ ++static void __init tl_wdr4900_v1_setup_arch(void) ++{ ++ if (ppc_md.progress) ++ ppc_md.progress("tl_wdr4900_v1_setup_arch()", 0); ++ ++ fsl_pci_assign_primary(); ++ ++ printk(KERN_INFO "TL-WDR4900 v1 board from TP-Link\n"); ++} ++ ++machine_arch_initcall(tl_wdr4900_v1, mpc85xx_common_publish_devices); ++machine_arch_initcall(tl_wdr4900_v1, swiotlb_setup_bus_notifier); ++ ++/* ++ * Called very early, device-tree isn't unflattened ++ */ ++static int __init tl_wdr4900_v1_probe(void) ++{ ++ unsigned long root = of_get_flat_dt_root(); ++ ++ if (of_flat_dt_is_compatible(root, "tp-link,TL-WDR4900v1")) ++ return 1; ++ ++ return 0; ++} ++ ++define_machine(tl_wdr4900_v1) { ++ .name = "Freescale P1014", ++ .probe = tl_wdr4900_v1_probe, ++ .setup_arch = tl_wdr4900_v1_setup_arch, ++ .init_IRQ = tl_wdr4900_v1_pic_init, ++#ifdef CONFIG_PCI ++ .pcibios_fixup_bus = fsl_pcibios_fixup_bus, ++#endif ++ .get_irq = mpic_get_irq, ++ .restart = fsl_rstcr_restart, ++ .calibrate_decr = generic_calibrate_decr, ++ .progress = udbg_progress, ++}; +diff --git a/target/linux/mpc85xx/patches-3.10/140-powerpc-85xx-tl-wdr4900-v1-support.patch b/target/linux/mpc85xx/patches-3.10/140-powerpc-85xx-tl-wdr4900-v1-support.patch +index 8407176..dae2305 100644 +--- a/target/linux/mpc85xx/patches-3.10/140-powerpc-85xx-tl-wdr4900-v1-support.patch ++++ b/target/linux/mpc85xx/patches-3.10/140-powerpc-85xx-tl-wdr4900-v1-support.patch +@@ -11,16 +11,9 @@ the Freescale P1014 SoC. + Signed-off-by: Gabor Juhos + --- + arch/powerpc/boot/Makefile | 3 + +- arch/powerpc/boot/cuboot-tl-wdr4900-v1.c | 164 ++++++++++++++++++++++++++ +- arch/powerpc/boot/dts/tl-wdr4900-v1.dts | 166 +++++++++++++++++++++++++++ + arch/powerpc/boot/wrapper | 4 + + arch/powerpc/platforms/85xx/Kconfig | 11 ++ + arch/powerpc/platforms/85xx/Makefile | 1 + +- arch/powerpc/platforms/85xx/tl_wdr4900_v1.c | 145 +++++++++++++++++++++++ +- 7 files changed, 494 insertions(+) +- create mode 100644 arch/powerpc/boot/cuboot-tl-wdr4900-v1.c +- create mode 100644 arch/powerpc/boot/dts/tl-wdr4900-v1.dts +- create mode 100644 arch/powerpc/platforms/85xx/tl_wdr4900_v1.c + + --- a/arch/powerpc/boot/Makefile + +++ b/arch/powerpc/boot/Makefile +@@ -41,388 +34,6 @@ Signed-off-by: Gabor Juhos + + # Board ports in arch/powerpc/platform/embedded6xx/Kconfig + image-$(CONFIG_STORCENTER) += cuImage.storcenter +---- /dev/null +-+++ b/arch/powerpc/boot/cuboot-tl-wdr4900-v1.c +-@@ -0,0 +1,164 @@ +-+/* +-+ * U-Boot compatibility wrapper for the TP-Link TL-WDR4900 v1 board +-+ * +-+ * Copyright (c) 2013 Gabor Juhos +-+ * +-+ * Based on: +-+ * cuboot-85xx.c +-+ * Author: Scott Wood +-+ * Copyright (c) 2007 Freescale Semiconductor, Inc. +-+ * +-+ * simpleboot.c +-+ * Authors: Scott Wood +-+ * Grant Likely +-+ * Copyright (c) 2007 Freescale Semiconductor, Inc. +-+ * Copyright (c) 2008 Secret Lab Technologies Ltd. +-+ * +-+ * This program is free software; you can redistribute it and/or modify it +-+ * under the terms of the GNU General Public License version 2 as published +-+ * by the Free Software Foundation. +-+ */ +-+ +-+#include "ops.h" +-+#include "types.h" +-+#include "io.h" +-+#include "stdio.h" +-+#include +-+ +-+BSS_STACK(4*1024); +-+ +-+static unsigned long bus_freq; +-+static unsigned long int_freq; +-+static u64 mem_size; +-+static unsigned char enetaddr[6]; +-+ +-+static void process_boot_dtb(void *boot_dtb) +-+{ +-+ const u32 *na, *ns, *reg, *val32; +-+ const char *path; +-+ u64 memsize64; +-+ int node, size, i; +-+ +-+ /* Make sure FDT blob is sane */ +-+ if (fdt_check_header(boot_dtb) != 0) +-+ fatal("Invalid device tree blob\n"); +-+ +-+ /* Find the #address-cells and #size-cells properties */ +-+ node = fdt_path_offset(boot_dtb, "/"); +-+ if (node < 0) +-+ fatal("Cannot find root node\n"); +-+ na = fdt_getprop(boot_dtb, node, "#address-cells", &size); +-+ if (!na || (size != 4)) +-+ fatal("Cannot find #address-cells property"); +-+ +-+ ns = fdt_getprop(boot_dtb, node, "#size-cells", &size); +-+ if (!ns || (size != 4)) +-+ fatal("Cannot find #size-cells property"); +-+ +-+ /* Find the memory range */ +-+ node = fdt_node_offset_by_prop_value(boot_dtb, -1, "device_type", +-+ "memory", sizeof("memory")); +-+ if (node < 0) +-+ fatal("Cannot find memory node\n"); +-+ reg = fdt_getprop(boot_dtb, node, "reg", &size); +-+ if (size < (*na+*ns) * sizeof(u32)) +-+ fatal("cannot get memory range\n"); +-+ +-+ /* Only interested in memory based at 0 */ +-+ for (i = 0; i < *na; i++) +-+ if (*reg++ != 0) +-+ fatal("Memory range is not based at address 0\n"); +-+ +-+ /* get the memsize and trucate it to under 4G on 32 bit machines */ +-+ memsize64 = 0; +-+ for (i = 0; i < *ns; i++) +-+ memsize64 = (memsize64 << 32) | *reg++; +-+ if (sizeof(void *) == 4 && memsize64 >= 0x100000000ULL) +-+ memsize64 = 0xffffffff; +-+ +-+ mem_size = memsize64; +-+ +-+ /* get clock frequencies */ +-+ node = fdt_node_offset_by_prop_value(boot_dtb, -1, "device_type", +-+ "cpu", sizeof("cpu")); +-+ if (!node) +-+ fatal("Cannot find cpu node\n"); +-+ +-+ val32 = fdt_getprop(boot_dtb, node, "clock-frequency", &size); +-+ if (!val32 || (size != 4)) +-+ fatal("Cannot get clock frequency"); +-+ +-+ int_freq = *val32; +-+ +-+ val32 = fdt_getprop(boot_dtb, node, "bus-frequency", &size); +-+ if (!val32 || (size != 4)) +-+ fatal("Cannot get bus frequency"); +-+ +-+ bus_freq = *val32; +-+ +-+ path = fdt_get_alias(boot_dtb, "ethernet0"); +-+ if (path) { +-+ const void *p; +-+ +-+ node = fdt_path_offset(boot_dtb, path); +-+ if (node < 0) +-+ fatal("Cannot find ethernet0 node"); +-+ +-+ p = fdt_getprop(boot_dtb, node, "mac-address", &size); +-+ if (!p || (size < 6)) { +-+ printf("no mac-address property, finding local\n\r"); +-+ p = fdt_getprop(boot_dtb, node, "local-mac-address", &size); +-+ } +-+ +-+ if (!p || (size < 6)) +-+ fatal("cannot get MAC addres"); +-+ +-+ memcpy(enetaddr, p, sizeof(enetaddr)); +-+ } +-+} +-+ +-+static void platform_fixups(void) +-+{ +-+ void *soc; +-+ +-+ dt_fixup_memory(0, mem_size); +-+ +-+ dt_fixup_mac_address_by_alias("ethernet0", enetaddr); +-+ dt_fixup_cpu_clocks(int_freq, bus_freq / 8, bus_freq); +-+ +-+ /* Unfortunately, the specific model number is encoded in the +-+ * soc node name in existing dts files -- once that is fixed, +-+ * this can do a simple path lookup. +-+ */ +-+ soc = find_node_by_devtype(NULL, "soc"); +-+ if (soc) { +-+ void *serial = NULL; +-+ +-+ setprop(soc, "bus-frequency", &bus_freq, sizeof(bus_freq)); +-+ +-+ while ((serial = find_node_by_devtype(serial, "serial"))) { +-+ if (get_parent(serial) != soc) +-+ continue; +-+ +-+ setprop(serial, "clock-frequency", &bus_freq, +-+ sizeof(bus_freq)); +-+ } +-+ } +-+} +-+ +-+void platform_init(unsigned long r3, unsigned long r4, unsigned long r5, +-+ unsigned long r6, unsigned long r7) +-+{ +-+ mem_size = 64 * 1024 * 1024; +-+ +-+ simple_alloc_init(_end, mem_size - (u32)_end - 1024*1024, 32, 64); +-+ +-+ fdt_init(_dtb_start); +-+ serial_console_init(); +-+ +-+ printf("\n\r-- TL-WDR4900 v1 boot wrapper --\n\r"); +-+ +-+ process_boot_dtb((void *) r3); +-+ +-+ platform_ops.fixups = platform_fixups; +-+} +---- /dev/null +-+++ b/arch/powerpc/boot/dts/tl-wdr4900-v1.dts +-@@ -0,0 +1,212 @@ +-+/* +-+ * TP-Link TL-WDR4900 v1 Device Tree Source +-+ * +-+ * Copyright 2013 Gabor Juhos +-+ * +-+ * This program is free software; you can redistribute it and/or modify it +-+ * under the terms of the GNU General Public License as published by the +-+ * Free Software Foundation; either version 2 of the License, or (at your +-+ * option) any later version. +-+ */ +-+ +-+/include/ "fsl/p1010si-pre.dtsi" +-+ +-+/ { +-+ model = "TP-Link TL-WDR4900 v1"; +-+ compatible = "tp-link,TL-WDR4900v1"; +-+ +-+ chosen { +-+ bootargs = "console=ttyS0,115200"; +-+/* +-+ linux,stdout-path = "/soc@ffe00000/serial@4500"; +-+*/ +-+ }; +-+ +-+ aliases { +-+ spi0 = &spi0; +-+ }; +-+ +-+ memory { +-+ device_type = "memory"; +-+ }; +-+ +-+ soc: soc@ffe00000 { +-+ ranges = <0x0 0x0 0xffe00000 0x100000>; +-+ +-+ spi0: spi@7000 { +-+ flash@0 { +-+ #address-cells = <1>; +-+ #size-cells = <1>; +-+ compatible = "spansion,s25fl129p1"; +-+ reg = <0>; +-+ spi-max-frequency = <25000000>; +-+ +-+ u-boot@0 { +-+ reg = <0x0 0x0050000>; +-+ label = "u-boot"; +-+ read-only; +-+ }; +-+ +-+ dtb@50000 { +-+ reg = <0x00050000 0x00010000>; +-+ label = "dtb"; +-+ read-only; +-+ }; +-+ +-+ kernel@60000 { +-+ reg = <0x00060000 0x002a0000>; +-+ label = "kernel"; +-+ }; +-+ +-+ rootfs@300000 { +-+ reg = <0x00300000 0x00ce0000>; +-+ label = "rootfs"; +-+ }; +-+ +-+ config@fe0000 { +-+ reg = <0x00fe0000 0x00010000>; +-+ label = "config"; +-+ read-only; +-+ }; +-+ +-+ caldata@ff0000 { +-+ reg = <0x00ff0000 0x00010000>; +-+ label = "caldata"; +-+ read-only; +-+ }; +-+ +-+ firmware@60000 { +-+ reg = <0x00060000 0x00f80000>; +-+ label = "firmware"; +-+ }; +-+ }; +-+ }; +-+ +-+ gpio0: gpio-controller@f000 { +-+ }; +-+ +-+ usb@22000 { +-+ phy_type = "utmi"; +-+ dr_mode = "host"; +-+ }; +-+ +-+ mdio@24000 { +-+ phy0: ethernet-phy@0 { +-+ reg = <0x0>; +-+ qca,ar8327-initvals = < +-+ 0x00004 0x07600000 /* PAD0_MODE */ +-+ 0x00008 0x00000000 /* PAD5_MODE */ +-+ 0x0000c 0x01000000 /* PAD6_MODE */ +-+ 0x00010 0x40000000 /* POWER_ON_STRIP */ +-+ 0x00050 0xcf35cf35 /* LED_CTRL0 */ +-+ 0x00054 0xcf35cf35 /* LED_CTRL1 */ +-+ 0x00058 0xcf35cf35 /* LED_CTRL2 */ +-+ 0x0005c 0x03ffff00 /* LED_CTRL3 */ +-+ 0x0007c 0x0000007e /* PORT0_STATUS */ +-+ >; +-+ }; +-+ }; +-+ +-+ mdio@25000 { +-+ status = "disabled"; +-+ }; +-+ +-+ mdio@26000 { +-+ status = "disabled"; +-+ }; +-+ +-+ enet0: ethernet@b0000 { +-+ phy-handle = <&phy0>; +-+ phy-connection-type = "rgmii-id"; +-+ }; +-+ +-+ enet1: ethernet@b1000 { +-+ status = "disabled"; +-+ }; +-+ +-+ enet2: ethernet@b2000 { +-+ status = "disabled"; +-+ }; +-+ +-+ sdhc@2e000 { +-+ status = "disabled"; +-+ }; +-+ +-+ serial1: serial@4600 { +-+ status = "disabled"; +-+ }; +-+ +-+ can0: can@1c000 { +-+ status = "disabled"; +-+ }; +-+ +-+ can1: can@1d000 { +-+ status = "disabled"; +-+ }; +-+ }; +-+ +-+ pci0: pcie@ffe09000 { +-+ reg = <0 0xffe09000 0 0x1000>; +-+ ranges = <0x2000000 0x0 0xa0000000 0 0xa0000000 0x0 0x20000000 +-+ 0x1000000 0x0 0x00000000 0 0xffc10000 0x0 0x10000>; +-+ pcie@0 { +-+ ranges = <0x2000000 0x0 0xa0000000 +-+ 0x2000000 0x0 0xa0000000 +-+ 0x0 0x20000000 +-+ +-+ 0x1000000 0x0 0x0 +-+ 0x1000000 0x0 0x0 +-+ 0x0 0x100000>; +-+ }; +-+ }; +-+ +-+ pci1: pcie@ffe0a000 { +-+ reg = <0 0xffe0a000 0 0x1000>; +-+ ranges = <0x2000000 0x0 0x80000000 0 0x80000000 0x0 0x20000000 +-+ 0x1000000 0x0 0x00000000 0 0xffc00000 0x0 0x10000>; +-+ pcie@0 { +-+ ranges = <0x2000000 0x0 0x80000000 +-+ 0x2000000 0x0 0x80000000 +-+ 0x0 0x20000000 +-+ +-+ 0x1000000 0x0 0x0 +-+ 0x1000000 0x0 0x0 +-+ 0x0 0x100000>; +-+ }; +-+ }; +-+ +-+ ifc: ifc@ffe1e000 { +-+ status = "disabled"; +-+ }; +-+ +-+ leds { +-+ compatible = "gpio-leds"; +-+ +-+ system { +-+ gpios = <&gpio0 2 1>; /* active low */ +-+ label = "tp-link:blue:system"; +-+ }; +-+ +-+ usb1 { +-+ gpios = <&gpio0 3 1>; /* active low */ +-+ label = "tp-link:green:usb1"; +-+ }; +-+ +-+ usb2 { +-+ gpios = <&gpio0 4 1>; /* active low */ +-+ label = "tp-link:green:usb2"; +-+ }; +-+ }; +-+ +-+ buttons { +-+ compatible = "gpio-keys"; +-+ +-+ reset { +-+ label = "Reset button"; +-+ gpios = <&gpio0 5 1>; /* active low */ +-+ linux,code = <0x198>; /* KEY_RESTART */ +-+ }; +-+ }; +-+}; +-+ +-+/include/ "fsl/p1010si-post.dtsi" + --- a/arch/powerpc/boot/wrapper + +++ b/arch/powerpc/boot/wrapper + @@ -197,6 +197,10 @@ cuboot*) +@@ -466,151 +77,3 @@ Signed-off-by: Gabor Juhos + obj-$(CONFIG_SBC8548) += sbc8548.o + obj-$(CONFIG_PPA8548) += ppa8548.o + obj-$(CONFIG_SOCRATES) += socrates.o socrates_fpga_pic.o +---- /dev/null +-+++ b/arch/powerpc/platforms/85xx/tl_wdr4900_v1.c +-@@ -0,0 +1,145 @@ +-+/* +-+ * TL-WDR4900 v1 board setup +-+ * +-+ * Copyright (c) 2013 Gabor Juhos +-+ * +-+ * Based on: +-+ * p1010rdb.c: +-+ * P1010RDB Board Setup +-+ * Copyright 2011 Freescale Semiconductor Inc. +-+ * +-+ * This program is free software; you can redistribute it and/or modify it +-+ * under the terms of the GNU General Public License as published by the +-+ * Free Software Foundation; either version 2 of the License, or (at your +-+ * option) any later version. +-+ */ +-+ +-+#include +-+#include +-+#include +-+#include +-+#include +-+#include +-+#include +-+#include +-+ +-+#include +-+#include +-+#include +-+#include +-+#include +-+#include +-+#include +-+ +-+#include +-+#include +-+ +-+#include "mpc85xx.h" +-+ +-+void __init tl_wdr4900_v1_pic_init(void) +-+{ +-+ struct mpic *mpic = mpic_alloc(NULL, 0, MPIC_BIG_ENDIAN | +-+ MPIC_SINGLE_DEST_CPU, +-+ 0, 256, " OpenPIC "); +-+ +-+ BUG_ON(mpic == NULL); +-+ +-+ mpic_init(mpic); +-+} +-+ +-+#ifdef CONFIG_PCI +-+static struct gpio_led tl_wdr4900_v1_wmac_leds_gpio[] = { +-+ { +-+ .name = "tp-link:blue:wps", +-+ .gpio = 1, +-+ .active_low = 1, +-+ }, +-+}; +-+ +-+static struct ath9k_platform_data tl_wdr4900_v1_wmac0_data = { +-+ .led_pin = 0, +-+ .eeprom_name = "pci_wmac0.eeprom", +-+ .leds = tl_wdr4900_v1_wmac_leds_gpio, +-+ .num_leds = ARRAY_SIZE(tl_wdr4900_v1_wmac_leds_gpio), +-+}; +-+ +-+static struct ath9k_platform_data tl_wdr4900_v1_wmac1_data = { +-+ .led_pin = 0, +-+ .eeprom_name = "pci_wmac1.eeprom", +-+}; +-+ +-+static void tl_wdr4900_v1_pci_wmac_fixup(struct pci_dev *dev) +-+{ +-+ if (!machine_is(tl_wdr4900_v1)) +-+ return; +-+ +-+ if (dev->bus->number == 1 && +-+ PCI_SLOT(dev->devfn) == 0) { +-+ dev->dev.platform_data = &tl_wdr4900_v1_wmac0_data; +-+ return; +-+ } +-+ +-+ if (dev->bus->number == 3 && +-+ PCI_SLOT(dev->devfn) == 0 && +-+ dev->device == 0xabcd) { +-+ dev->dev.platform_data = &tl_wdr4900_v1_wmac1_data; +-+ +-+ /* +-+ * The PCI header of the AR9381 chip is not programmed +-+ * correctly by the bootloader and the device uses wrong +-+ * data due to that. Replace the broken values with the +-+ * correct ones. +-+ */ +-+ dev->device = 0x30; +-+ dev->class = 0x028000; +-+ +-+ pr_info("pci %s: AR9381 fixup applied\n", pci_name(dev)); +-+ } +-+} +-+ +-+DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_ATHEROS, PCI_ANY_ID, +-+ tl_wdr4900_v1_pci_wmac_fixup); +-+#endif /* CONFIG_PCI */ +-+ +-+/* +-+ * Setup the architecture +-+ */ +-+static void __init tl_wdr4900_v1_setup_arch(void) +-+{ +-+ if (ppc_md.progress) +-+ ppc_md.progress("tl_wdr4900_v1_setup_arch()", 0); +-+ +-+ fsl_pci_assign_primary(); +-+ +-+ printk(KERN_INFO "TL-WDR4900 v1 board from TP-Link\n"); +-+} +-+ +-+machine_arch_initcall(tl_wdr4900_v1, mpc85xx_common_publish_devices); +-+machine_arch_initcall(tl_wdr4900_v1, swiotlb_setup_bus_notifier); +-+ +-+/* +-+ * Called very early, device-tree isn't unflattened +-+ */ +-+static int __init tl_wdr4900_v1_probe(void) +-+{ +-+ unsigned long root = of_get_flat_dt_root(); +-+ +-+ if (of_flat_dt_is_compatible(root, "tp-link,TL-WDR4900v1")) +-+ return 1; +-+ +-+ return 0; +-+} +-+ +-+define_machine(tl_wdr4900_v1) { +-+ .name = "Freescale P1014", +-+ .probe = tl_wdr4900_v1_probe, +-+ .setup_arch = tl_wdr4900_v1_setup_arch, +-+ .init_IRQ = tl_wdr4900_v1_pic_init, +-+#ifdef CONFIG_PCI +-+ .pcibios_fixup_bus = fsl_pcibios_fixup_bus, +-+#endif +-+ .get_irq = mpic_get_irq, +-+ .restart = fsl_rstcr_restart, +-+ .calibrate_decr = generic_calibrate_decr, +-+ .progress = udbg_progress, +-+}; diff --git a/patches/openwrt/0033-mpc85xx-gianfar-add-add-mtd-mac-address-support.patch b/patches/openwrt/0033-mpc85xx-gianfar-add-add-mtd-mac-address-support.patch new file mode 100644 index 00000000..461e7479 --- /dev/null +++ b/patches/openwrt/0033-mpc85xx-gianfar-add-add-mtd-mac-address-support.patch @@ -0,0 +1,168 @@ +From: Matthias Schiffer +Date: Thu, 30 Apr 2015 02:10:54 +0200 +Subject: mpc85xx: gianfar: add add mtd-mac-address support + +diff --git a/target/linux/mpc85xx/patches-3.10/101-NET-add-of_get_mac_address_mtd.patch b/target/linux/mpc85xx/patches-3.10/101-NET-add-of_get_mac_address_mtd.patch +new file mode 100644 +index 0000000..cd88d2b +--- /dev/null ++++ b/target/linux/mpc85xx/patches-3.10/101-NET-add-of_get_mac_address_mtd.patch +@@ -0,0 +1,76 @@ ++From 92f38460229a8816404408f036f0a374f1013d0e Mon Sep 17 00:00:00 2001 ++From: John Crispin ++Date: Sun, 27 Jul 2014 09:40:01 +0100 ++Subject: NET: add of_get_mac_address_mtd() ++ ++Many embedded devices have information such as mac addresses stored inside mtd ++devices. This patch allows us to add a property inside a node describing a ++network interface. The new property points at a mtd partition with an offset ++where the mac address can be found. ++ ++Signed-off-by: John Crispin ++--- ++ drivers/of/of_net.c | 37 +++++++++++++++++++++++++++++++++++++ ++ include/linux/of_net.h | 1 + ++ 2 files changed, 38 insertions(+) ++ ++--- a/drivers/of/of_net.c +++++ b/drivers/of/of_net.c ++@@ -10,6 +10,7 @@ ++ #include ++ #include ++ #include +++#include ++ ++ /** ++ * It maps 'enum phy_interface_t' found in include/linux/phy.h ++@@ -92,3 +93,39 @@ const void *of_get_mac_address(struct de ++ return NULL; ++ } ++ EXPORT_SYMBOL(of_get_mac_address); +++ +++int of_get_mac_address_mtd(struct device_node *np, void *mac) +++{ +++ struct device_node *mtd_np = NULL; +++ size_t retlen; +++ int size, ret; +++ struct mtd_info *mtd; +++ const char *part; +++ const __be32 *list; +++ phandle phandle; +++ +++ list = of_get_property(np, "mtd-mac-address", &size); +++ if (!list || (size != (2 * sizeof(*list)))) +++ return -ENOENT; +++ +++ phandle = be32_to_cpup(list++); +++ if (phandle) +++ mtd_np = of_find_node_by_phandle(phandle); +++ +++ if (!mtd_np) +++ return -ENOENT; +++ +++ part = of_get_property(mtd_np, "label", NULL); +++ if (!part) +++ part = mtd_np->name; +++ +++ mtd = get_mtd_device_nm(part); +++ if (IS_ERR(mtd)) +++ return PTR_ERR(mtd); +++ +++ ret = mtd_read(mtd, be32_to_cpup(list), 6, &retlen, (u_char *) mac); +++ put_mtd_device(mtd); +++ +++ return ret; +++} +++EXPORT_SYMBOL_GPL(of_get_mac_address_mtd); ++--- a/include/linux/of_net.h +++++ b/include/linux/of_net.h ++@@ -11,6 +11,7 @@ ++ #include ++ extern const int of_get_phy_mode(struct device_node *np); ++ extern const void *of_get_mac_address(struct device_node *np); +++extern int of_get_mac_address_mtd(struct device_node *np, void *mac); ++ #else ++ static inline const int of_get_phy_mode(struct device_node *np) ++ { +diff --git a/target/linux/mpc85xx/patches-3.10/201-net-gianfar-use-mtd-mac-address.patch b/target/linux/mpc85xx/patches-3.10/201-net-gianfar-use-mtd-mac-address.patch +new file mode 100644 +index 0000000..1de4418 +--- /dev/null ++++ b/target/linux/mpc85xx/patches-3.10/201-net-gianfar-use-mtd-mac-address.patch +@@ -0,0 +1,19 @@ ++--- a/drivers/net/ethernet/freescale/gianfar.c +++++ b/drivers/net/ethernet/freescale/gianfar.c ++@@ -741,10 +741,13 @@ static int gfar_of_init(struct platform_ ++ if (stash_len || stash_idx) ++ priv->device_flags |= FSL_GIANFAR_DEV_HAS_BUF_STASHING; ++ ++- mac_addr = of_get_mac_address(np); +++ err = of_get_mac_address_mtd(np, dev->dev_addr); +++ if (err) { +++ mac_addr = of_get_mac_address(np); ++ ++- if (mac_addr) ++- memcpy(dev->dev_addr, mac_addr, ETH_ALEN); +++ if (mac_addr) +++ memcpy(dev->dev_addr, mac_addr, ETH_ALEN); +++ } ++ ++ if (model && !strcasecmp(model, "TSEC")) ++ priv->device_flags = FSL_GIANFAR_DEV_HAS_GIGABIT | +diff --git a/target/linux/mpc85xx/patches-3.10/220-fix_gianfar_reported_number_of_sent_bytes_to_BQL.patch b/target/linux/mpc85xx/patches-3.10/220-fix_gianfar_reported_number_of_sent_bytes_to_BQL.patch +index d0380ff..0d510bc 100644 +--- a/target/linux/mpc85xx/patches-3.10/220-fix_gianfar_reported_number_of_sent_bytes_to_BQL.patch ++++ b/target/linux/mpc85xx/patches-3.10/220-fix_gianfar_reported_number_of_sent_bytes_to_BQL.patch +@@ -1,6 +1,6 @@ + --- a/drivers/net/ethernet/freescale/gianfar.c + +++ b/drivers/net/ethernet/freescale/gianfar.c +-@@ -2064,7 +2064,7 @@ static int gfar_start_xmit(struct sk_buf ++@@ -2067,7 +2067,7 @@ static int gfar_start_xmit(struct sk_buf + int i, rq = 0, do_tstamp = 0; + u32 bufaddr; + unsigned long flags; +@@ -9,7 +9,7 @@ + + /* TOE=1 frames larger than 2500 bytes may see excess delays + * before start of transmission. +-@@ -2130,7 +2130,10 @@ static int gfar_start_xmit(struct sk_buf ++@@ -2133,7 +2133,10 @@ static int gfar_start_xmit(struct sk_buf + } + + /* Update transmit stats */ +@@ -21,7 +21,7 @@ + tx_queue->stats.tx_packets++; + + txbdp = txbdp_start = tx_queue->cur_tx; +-@@ -2150,12 +2153,13 @@ static int gfar_start_xmit(struct sk_buf ++@@ -2153,12 +2156,13 @@ static int gfar_start_xmit(struct sk_buf + } else { + /* Place the fragment addresses and lengths into the TxBDs */ + for (i = 0; i < nr_frags; i++) { +@@ -37,7 +37,7 @@ + BD_LFLAG(TXBD_READY); + + /* Handle the last BD specially */ +-@@ -2165,7 +2169,7 @@ static int gfar_start_xmit(struct sk_buf ++@@ -2168,7 +2172,7 @@ static int gfar_start_xmit(struct sk_buf + bufaddr = skb_frag_dma_map(priv->dev, + &skb_shinfo(skb)->frags[i], + 0, +@@ -46,7 +46,7 @@ + DMA_TO_DEVICE); + + /* set the TxBD length and buffer pointer */ +-@@ -2231,7 +2235,7 @@ static int gfar_start_xmit(struct sk_buf ++@@ -2234,7 +2238,7 @@ static int gfar_start_xmit(struct sk_buf + lstatus |= BD_LFLAG(TXBD_CRC | TXBD_READY) | skb_headlen(skb); + } + +@@ -55,7 +55,7 @@ + + /* We can work in parallel with gfar_clean_tx_ring(), except + * when modifying num_txbdfree. Note that we didn't grab the lock +-@@ -2551,7 +2555,7 @@ static void gfar_clean_tx_ring(struct gf ++@@ -2554,7 +2558,7 @@ static void gfar_clean_tx_ring(struct gf + bdp = next_txbd(bdp, base, tx_ring_size); + } + diff --git a/patches/openwrt/0034-mpc85xx-replace-WDR4900-uci-defaults-ethernet-MAC-address-hack-with-DTS-entry.patch b/patches/openwrt/0034-mpc85xx-replace-WDR4900-uci-defaults-ethernet-MAC-address-hack-with-DTS-entry.patch new file mode 100644 index 00000000..d27b0f0d --- /dev/null +++ b/patches/openwrt/0034-mpc85xx-replace-WDR4900-uci-defaults-ethernet-MAC-address-hack-with-DTS-entry.patch @@ -0,0 +1,41 @@ +From: Matthias Schiffer +Date: Thu, 30 Apr 2015 02:12:18 +0200 +Subject: mpc85xx: replace WDR4900 uci-defaults ethernet MAC address hack with DTS entry + +This also changes the MAC address to one of the adresses actually used by the +stock firmware on one of the ethernet interfaces. + +diff --git a/target/linux/mpc85xx/base-files/etc/uci-defaults/02_network b/target/linux/mpc85xx/base-files/etc/uci-defaults/02_network +index e4e3566..525a552 100755 +--- a/target/linux/mpc85xx/base-files/etc/uci-defaults/02_network ++++ b/target/linux/mpc85xx/base-files/etc/uci-defaults/02_network +@@ -20,8 +20,6 @@ tl-wdr4900-v1) + ucidef_add_switch "switch0" "1" "1" + ucidef_add_switch_vlan "switch0" "1" "0t 2 3 4 5" + ucidef_add_switch_vlan "switch0" "2" "0t 1" +- ucidef_set_interface_macaddr lan "$(mtd_get_mac_binary config 338)" +- ucidef_set_interface_macaddr wan "$(mtd_get_mac_binary config 344)" + ;; + *) + ucidef_set_interfaces_lan_wan "eth0" "eth1" +diff --git a/target/linux/mpc85xx/files/arch/powerpc/boot/dts/tl-wdr4900-v1.dts b/target/linux/mpc85xx/files/arch/powerpc/boot/dts/tl-wdr4900-v1.dts +index 49e516c..7e48e23 100644 +--- a/target/linux/mpc85xx/files/arch/powerpc/boot/dts/tl-wdr4900-v1.dts ++++ b/target/linux/mpc85xx/files/arch/powerpc/boot/dts/tl-wdr4900-v1.dts +@@ -63,7 +63,7 @@ + label = "rootfs"; + }; + +- config@fe0000 { ++ config: config@fe0000 { + reg = <0x00fe0000 0x00010000>; + label = "config"; + read-only; +@@ -118,6 +118,7 @@ + enet0: ethernet@b0000 { + phy-handle = <&phy0>; + phy-connection-type = "rgmii-id"; ++ mtd-mac-address = <&config 0x14c>; + }; + + enet1: ethernet@b1000 { From 00c47f2912604c75abd8cc3a4663ca12d471ed0e Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Thu, 30 Apr 2015 13:05:15 +0200 Subject: [PATCH 10/62] gluon-mesh-vpn-fastd: extend site configuration to allow multiple and nested peer groups --- docs/site-example/site.conf | 42 +++++++---- docs/user/site.rst | 16 ++-- package/gluon-mesh-vpn-fastd/check_site.lua | 29 +++++--- .../lib/gluon/announce/statistics.d/mesh_vpn | 65 +++++++++++++---- .../lib/gluon/upgrade/400-mesh-vpn-fastd | 73 +++++++++++++------ 5 files changed, 159 insertions(+), 66 deletions(-) diff --git a/docs/site-example/site.conf b/docs/site-example/site.conf index d5372512..e2c03434 100644 --- a/docs/site-example/site.conf +++ b/docs/site-example/site.conf @@ -90,24 +90,38 @@ -- List of crypto-methods to use. methods = {'salsa2012+umac'}, mtu = 1426, - backbone = { - -- Limit number of connected peers to reduce bandwidth. - limit = 2, + groups = { + backbone = { + -- Limit number of connected peers to reduce bandwidth. + limit = 2, - -- List of peers. - peers = { - peer1 = { - key = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx', + -- List of peers. + peers = { + peer1 = { + key = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx', - -- This is a list, so you might add multiple entries. - remotes = {'ipv4 "xxx.somehost.invalid" port xxxxxx'}, - }, - peer2 = { - key = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx', - -- You can also omit the ipv4 to allow both connection via ipv4 and ipv6 - remotes = {'"xxx.somehost2.invalid" port xxxxx'}, + -- This is a list, so you might add multiple entries. + remotes = {'ipv4 "xxx.somehost.invalid" port xxxxxx'}, + }, + peer2 = { + key = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx', + -- You can also omit the ipv4 to allow both connection via ipv4 and ipv6 + remotes = {'"xxx.somehost2.invalid" port xxxxx'}, + }, }, + + -- Optional: nested peer groups + -- groups = { + -- backbone_sub = { + -- ... + -- }, + -- ... + -- }, }, + -- Optional: additional peer groups, possibly with other limits + -- backbone2 = { + -- ... + -- }, }, }, diff --git a/docs/user/site.rst b/docs/user/site.rst index b15d9d72..f555bb7d 100644 --- a/docs/user/site.rst +++ b/docs/user/site.rst @@ -103,13 +103,15 @@ fastd_mesh_vpn fastd_mesh_vpn = { methods = {'salsa2012+umac'}, mtu = 1426, - backbone = { - limit = 2, - peers = { - peer1 = { - key = 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX', - remotes = {'ipv4 "vpn1.entenhausen.freifunk.net" port 10000'}, - }, + groups = { + backbone = { + limit = 2, + peers = { + peer1 = { + key = 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX', + remotes = {'ipv4 "vpn1.entenhausen.freifunk.net" port 10000'}, + }, + } } } } diff --git a/package/gluon-mesh-vpn-fastd/check_site.lua b/package/gluon-mesh-vpn-fastd/check_site.lua index fc9d8221..cade1c17 100644 --- a/package/gluon-mesh-vpn-fastd/check_site.lua +++ b/package/gluon-mesh-vpn-fastd/check_site.lua @@ -1,14 +1,25 @@ -need_string_array 'fastd_mesh_vpn.methods' -need_number 'fastd_mesh_vpn.mtu' -need_number 'fastd_mesh_vpn.backbone.limit' +need_string_array('fastd_mesh_vpn.methods') +need_number('fastd_mesh_vpn.mtu') +need_boolean('fastd_mesh_vpn.enabled', false) -local function check_peer(k, _) - local prefix = string.format('fastd_mesh_vpn.backbone.peers[%q].', k) +local function check_peer(prefix) + return function(k, _) + local table = string.format('%s[%q].', prefix, k) - need_string(prefix .. 'key') - need_string_array(prefix .. 'remotes') + need_string(table .. 'key') + need_string_array(table .. 'remotes') + end end -need_table('fastd_mesh_vpn.backbone.peers', check_peer) -need_boolean('fastd_mesh_vpn.enabled', false) +local function check_group(prefix) + return function(k, _) + local table = string.format('%s[%q].', prefix, k) + + need_number(table .. 'limit', false) + need_table(table .. 'peers', check_peer(table .. 'peers'), false) + need_table(table .. 'groups', check_group(table .. 'groups'), false) + end +end + +need_table('fastd_mesh_vpn.groups', check_group('fastd_mesh_vpn.groups')) diff --git a/package/gluon-mesh-vpn-fastd/files/lib/gluon/announce/statistics.d/mesh_vpn b/package/gluon-mesh-vpn-fastd/files/lib/gluon/announce/statistics.d/mesh_vpn index 5e4e6a7a..a67b9a07 100644 --- a/package/gluon-mesh-vpn-fastd/files/lib/gluon/announce/statistics.d/mesh_vpn +++ b/package/gluon-mesh-vpn-fastd/files/lib/gluon/announce/statistics.d/mesh_vpn @@ -1,32 +1,71 @@ -local nixio = require('nixio') -local ltn12 = require('luci.ltn12') -local json = require('luci.json') +local json = require 'luci.json' +local ltn12 = require 'luci.ltn12' +local nixio = require 'nixio' +local site = require 'gluon.site_config' local uci = require('luci.model.uci').cursor() -local socket_path = uci:get('fastd', 'mesh_vpn', 'status_socket') local fastd_sock = nixio.socket('unix', 'stream') +local socket_path = uci:get('fastd', 'mesh_vpn', 'status_socket') if not fastd_sock:connect(socket_path) then return nil end -decoder = json.Decoder() +local decoder = json.Decoder() ltn12.pump.all(ltn12.source.file(fastd_sock), decoder:sink()) local status = decoder:get() -local output = {} -for key, peer in pairs(status.peers) do - local name, valid = peer.name:gsub('^mesh_vpn_backbone_peer_', '') - if valid == 1 then +local peer_groups + +local function peer_connection(config) + local peer = status.peers[config.key] + if peer then if peer.connection then - output[name] = {} - output[name].established = peer.connection.established/1000 + return { + established = peer.connection.established/1000 + } else - output[name] = json.null + return json.null end end end -return output +local function peer_group(config) + local ret = {} + + if config.peers then + local peers = {} + + for peername, peerconfig in pairs(config.peers) do + peers[peername] = peer_connection(peerconfig) + end + + if next(peers) then + ret.peers = peers + end + end + + ret.groups = peer_groups(config.groups) + + if next(ret) then + return ret + end +end + +function peer_groups(groups) + if groups then + local ret = {} + + for name, group in pairs(groups) do + ret[name] = peer_group(group) + end + + if next(ret) then + return ret + end + end +end + +return peer_group(site.fastd_mesh_vpn) diff --git a/package/gluon-mesh-vpn-fastd/files/lib/gluon/upgrade/400-mesh-vpn-fastd b/package/gluon-mesh-vpn-fastd/files/lib/gluon/upgrade/400-mesh-vpn-fastd index 0585f5a7..f370bbf3 100755 --- a/package/gluon-mesh-vpn-fastd/files/lib/gluon/upgrade/400-mesh-vpn-fastd +++ b/package/gluon-mesh-vpn-fastd/files/lib/gluon/upgrade/400-mesh-vpn-fastd @@ -36,33 +36,60 @@ uci:section('fastd', 'fastd', 'mesh_vpn', ) uci:delete('fastd', 'mesh_vpn', 'user') -uci:delete('fastd', 'mesh_vpn_backbone') -uci:section('fastd', 'peer_group', 'mesh_vpn_backbone', - { - enabled = 1, - net = 'mesh_vpn', - peer_limit = site.fastd_mesh_vpn.backbone.limit, - } -) -uci:delete_all('fastd', 'peer', - function(peer) - return peer.net == 'mesh_vpn' and peer.group == 'mesh_vpn_backbone' - end -) +local add_groups -for name, config in pairs(site.fastd_mesh_vpn.backbone.peers) do - uci:section('fastd', 'peer', 'mesh_vpn_backbone_peer_' .. name, - { - enabled = 1, - net = 'mesh_vpn', - group = 'mesh_vpn_backbone', - key = config.key, - remote = config.remotes, - } - ) +local function add_peer(group, name, config) + uci:section('fastd', 'peer', group .. '_peer_' .. name, + { + enabled = 1, + net = 'mesh_vpn', + group = group, + key = config.key, + remote = config.remotes, + } + ) end +local function add_group(name, config, parent) + uci:delete('fastd', name) + uci:delete_all('fastd', 'peer', + function(peer) + return (peer.net == 'mesh_vpn' and peer.group == name) + end + ) + + + uci:section('fastd', 'peer_group', name, + { + enabled = 1, + net = 'mesh_vpn', + parent = parent, + peer_limit = config.limit, + } + ) + + if config.peers then + for peername, peerconfig in pairs(config.peers) do + add_peer(name, peername, peerconfig) + end + end + + add_groups(name, config.groups, name) +end + +-- declared local above +function add_groups(prefix, groups, parent) + if groups then + for name, group in pairs(groups) do + add_group(prefix .. '_' .. name, group, parent) + end + end +end + +add_groups('mesh_vpn', site.fastd_mesh_vpn.groups) + + uci:save('fastd') uci:commit('fastd') From 0e5a1b9a2d64d75788cc690e7191741f1eac60f4 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Thu, 30 Apr 2015 19:09:13 +0200 Subject: [PATCH 11/62] docs: add fastd_mesh_vpn changes to changelog --- docs/releases/v2015.1.rst | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/docs/releases/v2015.1.rst b/docs/releases/v2015.1.rst index c52ef920..17a3c80a 100644 --- a/docs/releases/v2015.1.rst +++ b/docs/releases/v2015.1.rst @@ -22,6 +22,24 @@ Site changes to keep the old behaviour, you have to append the hyphen to the ``hostname_prefix`` field of your ``site.conf``. + - ``mesh_vpn_fastd``: The default peer group name ``backbone`` isn't hardcoded anymore, any + group name can be used. Instead, the ``fastd_mesh_vpn`` table must now contain an element ``groups``, + for example:: + + fastd_mesh_vpn = { + methods = {'salsa2012+umac'}, + mtu = 1426, + groups = { + backbone = { + limit = 2, + peers = { + -- ... + } + } + } + } + + * ``site.mk`` - The packages ``gluon-setup-mode`` and ``gluon-config-mode-core`` must now be From 1b7c3e060bbd8edd995b51405f0e07493c9b6321 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Thu, 30 Apr 2015 23:48:07 +0200 Subject: [PATCH 12/62] gluon-luci-node-role: make node role display strings translatable --- docs/releases/v2015.1.rst | 13 +++++++++++++ docs/site-example/site.conf | 10 +++++----- docs/user/site.rst | 12 ++++++++---- package/gluon-luci-node-role/check_site.lua | 10 ++-------- .../usr/lib/lua/luci/model/cbi/admin/noderole.lua | 4 ++-- package/gluon-node-info/check_site.lua | 7 ------- 6 files changed, 30 insertions(+), 26 deletions(-) diff --git a/docs/releases/v2015.1.rst b/docs/releases/v2015.1.rst index 17a3c80a..83a57666 100644 --- a/docs/releases/v2015.1.rst +++ b/docs/releases/v2015.1.rst @@ -39,6 +39,19 @@ Site changes } } + - ``roles``: The display strings for the node roles aren't configured in the ``site.conf`` anymore, but + in the site i18n files. The ``site.conf`` section becomes:: + + roles = { + default = 'foo', + list = { + 'foo', + 'bar', + } + } + + The display string use i18n message IDs like ``gluon-luci-node-role:role:foo`` and ``gluon-luci-node-role:role:bar``. + * ``site.mk`` diff --git a/docs/site-example/site.conf b/docs/site-example/site.conf index e2c03434..a25857a9 100644 --- a/docs/site-example/site.conf +++ b/docs/site-example/site.conf @@ -154,13 +154,13 @@ }, -- Node roles - -- roles { + -- roles = { -- default = 'node', -- list = { - -- node = 'Normal Node', - -- test = 'Test Node', - -- backbone = 'Backbone Node', - -- service = 'Service Node', + -- 'node', + -- 'test', + -- 'backbone', + -- 'service', -- }, -- }, diff --git a/docs/user/site.rst b/docs/user/site.rst index f555bb7d..65c9022f 100644 --- a/docs/user/site.rst +++ b/docs/user/site.rst @@ -150,15 +150,19 @@ roles : optional ``default`` takes the default role which is set initially. This value should be part of ``list``. If you want node owners to change the role via config mode add the package ``gluon-luci-node-role`` to ``site.mk``. + + The strings to display in the LuCI interface can be configured per language in the + ``i18n/en.po``, ``i18n/de.po``, etc. files of the site repository using message IDs like + ``gluon-luci-node-role:role:node`` and ``gluon-luci-node-role:role:backbone``. :: roles = { default = 'node', list = { - node = 'Normal Node', - test = 'Test Node', - backbone = 'Backbone Node', - service = 'Service Node', + 'node', + 'test', + 'backbone', + 'service', }, }, diff --git a/package/gluon-luci-node-role/check_site.lua b/package/gluon-luci-node-role/check_site.lua index cd3ca937..ab01eeb5 100644 --- a/package/gluon-luci-node-role/check_site.lua +++ b/package/gluon-luci-node-role/check_site.lua @@ -1,8 +1,2 @@ -local function check_role(k, _) - local role = string.format('roles.list[%q]', k) - - need_string(role) -end - -need_string('roles.default') -need_table('roles.list', check_role) +need_string 'roles.default' +need_string_array 'roles.list' diff --git a/package/gluon-luci-node-role/files/usr/lib/lua/luci/model/cbi/admin/noderole.lua b/package/gluon-luci-node-role/files/usr/lib/lua/luci/model/cbi/admin/noderole.lua index d2ab51a7..e7832ad9 100644 --- a/package/gluon-luci-node-role/files/usr/lib/lua/luci/model/cbi/admin/noderole.lua +++ b/package/gluon-luci-node-role/files/usr/lib/lua/luci/model/cbi/admin/noderole.lua @@ -18,8 +18,8 @@ s = f:section(SimpleSection, nil, i18n.translate( o = s:option(ListValue, "role", i18n.translate("Role")) o.default = role o.rmempty = false -for role, prettyname in pairs(site.roles.list) do - o:value(role, prettyname) +for _, role in ipairs(site.roles.list) do + o:value(role, i18n.translate('gluon-luci-node-role:role:' .. role)) end function f.handle(self, state, data) diff --git a/package/gluon-node-info/check_site.lua b/package/gluon-node-info/check_site.lua index d8d46408..7e50edfc 100644 --- a/package/gluon-node-info/check_site.lua +++ b/package/gluon-node-info/check_site.lua @@ -1,8 +1 @@ -local function check_role(k, _) - local role = string.format('roles.list[%q]', k) - - need_string(role) -end - need_string('roles.default', false) -need_table('roles.list', check_role, false) From 82fa93faa8eba041d72beb79400a8e6d5d98f0ba Mon Sep 17 00:00:00 2001 From: do9xe Date: Thu, 30 Apr 2015 22:20:32 +0200 Subject: [PATCH 13/62] update the table of supported hardware --- docs/index.rst | 55 ++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 49 insertions(+), 6 deletions(-) diff --git a/docs/index.rst b/docs/index.rst index a53c0a8d..d22f04b0 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -41,8 +41,14 @@ Developer Documentation dev/configmode dev/wan -Supported Devices ------------------ +Supported Devices & Architectures +--------------------------------- + +ar71xx-generic +^^^^^^^^^^^^^^ + +* Allnet + - ALL0315N * Buffalo @@ -52,11 +58,20 @@ Supported Devices * D-Link - DIR-825 (B1) + - DIR-615 (C1) + +* GL-Inet + - 6408A (v1) + - 6416a (v1) * Linksys - WRT160NL +* Netgear + - WNDR3700 (v1, v2) + - WNDR3800 + * TP-Link - CPE210 (v1) @@ -65,12 +80,14 @@ Supported Devices - CPE520 (v1) - TL-MR3020 (v1) - TL-MR3040 (v1, v2) - - TL-MR3220 (v1) + - TL-MR3220 (v1, v2) - TL-MR3420 (v1, v2) + - TL-WA701N/ND (v1) - TL-WA750RE (v1) - TL-WA801N/ND (v2) - TL-WA850RE (v1) - - TL-WA901N/ND (v2) + - TL-WA860RE (v1) + - TL-WA901N/ND (v2, v3) - TL-WDR3500 (v1) - TL-WDR3600 (v1) - TL-WDR4300 (v1) @@ -79,18 +96,45 @@ Supported Devices - TL-WR710N (v1) - TL-WR740N (v1, v3, v4) - TL-WR741N/ND (v1, v2, v4) + - TL-WR743N/ND (v1, v2) - TL-WR841N/ND (v3, v5, v7, v8, v9) - TL-WR842N/ND (v1, v2) - - TL-WR941N/ND (v2, v3, v4) + - TL-WR941N/ND (v2, v3, v4, v5) + - TL-WR2543N/ND (v1) * Ubiquiti - Bullet M2 - Nanostation M2 + - Nanostation M XW + - Loco M XW - Picostation M2 - UniFi AP + - UniFi AP Pro - UniFi AP Outdoor +ar71xx-nand +^^^^^^^^^^^ + +* Netgear + - WNDR3700 (v4) + - WNDR3700 (v1) + +mpc85xx-generic +^^^^^^^^^^^^^^^ + +* TP-Link + - TL-WDR4900 (v1) + +x86-generic +^^^^^^^^^^^ +* x86-generic +* x86-virtualbox +* x86-vmware + +x86-kvm_guest +^^^^^^^^^^^^^ +* x86-kvm Releases -------- @@ -116,4 +160,3 @@ Indices and tables * :ref:`genindex` * :ref:`search` - From ecc90dd97cb11a35dcb491b9447eef420084b2c1 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Fri, 1 May 2015 01:14:57 +0200 Subject: [PATCH 14/62] docs: reorder index to make the release notes more prominent --- docs/index.rst | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/docs/index.rst b/docs/index.rst index 86051970..5213a8aa 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -42,6 +42,18 @@ Developer Documentation dev/wan dev/i18n +Releases +-------- + +.. toctree:: + :maxdepth: 1 + + releases/v2015.1 + releases/v2014.4 + releases/v2014.3.1 + releases/v2014.3 + + Supported Devices & Architectures --------------------------------- @@ -138,18 +150,6 @@ x86-kvm_guest ^^^^^^^^^^^^^ * x86-kvm -Releases --------- - -.. toctree:: - :maxdepth: 1 - - releases/v2015.1 - releases/v2014.4 - releases/v2014.3.1 - releases/v2014.3 - - License ------- From d63bbf2be60afa7a2c9af5566ef0b530e32815a3 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Fri, 1 May 2015 01:16:31 +0200 Subject: [PATCH 15/62] docs: fix hardware list formatting --- docs/index.rst | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/docs/index.rst b/docs/index.rst index 5213a8aa..bba84aad 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -61,6 +61,7 @@ ar71xx-generic ^^^^^^^^^^^^^^ * Allnet + - ALL0315N * Buffalo @@ -74,6 +75,7 @@ ar71xx-generic - DIR-615 (C1) * GL-Inet + - 6408A (v1) - 6416a (v1) @@ -82,6 +84,7 @@ ar71xx-generic - WRT160NL * Netgear + - WNDR3700 (v1, v2) - WNDR3800 @@ -131,6 +134,7 @@ ar71xx-nand ^^^^^^^^^^^ * Netgear + - WNDR3700 (v4) - WNDR3700 (v1) @@ -138,6 +142,7 @@ mpc85xx-generic ^^^^^^^^^^^^^^^ * TP-Link + - TL-WDR4900 (v1) x86-generic From 631403c0a98286a5021c8b2f0b7c2eb21c344227 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Fri, 1 May 2015 03:36:38 +0200 Subject: [PATCH 16/62] docs: update site-ffhl link --- docs/user/site.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/user/site.rst b/docs/user/site.rst index 65c9022f..689dd51d 100644 --- a/docs/user/site.rst +++ b/docs/user/site.rst @@ -288,7 +288,7 @@ This is a non-exhaustive list of site-repos from various communities: * `site-ffgoe `_ (Göttingen) * `site-ffhh `_ (Hamburg) * `site-ffhgw `_ (Greifswald) -* `site-ffhl `_ (Lübeck) +* `site-ffhl `_ (Lübeck) * `site-ffmd `_ (Magdeburg) * `site-ffmwu `_ (Mainz, Wiesbaden & Umgebung) * `site-ffmyk `_ (Mayen-Koblenz) From 34d48501cf075bf6b81316c59fb263fb4064c52d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hendrik=20L=C3=BCth?= Date: Fri, 1 May 2015 05:36:14 +0200 Subject: [PATCH 17/62] fix the data types in the check_site.lua --- package/gluon-mesh-batman-adv-core/check_site.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package/gluon-mesh-batman-adv-core/check_site.lua b/package/gluon-mesh-batman-adv-core/check_site.lua index 867ebc26..baed26cb 100644 --- a/package/gluon-mesh-batman-adv-core/check_site.lua +++ b/package/gluon-mesh-batman-adv-core/check_site.lua @@ -8,8 +8,8 @@ for _, config in ipairs({'wifi24', 'wifi5'}) do need_string_match(config .. '.mesh_bssid', '^%x[02468aAcCeE]:%x%x:%x%x:%x%x:%x%x:%x%x$') need_number(config .. '.mesh_mcast_rate') need_number(config .. '.mesh_vlan', false) - need_number(config .. '.client_disabled', false) - need_number(config .. '.mesh_disabled', false) + need_boolean(config .. '.client_disabled', false) + need_boolean(config .. '.mesh_disabled', false) end need_boolean('mesh_on_wan', false) From 2deb82bcb6427e9c3a5640a963dba9b5ae8ca94e Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Fri, 1 May 2015 19:50:40 +0200 Subject: [PATCH 18/62] gluon-setup-mode: set regdom OpenWrt doesn't set the regdom unless a WLAN device is started. Explicitly set the regdom in the setup mode to get the correct list of allowed txpower entries in the planned LuCI module. --- .../gluon-setup-mode/files/lib/gluon/setup-mode/rc.d/S20network | 1 + 1 file changed, 1 insertion(+) diff --git a/package/gluon-setup-mode/files/lib/gluon/setup-mode/rc.d/S20network b/package/gluon-setup-mode/files/lib/gluon/setup-mode/rc.d/S20network index 8bc0ba4f..15f0e278 100755 --- a/package/gluon-setup-mode/files/lib/gluon/setup-mode/rc.d/S20network +++ b/package/gluon-setup-mode/files/lib/gluon/setup-mode/rc.d/S20network @@ -45,6 +45,7 @@ init_switch() { start_service() { prepare_config init_switch + iw reg set "$(lua -e 'print(require("gluon.site_config").regdom)')" procd_open_instance procd_set_param command /sbin/netifd -c /var/gluon/setup-mode/config From 1838cee0d670ed915454f83c7abfd368ef01a704 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Fri, 1 May 2015 19:57:45 +0200 Subject: [PATCH 19/62] gluon-setup-mode: set br-setup MAC address to the primary MAC address This allows to reach the node in setup mode over the same link-local IPv6 address as br-client uses during normal operation. --- .../gluon-setup-mode/files/lib/gluon/setup-mode/rc.d/S20network | 1 + 1 file changed, 1 insertion(+) diff --git a/package/gluon-setup-mode/files/lib/gluon/setup-mode/rc.d/S20network b/package/gluon-setup-mode/files/lib/gluon/setup-mode/rc.d/S20network index 15f0e278..ef4cc4ad 100755 --- a/package/gluon-setup-mode/files/lib/gluon/setup-mode/rc.d/S20network +++ b/package/gluon-setup-mode/files/lib/gluon/setup-mode/rc.d/S20network @@ -26,6 +26,7 @@ prepare_config() { uci_add network interface setup uci_set network setup ifname "$(lua -e 'print(require("gluon.sysconfig").setup_ifname)')" + uci_set network setup macaddr "$(lua -e 'print(require("gluon.sysconfig").primary_mac)')" uci_set network setup type 'bridge' uci_set network setup proto 'static' uci_set network setup ipaddr "$SETUP_MODE_ADDR" From 4d7e84b40511757d3355333c2c1572705899a9d0 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sun, 3 May 2015 01:58:07 +0200 Subject: [PATCH 20/62] gluon-config-mode-core: nicer LuCI view filenames --- .../usr/lib/lua/luci/controller/gluon-config-mode/index.lua | 2 +- .../usr/lib/lua/luci/model/cbi/gluon-config-mode/wizard.lua | 2 +- .../cbi/wizard.htm => gluon/cbi/config-mode.htm} | 0 .../view/{gluon-config-mode => gluon/config-mode}/reboot.htm | 0 4 files changed, 2 insertions(+), 2 deletions(-) rename package/gluon-config-mode-core/files/usr/lib/lua/luci/view/{gluon-config-mode/cbi/wizard.htm => gluon/cbi/config-mode.htm} (100%) rename package/gluon-config-mode-core/files/usr/lib/lua/luci/view/{gluon-config-mode => gluon/config-mode}/reboot.htm (100%) 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/files/usr/lib/lua/luci/controller/gluon-config-mode/index.lua index 8f55f540..c3ab070d 100644 --- a/package/gluon-config-mode-core/files/usr/lib/lua/luci/controller/gluon-config-mode/index.lua +++ b/package/gluon-config-mode-core/files/usr/lib/lua/luci/controller/gluon-config-mode/index.lua @@ -69,7 +69,7 @@ function action_reboot() local hostname = uci:get_first("system", "system", "hostname") - luci.template.render("gluon-config-mode/reboot", { parts=parts + luci.template.render("gluon/config-mode/reboot", { parts=parts , hostname=hostname }) else 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/files/usr/lib/lua/luci/model/cbi/gluon-config-mode/wizard.lua index 706543b2..101a02e3 100644 --- a/package/gluon-config-mode-core/files/usr/lib/lua/luci/model/cbi/gluon-config-mode/wizard.lua +++ b/package/gluon-config-mode-core/files/usr/lib/lua/luci/model/cbi/gluon-config-mode/wizard.lua @@ -17,7 +17,7 @@ end f = SimpleForm("wizard") f.reset = false -f.template = "gluon-config-mode/cbi/wizard" +f.template = "gluon/cbi/config-mode" for _, s in ipairs(wizard) do s.section(f) diff --git a/package/gluon-config-mode-core/files/usr/lib/lua/luci/view/gluon-config-mode/cbi/wizard.htm b/package/gluon-config-mode-core/files/usr/lib/lua/luci/view/gluon/cbi/config-mode.htm similarity index 100% rename from package/gluon-config-mode-core/files/usr/lib/lua/luci/view/gluon-config-mode/cbi/wizard.htm rename to package/gluon-config-mode-core/files/usr/lib/lua/luci/view/gluon/cbi/config-mode.htm 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 similarity index 100% rename from package/gluon-config-mode-core/files/usr/lib/lua/luci/view/gluon-config-mode/reboot.htm rename to package/gluon-config-mode-core/files/usr/lib/lua/luci/view/gluon/config-mode/reboot.htm From adf7b0d810bfeb4b3b3162726e0e733141796781 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sun, 3 May 2015 20:38:34 +0200 Subject: [PATCH 21/62] docs: make gluon-batman-adv-15 the recommended batman-adv version --- docs/releases/v2015.1.rst | 2 ++ docs/site-example/site.mk | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/releases/v2015.1.rst b/docs/releases/v2015.1.rst index 83a57666..a086dc7e 100644 --- a/docs/releases/v2015.1.rst +++ b/docs/releases/v2015.1.rst @@ -55,6 +55,8 @@ Site changes * ``site.mk`` + - ``gluon-mesh-batman-adv-15`` is now the recommended batman-adv version for new Gluon deployments. + - The packages ``gluon-setup-mode`` and ``gluon-config-mode-core`` must now be added to ``GLUON_SITE_PACKAGES`` explicitly (to allow replacing them with community-specific implementations). diff --git a/docs/site-example/site.mk b/docs/site-example/site.mk index 9b0e8476..5e5a9f99 100644 --- a/docs/site-example/site.mk +++ b/docs/site-example/site.mk @@ -5,7 +5,7 @@ # The gluon-mesh-batman-adv-* package must come first because of the dependency resolution GLUON_SITE_PACKAGES := \ - gluon-mesh-batman-adv-14 \ + gluon-mesh-batman-adv-15 \ gluon-alfred \ gluon-announced \ gluon-autoupdater \ From 623966afae4c7085d5a2f09e5ad247e4a2188831 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Mon, 4 May 2015 01:29:03 +0200 Subject: [PATCH 22/62] gluon-luci-theme: more consistent button spacing --- .../files/www/luci-static/gluon/cascade.css | 3 ++- package/gluon-luci-theme/sass/cascade.scss | 6 +----- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/package/gluon-luci-theme/files/www/luci-static/gluon/cascade.css b/package/gluon-luci-theme/files/www/luci-static/gluon/cascade.css index ba2fb888..63df1b04 100644 --- a/package/gluon-luci-theme/files/www/luci-static/gluon/cascade.css +++ b/package/gluon-luci-theme/files/www/luci-static/gluon/cascade.css @@ -1 +1,2 @@ -@charset "UTF-8";.lang_he{direction:RTL;unicode-bidi:embed}.hidden{display:none}html{min-height:100%;height:auto;position:relative}body,input,select,option{font-family:'Open Sans', Arial, sans-serif;font-size:12pt}body{color:#4d4e53;line-height:1.5em;margin:0;display:flex;flex-direction:column;min-height:100vh;background-color:#f3f3f3}a img{border:none;text-decoration:none}.tabmenu1{text-align:center}ul.tabmenu{list-style:none;padding:0;margin:2em 0;display:inline-flex}ul.tabmenu li{white-space:nowrap;margin:0 0.5em;padding:0;text-align:center}ul.tabmenu li a{display:block;text-decoration:none;padding:1em;margin:0;color:#333;border-radius:2em}ul.tabmenu li a:hover{background:#ffe9b3}ul.tabmenu li.active a{font-weight:bold;background:white;color:#333}abbr,acronym{font-style:normal;font-variant:normal}abbr[title],acronym[title]{border-bottom:1px dotted;cursor:help}a:link abbr[title],a:visited abbr[title],a:link acronym[title],a:visited acronym[title]{cursor:pointer}code{font-family:monospace;white-space:pre}#maincontent ul{margin-left:2em}.warning{color:red;background-color:white;font-weight:bold}.clear{clear:both}.error{color:#ff0000;background-color:white}div.hostinfo{margin:0;padding:0;font-size:80%;padding:0.5em;flex:1;font-weight:bold}#xhr_poll_status{cursor:pointer}#xhr_poll_status #xhr_poll_status_off{font-weight:bold;color:#FF0000}#xhr_poll_status #xhr_poll_status_on{font-weight:bold;color:#00FF00}#menubar{display:flex;background:#dc0067;color:#ffffff}#menubar .warning{color:red;background-color:#557788}#menubar a:link,#menubar a:visited{position:relative;display:block;padding:0.5em;text-decoration:none;font-size:80%;font-weight:normal;color:white}#menubar a:link:hover,#menubar a:visited:hover,#menubar a:link:focus,#menubar a:visited:focus{background:#ffb400;color:black}#menubar a:link.active,#menubar a:visited.active{background:#ffb400;color:black;font-weight:bold}#menubar a:link.warning,#menubar a:visited.warning{background:#000000;color:red;font-weight:bold}#modemenu{list-style:none;margin:0;padding:0}#modemenu li{display:inline-block}.lang_de #submenu_admin_uci{width:12em}.lang_ru #submenu_admin_uci{width:11.5em}textarea#syslog{width:98%;min-height:500px;border:3px solid #cccccc;padding:5px;font-family:monospace}#maincontent{padding:0 1em 2em;max-width:60em;min-width:40em;margin:1em auto}.lang_he #maincontent{direction:rtl}#maincontent p{margin-bottom:1em}.cbi-section{margin:0;padding:0;border:none}.cbi-section legend{font-size:1.4em;font-weight:bold;color:#dc0067;position:relative;padding:0;margin-bottom:0.5em}.cbi-section h2{margin:0em 0 0.5em -0.5em !important}.cbi-section h3{text-decoration:none !important;font-weight:bold !important;color:#555555 !important;margin:0.25em !important;font-size:100% !important}.cbi-section-descr{margin-bottom:2em}.cbi-title-ref{color:inherit;text-decoration:none;padding-right:18px;background:url("../resources/cbi/link.gif") no-repeat scroll right center;background-color:inherit}ul.cbi-apply{font-size:90%}input:-webkit-input-placeholder{color:#AAAAAA}input:-moz-placeholder{color:#AAAAAA}input:-ms-input-placeholder{color:#AAAAAA}input[type=checkbox]{display:none}input[type=checkbox]+label{display:inline-block;width:1em;height:1em;margin:0}input[type=checkbox]:checked+label:after{content:'✔';color:#dc0067;vertical-align:middle;position:absolute;top:50%;left:0;margin-top:-0.5em;width:100%;text-align:center;font-size:1.7em}input[type=submit],input[type=reset],input[type=image],input[type=button]{cursor:pointer}select,input,textarea,input[type=checkbox]+label{color:#003247;border:none;background:#ffe199;border-radius:3pt;padding:0.5em}input[type=image]{border:none}select,input[type=text],input[type=password]{width:20em}td select,td input[type=text],td input[type=password]{width:99%}img.cbi-image-button{cursor:pointer;margin:0 2px;vertical-align:middle}input.cbi-button{display:inline-block;zoom:1;line-height:normal;white-space:nowrap;vertical-align:baseline;text-align:center;cursor:pointer;-webkit-user-drag:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;font-size:100%;padding:0.5em 1em;color:rgba(0,0,0,0.8);border:none transparent;background-color:#E6E6E6;text-decoration:none;border-radius:2px;-webkit-transition:0.1s linear -webkit-box-shadow;-moz-transition:0.1s linear -moz-box-shadow;-ms-transition:0.1s linear box-shadow;-o-transition:0.1s linear box-shadow;transition:0.1s linear box-shadow;background-repeat:no-repeat}input.cbi-button::-moz-focus-inner{padding:0;border:0}input.cbi-button:active{box-shadow:0 0 0 1px rgba(0,0,0,0.15) inset,0 0 6px rgba(0,0,0,0.2) inset}input.cbi-button:focus{outline:0}input.cbi-button:hover,input.cbi-button:focus{background-image:-webkit-gradient(linear, 0 0, 0 100%, from(transparent), color-stop(40%, rgba(0,0,0,0.05)), to(rgba(0,0,0,0.1)));background-image:-webkit-linear-gradient(transparent, rgba(0,0,0,0.05) 40%, rgba(0,0,0,0.1));background-image:-moz-linear-gradient(top, rgba(0,0,0,0.05) 0%, rgba(0,0,0,0.1));background-image:-o-linear-gradient(transparent, rgba(0,0,0,0.05) 40%, rgba(0,0,0,0.1));background-image:linear-gradient(transparent, rgba(0,0,0,0.05) 40%, rgba(0,0,0,0.1))}input.cbi-button[disabled]{border:none;background-image:none;opacity:0.40;cursor:not-allowed;box-shadow:none}input.cbi-input-user{background-image:url("../resources/cbi/user.gif");background-repeat:no-repeat;background-position:1px center;color:#000000;text-indent:17px}input.cbi-input-find,input.cbi-button-find{background-image:url("../resources/cbi/find.gif");color:#000000;padding-left:17px}input.cbi-input-reload{background-image:url("../resources/cbi/reload.gif");color:#000000;padding-left:17px}input.cbi-input-add,input.cbi-button-add{background-image:url("../resources/cbi/add.gif");color:#000000;padding-left:17px;padding-right:1px}input.cbi-input-fieldadd,input.cbi-button-fieldadd{background-image:url(../resources/cbi/fieldadd.gif);color:#000000;padding-left:17px;padding-right:1px}input.cbi-input-reset,input.cbi-button-reset{background-color:#e30;color:#fff}input.cbi-input-save,input.cbi-button-save{background-color:#009ee0;color:#fff}input.cbi-input-apply,input.cbi-button-apply{background-color:#009ee0;color:#fff}input.cbi-input-link,input.cbi-button-link{background-image:url("../resources/cbi/link.gif");color:#000000;padding-left:17px;padding-right:1px}input.cbi-input-download,input.cbi-button-download{background-image:url("../resources/cbi/download.gif");color:#000000;padding-left:17px;padding-right:1px}input.cbi-input-remove,div.cbi-section-remove input{background-image:url("../resources/cbi/remove.gif");color:#000000;padding-left:17px;padding-right:1px}input.cbi-button-up{background-image:url("../resources/cbi/up.gif");padding-left:11px;padding-right:1px}input.cbi-button-down{background-image:url("../resources/cbi/down.gif");padding-left:11px;padding-right:1px}input.cbi-button-edit{background-image:url("../resources/cbi/edit.gif");color:#000000;padding-left:17px;padding-right:1px}input.cbi-button-reload{background-image:url("../resources/cbi/reload.gif");color:#000000;padding-left:17px;padding-right:1px}input.cbi-button-remove{background-image:url("../resources/cbi/remove.gif");color:#000000;padding-left:17px;padding-right:1px}.cbi-input-invalid{background:#e30 !important;color:white}div.cbi-section-remove input{border-bottom:none}textarea{margin-left:-1px;margin-bottom:0.5em}form>div>input[type=submit],form>div>input[type=reset]{margin-left:0.5em}table td,table th{color:#000000}table.smalltext{background:#f5f5f5;color:#000000;border-top:1px solid #666666;border-right:1px solid #666666;border-bottom:1px solid #666666;font-size:90%;width:80%;margin-left:auto;margin-right:auto;border-collapse:collapse}table.smalltext tr:hover td{background-color:#bbddee;color:#000000}table.smalltext tr th{padding:0 0.25em;border-left:1px solid #666666;text-align:left}table.smalltext tr td{padding:0 0.25em;border-top:1px solid #666666;border-left:1px solid #666666}table.cbi-section-table .cbi-rowstyle-1{background-color:#eeeeff;color:#000000}table.cbi-section-table .cbi-rowstyle-1:hover,table.cbi-section-table .cbi-rowstyle-2:hover{background-color:#b2c8d4;color:#000000}table.cbi-section-table .cbi-section-table-cell{padding:3px;white-space:nowrap}.cbi-section .cbi-rowstyle-1 h3{background-color:#eeeeff;color:#555555}.cbi-rowstyle-2{color:#000000}div.cbi-value{display:flex;flex-direction:row;margin-bottom:0.5em}.cbi-value-title{flex:2;text-align:right;padding-right:1em;font-weight:bold}div.cbi-value-field{flex:3;position:relative}div.cbi-value-field input,div.cbi-value-field select,div.cbi-value-field input+label{position:relative;top:-0.39em}div.cbi-value-description{font-size:8pt}div.cbi-section-create{clear:left;white-space:nowrap;vertical-align:top}div.cbi-section-create .cbi-button{margin:0.25em}input.cbi-section-create-name{margin-right:-0.25em}div.cbi-map-descr{margin-bottom:1em}.cbi-map-descr:empty,.cbi-section-descr:empty{display:none}.cbi-map-descr,.cbi-section-descr,.cbi-page-actions{padding:1em;background:#ececec}.cbi-page-actions{text-align:right;display:flex;display:-moz-flex;-moz-flex-flow:row-reverse;flex-flow:row-reverse}div.cbi-optionals{padding:0.25em;border-bottom:1px dotted #bbbbbb}div.cbi-section-remove{float:right}.cbi-section-node{clear:both;position:relative;border:none}.cbi-section-node-tabbed{border-top-left-radius:0}.cbi-section-node .cbi-value-last{border-bottom:none}.cbi-section-node table div{padding-bottom:0;border-bottom:none}.cbi-section-node div.cbi-section-table-row{margin:0.25em}table.cbi-section-table{width:100%;font-size:95%}table.cbi-section-table th,table.cbi-section-table td{text-align:center}tr.cbi-section-table-descr th{font-weight:normal;font-size:90%;vertical-align:top}td.cbi-section-table-optionals{text-align:left !important;padding-top:1em}.cbi-value-helpicon img{display:none}div.cbi-error{font-size:95%;font-weight:bold;color:#ff0000;background-color:#ffffff}td.cbi-value-error{border-color:red}.cbi-value-error input,.cbi-value-error select{background-color:#ffcccc}.cbi-section-error{color:red;background-color:white;font-size:95%;border:1px dotted red;margin:3px;padding:3px}.cbi-value-field var{color:#2222FF}ul.cbi-tabmenu{padding:3px 0;margin-left:0 !important;list-style-type:none;position:relative;z-index:10;top:4px;line-height:20px}ul.cbi-tabmenu li.cbi-tab,ul.cbi-tabmenu li.cbi-tab-disabled{display:inline;margin:0}ul.cbi-tabmenu li.cbi-tab a,ul.cbi-tabmenu li.cbi-tab-disabled a{text-decoration:none;padding:3px 7px;margin-right:3px;border:1px solid #BBBBBB;border-bottom:none;border-radius:3px 3px 0 0;background-color:#EEEEEE;color:#BBBBBB}ul.cbi-tabmenu li.cbi-tab-highlighted a{color:#000000;background-color:#FFEEAA}ul.cbi-tabmenu li a:hover{color:#000000}ul.cbi-tabmenu li.cbi-tab a{padding-top:4px;color:#000000;background-color:#FFFFFF}div.cbi-tab-descr{background-image:url(/luci-static/resources/cbi/help.gif);background-position:0.25em 50%;background-repeat:no-repeat;border-bottom:1px solid #CCCCCC;margin:0.25em 0.25em 2em;padding:0.5em 0.5em 0.5em 2em}.left{text-align:left !important}.right{text-align:right !important}.luci{position:absolute;bottom:0;left:1em;height:1.5em;font-size:80%}.luci a:link,.luci a:visited{background-color:transparent;color:#666666;text-decoration:none;font-size:70%}.inline{display:inline}.error500{white-space:normal;border:1px dotted #ff0000;background-color:#ffffff;color:#000000;padding:0.5em}.errorbox{border:1px solid #FF0000;background-color:#FFCCCC;padding:5px;margin-bottom:5px}.errorbox a{color:#000000 !important}.ifacebox{background-color:#FFFFFF;border:1px solid #CCCCCC;margin:0 10px;text-align:center;white-space:nowrap}.ifacebox .ifacebox-head{border-bottom:1px solid #CCCCCC;padding:2px}.ifacebox .ifacebox-body{padding:2px}.ifacebadge{background-color:#FFFFFF;border:1px solid #CCCCCC;padding:2px;margin-left:2px;display:inline-block}.ifacebadge-active{border-color:#000000;font-weight:bold}.zonebadge{padding:2px;display:inline-block;white-space:nowrap;cursor:pointer}.zonebadge em,.zonebadge strong{margin:3px;display:inline-block}.zonebadge input{width:6em;height:1.5em}.zonebadge-empty{border:1px dashed #AAAAAA;color:#AAAAAA;font-style:italic;font-size:smaller}.uci-change-list{font-family:monospace}.uci-change-list ins,.uci-change-legend-label ins{text-decoration:none;border:1px solid #00FF00;background-color:#CCFFCC;display:block;padding:2px}.uci-change-list del,.uci-change-legend-label del{text-decoration:none;border:1px solid #FF0000;background-color:#FFCCCC;display:block;font-style:normal;padding:2px}.uci-change-list var,.uci-change-legend-label var{text-decoration:none;border:1px solid #CCCCCC;background-color:#EEEEEE;display:block;font-style:normal;padding:2px}.uci-change-list var ins,.uci-change-list var del{border:none;white-space:pre;font-style:normal;padding:0px}.uci-change-legend{padding:5px}.uci-change-legend-label{width:150px;float:left;font-size:80%}.uci-change-legend-label>ins,.uci-change-legend-label>del,.uci-change-legend-label>var{float:left;margin-right:4px;width:10px;height:10px;display:block}.uci-change-legend-label var ins,.uci-change-legend-label var del{line-height:6px;border:none}.cbi-input-password+img{display:none}.the-key{text-align:left;font-size:1.4em;background:#ffe9b3;border:3pt dashed #dc0067;margin-bottom:0.5em;padding:0.5em} +.lang_he{direction:RTL;unicode-bidi:embed}.hidden{display:none}html{min-height:100%;height:auto;position:relative}body,input,select,option{font-family:'Open Sans', Arial, sans-serif;font-size:12pt}body{color:#4d4e53;line-height:1.5em;margin:0;display:flex;flex-direction:column;min-height:100vh;background-color:#f3f3f3}a img{border:none;text-decoration:none}.tabmenu1{text-align:center}ul.tabmenu{list-style:none;padding:0;margin:2em 0;display:inline-flex}ul.tabmenu li{white-space:nowrap;margin:0 0.5em;padding:0;text-align:center}ul.tabmenu li a{display:block;text-decoration:none;padding:1em;margin:0;color:#333;border-radius:2em}ul.tabmenu li a:hover{background:#ffe9b3}ul.tabmenu li.active a{font-weight:bold;background:white;color:#333}abbr,acronym{font-style:normal;font-variant:normal}abbr[title],acronym[title]{border-bottom:1px dotted;cursor:help}a:link abbr[title],a:visited abbr[title],a:link acronym[title],a:visited acronym[title]{cursor:pointer}code{font-family:monospace;white-space:pre}#maincontent ul{margin-left:2em}.warning{color:red;background-color:white;font-weight:bold}.clear{clear:both}.error{color:#ff0000;background-color:white}div.hostinfo{margin:0;padding:0;font-size:80%;padding:0.5em;flex:1;font-weight:bold}#xhr_poll_status{cursor:pointer}#xhr_poll_status #xhr_poll_status_off{font-weight:bold;color:#FF0000}#xhr_poll_status #xhr_poll_status_on{font-weight:bold;color:#00FF00}#menubar{display:flex;background:#dc0067;color:#ffffff}#menubar .warning{color:red;background-color:#557788}#menubar a:link,#menubar a:visited{position:relative;display:block;padding:0.5em;text-decoration:none;font-size:80%;font-weight:normal;color:white}#menubar a:link:hover,#menubar a:visited:hover,#menubar a:link:focus,#menubar a:visited:focus{background:#ffb400;color:black}#menubar a:link.active,#menubar a:visited.active{background:#ffb400;color:black;font-weight:bold}#menubar a:link.warning,#menubar a:visited.warning{background:#000000;color:red;font-weight:bold}#modemenu{list-style:none;margin:0;padding:0}#modemenu li{display:inline-block}.lang_de #submenu_admin_uci{width:12em}.lang_ru #submenu_admin_uci{width:11.5em}textarea#syslog{width:98%;min-height:500px;border:3px solid #cccccc;padding:5px;font-family:monospace}#maincontent{padding:0 1em 2em;max-width:60em;min-width:40em;margin:1em auto}.lang_he #maincontent{direction:rtl}#maincontent p{margin-bottom:1em}.cbi-section{margin:0;padding:0;border:none}.cbi-section legend{font-size:1.4em;font-weight:bold;color:#dc0067;position:relative;padding:0;margin-bottom:0.5em}.cbi-section h2{margin:0em 0 0.5em -0.5em !important}.cbi-section h3{text-decoration:none !important;font-weight:bold !important;color:#555555 !important;margin:0.25em !important;font-size:100% !important}.cbi-section-descr{margin-bottom:2em}.cbi-title-ref{color:inherit;text-decoration:none;padding-right:18px;background:url("../resources/cbi/link.gif") no-repeat scroll right center;background-color:inherit}ul.cbi-apply{font-size:90%}input:-webkit-input-placeholder{color:#AAAAAA}input:-moz-placeholder{color:#AAAAAA}input:-ms-input-placeholder{color:#AAAAAA}input[type=checkbox]{display:none}input[type=checkbox]+label{display:inline-block;width:1em;height:1em;margin:0}input[type=checkbox]:checked+label:after{content:'✔';color:#dc0067;vertical-align:middle;position:absolute;top:50%;left:0;margin-top:-0.5em;width:100%;text-align:center;font-size:1.7em}input[type=submit],input[type=reset],input[type=image],input[type=button]{cursor:pointer}select,input,textarea,input[type=checkbox]+label{color:#003247;border:none;background:#ffe199;border-radius:3pt;padding:0.5em}input[type=image]{border:none}select,input[type=text],input[type=password]{width:20em}td select,td input[type=text],td input[type=password]{width:99%}img.cbi-image-button{cursor:pointer;margin:0 2px;vertical-align:middle}input.cbi-button{display:inline-block;zoom:1;line-height:normal;white-space:nowrap;vertical-align:baseline;text-align:center;cursor:pointer;-webkit-user-drag:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;font-size:100%;padding:0.5em 1em;color:rgba(0,0,0,0.8);border:none transparent;background-color:#E6E6E6;text-decoration:none;border-radius:2px;-webkit-transition:0.1s linear -webkit-box-shadow;-moz-transition:0.1s linear -moz-box-shadow;-ms-transition:0.1s linear box-shadow;-o-transition:0.1s linear box-shadow;transition:0.1s linear box-shadow;margin-left:0.5em;background-repeat:no-repeat}input.cbi-button::-moz-focus-inner{padding:0;border:0}input.cbi-button:active{box-shadow:0 0 0 1px rgba(0,0,0,0.15) inset,0 0 6px rgba(0,0,0,0.2) inset}input.cbi-button:focus{outline:0}input.cbi-button:hover,input.cbi-button:focus{background-image:-webkit-gradient(linear, 0 0, 0 100%, from(transparent), color-stop(40%, rgba(0,0,0,0.05)), to(rgba(0,0,0,0.1)));background-image:-webkit-linear-gradient(transparent, rgba(0,0,0,0.05) 40%, rgba(0,0,0,0.1));background-image:-moz-linear-gradient(top, rgba(0,0,0,0.05) 0%, rgba(0,0,0,0.1));background-image:-o-linear-gradient(transparent, rgba(0,0,0,0.05) 40%, rgba(0,0,0,0.1));background-image:linear-gradient(transparent, rgba(0,0,0,0.05) 40%, rgba(0,0,0,0.1))}input.cbi-button[disabled]{border:none;background-image:none;opacity:0.40;cursor:not-allowed;box-shadow:none}input.cbi-input-user{background-image:url("../resources/cbi/user.gif");background-repeat:no-repeat;background-position:1px center;color:#000000;text-indent:17px}input.cbi-input-find,input.cbi-button-find{background-image:url("../resources/cbi/find.gif");color:#000000;padding-left:17px}input.cbi-input-reload{background-image:url("../resources/cbi/reload.gif");color:#000000;padding-left:17px}input.cbi-input-add,input.cbi-button-add{background-image:url("../resources/cbi/add.gif");color:#000000;padding-left:17px;padding-right:1px}input.cbi-input-fieldadd,input.cbi-button-fieldadd{background-image:url(../resources/cbi/fieldadd.gif);color:#000000;padding-left:17px;padding-right:1px}input.cbi-input-reset,input.cbi-button-reset{background-color:#e30;color:#fff}input.cbi-input-save,input.cbi-button-save{background-color:#009ee0;color:#fff}input.cbi-input-apply,input.cbi-button-apply{background-color:#009ee0;color:#fff}input.cbi-input-link,input.cbi-button-link{background-image:url("../resources/cbi/link.gif");color:#000000;padding-left:17px;padding-right:1px}input.cbi-input-download,input.cbi-button-download{background-image:url("../resources/cbi/download.gif");color:#000000;padding-left:17px;padding-right:1px}input.cbi-input-remove,div.cbi-section-remove input{background-image:url("../resources/cbi/remove.gif");color:#000000;padding-left:17px;padding-right:1px}input.cbi-button-up{background-image:url("../resources/cbi/up.gif");padding-left:11px;padding-right:1px}input.cbi-button-down{background-image:url("../resources/cbi/down.gif");padding-left:11px;padding-right:1px}input.cbi-button-edit{background-image:url("../resources/cbi/edit.gif");color:#000000;padding-left:17px;padding-right:1px}input.cbi-button-reload{background-image:url("../resources/cbi/reload.gif");color:#000000;padding-left:17px;padding-right:1px}input.cbi-button-remove{background-image:url("../resources/cbi/remove.gif");color:#000000;padding-left:17px;padding-right:1px}.cbi-input-invalid{background:#e30 !important;color:white}div.cbi-section-remove input{border-bottom:none}textarea{margin-left:-1px;margin-bottom:0.5em}table td,table th{color:#000000}table.smalltext{background:#f5f5f5;color:#000000;border-top:1px solid #666666;border-right:1px solid #666666;border-bottom:1px solid #666666;font-size:90%;width:80%;margin-left:auto;margin-right:auto;border-collapse:collapse}table.smalltext tr:hover td{background-color:#bbddee;color:#000000}table.smalltext tr th{padding:0 0.25em;border-left:1px solid #666666;text-align:left}table.smalltext tr td{padding:0 0.25em;border-top:1px solid #666666;border-left:1px solid #666666}table.cbi-section-table .cbi-rowstyle-1{background-color:#eeeeff;color:#000000}table.cbi-section-table .cbi-rowstyle-1:hover,table.cbi-section-table .cbi-rowstyle-2:hover{background-color:#b2c8d4;color:#000000}table.cbi-section-table .cbi-section-table-cell{padding:3px;white-space:nowrap}.cbi-section .cbi-rowstyle-1 h3{background-color:#eeeeff;color:#555555}.cbi-rowstyle-2{color:#000000}div.cbi-value{display:flex;flex-direction:row;margin-bottom:0.5em}.cbi-value-title{flex:2;text-align:right;padding-right:1em;font-weight:bold}div.cbi-value-field{flex:3;position:relative}div.cbi-value-field input,div.cbi-value-field select,div.cbi-value-field input+label{position:relative;top:-0.39em}div.cbi-value-description{font-size:8pt}div.cbi-section-create{clear:left;white-space:nowrap;vertical-align:top}div.cbi-section-create .cbi-button{margin:0.25em}input.cbi-section-create-name{margin-right:-0.25em}div.cbi-map-descr{margin-bottom:1em}.cbi-map-descr:empty,.cbi-section-descr:empty{display:none}.cbi-map-descr,.cbi-section-descr,.cbi-page-actions{padding:1em;background:#ececec}.cbi-page-actions{text-align:right;display:flex;display:-moz-flex;-moz-flex-flow:row-reverse;flex-flow:row-reverse}div.cbi-optionals{padding:0.25em;border-bottom:1px dotted #bbbbbb}div.cbi-section-remove{float:right}.cbi-section-node{clear:both;position:relative;border:none}.cbi-section-node-tabbed{border-top-left-radius:0}.cbi-section-node .cbi-value-last{border-bottom:none}.cbi-section-node table div{padding-bottom:0;border-bottom:none}.cbi-section-node div.cbi-section-table-row{margin:0.25em}table.cbi-section-table{width:100%;font-size:95%}table.cbi-section-table th,table.cbi-section-table td{text-align:center}tr.cbi-section-table-descr th{font-weight:normal;font-size:90%;vertical-align:top}td.cbi-section-table-optionals{text-align:left !important;padding-top:1em}.cbi-value-helpicon img{display:none}div.cbi-error{font-size:95%;font-weight:bold;color:#ff0000;background-color:#ffffff}td.cbi-value-error{border-color:red}.cbi-value-error input,.cbi-value-error select{background-color:#ffcccc}.cbi-section-error{color:red;background-color:white;font-size:95%;border:1px dotted red;margin:3px;padding:3px}.cbi-value-field var{color:#2222FF}ul.cbi-tabmenu{padding:3px 0;margin-left:0 !important;list-style-type:none;position:relative;z-index:10;top:4px;line-height:20px}ul.cbi-tabmenu li.cbi-tab,ul.cbi-tabmenu li.cbi-tab-disabled{display:inline;margin:0}ul.cbi-tabmenu li.cbi-tab a,ul.cbi-tabmenu li.cbi-tab-disabled a{text-decoration:none;padding:3px 7px;margin-right:3px;border:1px solid #BBBBBB;border-bottom:none;border-radius:3px 3px 0 0;background-color:#EEEEEE;color:#BBBBBB}ul.cbi-tabmenu li.cbi-tab-highlighted a{color:#000000;background-color:#FFEEAA}ul.cbi-tabmenu li a:hover{color:#000000}ul.cbi-tabmenu li.cbi-tab a{padding-top:4px;color:#000000;background-color:#FFFFFF}div.cbi-tab-descr{background-image:url(/luci-static/resources/cbi/help.gif);background-position:0.25em 50%;background-repeat:no-repeat;border-bottom:1px solid #CCCCCC;margin:0.25em 0.25em 2em;padding:0.5em 0.5em 0.5em 2em}.left{text-align:left !important}.right{text-align:right !important}.luci{position:absolute;bottom:0;left:1em;height:1.5em;font-size:80%}.luci a:link,.luci a:visited{background-color:transparent;color:#666666;text-decoration:none;font-size:70%}.inline{display:inline}.error500{white-space:normal;border:1px dotted #ff0000;background-color:#ffffff;color:#000000;padding:0.5em}.errorbox{border:1px solid #FF0000;background-color:#FFCCCC;padding:5px;margin-bottom:5px}.errorbox a{color:#000000 !important}.ifacebox{background-color:#FFFFFF;border:1px solid #CCCCCC;margin:0 10px;text-align:center;white-space:nowrap}.ifacebox .ifacebox-head{border-bottom:1px solid #CCCCCC;padding:2px}.ifacebox .ifacebox-body{padding:2px}.ifacebadge{background-color:#FFFFFF;border:1px solid #CCCCCC;padding:2px;margin-left:2px;display:inline-block}.ifacebadge-active{border-color:#000000;font-weight:bold}.zonebadge{padding:2px;display:inline-block;white-space:nowrap;cursor:pointer}.zonebadge em,.zonebadge strong{margin:3px;display:inline-block}.zonebadge input{width:6em;height:1.5em}.zonebadge-empty{border:1px dashed #AAAAAA;color:#AAAAAA;font-style:italic;font-size:smaller}.uci-change-list{font-family:monospace}.uci-change-list ins,.uci-change-legend-label ins{text-decoration:none;border:1px solid #00FF00;background-color:#CCFFCC;display:block;padding:2px}.uci-change-list del,.uci-change-legend-label del{text-decoration:none;border:1px solid #FF0000;background-color:#FFCCCC;display:block;font-style:normal;padding:2px}.uci-change-list var,.uci-change-legend-label var{text-decoration:none;border:1px solid #CCCCCC;background-color:#EEEEEE;display:block;font-style:normal;padding:2px}.uci-change-list var ins,.uci-change-list var del{border:none;white-space:pre;font-style:normal;padding:0px}.uci-change-legend{padding:5px}.uci-change-legend-label{width:150px;float:left;font-size:80%}.uci-change-legend-label>ins,.uci-change-legend-label>del,.uci-change-legend-label>var{float:left;margin-right:4px;width:10px;height:10px;display:block}.uci-change-legend-label var ins,.uci-change-legend-label var del{line-height:6px;border:none}.cbi-input-password+img{display:none}.the-key{text-align:left;font-size:1.4em;background:#ffe9b3;border:3pt dashed #dc0067;margin-bottom:0.5em;padding:0.5em} +/*# sourceMappingURL=cascade.css.map */ diff --git a/package/gluon-luci-theme/sass/cascade.scss b/package/gluon-luci-theme/sass/cascade.scss index 80e407be..8f62a0e1 100644 --- a/package/gluon-luci-theme/sass/cascade.scss +++ b/package/gluon-luci-theme/sass/cascade.scss @@ -438,6 +438,7 @@ img.cbi-image-button { input.cbi-button { @include button; + margin-left: 0.5em; background-repeat: no-repeat; } @@ -565,11 +566,6 @@ textarea { margin-bottom: 0.5em; } -form > div > input[type=submit], -form > div > input[type=reset] { - margin-left: 0.5em; -} - table td, table th { color: #000000; From e1f2ac11b631df1166360bc5d0d1c8abf1665b10 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Mon, 4 May 2015 01:29:29 +0200 Subject: [PATCH 23/62] gluon-luci-admin: i18n --- package/gluon-luci-admin/Makefile | 12 +- .../lib/lua/luci/controller/admin/index.lua | 6 +- .../lib/lua/luci/controller/admin/upgrade.lua | 2 +- .../lib/lua/luci/model/cbi/admin/remote.lua | 33 +++--- .../usr/lib/lua/luci/view/admin/info.htm | 17 +-- .../usr/lib/lua/luci/view/admin/upgrade.htm | 58 ++++----- .../lua/luci/view/admin/upgrade_confirm.htm | 16 +-- .../lua/luci/view/admin/upgrade_reboot.htm | 9 +- package/gluon-luci-admin/i18n/de.po | 111 ++++++++++++++++++ .../i18n/gluon-luci-admin.pot | 93 +++++++++++++++ 10 files changed, 279 insertions(+), 78 deletions(-) create mode 100644 package/gluon-luci-admin/i18n/de.po create mode 100644 package/gluon-luci-admin/i18n/gluon-luci-admin.pot diff --git a/package/gluon-luci-admin/Makefile b/package/gluon-luci-admin/Makefile index 0208ace2..3e20d179 100644 --- a/package/gluon-luci-admin/Makefile +++ b/package/gluon-luci-admin/Makefile @@ -4,12 +4,14 @@ include $(TOPDIR)/rules.mk PKG_NAME:=gluon-luci-admin -PKG_VERSION:=0.1 +PKG_VERSION:=1 PKG_RELEASE:=1 PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME) -include $(INCLUDE_DIR)/package.mk +include $(GLUONDIR)/include/package.mk + +PKG_CONFIG_DEPENDS += $(GLUON_I18N_CONFIG) define Package/gluon-luci-admin SECTION:=gluon @@ -18,10 +20,6 @@ define Package/gluon-luci-admin DEPENDS:=gluon-config-mode-core-virtual endef -define Package/gluon-luci-admin/description - Luci based config mode -endef - define Build/Prepare mkdir -p $(PKG_BUILD_DIR) endef @@ -30,10 +28,12 @@ define Build/Configure endef define Build/Compile + $(call GluonBuildI18N,gluon-luci-admin,i18n) endef define Package/gluon-luci-admin/install $(CP) ./files/* $(1)/ + $(call GluonInstallI18N,gluon-luci-admin,$(1)) endef $(eval $(call BuildPackage,gluon-luci-admin)) diff --git a/package/gluon-luci-admin/files/usr/lib/lua/luci/controller/admin/index.lua b/package/gluon-luci-admin/files/usr/lib/lua/luci/controller/admin/index.lua index 284cc162..55c0a248 100644 --- a/package/gluon-luci-admin/files/usr/lib/lua/luci/controller/admin/index.lua +++ b/package/gluon-luci-admin/files/usr/lib/lua/luci/controller/admin/index.lua @@ -29,11 +29,11 @@ function index() root.index = true end - local page = entry({"admin"}, alias("admin", "index"), "Expert Mode", 10) + local page = entry({"admin"}, alias("admin", "index"), _("Expert Mode"), 10) page.sysauth = "root" page.sysauth_authenticator = function() return "root" end page.index = true - entry({"admin", "index"}, cbi("admin/info"), _("Info"), 1).ignoreindex = true - entry({"admin", "remote"}, cbi("admin/remote"), _("Remotezugriff"), 10) + entry({"admin", "index"}, cbi("admin/info"), _("Information"), 1).ignoreindex = true + entry({"admin", "remote"}, cbi("admin/remote"), _("Remote access"), 10) end diff --git a/package/gluon-luci-admin/files/usr/lib/lua/luci/controller/admin/upgrade.lua b/package/gluon-luci-admin/files/usr/lib/lua/luci/controller/admin/upgrade.lua index 868c2bbd..29aecb95 100644 --- a/package/gluon-luci-admin/files/usr/lib/lua/luci/controller/admin/upgrade.lua +++ b/package/gluon-luci-admin/files/usr/lib/lua/luci/controller/admin/upgrade.lua @@ -18,7 +18,7 @@ module("luci.controller.admin.upgrade", package.seeall) function index() local has_platform = nixio.fs.access("/lib/upgrade/platform.sh") if has_platform then - entry({"admin", "upgrade"}, call("action_upgrade"), "Firmware aktualisieren", 90) + entry({"admin", "upgrade"}, call("action_upgrade"), _("Upgrade firmware"), 90) entry({"admin", "upgrade", "reboot"}, template("admin/upgrade_reboot"), nil, nil) end end diff --git a/package/gluon-luci-admin/files/usr/lib/lua/luci/model/cbi/admin/remote.lua b/package/gluon-luci-admin/files/usr/lib/lua/luci/model/cbi/admin/remote.lua index dfba5e66..5797b623 100644 --- a/package/gluon-luci-admin/files/usr/lib/lua/luci/model/cbi/admin/remote.lua +++ b/package/gluon-luci-admin/files/usr/lib/lua/luci/model/cbi/admin/remote.lua @@ -16,15 +16,13 @@ $Id$ local fs = require "nixio.fs" -local m = Map("system", "SSH-Keys") -m.submit = "Speichern" -m.reset = "Zurücksetzen" +local m = Map("system", translate("SSH keys")) m.pageaction = false m.template = "admin/expertmode" if fs.access("/etc/config/dropbear") then local s = m:section(TypedSection, "_dummy1", nil, - "Hier hast du die Möglichkeit SSH-Keys (einen pro Zeile) zu hinterlegen:") + translate("You can provide your SSH keys here (one per line):")) s.addremove = false s.anonymous = true @@ -57,23 +55,22 @@ if fs.access("/etc/config/dropbear") then end end -local m2 = Map("system", "Passwort") -m2.submit = "Speichern" +local m2 = Map("system", translate("Password")) m2.reset = false m2.pageaction = false m2.template = "admin/expertmode" -local s = m2:section(TypedSection, "_dummy2", nil, -[[Alternativ kannst du auch ein Passwort setzen. Wähle bitte ein sicheres Passwort, das du nirgendwo anders verwendest.

-Beim Setzen eines leeren Passworts wird der Login per Passwort gesperrt (dies ist die Standard-Einstellung).]]) +local s = m2:section(TypedSection, "_dummy2", nil, translate( + "Alternatively, you can set a password to access you node. Please choose a secure password you don't use anywhere else.

" + .. "If you set an empty password, login via password will be disabled. This is the default.")) s.addremove = false s.anonymous = true -local pw1 = s:option(Value, "pw1", "Passwort") +local pw1 = s:option(Value, "pw1", translate("Password")) pw1.password = true -local pw2 = s:option(Value, "pw2", "Wiederholung") +local pw2 = s:option(Value, "pw2", translate("Confirmation")) pw2.password = true function s.cfgsections() @@ -87,18 +84,18 @@ function m2.on_commit(map) if v1 and v2 then if v1 == v2 then if #v1 > 0 then - if luci.sys.user.setpasswd(luci.dispatcher.context.authuser, v1) == 0 then - m2.message = "Passwort geändert." - else - m2.errmessage = "Das Passwort konnte nicht geändert werden." - end + if luci.sys.user.setpasswd(luci.dispatcher.context.authuser, v1) == 0 then + m2.message = translate("Password changed.") + else + m2.errmessage = translate("Unable to change the password.") + end else -- We don't check the return code here as the error 'password for root is already locked' is normal... os.execute('passwd -l root >/dev/null') - m2.message = "Passwort gelöscht." + m2.message = translate("Password removed.") end else - m2.errmessage = "Die beiden Passwörter stimmen nicht überein." + m2.errmessage = translate("The password and the confirmation differ.") end end end 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 9c384399..a04a834d 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 @@ -2,6 +2,7 @@ local fs = require 'luci.fs' local uci = require('luci.model.uci').cursor() local util = require 'luci.util' + local i18n = require 'luci.i18n' local site = require 'gluon.site_config' local sysconfig = require 'gluon.sysconfig' @@ -9,13 +10,13 @@ local keys = { - hostname = 'Hostname', - primary_mac = 'MAC-Adresse', - model = 'Hardware-Modell', - version = 'Gluon-Version', - release = 'Firmware-Release', - site = 'Site', - pubkey = 'Öffentlicher VPN-Schlüssel', + 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 = { @@ -36,7 +37,7 @@ end end -%> -

Info

+

<%:Information%>

<% for _, key in ipairs({'hostname', 'primary_mac', 'model', 'version', 'release', 'site', 'pubkey'}) do %>
<%=keys[key]%>
<%=values[key] or 'n/a'%>
diff --git a/package/gluon-luci-admin/files/usr/lib/lua/luci/view/admin/upgrade.htm b/package/gluon-luci-admin/files/usr/lib/lua/luci/view/admin/upgrade.htm index 343ed495..a2b82235 100644 --- a/package/gluon-luci-admin/files/usr/lib/lua/luci/view/admin/upgrade.htm +++ b/package/gluon-luci-admin/files/usr/lib/lua/luci/view/admin/upgrade.htm @@ -15,41 +15,41 @@ $Id$ <%+header%> -

Firmware aktualisieren

+

<%:Upgrade firmware%>

-

- Hier kannst du ein manuelles Firmwareupdate durchführen. -

-<% if bad_image then %> -

Die übermittelte Firmwaredatei kann nicht verwendet werden.

-<% end %> -
-
- -
- +

+ <%:You can manually upgrade your firmware here.%> +

+ <% if bad_image then %> +

<%:The provided firmware image is not valid for this device.%>

+ <% end %> +
+
+ +
+ +
+
+ +
+ + +
+ + +
-
- - -
- - -
+
+ +
-
- -
- - -
<%+footer%> diff --git a/package/gluon-luci-admin/files/usr/lib/lua/luci/view/admin/upgrade_confirm.htm b/package/gluon-luci-admin/files/usr/lib/lua/luci/view/admin/upgrade_confirm.htm index ac375761..5618728f 100644 --- a/package/gluon-luci-admin/files/usr/lib/lua/luci/view/admin/upgrade_confirm.htm +++ b/package/gluon-luci-admin/files/usr/lib/lua/luci/view/admin/upgrade_confirm.htm @@ -15,20 +15,20 @@ $Id$ <%+header%> -

Firmware aktualisieren

+

<%:Upgrade firmware%>

+

- Die Firmwaredatei wurde übermittelt. Bitte vergleiche MD5-Checksumme - und Dateigröße und klicke anschließend auf "Fortfahren". + <%:The firmware image has been transmitted. Please ensure the MD5 checksum and image size are correct and click "continue".%>

<% if flashsize > 0 and filesize > flashsize then %> -

Die Firmware passt nicht in den Speicher des Gerätes.

+

<%:The firmware is too big for your device's storage.%>

<% end %>

  • md5sum: <%=checksum%>
  • -
  • Größe: <% +
  • <%:Size%>: <% function byte_format(byte) local suff = {"B", "KB", "MB", "GB", "TB"} for i=1, 5 do @@ -51,16 +51,16 @@ $Id$ %>

-
+
" /> - +
" /> - +
<%+footer%> diff --git a/package/gluon-luci-admin/files/usr/lib/lua/luci/view/admin/upgrade_reboot.htm b/package/gluon-luci-admin/files/usr/lib/lua/luci/view/admin/upgrade_reboot.htm index b9baa279..3e89e778 100644 --- a/package/gluon-luci-admin/files/usr/lib/lua/luci/view/admin/upgrade_reboot.htm +++ b/package/gluon-luci-admin/files/usr/lib/lua/luci/view/admin/upgrade_reboot.htm @@ -3,17 +3,16 @@ - Firmware wird aktualisiert + <%:Upgrading firmware%>

- Die Firmware wird jetzt aktualisiert. - UNTERBRICH AUF KEINEN FALL DIE STROMVERSORGUNG! - Dieser Vorgang wird einige Minuten dauern. - Anschließend startet das Gerät automatisch neu. + <%:The firmware is currently being upgraded.%> + <%:Don't switch off the device in any circumstance!%> + <%:The upgrade will take a few minutes. When it is finished, your node will reboot automatically.%>

diff --git a/package/gluon-luci-admin/i18n/de.po b/package/gluon-luci-admin/i18n/de.po new file mode 100644 index 00000000..e3a1aa20 --- /dev/null +++ b/package/gluon-luci-admin/i18n/de.po @@ -0,0 +1,111 @@ +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"PO-Revision-Date: 2015-05-04 00:34+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" + +msgid "" +"Alternatively, you can set a password to access you node. Please choose a " +"secure password you don't use anywhere else.

If you set an empty " +"password, login via password will be disabled. This is the default." +msgstr "" +"Alternativ kannst du auch ein Passwort setzen. Wähle bitte ein sicheres " +"Passwort, das du nirgendwo anders verwendest.

Beim Setzen eines " +"leeren Passworts wird der Login per Passwort gesperrt (dies ist die Standard-" +"Einstellung)." + +msgid "Continue" +msgstr "Fortfahren" + +msgid "Don't switch off the device in any circumstance!" +msgstr "Unterbrich auf keinen Fall die Stromversorgung!" + +msgid "Expert Mode" +msgstr "Export Mode" + +msgid "Firmware image" +msgstr "Firmware-Datei" + +msgid "Firmware release" +msgstr "Firmware-Release" + +msgid "Gluon version" +msgstr "Gluon-Version" + +msgid "Hardware model" +msgstr "Hardware-Modell" + +msgid "Information" +msgstr "Info" + +msgid "MAC address" +msgstr "MAC-Adresse" + +msgid "Password changed." +msgstr "Passwort geändert." + +msgid "Password removed." +msgstr "Passwort gelöscht." + +msgid "Public VPN key" +msgstr "Öffentlicher VPN-Schlüssel" + +msgid "Remote access" +msgstr "Remotezugriff" + +msgid "SSH keys" +msgstr "SSH-Schlüssel" + +msgid "Site" +msgstr "Site" + +msgid "" +"The firmware image has been transmitted. Please ensure the MD5 checksum and " +"image size are correct and click \"continue\"." +msgstr "" +"Die Firmwaredatei wurde übermittelt. Bitte vergleiche MD5-Checksumme und " +"Dateigröße und klicke anschließend auf \"fortfahren\"." + +msgid "The firmware is currently being upgraded." +msgstr "Die Firmware wird jetzt aktualisiert." + +msgid "The firmware is too big for your device's storage." +msgstr "Die Firmware passt nicht in den Speicher des Gerätes." + +msgid "The password and the confirmation differ." +msgstr "Die beiden Passwörter stimmen nicht überein." + +msgid "The provided firmware image is not valid for this device." +msgstr "Die übermittelte Datei ist keine gültige Firmware für dieses Gerät." + +msgid "" +"The upgrade will take a few minutes. When it is finished, your node will " +"reboot automatically." +msgstr "" +"Dieser Vorgang wird einige Minuten dauern. Anschließend startet das Gerät " +"automatisch neu." + +msgid "Unable to change the password." +msgstr "Das Passwort konnte nicht geändert werden." + +msgid "Upgrade firmware" +msgstr "Firmware aktualisieren" + +msgid "Upgrading firmware" +msgstr "Firmware wird aktualisiert" + +msgid "Upload image" +msgstr "Datei hochladen" + +msgid "You can manually upgrade your firmware here." +msgstr "Hier kannst du ein manuelles Firmwareupdate durchführen." + +msgid "You can provide your SSH keys here (one per line):" +msgstr "" +"Hier hast du die Möglichkeit, SSH-Keys zu hinterlegen (einen pro Zeile):" diff --git a/package/gluon-luci-admin/i18n/gluon-luci-admin.pot b/package/gluon-luci-admin/i18n/gluon-luci-admin.pot new file mode 100644 index 00000000..197b6367 --- /dev/null +++ b/package/gluon-luci-admin/i18n/gluon-luci-admin.pot @@ -0,0 +1,93 @@ +msgid "" +msgstr "Content-Type: text/plain; charset=UTF-8" + +msgid "" +"Alternatively, you can set a password to access you node. Please choose a " +"secure password you don't use anywhere else.

If you set an empty " +"password, login via password will be disabled. This is the default." +msgstr "" + +msgid "Continue" +msgstr "" + +msgid "Don't switch off the device in any circumstance!" +msgstr "" + +msgid "Expert Mode" +msgstr "" + +msgid "Firmware image" +msgstr "" + +msgid "Firmware release" +msgstr "" + +msgid "Gluon version" +msgstr "" + +msgid "Hardware model" +msgstr "" + +msgid "Information" +msgstr "" + +msgid "MAC address" +msgstr "" + +msgid "Password changed." +msgstr "" + +msgid "Password removed." +msgstr "" + +msgid "Public VPN key" +msgstr "" + +msgid "Remote access" +msgstr "" + +msgid "SSH keys" +msgstr "" + +msgid "Site" +msgstr "" + +msgid "" +"The firmware image has been transmitted. Please ensure the MD5 checksum and " +"image size are correct and click \"continue\"." +msgstr "" + +msgid "The firmware is currently being upgraded." +msgstr "" + +msgid "The firmware is too big for your device's storage." +msgstr "" + +msgid "The password and the confirmation differ." +msgstr "" + +msgid "The provided firmware image is not valid for this device." +msgstr "" + +msgid "" +"The upgrade will take a few minutes. When it is finished, your node will " +"reboot automatically." +msgstr "" + +msgid "Unable to change the password." +msgstr "" + +msgid "Upgrade firmware" +msgstr "" + +msgid "Upgrading firmware" +msgstr "" + +msgid "Upload image" +msgstr "" + +msgid "You can manually upgrade your firmware here." +msgstr "" + +msgid "You can provide your SSH keys here (one per line):" +msgstr "" From fe265126a9c00c82b29a03e57f994d009dfdd980 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Mon, 4 May 2015 01:57:50 +0200 Subject: [PATCH 24/62] gluon-luci-autoupdater: i18n --- package/gluon-luci-autoupdater/Makefile | 12 ++++++------ .../lua/luci/controller/admin/autoupdater.lua | 3 +-- .../lua/luci/model/cbi/admin/autoupdater.lua | 8 +++----- package/gluon-luci-autoupdater/i18n/de.po | 17 +++++++++++++++++ .../i18n/gluon-luci-autoupdater.pot | 8 ++++++++ 5 files changed, 35 insertions(+), 13 deletions(-) create mode 100644 package/gluon-luci-autoupdater/i18n/de.po create mode 100644 package/gluon-luci-autoupdater/i18n/gluon-luci-autoupdater.pot diff --git a/package/gluon-luci-autoupdater/Makefile b/package/gluon-luci-autoupdater/Makefile index 518bd6df..650c4692 100644 --- a/package/gluon-luci-autoupdater/Makefile +++ b/package/gluon-luci-autoupdater/Makefile @@ -4,12 +4,14 @@ include $(TOPDIR)/rules.mk PKG_NAME:=gluon-luci-autoupdater -PKG_VERSION:=0.1 +PKG_VERSION:=1 PKG_RELEASE:=1 PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME) -include $(INCLUDE_DIR)/package.mk +include $(GLUONDIR)/include/package.mk + +PKG_CONFIG_DEPENDS += $(GLUON_I18N_CONFIG) define Package/gluon-luci-autoupdater SECTION:=gluon @@ -18,10 +20,6 @@ define Package/gluon-luci-autoupdater DEPENDS:=+gluon-luci-admin +gluon-autoupdater endef -define Package/gluon-luci-autoupdater/description - Luci module for gluon-autoupdater -endef - define Build/Prepare mkdir -p $(PKG_BUILD_DIR) endef @@ -30,10 +28,12 @@ define Build/Configure endef define Build/Compile + $(call GluonBuildI18N,gluon-luci-autoupdater,i18n) endef define Package/gluon-luci-autoupdater/install $(CP) ./files/* $(1)/ + $(call GluonInstallI18N,gluon-luci-autoupdater,$(1)) endef $(eval $(call BuildPackage,gluon-luci-autoupdater)) diff --git a/package/gluon-luci-autoupdater/files/usr/lib/lua/luci/controller/admin/autoupdater.lua b/package/gluon-luci-autoupdater/files/usr/lib/lua/luci/controller/admin/autoupdater.lua index 9e6fd79f..7cc22693 100644 --- a/package/gluon-luci-autoupdater/files/usr/lib/lua/luci/controller/admin/autoupdater.lua +++ b/package/gluon-luci-autoupdater/files/usr/lib/lua/luci/controller/admin/autoupdater.lua @@ -15,6 +15,5 @@ $Id$ module("luci.controller.admin.autoupdater", package.seeall) function index() - entry({"admin", "autoupdater"}, cbi("admin/autoupdater"), _("Autoupdater"), 20) + entry({"admin", "autoupdater"}, cbi("admin/autoupdater"), _("Automatic updates"), 20) end - diff --git a/package/gluon-luci-autoupdater/files/usr/lib/lua/luci/model/cbi/admin/autoupdater.lua b/package/gluon-luci-autoupdater/files/usr/lib/lua/luci/model/cbi/admin/autoupdater.lua index 6800422b..a8f9d3b3 100644 --- a/package/gluon-luci-autoupdater/files/usr/lib/lua/luci/model/cbi/admin/autoupdater.lua +++ b/package/gluon-luci-autoupdater/files/usr/lib/lua/luci/model/cbi/admin/autoupdater.lua @@ -12,9 +12,7 @@ You may obtain a copy of the License at $Id$ ]]-- -m = Map("autoupdater", "Autoupdater") -m.submit = "Speichern" -m.reset = "Zurücksetzen" +m = Map("autoupdater", translate("Automatic updates")) m.pageaction = false m.template = "admin/expertmode" @@ -22,8 +20,8 @@ s = m:section(TypedSection, "autoupdater", nil) s.addremove = false s.anonymous = true -s:option(Flag, "enabled", "Aktivieren") -f = s:option(ListValue, "branch", "Branch") +s:option(Flag, "enabled", translate("Enable")) +f = s:option(ListValue, "branch", translate("Branch")) uci.cursor():foreach("autoupdater", "branch", function (section) f:value(section[".name"]) end) diff --git a/package/gluon-luci-autoupdater/i18n/de.po b/package/gluon-luci-autoupdater/i18n/de.po new file mode 100644 index 00000000..9fd4cf53 --- /dev/null +++ b/package/gluon-luci-autoupdater/i18n/de.po @@ -0,0 +1,17 @@ +msgid "" +msgstr "" +"Content-Type: text/plain; charset=UTF-8\n" +"Project-Id-Version: PACKAGE VERSION\n" +"PO-Revision-Date: 2015-05-04 01:55+0200\n" +"Last-Translator: \n" +"Language-Team: German\n" +"Language: de\n" +"MIME-Version: 1.0\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +msgid "Automatic updates" +msgstr "Automatische Updates" + +msgid "Branch" +msgstr "Branch" diff --git a/package/gluon-luci-autoupdater/i18n/gluon-luci-autoupdater.pot b/package/gluon-luci-autoupdater/i18n/gluon-luci-autoupdater.pot new file mode 100644 index 00000000..678bdbaf --- /dev/null +++ b/package/gluon-luci-autoupdater/i18n/gluon-luci-autoupdater.pot @@ -0,0 +1,8 @@ +msgid "" +msgstr "Content-Type: text/plain; charset=UTF-8" + +msgid "Automatic updates" +msgstr "" + +msgid "Branch" +msgstr "" From cdc16af1bd01fe83822690837e9dec3f8a4cfdaf Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Mon, 4 May 2015 02:10:29 +0200 Subject: [PATCH 25/62] gluon-luci-portconfig: i18n --- package/gluon-luci-portconfig/Makefile | 12 +++---- .../lua/luci/controller/admin/portconfig.lua | 3 +- .../lua/luci/model/cbi/admin/portconfig.lua | 34 +++++++++---------- package/gluon-luci-portconfig/i18n/de.po | 29 ++++++++++++++++ .../i18n/gluon-luci-portconfig.pot | 20 +++++++++++ 5 files changed, 72 insertions(+), 26 deletions(-) create mode 100644 package/gluon-luci-portconfig/i18n/de.po create mode 100644 package/gluon-luci-portconfig/i18n/gluon-luci-portconfig.pot diff --git a/package/gluon-luci-portconfig/Makefile b/package/gluon-luci-portconfig/Makefile index 92b3cbcf..007c5fea 100644 --- a/package/gluon-luci-portconfig/Makefile +++ b/package/gluon-luci-portconfig/Makefile @@ -4,12 +4,14 @@ include $(TOPDIR)/rules.mk PKG_NAME:=gluon-luci-portconfig -PKG_VERSION:=0.1 +PKG_VERSION:=1 PKG_RELEASE:=1 PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME) -include $(INCLUDE_DIR)/package.mk +include $(GLUONDIR)/include/package.mk + +PKG_CONFIG_DEPENDS += $(GLUON_I18N_CONFIG) define Package/gluon-luci-portconfig SECTION:=gluon @@ -18,10 +20,6 @@ define Package/gluon-luci-portconfig DEPENDS:=+gluon-luci-admin +gluon-mesh-batman-adv endef -define Package/gluon-luci-portconfig/description - Luci module for advanced ethernet port configuration -endef - define Build/Prepare mkdir -p $(PKG_BUILD_DIR) endef @@ -30,10 +28,12 @@ define Build/Configure endef define Build/Compile + $(call GluonBuildI18N,gluon-luci-portconfig,i18n) endef define Package/gluon-luci-portconfig/install $(CP) ./files/* $(1)/ + $(call GluonInstallI18N,gluon-luci-portconfig,$(1)) endef $(eval $(call BuildPackage,gluon-luci-portconfig)) diff --git a/package/gluon-luci-portconfig/files/usr/lib/lua/luci/controller/admin/portconfig.lua b/package/gluon-luci-portconfig/files/usr/lib/lua/luci/controller/admin/portconfig.lua index ff0e0af2..037b56c8 100644 --- a/package/gluon-luci-portconfig/files/usr/lib/lua/luci/controller/admin/portconfig.lua +++ b/package/gluon-luci-portconfig/files/usr/lib/lua/luci/controller/admin/portconfig.lua @@ -15,6 +15,5 @@ $Id$ module("luci.controller.admin.portconfig", package.seeall) function index() - entry({"admin", "portconfig"}, cbi("admin/portconfig"), _("Schnittstellen"), 20) + entry({"admin", "portconfig"}, cbi("admin/portconfig"), _("Network"), 20) end - diff --git a/package/gluon-luci-portconfig/files/usr/lib/lua/luci/model/cbi/admin/portconfig.lua b/package/gluon-luci-portconfig/files/usr/lib/lua/luci/model/cbi/admin/portconfig.lua index 7233d5c9..ccade674 100644 --- a/package/gluon-luci-portconfig/files/usr/lib/lua/luci/model/cbi/admin/portconfig.lua +++ b/package/gluon-luci-portconfig/files/usr/lib/lua/luci/model/cbi/admin/portconfig.lua @@ -18,35 +18,33 @@ local wan = uci:get_all("network", "wan") local wan6 = uci:get_all("network", "wan6") local dns = uci:get_first("gluon-wan-dnsmasq", "static") -local f = SimpleForm("portconfig", "WAN-Verbindung") +local f = SimpleForm("portconfig", translate("WAN connection")) f.template = "admin/expertmode" -f.submit = "Speichern" -f.reset = "Zurücksetzen" local s local o s = f:section(SimpleSection, nil, nil) -o = s:option(ListValue, "ipv4", "IPv4") -o:value("dhcp", "Automatisch (DHCP)") -o:value("static", "Statisch") -o:value("none", "Deaktiviert") +o = s:option(ListValue, "ipv4", translate("IPv4")) +o:value("dhcp", translate("Automatic (DHCP)")) +o:value("static", translate("Static")) +o:value("none", translate("Disabled")) o.default = wan.proto -o = s:option(Value, "ipv4_addr", "IP-Adresse") +o = s:option(Value, "ipv4_addr", translate("IP address")) o:depends("ipv4", "static") o.value = wan.ipaddr o.datatype = "ip4addr" o.rmempty = false -o = s:option(Value, "ipv4_netmask", "Netzmaske") +o = s:option(Value, "ipv4_netmask", translate("Netmask")) o:depends("ipv4", "static") o.value = wan.netmask or "255.255.255.0" o.datatype = "ip4addr" o.rmempty = false -o = s:option(Value, "ipv4_gateway", "Gateway") +o = s:option(Value, "ipv4_gateway", translate("Gateway")) o:depends("ipv4", "static") o.value = wan.gateway o.datatype = "ip4addr" @@ -55,19 +53,19 @@ o.rmempty = false s = f:section(SimpleSection, nil, nil) -o = s:option(ListValue, "ipv6", "IPv6") -o:value("dhcpv6", "Automatisch (RA/DHCPv6)") -o:value("static", "Statisch") -o:value("none", "Deaktiviert") +o = s:option(ListValue, "ipv6", translate("IPv6")) +o:value("dhcpv6", translate("Automatic (RA/DHCPv6)")) +o:value("static", translate("Static")) +o:value("none", translate("Disabled")) o.default = wan6.proto -o = s:option(Value, "ipv6_addr", "IP-Adresse") +o = s:option(Value, "ipv6_addr", translate("IP address")) o:depends("ipv6", "static") o.value = wan6.ip6addr o.datatype = "ip6addr" o.rmempty = false -o = s:option(Value, "ipv6_gateway", "Gateway") +o = s:option(Value, "ipv6_gateway", translate("Gateway")) o:depends("ipv6", "static") o.value = wan6.ip6gw o.datatype = "ip6addr" @@ -77,14 +75,14 @@ o.rmempty = false if dns then s = f:section(SimpleSection, nil, nil) - o = s:option(DynamicList, "dns", "Statische DNS-Server") + o = s:option(DynamicList, "dns", translate("Static DNS servers")) o:write(nil, uci:get("gluon-wan-dnsmasq", dns, "server")) o.datatype = "ipaddr" end s = f:section(SimpleSection, nil, nil) -o = s:option(Flag, "mesh_wan", "Mesh auf dem WAN-Port aktivieren") +o = s:option(Flag, "mesh_wan", translate("Enable meshing on the WAN interface")) o.default = uci:get_bool("network", "mesh_wan", "auto") and o.enabled or o.disabled o.rmempty = false diff --git a/package/gluon-luci-portconfig/i18n/de.po b/package/gluon-luci-portconfig/i18n/de.po new file mode 100644 index 00000000..6cc06e20 --- /dev/null +++ b/package/gluon-luci-portconfig/i18n/de.po @@ -0,0 +1,29 @@ +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-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +msgid "Automatic (DHCP)" +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 "Static" +msgstr "Statisch" + +msgid "Static DNS servers" +msgstr "Statische DNS-Server" + +msgid "WAN connection" +msgstr "WAN-Verbindung" diff --git a/package/gluon-luci-portconfig/i18n/gluon-luci-portconfig.pot b/package/gluon-luci-portconfig/i18n/gluon-luci-portconfig.pot new file mode 100644 index 00000000..1800f8d0 --- /dev/null +++ b/package/gluon-luci-portconfig/i18n/gluon-luci-portconfig.pot @@ -0,0 +1,20 @@ +msgid "" +msgstr "Content-Type: text/plain; charset=UTF-8" + +msgid "Automatic (DHCP)" +msgstr "" + +msgid "Automatic (RA/DHCPv6)" +msgstr "" + +msgid "Enable meshing on the WAN interface" +msgstr "" + +msgid "Static" +msgstr "" + +msgid "Static DNS servers" +msgstr "" + +msgid "WAN connection" +msgstr "" From 56c8fe514509e91fafe923865a5d81ac681df996 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Mon, 4 May 2015 02:17:38 +0200 Subject: [PATCH 26/62] gluon-luci-autoupdater: order next to the manual upgrades in the navigation --- .../files/usr/lib/lua/luci/controller/admin/autoupdater.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package/gluon-luci-autoupdater/files/usr/lib/lua/luci/controller/admin/autoupdater.lua b/package/gluon-luci-autoupdater/files/usr/lib/lua/luci/controller/admin/autoupdater.lua index 7cc22693..64e1acbd 100644 --- a/package/gluon-luci-autoupdater/files/usr/lib/lua/luci/controller/admin/autoupdater.lua +++ b/package/gluon-luci-autoupdater/files/usr/lib/lua/luci/controller/admin/autoupdater.lua @@ -15,5 +15,5 @@ $Id$ module("luci.controller.admin.autoupdater", package.seeall) function index() - entry({"admin", "autoupdater"}, cbi("admin/autoupdater"), _("Automatic updates"), 20) + entry({"admin", "autoupdater"}, cbi("admin/autoupdater"), _("Automatic updates"), 80) end From a02d7ad8005268a3a0200878008740f1932680c7 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Mon, 4 May 2015 02:29:03 +0200 Subject: [PATCH 27/62] gluon-luci-private-wifi: i18n --- package/gluon-luci-private-wifi/Makefile | 8 +++-- .../lua/luci/controller/admin/privatewifi.lua | 2 +- .../lua/luci/model/cbi/admin/privatewifi.lua | 22 ++++++------- package/gluon-luci-private-wifi/i18n/de.po | 32 +++++++++++++++++++ .../i18n/gluon-luci-private-wifi.pot | 18 +++++++++++ 5 files changed, 67 insertions(+), 15 deletions(-) create mode 100644 package/gluon-luci-private-wifi/i18n/de.po create mode 100644 package/gluon-luci-private-wifi/i18n/gluon-luci-private-wifi.pot diff --git a/package/gluon-luci-private-wifi/Makefile b/package/gluon-luci-private-wifi/Makefile index 0d5c4619..604929dd 100644 --- a/package/gluon-luci-private-wifi/Makefile +++ b/package/gluon-luci-private-wifi/Makefile @@ -1,12 +1,14 @@ include $(TOPDIR)/rules.mk PKG_NAME:=gluon-luci-private-wifi -PKG_VERSION:=0.1 +PKG_VERSION:=1 PKG_RELEASE:=1 PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME) -include $(INCLUDE_DIR)/package.mk +include $(GLUONDIR)/include/package.mk + +PKG_CONFIG_DEPENDS += $(GLUON_I18N_CONFIG) define Package/gluon-luci-private-wifi SECTION:=gluon @@ -23,10 +25,12 @@ define Build/Configure endef define Build/Compile + $(call GluonBuildI18N,gluon-luci-private-wifi,i18n) endef define Package/gluon-luci-private-wifi/install $(CP) ./files/* $(1)/ + $(call GluonInstallI18N,gluon-luci-private-wifi,$(1)) endef $(eval $(call BuildPackage,gluon-luci-private-wifi)) diff --git a/package/gluon-luci-private-wifi/files/usr/lib/lua/luci/controller/admin/privatewifi.lua b/package/gluon-luci-private-wifi/files/usr/lib/lua/luci/controller/admin/privatewifi.lua index 0b10b4e9..e11ba58b 100644 --- a/package/gluon-luci-private-wifi/files/usr/lib/lua/luci/controller/admin/privatewifi.lua +++ b/package/gluon-luci-private-wifi/files/usr/lib/lua/luci/controller/admin/privatewifi.lua @@ -1,5 +1,5 @@ module("luci.controller.admin.privatewifi", package.seeall) function index() - entry({"admin", "privatewifi"}, cbi("admin/privatewifi"), "Privates WLAN", 10) + entry({"admin", "privatewifi"}, cbi("admin/privatewifi"), _("Private WLAN"), 10) end diff --git a/package/gluon-luci-private-wifi/files/usr/lib/lua/luci/model/cbi/admin/privatewifi.lua b/package/gluon-luci-private-wifi/files/usr/lib/lua/luci/model/cbi/admin/privatewifi.lua index b9157310..f2f00350 100644 --- a/package/gluon-luci-private-wifi/files/usr/lib/lua/luci/model/cbi/admin/privatewifi.lua +++ b/package/gluon-luci-private-wifi/files/usr/lib/lua/luci/model/cbi/admin/privatewifi.lua @@ -6,26 +6,24 @@ local config = 'wireless' local primary_iface = 'wan_radio0' local ssid = uci:get(config, primary_iface, "ssid") -f = SimpleForm("wifi", "Privates WLAN") -f.reset = false +f = SimpleForm("wifi", translate("Private WLAN")) f.template = "admin/expertmode" -f.submit = "Fertig" -s = f:section(SimpleSection, nil, [[ -Dein Freifunk-Router kann ebenfalls die Reichweite deines privaten Netzes erweitern. -Hierfür wird der WAN-Port mit einem seperaten WLAN gebridged. -Diese Funktionalität ist völlig unabhängig von Freifunk. -Beachte, dass du nicht gleichzeitig das Meshen über den WAN Port aktiviert haben solltest. -]]) +s = f:section(SimpleSection, nil, translate( + 'Your node can additionally extend your private network by bridging the WAN interface ' + .. 'with a seperate WLAN. This feature is completely independent of the mesh functionality. ' + .. 'Please note that the private WLAN and meshing on the WAN interface should not be enabled ' + .. 'at the same time.' +)) -o = s:option(Flag, "enabled", "Aktiviert") +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.rmempty = false -o = s:option(Value, "ssid", "Name (SSID)") +o = s:option(Value, "ssid", translate("Name (SSID)")) o.default = ssid -o = s:option(Value, "key", "Schlüssel", "8-63 Zeichen") +o = s:option(Value, "key", translate("Key"), translate("8-63 characters")) o.datatype = "wpakey" o.default = uci:get(config, primary_iface, "key") diff --git a/package/gluon-luci-private-wifi/i18n/de.po b/package/gluon-luci-private-wifi/i18n/de.po new file mode 100644 index 00000000..ccf51341 --- /dev/null +++ b/package/gluon-luci-private-wifi/i18n/de.po @@ -0,0 +1,32 @@ +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"PO-Revision-Date: 2015-05-04 02:25+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" + +msgid "8-63 characters" +msgstr "8-63 Zeichen" + +msgid "Name (SSID)" +msgstr "Name (SSID)" + +msgid "Private WLAN" +msgstr "Privates WLAN" + +msgid "" +"Your node can additionally extend your private network by bridging the WAN " +"interface with a seperate WLAN. This feature is completely independent of " +"the mesh functionality. Please note that the private WLAN and meshing on the " +"WAN interface should not be enabled at the same time." +msgstr "" +"Dein Knoten kann zusätzlich die Reichweite deines privaten Netzes erweitern. " +"Hierfür wird der WAN-Port mit einem seperaten WLAN gebridged. Diese " +"Funktionalität ist völlig unabhängig von den Mesh-Funktionen des Knotens. " +"Beachte, dass du nicht gleichzeitig das Meshen über den WAN-Port aktiviert " +"haben solltest." diff --git a/package/gluon-luci-private-wifi/i18n/gluon-luci-private-wifi.pot b/package/gluon-luci-private-wifi/i18n/gluon-luci-private-wifi.pot new file mode 100644 index 00000000..4051319f --- /dev/null +++ b/package/gluon-luci-private-wifi/i18n/gluon-luci-private-wifi.pot @@ -0,0 +1,18 @@ +msgid "" +msgstr "Content-Type: text/plain; charset=UTF-8" + +msgid "8-63 characters" +msgstr "" + +msgid "Name (SSID)" +msgstr "" + +msgid "Private WLAN" +msgstr "" + +msgid "" +"Your node can additionally extend your private network by bridging the WAN " +"interface with a seperate WLAN. This feature is completely independent of " +"the mesh functionality. Please note that the private WLAN and meshing on the " +"WAN interface should not be enabled at the same time." +msgstr "" From 4b06bc6a3de9cb91b0c17e50b65e7db804d5429a Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Mon, 4 May 2015 02:49:40 +0200 Subject: [PATCH 28/62] gluon-luci-theme: don't color section titles All other titles are grey, the magenta-colored section titles inbetween look weird. --- .../gluon-luci-theme/files/www/luci-static/gluon/cascade.css | 2 +- package/gluon-luci-theme/sass/cascade.scss | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/package/gluon-luci-theme/files/www/luci-static/gluon/cascade.css b/package/gluon-luci-theme/files/www/luci-static/gluon/cascade.css index 63df1b04..66795ea8 100644 --- a/package/gluon-luci-theme/files/www/luci-static/gluon/cascade.css +++ b/package/gluon-luci-theme/files/www/luci-static/gluon/cascade.css @@ -1,2 +1,2 @@ -.lang_he{direction:RTL;unicode-bidi:embed}.hidden{display:none}html{min-height:100%;height:auto;position:relative}body,input,select,option{font-family:'Open Sans', Arial, sans-serif;font-size:12pt}body{color:#4d4e53;line-height:1.5em;margin:0;display:flex;flex-direction:column;min-height:100vh;background-color:#f3f3f3}a img{border:none;text-decoration:none}.tabmenu1{text-align:center}ul.tabmenu{list-style:none;padding:0;margin:2em 0;display:inline-flex}ul.tabmenu li{white-space:nowrap;margin:0 0.5em;padding:0;text-align:center}ul.tabmenu li a{display:block;text-decoration:none;padding:1em;margin:0;color:#333;border-radius:2em}ul.tabmenu li a:hover{background:#ffe9b3}ul.tabmenu li.active a{font-weight:bold;background:white;color:#333}abbr,acronym{font-style:normal;font-variant:normal}abbr[title],acronym[title]{border-bottom:1px dotted;cursor:help}a:link abbr[title],a:visited abbr[title],a:link acronym[title],a:visited acronym[title]{cursor:pointer}code{font-family:monospace;white-space:pre}#maincontent ul{margin-left:2em}.warning{color:red;background-color:white;font-weight:bold}.clear{clear:both}.error{color:#ff0000;background-color:white}div.hostinfo{margin:0;padding:0;font-size:80%;padding:0.5em;flex:1;font-weight:bold}#xhr_poll_status{cursor:pointer}#xhr_poll_status #xhr_poll_status_off{font-weight:bold;color:#FF0000}#xhr_poll_status #xhr_poll_status_on{font-weight:bold;color:#00FF00}#menubar{display:flex;background:#dc0067;color:#ffffff}#menubar .warning{color:red;background-color:#557788}#menubar a:link,#menubar a:visited{position:relative;display:block;padding:0.5em;text-decoration:none;font-size:80%;font-weight:normal;color:white}#menubar a:link:hover,#menubar a:visited:hover,#menubar a:link:focus,#menubar a:visited:focus{background:#ffb400;color:black}#menubar a:link.active,#menubar a:visited.active{background:#ffb400;color:black;font-weight:bold}#menubar a:link.warning,#menubar a:visited.warning{background:#000000;color:red;font-weight:bold}#modemenu{list-style:none;margin:0;padding:0}#modemenu li{display:inline-block}.lang_de #submenu_admin_uci{width:12em}.lang_ru #submenu_admin_uci{width:11.5em}textarea#syslog{width:98%;min-height:500px;border:3px solid #cccccc;padding:5px;font-family:monospace}#maincontent{padding:0 1em 2em;max-width:60em;min-width:40em;margin:1em auto}.lang_he #maincontent{direction:rtl}#maincontent p{margin-bottom:1em}.cbi-section{margin:0;padding:0;border:none}.cbi-section legend{font-size:1.4em;font-weight:bold;color:#dc0067;position:relative;padding:0;margin-bottom:0.5em}.cbi-section h2{margin:0em 0 0.5em -0.5em !important}.cbi-section h3{text-decoration:none !important;font-weight:bold !important;color:#555555 !important;margin:0.25em !important;font-size:100% !important}.cbi-section-descr{margin-bottom:2em}.cbi-title-ref{color:inherit;text-decoration:none;padding-right:18px;background:url("../resources/cbi/link.gif") no-repeat scroll right center;background-color:inherit}ul.cbi-apply{font-size:90%}input:-webkit-input-placeholder{color:#AAAAAA}input:-moz-placeholder{color:#AAAAAA}input:-ms-input-placeholder{color:#AAAAAA}input[type=checkbox]{display:none}input[type=checkbox]+label{display:inline-block;width:1em;height:1em;margin:0}input[type=checkbox]:checked+label:after{content:'✔';color:#dc0067;vertical-align:middle;position:absolute;top:50%;left:0;margin-top:-0.5em;width:100%;text-align:center;font-size:1.7em}input[type=submit],input[type=reset],input[type=image],input[type=button]{cursor:pointer}select,input,textarea,input[type=checkbox]+label{color:#003247;border:none;background:#ffe199;border-radius:3pt;padding:0.5em}input[type=image]{border:none}select,input[type=text],input[type=password]{width:20em}td select,td input[type=text],td input[type=password]{width:99%}img.cbi-image-button{cursor:pointer;margin:0 2px;vertical-align:middle}input.cbi-button{display:inline-block;zoom:1;line-height:normal;white-space:nowrap;vertical-align:baseline;text-align:center;cursor:pointer;-webkit-user-drag:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;font-size:100%;padding:0.5em 1em;color:rgba(0,0,0,0.8);border:none transparent;background-color:#E6E6E6;text-decoration:none;border-radius:2px;-webkit-transition:0.1s linear -webkit-box-shadow;-moz-transition:0.1s linear -moz-box-shadow;-ms-transition:0.1s linear box-shadow;-o-transition:0.1s linear box-shadow;transition:0.1s linear box-shadow;margin-left:0.5em;background-repeat:no-repeat}input.cbi-button::-moz-focus-inner{padding:0;border:0}input.cbi-button:active{box-shadow:0 0 0 1px rgba(0,0,0,0.15) inset,0 0 6px rgba(0,0,0,0.2) inset}input.cbi-button:focus{outline:0}input.cbi-button:hover,input.cbi-button:focus{background-image:-webkit-gradient(linear, 0 0, 0 100%, from(transparent), color-stop(40%, rgba(0,0,0,0.05)), to(rgba(0,0,0,0.1)));background-image:-webkit-linear-gradient(transparent, rgba(0,0,0,0.05) 40%, rgba(0,0,0,0.1));background-image:-moz-linear-gradient(top, rgba(0,0,0,0.05) 0%, rgba(0,0,0,0.1));background-image:-o-linear-gradient(transparent, rgba(0,0,0,0.05) 40%, rgba(0,0,0,0.1));background-image:linear-gradient(transparent, rgba(0,0,0,0.05) 40%, rgba(0,0,0,0.1))}input.cbi-button[disabled]{border:none;background-image:none;opacity:0.40;cursor:not-allowed;box-shadow:none}input.cbi-input-user{background-image:url("../resources/cbi/user.gif");background-repeat:no-repeat;background-position:1px center;color:#000000;text-indent:17px}input.cbi-input-find,input.cbi-button-find{background-image:url("../resources/cbi/find.gif");color:#000000;padding-left:17px}input.cbi-input-reload{background-image:url("../resources/cbi/reload.gif");color:#000000;padding-left:17px}input.cbi-input-add,input.cbi-button-add{background-image:url("../resources/cbi/add.gif");color:#000000;padding-left:17px;padding-right:1px}input.cbi-input-fieldadd,input.cbi-button-fieldadd{background-image:url(../resources/cbi/fieldadd.gif);color:#000000;padding-left:17px;padding-right:1px}input.cbi-input-reset,input.cbi-button-reset{background-color:#e30;color:#fff}input.cbi-input-save,input.cbi-button-save{background-color:#009ee0;color:#fff}input.cbi-input-apply,input.cbi-button-apply{background-color:#009ee0;color:#fff}input.cbi-input-link,input.cbi-button-link{background-image:url("../resources/cbi/link.gif");color:#000000;padding-left:17px;padding-right:1px}input.cbi-input-download,input.cbi-button-download{background-image:url("../resources/cbi/download.gif");color:#000000;padding-left:17px;padding-right:1px}input.cbi-input-remove,div.cbi-section-remove input{background-image:url("../resources/cbi/remove.gif");color:#000000;padding-left:17px;padding-right:1px}input.cbi-button-up{background-image:url("../resources/cbi/up.gif");padding-left:11px;padding-right:1px}input.cbi-button-down{background-image:url("../resources/cbi/down.gif");padding-left:11px;padding-right:1px}input.cbi-button-edit{background-image:url("../resources/cbi/edit.gif");color:#000000;padding-left:17px;padding-right:1px}input.cbi-button-reload{background-image:url("../resources/cbi/reload.gif");color:#000000;padding-left:17px;padding-right:1px}input.cbi-button-remove{background-image:url("../resources/cbi/remove.gif");color:#000000;padding-left:17px;padding-right:1px}.cbi-input-invalid{background:#e30 !important;color:white}div.cbi-section-remove input{border-bottom:none}textarea{margin-left:-1px;margin-bottom:0.5em}table td,table th{color:#000000}table.smalltext{background:#f5f5f5;color:#000000;border-top:1px solid #666666;border-right:1px solid #666666;border-bottom:1px solid #666666;font-size:90%;width:80%;margin-left:auto;margin-right:auto;border-collapse:collapse}table.smalltext tr:hover td{background-color:#bbddee;color:#000000}table.smalltext tr th{padding:0 0.25em;border-left:1px solid #666666;text-align:left}table.smalltext tr td{padding:0 0.25em;border-top:1px solid #666666;border-left:1px solid #666666}table.cbi-section-table .cbi-rowstyle-1{background-color:#eeeeff;color:#000000}table.cbi-section-table .cbi-rowstyle-1:hover,table.cbi-section-table .cbi-rowstyle-2:hover{background-color:#b2c8d4;color:#000000}table.cbi-section-table .cbi-section-table-cell{padding:3px;white-space:nowrap}.cbi-section .cbi-rowstyle-1 h3{background-color:#eeeeff;color:#555555}.cbi-rowstyle-2{color:#000000}div.cbi-value{display:flex;flex-direction:row;margin-bottom:0.5em}.cbi-value-title{flex:2;text-align:right;padding-right:1em;font-weight:bold}div.cbi-value-field{flex:3;position:relative}div.cbi-value-field input,div.cbi-value-field select,div.cbi-value-field input+label{position:relative;top:-0.39em}div.cbi-value-description{font-size:8pt}div.cbi-section-create{clear:left;white-space:nowrap;vertical-align:top}div.cbi-section-create .cbi-button{margin:0.25em}input.cbi-section-create-name{margin-right:-0.25em}div.cbi-map-descr{margin-bottom:1em}.cbi-map-descr:empty,.cbi-section-descr:empty{display:none}.cbi-map-descr,.cbi-section-descr,.cbi-page-actions{padding:1em;background:#ececec}.cbi-page-actions{text-align:right;display:flex;display:-moz-flex;-moz-flex-flow:row-reverse;flex-flow:row-reverse}div.cbi-optionals{padding:0.25em;border-bottom:1px dotted #bbbbbb}div.cbi-section-remove{float:right}.cbi-section-node{clear:both;position:relative;border:none}.cbi-section-node-tabbed{border-top-left-radius:0}.cbi-section-node .cbi-value-last{border-bottom:none}.cbi-section-node table div{padding-bottom:0;border-bottom:none}.cbi-section-node div.cbi-section-table-row{margin:0.25em}table.cbi-section-table{width:100%;font-size:95%}table.cbi-section-table th,table.cbi-section-table td{text-align:center}tr.cbi-section-table-descr th{font-weight:normal;font-size:90%;vertical-align:top}td.cbi-section-table-optionals{text-align:left !important;padding-top:1em}.cbi-value-helpicon img{display:none}div.cbi-error{font-size:95%;font-weight:bold;color:#ff0000;background-color:#ffffff}td.cbi-value-error{border-color:red}.cbi-value-error input,.cbi-value-error select{background-color:#ffcccc}.cbi-section-error{color:red;background-color:white;font-size:95%;border:1px dotted red;margin:3px;padding:3px}.cbi-value-field var{color:#2222FF}ul.cbi-tabmenu{padding:3px 0;margin-left:0 !important;list-style-type:none;position:relative;z-index:10;top:4px;line-height:20px}ul.cbi-tabmenu li.cbi-tab,ul.cbi-tabmenu li.cbi-tab-disabled{display:inline;margin:0}ul.cbi-tabmenu li.cbi-tab a,ul.cbi-tabmenu li.cbi-tab-disabled a{text-decoration:none;padding:3px 7px;margin-right:3px;border:1px solid #BBBBBB;border-bottom:none;border-radius:3px 3px 0 0;background-color:#EEEEEE;color:#BBBBBB}ul.cbi-tabmenu li.cbi-tab-highlighted a{color:#000000;background-color:#FFEEAA}ul.cbi-tabmenu li a:hover{color:#000000}ul.cbi-tabmenu li.cbi-tab a{padding-top:4px;color:#000000;background-color:#FFFFFF}div.cbi-tab-descr{background-image:url(/luci-static/resources/cbi/help.gif);background-position:0.25em 50%;background-repeat:no-repeat;border-bottom:1px solid #CCCCCC;margin:0.25em 0.25em 2em;padding:0.5em 0.5em 0.5em 2em}.left{text-align:left !important}.right{text-align:right !important}.luci{position:absolute;bottom:0;left:1em;height:1.5em;font-size:80%}.luci a:link,.luci a:visited{background-color:transparent;color:#666666;text-decoration:none;font-size:70%}.inline{display:inline}.error500{white-space:normal;border:1px dotted #ff0000;background-color:#ffffff;color:#000000;padding:0.5em}.errorbox{border:1px solid #FF0000;background-color:#FFCCCC;padding:5px;margin-bottom:5px}.errorbox a{color:#000000 !important}.ifacebox{background-color:#FFFFFF;border:1px solid #CCCCCC;margin:0 10px;text-align:center;white-space:nowrap}.ifacebox .ifacebox-head{border-bottom:1px solid #CCCCCC;padding:2px}.ifacebox .ifacebox-body{padding:2px}.ifacebadge{background-color:#FFFFFF;border:1px solid #CCCCCC;padding:2px;margin-left:2px;display:inline-block}.ifacebadge-active{border-color:#000000;font-weight:bold}.zonebadge{padding:2px;display:inline-block;white-space:nowrap;cursor:pointer}.zonebadge em,.zonebadge strong{margin:3px;display:inline-block}.zonebadge input{width:6em;height:1.5em}.zonebadge-empty{border:1px dashed #AAAAAA;color:#AAAAAA;font-style:italic;font-size:smaller}.uci-change-list{font-family:monospace}.uci-change-list ins,.uci-change-legend-label ins{text-decoration:none;border:1px solid #00FF00;background-color:#CCFFCC;display:block;padding:2px}.uci-change-list del,.uci-change-legend-label del{text-decoration:none;border:1px solid #FF0000;background-color:#FFCCCC;display:block;font-style:normal;padding:2px}.uci-change-list var,.uci-change-legend-label var{text-decoration:none;border:1px solid #CCCCCC;background-color:#EEEEEE;display:block;font-style:normal;padding:2px}.uci-change-list var ins,.uci-change-list var del{border:none;white-space:pre;font-style:normal;padding:0px}.uci-change-legend{padding:5px}.uci-change-legend-label{width:150px;float:left;font-size:80%}.uci-change-legend-label>ins,.uci-change-legend-label>del,.uci-change-legend-label>var{float:left;margin-right:4px;width:10px;height:10px;display:block}.uci-change-legend-label var ins,.uci-change-legend-label var del{line-height:6px;border:none}.cbi-input-password+img{display:none}.the-key{text-align:left;font-size:1.4em;background:#ffe9b3;border:3pt dashed #dc0067;margin-bottom:0.5em;padding:0.5em} +.lang_he{direction:RTL;unicode-bidi:embed}.hidden{display:none}html{min-height:100%;height:auto;position:relative}body,input,select,option{font-family:'Open Sans', Arial, sans-serif;font-size:12pt}body{color:#4d4e53;line-height:1.5em;margin:0;display:flex;flex-direction:column;min-height:100vh;background-color:#f3f3f3}a img{border:none;text-decoration:none}.tabmenu1{text-align:center}ul.tabmenu{list-style:none;padding:0;margin:2em 0;display:inline-flex}ul.tabmenu li{white-space:nowrap;margin:0 0.5em;padding:0;text-align:center}ul.tabmenu li a{display:block;text-decoration:none;padding:1em;margin:0;color:#333;border-radius:2em}ul.tabmenu li a:hover{background:#ffe9b3}ul.tabmenu li.active a{font-weight:bold;background:white;color:#333}abbr,acronym{font-style:normal;font-variant:normal}abbr[title],acronym[title]{border-bottom:1px dotted;cursor:help}a:link abbr[title],a:visited abbr[title],a:link acronym[title],a:visited acronym[title]{cursor:pointer}code{font-family:monospace;white-space:pre}#maincontent ul{margin-left:2em}.warning{color:red;background-color:white;font-weight:bold}.clear{clear:both}.error{color:#ff0000;background-color:white}div.hostinfo{margin:0;padding:0;font-size:80%;padding:0.5em;flex:1;font-weight:bold}#xhr_poll_status{cursor:pointer}#xhr_poll_status #xhr_poll_status_off{font-weight:bold;color:#FF0000}#xhr_poll_status #xhr_poll_status_on{font-weight:bold;color:#00FF00}#menubar{display:flex;background:#dc0067;color:#ffffff}#menubar .warning{color:red;background-color:#557788}#menubar a:link,#menubar a:visited{position:relative;display:block;padding:0.5em;text-decoration:none;font-size:80%;font-weight:normal;color:white}#menubar a:link:hover,#menubar a:visited:hover,#menubar a:link:focus,#menubar a:visited:focus{background:#ffb400;color:black}#menubar a:link.active,#menubar a:visited.active{background:#ffb400;color:black;font-weight:bold}#menubar a:link.warning,#menubar a:visited.warning{background:#000000;color:red;font-weight:bold}#modemenu{list-style:none;margin:0;padding:0}#modemenu li{display:inline-block}.lang_de #submenu_admin_uci{width:12em}.lang_ru #submenu_admin_uci{width:11.5em}textarea#syslog{width:98%;min-height:500px;border:3px solid #cccccc;padding:5px;font-family:monospace}#maincontent{padding:0 1em 2em;max-width:60em;min-width:40em;margin:1em auto}.lang_he #maincontent{direction:rtl}#maincontent p{margin-bottom:1em}.cbi-section{margin:0;padding:0;border:none}.cbi-section legend{font-size:1.4em;font-weight:bold;position:relative;padding:0;margin-bottom:0.5em}.cbi-section h2{margin:0em 0 0.5em -0.5em !important}.cbi-section h3{text-decoration:none !important;font-weight:bold !important;color:#555555 !important;margin:0.25em !important;font-size:100% !important}.cbi-section-descr{margin-bottom:2em}.cbi-title-ref{color:inherit;text-decoration:none;padding-right:18px;background:url("../resources/cbi/link.gif") no-repeat scroll right center;background-color:inherit}ul.cbi-apply{font-size:90%}input:-webkit-input-placeholder{color:#AAAAAA}input:-moz-placeholder{color:#AAAAAA}input:-ms-input-placeholder{color:#AAAAAA}input[type=checkbox]{display:none}input[type=checkbox]+label{display:inline-block;width:1em;height:1em;margin:0}input[type=checkbox]:checked+label:after{content:'✔';color:#dc0067;vertical-align:middle;position:absolute;top:50%;left:0;margin-top:-0.5em;width:100%;text-align:center;font-size:1.7em}input[type=submit],input[type=reset],input[type=image],input[type=button]{cursor:pointer}select,input,textarea,input[type=checkbox]+label{color:#003247;border:none;background:#ffe199;border-radius:3pt;padding:0.5em}input[type=image]{border:none}select,input[type=text],input[type=password]{width:20em}td select,td input[type=text],td input[type=password]{width:99%}img.cbi-image-button{cursor:pointer;margin:0 2px;vertical-align:middle}input.cbi-button{display:inline-block;zoom:1;line-height:normal;white-space:nowrap;vertical-align:baseline;text-align:center;cursor:pointer;-webkit-user-drag:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;font-size:100%;padding:0.5em 1em;color:rgba(0,0,0,0.8);border:none transparent;background-color:#E6E6E6;text-decoration:none;border-radius:2px;-webkit-transition:0.1s linear -webkit-box-shadow;-moz-transition:0.1s linear -moz-box-shadow;-ms-transition:0.1s linear box-shadow;-o-transition:0.1s linear box-shadow;transition:0.1s linear box-shadow;margin-left:0.5em;background-repeat:no-repeat}input.cbi-button::-moz-focus-inner{padding:0;border:0}input.cbi-button:active{box-shadow:0 0 0 1px rgba(0,0,0,0.15) inset,0 0 6px rgba(0,0,0,0.2) inset}input.cbi-button:focus{outline:0}input.cbi-button:hover,input.cbi-button:focus{background-image:-webkit-gradient(linear, 0 0, 0 100%, from(transparent), color-stop(40%, rgba(0,0,0,0.05)), to(rgba(0,0,0,0.1)));background-image:-webkit-linear-gradient(transparent, rgba(0,0,0,0.05) 40%, rgba(0,0,0,0.1));background-image:-moz-linear-gradient(top, rgba(0,0,0,0.05) 0%, rgba(0,0,0,0.1));background-image:-o-linear-gradient(transparent, rgba(0,0,0,0.05) 40%, rgba(0,0,0,0.1));background-image:linear-gradient(transparent, rgba(0,0,0,0.05) 40%, rgba(0,0,0,0.1))}input.cbi-button[disabled]{border:none;background-image:none;opacity:0.40;cursor:not-allowed;box-shadow:none}input.cbi-input-user{background-image:url("../resources/cbi/user.gif");background-repeat:no-repeat;background-position:1px center;color:#000000;text-indent:17px}input.cbi-input-find,input.cbi-button-find{background-image:url("../resources/cbi/find.gif");color:#000000;padding-left:17px}input.cbi-input-reload{background-image:url("../resources/cbi/reload.gif");color:#000000;padding-left:17px}input.cbi-input-add,input.cbi-button-add{background-image:url("../resources/cbi/add.gif");color:#000000;padding-left:17px;padding-right:1px}input.cbi-input-fieldadd,input.cbi-button-fieldadd{background-image:url(../resources/cbi/fieldadd.gif);color:#000000;padding-left:17px;padding-right:1px}input.cbi-input-reset,input.cbi-button-reset{background-color:#e30;color:#fff}input.cbi-input-save,input.cbi-button-save{background-color:#009ee0;color:#fff}input.cbi-input-apply,input.cbi-button-apply{background-color:#009ee0;color:#fff}input.cbi-input-link,input.cbi-button-link{background-image:url("../resources/cbi/link.gif");color:#000000;padding-left:17px;padding-right:1px}input.cbi-input-download,input.cbi-button-download{background-image:url("../resources/cbi/download.gif");color:#000000;padding-left:17px;padding-right:1px}input.cbi-input-remove,div.cbi-section-remove input{background-image:url("../resources/cbi/remove.gif");color:#000000;padding-left:17px;padding-right:1px}input.cbi-button-up{background-image:url("../resources/cbi/up.gif");padding-left:11px;padding-right:1px}input.cbi-button-down{background-image:url("../resources/cbi/down.gif");padding-left:11px;padding-right:1px}input.cbi-button-edit{background-image:url("../resources/cbi/edit.gif");color:#000000;padding-left:17px;padding-right:1px}input.cbi-button-reload{background-image:url("../resources/cbi/reload.gif");color:#000000;padding-left:17px;padding-right:1px}input.cbi-button-remove{background-image:url("../resources/cbi/remove.gif");color:#000000;padding-left:17px;padding-right:1px}.cbi-input-invalid{background:#e30 !important;color:white}div.cbi-section-remove input{border-bottom:none}textarea{margin-left:-1px;margin-bottom:0.5em}table td,table th{color:#000000}table.smalltext{background:#f5f5f5;color:#000000;border-top:1px solid #666666;border-right:1px solid #666666;border-bottom:1px solid #666666;font-size:90%;width:80%;margin-left:auto;margin-right:auto;border-collapse:collapse}table.smalltext tr:hover td{background-color:#bbddee;color:#000000}table.smalltext tr th{padding:0 0.25em;border-left:1px solid #666666;text-align:left}table.smalltext tr td{padding:0 0.25em;border-top:1px solid #666666;border-left:1px solid #666666}table.cbi-section-table .cbi-rowstyle-1{background-color:#eeeeff;color:#000000}table.cbi-section-table .cbi-rowstyle-1:hover,table.cbi-section-table .cbi-rowstyle-2:hover{background-color:#b2c8d4;color:#000000}table.cbi-section-table .cbi-section-table-cell{padding:3px;white-space:nowrap}.cbi-section .cbi-rowstyle-1 h3{background-color:#eeeeff;color:#555555}.cbi-rowstyle-2{color:#000000}div.cbi-value{display:flex;flex-direction:row;margin-bottom:0.5em}.cbi-value-title{flex:2;text-align:right;padding-right:1em;font-weight:bold}div.cbi-value-field{flex:3;position:relative}div.cbi-value-field input,div.cbi-value-field select,div.cbi-value-field input+label{position:relative;top:-0.39em}div.cbi-value-description{font-size:8pt}div.cbi-section-create{clear:left;white-space:nowrap;vertical-align:top}div.cbi-section-create .cbi-button{margin:0.25em}input.cbi-section-create-name{margin-right:-0.25em}div.cbi-map-descr{margin-bottom:1em}.cbi-map-descr:empty,.cbi-section-descr:empty{display:none}.cbi-map-descr,.cbi-section-descr,.cbi-page-actions{padding:1em;background:#ececec}.cbi-page-actions{text-align:right;display:flex;display:-moz-flex;-moz-flex-flow:row-reverse;flex-flow:row-reverse}div.cbi-optionals{padding:0.25em;border-bottom:1px dotted #bbbbbb}div.cbi-section-remove{float:right}.cbi-section-node{clear:both;position:relative;border:none}.cbi-section-node-tabbed{border-top-left-radius:0}.cbi-section-node .cbi-value-last{border-bottom:none}.cbi-section-node table div{padding-bottom:0;border-bottom:none}.cbi-section-node div.cbi-section-table-row{margin:0.25em}table.cbi-section-table{width:100%;font-size:95%}table.cbi-section-table th,table.cbi-section-table td{text-align:center}tr.cbi-section-table-descr th{font-weight:normal;font-size:90%;vertical-align:top}td.cbi-section-table-optionals{text-align:left !important;padding-top:1em}.cbi-value-helpicon img{display:none}div.cbi-error{font-size:95%;font-weight:bold;color:#ff0000;background-color:#ffffff}td.cbi-value-error{border-color:red}.cbi-value-error input,.cbi-value-error select{background-color:#ffcccc}.cbi-section-error{color:red;background-color:white;font-size:95%;border:1px dotted red;margin:3px;padding:3px}.cbi-value-field var{color:#2222FF}ul.cbi-tabmenu{padding:3px 0;margin-left:0 !important;list-style-type:none;position:relative;z-index:10;top:4px;line-height:20px}ul.cbi-tabmenu li.cbi-tab,ul.cbi-tabmenu li.cbi-tab-disabled{display:inline;margin:0}ul.cbi-tabmenu li.cbi-tab a,ul.cbi-tabmenu li.cbi-tab-disabled a{text-decoration:none;padding:3px 7px;margin-right:3px;border:1px solid #BBBBBB;border-bottom:none;border-radius:3px 3px 0 0;background-color:#EEEEEE;color:#BBBBBB}ul.cbi-tabmenu li.cbi-tab-highlighted a{color:#000000;background-color:#FFEEAA}ul.cbi-tabmenu li a:hover{color:#000000}ul.cbi-tabmenu li.cbi-tab a{padding-top:4px;color:#000000;background-color:#FFFFFF}div.cbi-tab-descr{background-image:url(/luci-static/resources/cbi/help.gif);background-position:0.25em 50%;background-repeat:no-repeat;border-bottom:1px solid #CCCCCC;margin:0.25em 0.25em 2em;padding:0.5em 0.5em 0.5em 2em}.left{text-align:left !important}.right{text-align:right !important}.luci{position:absolute;bottom:0;left:1em;height:1.5em;font-size:80%}.luci a:link,.luci a:visited{background-color:transparent;color:#666666;text-decoration:none;font-size:70%}.inline{display:inline}.error500{white-space:normal;border:1px dotted #ff0000;background-color:#ffffff;color:#000000;padding:0.5em}.errorbox{border:1px solid #FF0000;background-color:#FFCCCC;padding:5px;margin-bottom:5px}.errorbox a{color:#000000 !important}.ifacebox{background-color:#FFFFFF;border:1px solid #CCCCCC;margin:0 10px;text-align:center;white-space:nowrap}.ifacebox .ifacebox-head{border-bottom:1px solid #CCCCCC;padding:2px}.ifacebox .ifacebox-body{padding:2px}.ifacebadge{background-color:#FFFFFF;border:1px solid #CCCCCC;padding:2px;margin-left:2px;display:inline-block}.ifacebadge-active{border-color:#000000;font-weight:bold}.zonebadge{padding:2px;display:inline-block;white-space:nowrap;cursor:pointer}.zonebadge em,.zonebadge strong{margin:3px;display:inline-block}.zonebadge input{width:6em;height:1.5em}.zonebadge-empty{border:1px dashed #AAAAAA;color:#AAAAAA;font-style:italic;font-size:smaller}.uci-change-list{font-family:monospace}.uci-change-list ins,.uci-change-legend-label ins{text-decoration:none;border:1px solid #00FF00;background-color:#CCFFCC;display:block;padding:2px}.uci-change-list del,.uci-change-legend-label del{text-decoration:none;border:1px solid #FF0000;background-color:#FFCCCC;display:block;font-style:normal;padding:2px}.uci-change-list var,.uci-change-legend-label var{text-decoration:none;border:1px solid #CCCCCC;background-color:#EEEEEE;display:block;font-style:normal;padding:2px}.uci-change-list var ins,.uci-change-list var del{border:none;white-space:pre;font-style:normal;padding:0px}.uci-change-legend{padding:5px}.uci-change-legend-label{width:150px;float:left;font-size:80%}.uci-change-legend-label>ins,.uci-change-legend-label>del,.uci-change-legend-label>var{float:left;margin-right:4px;width:10px;height:10px;display:block}.uci-change-legend-label var ins,.uci-change-legend-label var del{line-height:6px;border:none}.cbi-input-password+img{display:none}.the-key{text-align:left;font-size:1.4em;background:#ffe9b3;border:3pt dashed #dc0067;margin-bottom:0.5em;padding:0.5em} /*# sourceMappingURL=cascade.css.map */ diff --git a/package/gluon-luci-theme/sass/cascade.scss b/package/gluon-luci-theme/sass/cascade.scss index 8f62a0e1..7c57b2cc 100644 --- a/package/gluon-luci-theme/sass/cascade.scss +++ b/package/gluon-luci-theme/sass/cascade.scss @@ -325,7 +325,6 @@ textarea#syslog { .cbi-section legend { font-size: 1.4em; font-weight: bold; - color: $ffmagenta; position: relative; padding: 0; margin-bottom: 0.5em; From b76e1a9e485194fca2609dd0474180dc13388d47 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Mon, 4 May 2015 03:04:25 +0200 Subject: [PATCH 29/62] gluon-luci-wifi-config: i18n and miscellaneous fixes --- package/gluon-luci-wifi-config/Makefile | 8 ++- .../lua/luci/controller/admin/wifi-config.lua | 2 +- .../lua/luci/model/cbi/admin/wifi-config.lua | 63 ++++++++----------- package/gluon-luci-wifi-config/i18n/de.po | 32 ++++++++++ .../i18n/gluon-luci-wifi-config.pot | 20 ++++++ 5 files changed, 86 insertions(+), 39 deletions(-) create mode 100644 package/gluon-luci-wifi-config/i18n/de.po create mode 100644 package/gluon-luci-wifi-config/i18n/gluon-luci-wifi-config.pot diff --git a/package/gluon-luci-wifi-config/Makefile b/package/gluon-luci-wifi-config/Makefile index 2dd03f09..75e70863 100644 --- a/package/gluon-luci-wifi-config/Makefile +++ b/package/gluon-luci-wifi-config/Makefile @@ -1,12 +1,14 @@ include $(TOPDIR)/rules.mk PKG_NAME:=gluon-luci-wifi-config -PKG_VERSION:=0.1 +PKG_VERSION:=1 PKG_RELEASE:=1 PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME) -include $(INCLUDE_DIR)/package.mk +include $(GLUONDIR)/include/package.mk + +PKG_CONFIG_DEPENDS += $(GLUON_I18N_CONFIG) define Package/gluon-luci-wifi-config SECTION:=gluon @@ -23,10 +25,12 @@ define Build/Configure endef define Build/Compile + $(call GluonBuildI18N,gluon-luci-wifi-config,i18n) endef define Package/gluon-luci-wifi-config/install $(CP) ./files/* $(1)/ + $(call GluonInstallI18N,gluon-luci-wifi-config,$(1)) endef $(eval $(call BuildPackage,gluon-luci-wifi-config)) diff --git a/package/gluon-luci-wifi-config/files/usr/lib/lua/luci/controller/admin/wifi-config.lua b/package/gluon-luci-wifi-config/files/usr/lib/lua/luci/controller/admin/wifi-config.lua index 3bcb0007..2ff1cb84 100644 --- a/package/gluon-luci-wifi-config/files/usr/lib/lua/luci/controller/admin/wifi-config.lua +++ b/package/gluon-luci-wifi-config/files/usr/lib/lua/luci/controller/admin/wifi-config.lua @@ -1,5 +1,5 @@ module("luci.controller.admin.wifi-config", package.seeall) function index() - entry({"admin", "wifi-config"}, cbi("admin/wifi-config"), "WLAN", 20) + entry({"admin", "wifi-config"}, cbi("admin/wifi-config"), _("WLAN"), 20) end 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/files/usr/lib/lua/luci/model/cbi/admin/wifi-config.lua index d6559b51..1b8ef7c4 100644 --- a/package/gluon-luci-wifi-config/files/usr/lib/lua/luci/model/cbi/admin/wifi-config.lua +++ b/package/gluon-luci-wifi-config/files/usr/lib/lua/luci/model/cbi/admin/wifi-config.lua @@ -1,74 +1,65 @@ local f, s, o local uci = luci.model.uci.cursor() ---set the heading, button and stuff -f = SimpleForm("wifi", "WLAN-Config") -f.reset = false +f = SimpleForm("wifi", translate("WLAN")) f.template = "admin/expertmode" -f.submit = "Speichern" --- text, which describes what the package does to the user -s = f:section(SimpleSection, nil, [[ -In diesem Abschnitt hast du die Möglichkeit die SSIDs des Client- und des -Mesh-Netzes zu deaktivieren. Bitte lass die SSID des Mesh-Netzes aktiviert, -damit sich auch andere Knoten über dich mit dem Freifunk verbinden können. -]]) +s = f:section(SimpleSection, nil, translate( + "You can enable or disable your node's client and mesh network " + .. "SSIDs here. Please don't disable the mesh network without " + .. "a good reason, so other nodes can mesh with yours." +)) local radios = {} -- look for wifi interfaces and add them to the array uci:foreach('wireless', 'wifi-device', -function(s) - table.insert(radios, s['.name']) -end + function(s) + table.insert(radios, s['.name']) + end ) ---add a client and mesh checkbox for each interface -for index, radio in ipairs(radios) do - --get the hwmode to seperate 2.4GHz and 5Ghz radios +-- add a client and mesh checkbox for each interface +for _, radio in ipairs(radios) do local hwmode = uci:get('wireless', radio, 'hwmode') local p - if hwmode == '11g' or hwmode == '11ng' then --if 2.4GHz - - p = f:section(SimpleSection, "2,4GHz-WLAN", nil) - - elseif hwmode == '11a' or hwmode == '11na' then --if 5GHz - - p = f:section(SimpleSection, "5GHz-WLAN", nil) - + if hwmode == '11g' or hwmode == '11ng' then + p = f:section(SimpleSection, translate("2.4GHz WLAN")) + elseif hwmode == '11a' or hwmode == '11na' then + p = f:section(SimpleSection, translate("5GHz WLAN")) end if p then - --box for the clientnet - o = p:option(Flag, 'clientbox' .. index, "Client-Netz aktivieren") - o.default = (uci:get_bool('wireless', 'client_' .. radio, "disabled")) and o.disabled or o.enabled + --box for the client network + o = p:option(Flag, 'clientbox_' .. radio, translate("Enable client network")) + o.default = uci:get_bool('wireless', 'client_' .. radio, "disabled") and o.disabled or o.enabled o.rmempty = false - --box for the meshnet - o = p:option(Flag, 'meshbox' .. index, "Mesh-Netz aktivieren") - o.default = (uci:get_bool('wireless', 'mesh_' .. radio, "disabled")) and o.disabled or o.enabled + --box for the mesh network + o = p:option(Flag, 'meshbox_' .. radio, translate("Enable mesh network")) + o.default = uci:get_bool('wireless', 'mesh_' .. radio, "disabled") and o.disabled or o.enabled o.rmempty = false end end ---if the save-button is pushed +--when the save-button is pushed function f.handle(self, state, data) if state == FORM_VALID then - for index, radio in ipairs(radios) do + for _, radio in ipairs(radios) do local clientdisabled = 0 local meshdisabled = 0 - -- get the data from the boxes and invert it - if data["clientbox"..index] == '0' then + -- get and invert the data from the boxes + if data["clientbox_"..radio] == '0' then clientdisabled = 1 end -- write the data to the config file uci:set('wireless', 'client_' .. radio, "disabled", clientdisabled) - if data["meshbox"..index] == '0' then - meshdisabled = 1 + if data["meshbox_"..radio] == '0' then + meshdisabled = 1 end uci:set('wireless', 'mesh_' .. radio, "disabled", meshdisabled) diff --git a/package/gluon-luci-wifi-config/i18n/de.po b/package/gluon-luci-wifi-config/i18n/de.po new file mode 100644 index 00000000..6d51ccf1 --- /dev/null +++ b/package/gluon-luci-wifi-config/i18n/de.po @@ -0,0 +1,32 @@ +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"PO-Revision-Date: 2015-05-04 02:54+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" + +msgid "2.4GHz WLAN" +msgstr "2,4GHz-WLAN" + +msgid "5GHz WLAN" +msgstr "5GHz-WLAN" + +msgid "Enable client network" +msgstr "Client-Netz aktivieren" + +msgid "Enable mesh network" +msgstr "Mesh-Netz aktivieren" + +msgid "" +"You can enable or disable your node's client and mesh network SSIDs here. " +"Please don't disable the mesh network without a good reason, so other nodes " +"can mesh with yours." +msgstr "" +"In diesem Abschnitt hast du die Möglichkeit, die SSIDs des Client- und des " +"Mesh-Netzes zu aktivieren bzw. deaktivieren. Bitte lass die SSID des Mesh-" +"Netzes aktiviert, damit sich andere Knoten mit deinem verbinden können." diff --git a/package/gluon-luci-wifi-config/i18n/gluon-luci-wifi-config.pot b/package/gluon-luci-wifi-config/i18n/gluon-luci-wifi-config.pot new file mode 100644 index 00000000..52dd7b66 --- /dev/null +++ b/package/gluon-luci-wifi-config/i18n/gluon-luci-wifi-config.pot @@ -0,0 +1,20 @@ +msgid "" +msgstr "Content-Type: text/plain; charset=UTF-8" + +msgid "2.4GHz WLAN" +msgstr "" + +msgid "5GHz WLAN" +msgstr "" + +msgid "Enable client network" +msgstr "" + +msgid "Enable mesh network" +msgstr "" + +msgid "" +"You can enable or disable your node's client and mesh network SSIDs here. " +"Please don't disable the mesh network without a good reason, so other nodes " +"can mesh with yours." +msgstr "" From a50cce4e0975afb9c93ffa40eb361825d407c394 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sat, 2 May 2015 22:55:23 +0200 Subject: [PATCH 30/62] gluon-mesh-vpn-fastd: make adding or removing the null method survive updates (if desired) --- package/gluon-mesh-vpn-fastd/check_site.lua | 1 + .../lib/gluon/upgrade/400-mesh-vpn-fastd | 30 ++++++++++++++++++- 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/package/gluon-mesh-vpn-fastd/check_site.lua b/package/gluon-mesh-vpn-fastd/check_site.lua index cade1c17..7a2c4913 100644 --- a/package/gluon-mesh-vpn-fastd/check_site.lua +++ b/package/gluon-mesh-vpn-fastd/check_site.lua @@ -1,6 +1,7 @@ need_string_array('fastd_mesh_vpn.methods') need_number('fastd_mesh_vpn.mtu') need_boolean('fastd_mesh_vpn.enabled', false) +need_boolean('fastd_mesh_vpn.configurable', false) local function check_peer(prefix) diff --git a/package/gluon-mesh-vpn-fastd/files/lib/gluon/upgrade/400-mesh-vpn-fastd b/package/gluon-mesh-vpn-fastd/files/lib/gluon/upgrade/400-mesh-vpn-fastd index f370bbf3..316546bc 100755 --- a/package/gluon-mesh-vpn-fastd/files/lib/gluon/upgrade/400-mesh-vpn-fastd +++ b/package/gluon-mesh-vpn-fastd/files/lib/gluon/upgrade/400-mesh-vpn-fastd @@ -5,6 +5,7 @@ local users = require 'gluon.users' local util = require 'gluon.util' local uci = require('luci.model.uci').cursor() +local lutil = require 'luci.util' -- The previously used user is removed, we need root privileges to use the packet_mark option @@ -20,6 +21,33 @@ if not enabled then end +local methods + +if site.fastd_mesh_vpn.configurable then + local has_null = lutil.contains(site.fastd_mesh_vpn.methods, 'null') + + local old_methods = uci:get('fastd', 'mesh_vpn', 'method') + if old_methods then + has_null = lutil.contains(old_methods, 'null') + end + + + methods = {} + if has_null then + table.insert(methods, 'null') + end + + for _, method in ipairs(site.fastd_mesh_vpn.methods) do + if method ~= 'null' then + table.insert(methods, method) + end + end + +else + methods = site.fastd_mesh_vpn.methods +end + + uci:section('fastd', 'fastd', 'mesh_vpn', { enabled = enabled, @@ -29,7 +57,7 @@ uci:section('fastd', 'fastd', 'mesh_vpn', mode = 'tap', mtu = site.fastd_mesh_vpn.mtu, secure_handshakes = 1, - method = site.fastd_mesh_vpn.methods, + method = methods, packet_mark = 1, status_socket = '/var/run/fastd.mesh_vpn.socket', } From ce2f494e0cb41a1f67551127e3e968429211387f Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sun, 3 May 2015 03:51:19 +0200 Subject: [PATCH 31/62] gluon-luci-theme: add cbi-value-field-long class This new class allows visually pleasing lists of radio buttons/checkboxes/etc. with long explanation texts. --- .../files/www/luci-static/gluon/cascade.css | 2 +- package/gluon-luci-theme/sass/cascade.scss | 15 +++++++++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/package/gluon-luci-theme/files/www/luci-static/gluon/cascade.css b/package/gluon-luci-theme/files/www/luci-static/gluon/cascade.css index 66795ea8..eb9833df 100644 --- a/package/gluon-luci-theme/files/www/luci-static/gluon/cascade.css +++ b/package/gluon-luci-theme/files/www/luci-static/gluon/cascade.css @@ -1,2 +1,2 @@ -.lang_he{direction:RTL;unicode-bidi:embed}.hidden{display:none}html{min-height:100%;height:auto;position:relative}body,input,select,option{font-family:'Open Sans', Arial, sans-serif;font-size:12pt}body{color:#4d4e53;line-height:1.5em;margin:0;display:flex;flex-direction:column;min-height:100vh;background-color:#f3f3f3}a img{border:none;text-decoration:none}.tabmenu1{text-align:center}ul.tabmenu{list-style:none;padding:0;margin:2em 0;display:inline-flex}ul.tabmenu li{white-space:nowrap;margin:0 0.5em;padding:0;text-align:center}ul.tabmenu li a{display:block;text-decoration:none;padding:1em;margin:0;color:#333;border-radius:2em}ul.tabmenu li a:hover{background:#ffe9b3}ul.tabmenu li.active a{font-weight:bold;background:white;color:#333}abbr,acronym{font-style:normal;font-variant:normal}abbr[title],acronym[title]{border-bottom:1px dotted;cursor:help}a:link abbr[title],a:visited abbr[title],a:link acronym[title],a:visited acronym[title]{cursor:pointer}code{font-family:monospace;white-space:pre}#maincontent ul{margin-left:2em}.warning{color:red;background-color:white;font-weight:bold}.clear{clear:both}.error{color:#ff0000;background-color:white}div.hostinfo{margin:0;padding:0;font-size:80%;padding:0.5em;flex:1;font-weight:bold}#xhr_poll_status{cursor:pointer}#xhr_poll_status #xhr_poll_status_off{font-weight:bold;color:#FF0000}#xhr_poll_status #xhr_poll_status_on{font-weight:bold;color:#00FF00}#menubar{display:flex;background:#dc0067;color:#ffffff}#menubar .warning{color:red;background-color:#557788}#menubar a:link,#menubar a:visited{position:relative;display:block;padding:0.5em;text-decoration:none;font-size:80%;font-weight:normal;color:white}#menubar a:link:hover,#menubar a:visited:hover,#menubar a:link:focus,#menubar a:visited:focus{background:#ffb400;color:black}#menubar a:link.active,#menubar a:visited.active{background:#ffb400;color:black;font-weight:bold}#menubar a:link.warning,#menubar a:visited.warning{background:#000000;color:red;font-weight:bold}#modemenu{list-style:none;margin:0;padding:0}#modemenu li{display:inline-block}.lang_de #submenu_admin_uci{width:12em}.lang_ru #submenu_admin_uci{width:11.5em}textarea#syslog{width:98%;min-height:500px;border:3px solid #cccccc;padding:5px;font-family:monospace}#maincontent{padding:0 1em 2em;max-width:60em;min-width:40em;margin:1em auto}.lang_he #maincontent{direction:rtl}#maincontent p{margin-bottom:1em}.cbi-section{margin:0;padding:0;border:none}.cbi-section legend{font-size:1.4em;font-weight:bold;position:relative;padding:0;margin-bottom:0.5em}.cbi-section h2{margin:0em 0 0.5em -0.5em !important}.cbi-section h3{text-decoration:none !important;font-weight:bold !important;color:#555555 !important;margin:0.25em !important;font-size:100% !important}.cbi-section-descr{margin-bottom:2em}.cbi-title-ref{color:inherit;text-decoration:none;padding-right:18px;background:url("../resources/cbi/link.gif") no-repeat scroll right center;background-color:inherit}ul.cbi-apply{font-size:90%}input:-webkit-input-placeholder{color:#AAAAAA}input:-moz-placeholder{color:#AAAAAA}input:-ms-input-placeholder{color:#AAAAAA}input[type=checkbox]{display:none}input[type=checkbox]+label{display:inline-block;width:1em;height:1em;margin:0}input[type=checkbox]:checked+label:after{content:'✔';color:#dc0067;vertical-align:middle;position:absolute;top:50%;left:0;margin-top:-0.5em;width:100%;text-align:center;font-size:1.7em}input[type=submit],input[type=reset],input[type=image],input[type=button]{cursor:pointer}select,input,textarea,input[type=checkbox]+label{color:#003247;border:none;background:#ffe199;border-radius:3pt;padding:0.5em}input[type=image]{border:none}select,input[type=text],input[type=password]{width:20em}td select,td input[type=text],td input[type=password]{width:99%}img.cbi-image-button{cursor:pointer;margin:0 2px;vertical-align:middle}input.cbi-button{display:inline-block;zoom:1;line-height:normal;white-space:nowrap;vertical-align:baseline;text-align:center;cursor:pointer;-webkit-user-drag:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;font-size:100%;padding:0.5em 1em;color:rgba(0,0,0,0.8);border:none transparent;background-color:#E6E6E6;text-decoration:none;border-radius:2px;-webkit-transition:0.1s linear -webkit-box-shadow;-moz-transition:0.1s linear -moz-box-shadow;-ms-transition:0.1s linear box-shadow;-o-transition:0.1s linear box-shadow;transition:0.1s linear box-shadow;margin-left:0.5em;background-repeat:no-repeat}input.cbi-button::-moz-focus-inner{padding:0;border:0}input.cbi-button:active{box-shadow:0 0 0 1px rgba(0,0,0,0.15) inset,0 0 6px rgba(0,0,0,0.2) inset}input.cbi-button:focus{outline:0}input.cbi-button:hover,input.cbi-button:focus{background-image:-webkit-gradient(linear, 0 0, 0 100%, from(transparent), color-stop(40%, rgba(0,0,0,0.05)), to(rgba(0,0,0,0.1)));background-image:-webkit-linear-gradient(transparent, rgba(0,0,0,0.05) 40%, rgba(0,0,0,0.1));background-image:-moz-linear-gradient(top, rgba(0,0,0,0.05) 0%, rgba(0,0,0,0.1));background-image:-o-linear-gradient(transparent, rgba(0,0,0,0.05) 40%, rgba(0,0,0,0.1));background-image:linear-gradient(transparent, rgba(0,0,0,0.05) 40%, rgba(0,0,0,0.1))}input.cbi-button[disabled]{border:none;background-image:none;opacity:0.40;cursor:not-allowed;box-shadow:none}input.cbi-input-user{background-image:url("../resources/cbi/user.gif");background-repeat:no-repeat;background-position:1px center;color:#000000;text-indent:17px}input.cbi-input-find,input.cbi-button-find{background-image:url("../resources/cbi/find.gif");color:#000000;padding-left:17px}input.cbi-input-reload{background-image:url("../resources/cbi/reload.gif");color:#000000;padding-left:17px}input.cbi-input-add,input.cbi-button-add{background-image:url("../resources/cbi/add.gif");color:#000000;padding-left:17px;padding-right:1px}input.cbi-input-fieldadd,input.cbi-button-fieldadd{background-image:url(../resources/cbi/fieldadd.gif);color:#000000;padding-left:17px;padding-right:1px}input.cbi-input-reset,input.cbi-button-reset{background-color:#e30;color:#fff}input.cbi-input-save,input.cbi-button-save{background-color:#009ee0;color:#fff}input.cbi-input-apply,input.cbi-button-apply{background-color:#009ee0;color:#fff}input.cbi-input-link,input.cbi-button-link{background-image:url("../resources/cbi/link.gif");color:#000000;padding-left:17px;padding-right:1px}input.cbi-input-download,input.cbi-button-download{background-image:url("../resources/cbi/download.gif");color:#000000;padding-left:17px;padding-right:1px}input.cbi-input-remove,div.cbi-section-remove input{background-image:url("../resources/cbi/remove.gif");color:#000000;padding-left:17px;padding-right:1px}input.cbi-button-up{background-image:url("../resources/cbi/up.gif");padding-left:11px;padding-right:1px}input.cbi-button-down{background-image:url("../resources/cbi/down.gif");padding-left:11px;padding-right:1px}input.cbi-button-edit{background-image:url("../resources/cbi/edit.gif");color:#000000;padding-left:17px;padding-right:1px}input.cbi-button-reload{background-image:url("../resources/cbi/reload.gif");color:#000000;padding-left:17px;padding-right:1px}input.cbi-button-remove{background-image:url("../resources/cbi/remove.gif");color:#000000;padding-left:17px;padding-right:1px}.cbi-input-invalid{background:#e30 !important;color:white}div.cbi-section-remove input{border-bottom:none}textarea{margin-left:-1px;margin-bottom:0.5em}table td,table th{color:#000000}table.smalltext{background:#f5f5f5;color:#000000;border-top:1px solid #666666;border-right:1px solid #666666;border-bottom:1px solid #666666;font-size:90%;width:80%;margin-left:auto;margin-right:auto;border-collapse:collapse}table.smalltext tr:hover td{background-color:#bbddee;color:#000000}table.smalltext tr th{padding:0 0.25em;border-left:1px solid #666666;text-align:left}table.smalltext tr td{padding:0 0.25em;border-top:1px solid #666666;border-left:1px solid #666666}table.cbi-section-table .cbi-rowstyle-1{background-color:#eeeeff;color:#000000}table.cbi-section-table .cbi-rowstyle-1:hover,table.cbi-section-table .cbi-rowstyle-2:hover{background-color:#b2c8d4;color:#000000}table.cbi-section-table .cbi-section-table-cell{padding:3px;white-space:nowrap}.cbi-section .cbi-rowstyle-1 h3{background-color:#eeeeff;color:#555555}.cbi-rowstyle-2{color:#000000}div.cbi-value{display:flex;flex-direction:row;margin-bottom:0.5em}.cbi-value-title{flex:2;text-align:right;padding-right:1em;font-weight:bold}div.cbi-value-field{flex:3;position:relative}div.cbi-value-field input,div.cbi-value-field select,div.cbi-value-field input+label{position:relative;top:-0.39em}div.cbi-value-description{font-size:8pt}div.cbi-section-create{clear:left;white-space:nowrap;vertical-align:top}div.cbi-section-create .cbi-button{margin:0.25em}input.cbi-section-create-name{margin-right:-0.25em}div.cbi-map-descr{margin-bottom:1em}.cbi-map-descr:empty,.cbi-section-descr:empty{display:none}.cbi-map-descr,.cbi-section-descr,.cbi-page-actions{padding:1em;background:#ececec}.cbi-page-actions{text-align:right;display:flex;display:-moz-flex;-moz-flex-flow:row-reverse;flex-flow:row-reverse}div.cbi-optionals{padding:0.25em;border-bottom:1px dotted #bbbbbb}div.cbi-section-remove{float:right}.cbi-section-node{clear:both;position:relative;border:none}.cbi-section-node-tabbed{border-top-left-radius:0}.cbi-section-node .cbi-value-last{border-bottom:none}.cbi-section-node table div{padding-bottom:0;border-bottom:none}.cbi-section-node div.cbi-section-table-row{margin:0.25em}table.cbi-section-table{width:100%;font-size:95%}table.cbi-section-table th,table.cbi-section-table td{text-align:center}tr.cbi-section-table-descr th{font-weight:normal;font-size:90%;vertical-align:top}td.cbi-section-table-optionals{text-align:left !important;padding-top:1em}.cbi-value-helpicon img{display:none}div.cbi-error{font-size:95%;font-weight:bold;color:#ff0000;background-color:#ffffff}td.cbi-value-error{border-color:red}.cbi-value-error input,.cbi-value-error select{background-color:#ffcccc}.cbi-section-error{color:red;background-color:white;font-size:95%;border:1px dotted red;margin:3px;padding:3px}.cbi-value-field var{color:#2222FF}ul.cbi-tabmenu{padding:3px 0;margin-left:0 !important;list-style-type:none;position:relative;z-index:10;top:4px;line-height:20px}ul.cbi-tabmenu li.cbi-tab,ul.cbi-tabmenu li.cbi-tab-disabled{display:inline;margin:0}ul.cbi-tabmenu li.cbi-tab a,ul.cbi-tabmenu li.cbi-tab-disabled a{text-decoration:none;padding:3px 7px;margin-right:3px;border:1px solid #BBBBBB;border-bottom:none;border-radius:3px 3px 0 0;background-color:#EEEEEE;color:#BBBBBB}ul.cbi-tabmenu li.cbi-tab-highlighted a{color:#000000;background-color:#FFEEAA}ul.cbi-tabmenu li a:hover{color:#000000}ul.cbi-tabmenu li.cbi-tab a{padding-top:4px;color:#000000;background-color:#FFFFFF}div.cbi-tab-descr{background-image:url(/luci-static/resources/cbi/help.gif);background-position:0.25em 50%;background-repeat:no-repeat;border-bottom:1px solid #CCCCCC;margin:0.25em 0.25em 2em;padding:0.5em 0.5em 0.5em 2em}.left{text-align:left !important}.right{text-align:right !important}.luci{position:absolute;bottom:0;left:1em;height:1.5em;font-size:80%}.luci a:link,.luci a:visited{background-color:transparent;color:#666666;text-decoration:none;font-size:70%}.inline{display:inline}.error500{white-space:normal;border:1px dotted #ff0000;background-color:#ffffff;color:#000000;padding:0.5em}.errorbox{border:1px solid #FF0000;background-color:#FFCCCC;padding:5px;margin-bottom:5px}.errorbox a{color:#000000 !important}.ifacebox{background-color:#FFFFFF;border:1px solid #CCCCCC;margin:0 10px;text-align:center;white-space:nowrap}.ifacebox .ifacebox-head{border-bottom:1px solid #CCCCCC;padding:2px}.ifacebox .ifacebox-body{padding:2px}.ifacebadge{background-color:#FFFFFF;border:1px solid #CCCCCC;padding:2px;margin-left:2px;display:inline-block}.ifacebadge-active{border-color:#000000;font-weight:bold}.zonebadge{padding:2px;display:inline-block;white-space:nowrap;cursor:pointer}.zonebadge em,.zonebadge strong{margin:3px;display:inline-block}.zonebadge input{width:6em;height:1.5em}.zonebadge-empty{border:1px dashed #AAAAAA;color:#AAAAAA;font-style:italic;font-size:smaller}.uci-change-list{font-family:monospace}.uci-change-list ins,.uci-change-legend-label ins{text-decoration:none;border:1px solid #00FF00;background-color:#CCFFCC;display:block;padding:2px}.uci-change-list del,.uci-change-legend-label del{text-decoration:none;border:1px solid #FF0000;background-color:#FFCCCC;display:block;font-style:normal;padding:2px}.uci-change-list var,.uci-change-legend-label var{text-decoration:none;border:1px solid #CCCCCC;background-color:#EEEEEE;display:block;font-style:normal;padding:2px}.uci-change-list var ins,.uci-change-list var del{border:none;white-space:pre;font-style:normal;padding:0px}.uci-change-legend{padding:5px}.uci-change-legend-label{width:150px;float:left;font-size:80%}.uci-change-legend-label>ins,.uci-change-legend-label>del,.uci-change-legend-label>var{float:left;margin-right:4px;width:10px;height:10px;display:block}.uci-change-legend-label var ins,.uci-change-legend-label var del{line-height:6px;border:none}.cbi-input-password+img{display:none}.the-key{text-align:left;font-size:1.4em;background:#ffe9b3;border:3pt dashed #dc0067;margin-bottom:0.5em;padding:0.5em} +.lang_he{direction:RTL;unicode-bidi:embed}.hidden{display:none}html{min-height:100%;height:auto;position:relative}body,input,select,option{font-family:'Open Sans', Arial, sans-serif;font-size:12pt}body{color:#4d4e53;line-height:1.5em;margin:0;display:flex;flex-direction:column;min-height:100vh;background-color:#f3f3f3}a img{border:none;text-decoration:none}.tabmenu1{text-align:center}ul.tabmenu{list-style:none;padding:0;margin:2em 0;display:inline-flex}ul.tabmenu li{white-space:nowrap;margin:0 0.5em;padding:0;text-align:center}ul.tabmenu li a{display:block;text-decoration:none;padding:1em;margin:0;color:#333;border-radius:2em}ul.tabmenu li a:hover{background:#ffe9b3}ul.tabmenu li.active a{font-weight:bold;background:white;color:#333}abbr,acronym{font-style:normal;font-variant:normal}abbr[title],acronym[title]{border-bottom:1px dotted;cursor:help}a:link abbr[title],a:visited abbr[title],a:link acronym[title],a:visited acronym[title]{cursor:pointer}code{font-family:monospace;white-space:pre}#maincontent ul{margin-left:2em}.warning{color:red;background-color:white;font-weight:bold}.clear{clear:both}.error{color:#ff0000;background-color:white}div.hostinfo{margin:0;padding:0;font-size:80%;padding:0.5em;flex:1;font-weight:bold}#xhr_poll_status{cursor:pointer}#xhr_poll_status #xhr_poll_status_off{font-weight:bold;color:#FF0000}#xhr_poll_status #xhr_poll_status_on{font-weight:bold;color:#00FF00}#menubar{display:flex;background:#dc0067;color:#ffffff}#menubar .warning{color:red;background-color:#557788}#menubar a:link,#menubar a:visited{position:relative;display:block;padding:0.5em;text-decoration:none;font-size:80%;font-weight:normal;color:white}#menubar a:link:hover,#menubar a:visited:hover,#menubar a:link:focus,#menubar a:visited:focus{background:#ffb400;color:black}#menubar a:link.active,#menubar a:visited.active{background:#ffb400;color:black;font-weight:bold}#menubar a:link.warning,#menubar a:visited.warning{background:#000000;color:red;font-weight:bold}#modemenu{list-style:none;margin:0;padding:0}#modemenu li{display:inline-block}.lang_de #submenu_admin_uci{width:12em}.lang_ru #submenu_admin_uci{width:11.5em}textarea#syslog{width:98%;min-height:500px;border:3px solid #cccccc;padding:5px;font-family:monospace}#maincontent{padding:0 1em 2em;max-width:60em;min-width:40em;margin:1em auto}.lang_he #maincontent{direction:rtl}#maincontent p{margin-bottom:1em}.cbi-section{margin:0;padding:0;border:none}.cbi-section legend{font-size:1.4em;font-weight:bold;position:relative;padding:0;margin-bottom:0.5em}.cbi-section h2{margin:0em 0 0.5em -0.5em !important}.cbi-section h3{text-decoration:none !important;font-weight:bold !important;color:#555555 !important;margin:0.25em !important;font-size:100% !important}.cbi-section-descr{margin-bottom:2em}.cbi-title-ref{color:inherit;text-decoration:none;padding-right:18px;background:url("../resources/cbi/link.gif") no-repeat scroll right center;background-color:inherit}ul.cbi-apply{font-size:90%}input:-webkit-input-placeholder{color:#AAAAAA}input:-moz-placeholder{color:#AAAAAA}input:-ms-input-placeholder{color:#AAAAAA}input[type=checkbox]{display:none}input[type=checkbox]+label{display:inline-block;width:1em;height:1em;margin:0}input[type=checkbox]:checked+label:after{content:'✔';color:#dc0067;vertical-align:middle;position:absolute;top:50%;left:0;margin-top:-0.5em;width:100%;text-align:center;font-size:1.7em}input[type=submit],input[type=reset],input[type=image],input[type=button]{cursor:pointer}select,input,textarea,input[type=checkbox]+label{color:#003247;border:none;background:#ffe199;border-radius:3pt;padding:0.5em}input[type=image]{border:none}select,input[type=text],input[type=password]{width:20em}td select,td input[type=text],td input[type=password]{width:99%}img.cbi-image-button{cursor:pointer;margin:0 2px;vertical-align:middle}input.cbi-button{display:inline-block;zoom:1;line-height:normal;white-space:nowrap;vertical-align:baseline;text-align:center;cursor:pointer;-webkit-user-drag:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;font-size:100%;padding:0.5em 1em;color:rgba(0,0,0,0.8);border:none transparent;background-color:#E6E6E6;text-decoration:none;border-radius:2px;-webkit-transition:0.1s linear -webkit-box-shadow;-moz-transition:0.1s linear -moz-box-shadow;-ms-transition:0.1s linear box-shadow;-o-transition:0.1s linear box-shadow;transition:0.1s linear box-shadow;margin-left:0.5em;background-repeat:no-repeat}input.cbi-button::-moz-focus-inner{padding:0;border:0}input.cbi-button:active{box-shadow:0 0 0 1px rgba(0,0,0,0.15) inset,0 0 6px rgba(0,0,0,0.2) inset}input.cbi-button:focus{outline:0}input.cbi-button:hover,input.cbi-button:focus{background-image:-webkit-gradient(linear, 0 0, 0 100%, from(transparent), color-stop(40%, rgba(0,0,0,0.05)), to(rgba(0,0,0,0.1)));background-image:-webkit-linear-gradient(transparent, rgba(0,0,0,0.05) 40%, rgba(0,0,0,0.1));background-image:-moz-linear-gradient(top, rgba(0,0,0,0.05) 0%, rgba(0,0,0,0.1));background-image:-o-linear-gradient(transparent, rgba(0,0,0,0.05) 40%, rgba(0,0,0,0.1));background-image:linear-gradient(transparent, rgba(0,0,0,0.05) 40%, rgba(0,0,0,0.1))}input.cbi-button[disabled]{border:none;background-image:none;opacity:0.40;cursor:not-allowed;box-shadow:none}input.cbi-input-user{background-image:url("../resources/cbi/user.gif");background-repeat:no-repeat;background-position:1px center;color:#000000;text-indent:17px}input.cbi-input-find,input.cbi-button-find{background-image:url("../resources/cbi/find.gif");color:#000000;padding-left:17px}input.cbi-input-reload{background-image:url("../resources/cbi/reload.gif");color:#000000;padding-left:17px}input.cbi-input-add,input.cbi-button-add{background-image:url("../resources/cbi/add.gif");color:#000000;padding-left:17px;padding-right:1px}input.cbi-input-fieldadd,input.cbi-button-fieldadd{background-image:url(../resources/cbi/fieldadd.gif);color:#000000;padding-left:17px;padding-right:1px}input.cbi-input-reset,input.cbi-button-reset{background-color:#e30;color:#fff}input.cbi-input-save,input.cbi-button-save{background-color:#009ee0;color:#fff}input.cbi-input-apply,input.cbi-button-apply{background-color:#009ee0;color:#fff}input.cbi-input-link,input.cbi-button-link{background-image:url("../resources/cbi/link.gif");color:#000000;padding-left:17px;padding-right:1px}input.cbi-input-download,input.cbi-button-download{background-image:url("../resources/cbi/download.gif");color:#000000;padding-left:17px;padding-right:1px}input.cbi-input-remove,div.cbi-section-remove input{background-image:url("../resources/cbi/remove.gif");color:#000000;padding-left:17px;padding-right:1px}input.cbi-button-up{background-image:url("../resources/cbi/up.gif");padding-left:11px;padding-right:1px}input.cbi-button-down{background-image:url("../resources/cbi/down.gif");padding-left:11px;padding-right:1px}input.cbi-button-edit{background-image:url("../resources/cbi/edit.gif");color:#000000;padding-left:17px;padding-right:1px}input.cbi-button-reload{background-image:url("../resources/cbi/reload.gif");color:#000000;padding-left:17px;padding-right:1px}input.cbi-button-remove{background-image:url("../resources/cbi/remove.gif");color:#000000;padding-left:17px;padding-right:1px}.cbi-input-invalid{background:#e30 !important;color:white}div.cbi-section-remove input{border-bottom:none}textarea{margin-left:-1px;margin-bottom:0.5em}table td,table th{color:#000000}table.smalltext{background:#f5f5f5;color:#000000;border-top:1px solid #666666;border-right:1px solid #666666;border-bottom:1px solid #666666;font-size:90%;width:80%;margin-left:auto;margin-right:auto;border-collapse:collapse}table.smalltext tr:hover td{background-color:#bbddee;color:#000000}table.smalltext tr th{padding:0 0.25em;border-left:1px solid #666666;text-align:left}table.smalltext tr td{padding:0 0.25em;border-top:1px solid #666666;border-left:1px solid #666666}table.cbi-section-table .cbi-rowstyle-1{background-color:#eeeeff;color:#000000}table.cbi-section-table .cbi-rowstyle-1:hover,table.cbi-section-table .cbi-rowstyle-2:hover{background-color:#b2c8d4;color:#000000}table.cbi-section-table .cbi-section-table-cell{padding:3px;white-space:nowrap}.cbi-section .cbi-rowstyle-1 h3{background-color:#eeeeff;color:#555555}.cbi-rowstyle-2{color:#000000}div.cbi-value{display:flex;flex-direction:row;margin-bottom:0.5em}.cbi-value-title{flex:2;text-align:right;padding-right:1em;font-weight:bold}div.cbi-value-field{flex:3;position:relative}div.cbi-value-field input,div.cbi-value-field select,div.cbi-value-field input+label{position:relative;top:-0.39em}div.cbi-value-field-long{flex:10;position:relative}div.cbi-value-field-long input,div.cbi-value-field-long select,div.cbi-value-field-long input+label{position:relative;top:-0.39em}div.cbi-value-field-long-after{flex:2}div.cbi-value-description{font-size:8pt}div.cbi-section-create{clear:left;white-space:nowrap;vertical-align:top}div.cbi-section-create .cbi-button{margin:0.25em}input.cbi-section-create-name{margin-right:-0.25em}div.cbi-map-descr{margin-bottom:1em}.cbi-map-descr:empty,.cbi-section-descr:empty{display:none}.cbi-map-descr,.cbi-section-descr,.cbi-page-actions{padding:1em;background:#ececec}.cbi-page-actions{text-align:right;display:flex;display:-moz-flex;-moz-flex-flow:row-reverse;flex-flow:row-reverse}div.cbi-optionals{padding:0.25em;border-bottom:1px dotted #bbbbbb}div.cbi-section-remove{float:right}.cbi-section-node{clear:both;position:relative;border:none}.cbi-section-node-tabbed{border-top-left-radius:0}.cbi-section-node .cbi-value-last{border-bottom:none}.cbi-section-node table div{padding-bottom:0;border-bottom:none}.cbi-section-node div.cbi-section-table-row{margin:0.25em}table.cbi-section-table{width:100%;font-size:95%}table.cbi-section-table th,table.cbi-section-table td{text-align:center}tr.cbi-section-table-descr th{font-weight:normal;font-size:90%;vertical-align:top}td.cbi-section-table-optionals{text-align:left !important;padding-top:1em}.cbi-value-helpicon img{display:none}div.cbi-error{font-size:95%;font-weight:bold;color:#ff0000;background-color:#ffffff}td.cbi-value-error{border-color:red}.cbi-value-error input,.cbi-value-error select{background-color:#ffcccc}.cbi-section-error{color:red;background-color:white;font-size:95%;border:1px dotted red;margin:3px;padding:3px}.cbi-value-field var{color:#2222FF}ul.cbi-tabmenu{padding:3px 0;margin-left:0 !important;list-style-type:none;position:relative;z-index:10;top:4px;line-height:20px}ul.cbi-tabmenu li.cbi-tab,ul.cbi-tabmenu li.cbi-tab-disabled{display:inline;margin:0}ul.cbi-tabmenu li.cbi-tab a,ul.cbi-tabmenu li.cbi-tab-disabled a{text-decoration:none;padding:3px 7px;margin-right:3px;border:1px solid #BBBBBB;border-bottom:none;border-radius:3px 3px 0 0;background-color:#EEEEEE;color:#BBBBBB}ul.cbi-tabmenu li.cbi-tab-highlighted a{color:#000000;background-color:#FFEEAA}ul.cbi-tabmenu li a:hover{color:#000000}ul.cbi-tabmenu li.cbi-tab a{padding-top:4px;color:#000000;background-color:#FFFFFF}div.cbi-tab-descr{background-image:url(/luci-static/resources/cbi/help.gif);background-position:0.25em 50%;background-repeat:no-repeat;border-bottom:1px solid #CCCCCC;margin:0.25em 0.25em 2em;padding:0.5em 0.5em 0.5em 2em}.left{text-align:left !important}.right{text-align:right !important}.luci{position:absolute;bottom:0;left:1em;height:1.5em;font-size:80%}.luci a:link,.luci a:visited{background-color:transparent;color:#666666;text-decoration:none;font-size:70%}.inline{display:inline}.error500{white-space:normal;border:1px dotted #ff0000;background-color:#ffffff;color:#000000;padding:0.5em}.errorbox{border:1px solid #FF0000;background-color:#FFCCCC;padding:5px;margin-bottom:5px}.errorbox a{color:#000000 !important}.ifacebox{background-color:#FFFFFF;border:1px solid #CCCCCC;margin:0 10px;text-align:center;white-space:nowrap}.ifacebox .ifacebox-head{border-bottom:1px solid #CCCCCC;padding:2px}.ifacebox .ifacebox-body{padding:2px}.ifacebadge{background-color:#FFFFFF;border:1px solid #CCCCCC;padding:2px;margin-left:2px;display:inline-block}.ifacebadge-active{border-color:#000000;font-weight:bold}.zonebadge{padding:2px;display:inline-block;white-space:nowrap;cursor:pointer}.zonebadge em,.zonebadge strong{margin:3px;display:inline-block}.zonebadge input{width:6em;height:1.5em}.zonebadge-empty{border:1px dashed #AAAAAA;color:#AAAAAA;font-style:italic;font-size:smaller}.uci-change-list{font-family:monospace}.uci-change-list ins,.uci-change-legend-label ins{text-decoration:none;border:1px solid #00FF00;background-color:#CCFFCC;display:block;padding:2px}.uci-change-list del,.uci-change-legend-label del{text-decoration:none;border:1px solid #FF0000;background-color:#FFCCCC;display:block;font-style:normal;padding:2px}.uci-change-list var,.uci-change-legend-label var{text-decoration:none;border:1px solid #CCCCCC;background-color:#EEEEEE;display:block;font-style:normal;padding:2px}.uci-change-list var ins,.uci-change-list var del{border:none;white-space:pre;font-style:normal;padding:0px}.uci-change-legend{padding:5px}.uci-change-legend-label{width:150px;float:left;font-size:80%}.uci-change-legend-label>ins,.uci-change-legend-label>del,.uci-change-legend-label>var{float:left;margin-right:4px;width:10px;height:10px;display:block}.uci-change-legend-label var ins,.uci-change-legend-label var del{line-height:6px;border:none}.cbi-input-password+img{display:none}.the-key{text-align:left;font-size:1.4em;background:#ffe9b3;border:3pt dashed #dc0067;margin-bottom:0.5em;padding:0.5em} /*# sourceMappingURL=cascade.css.map */ diff --git a/package/gluon-luci-theme/sass/cascade.scss b/package/gluon-luci-theme/sass/cascade.scss index 7c57b2cc..bfcfc58c 100644 --- a/package/gluon-luci-theme/sass/cascade.scss +++ b/package/gluon-luci-theme/sass/cascade.scss @@ -648,6 +648,21 @@ div.cbi-value-field { } } +div.cbi-value-field-long { + flex: 10; + position: relative; + + + input, select, input + label { + position: relative; + top: -0.39em; + } +} + +div.cbi-value-field-long-after { + flex: 2; +} + div.cbi-value-description { font-size: 8pt; } From 76607b007066280cf47abca30130cc630a3096ab Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sun, 3 May 2015 01:47:48 +0200 Subject: [PATCH 32/62] Add new package gluon-luci-mesh-vpn-fastd This new package allows enabling or disabling the null method for the fastd mesh VPN. --- package/gluon-luci-mesh-vpn-fastd/Makefile | 41 +++++++++++++++++++ .../gluon-luci-mesh-vpn-fastd/check_site.lua | 2 + .../luci/controller/admin/mesh_vpn_fastd.lua | 5 +++ .../luci/model/cbi/admin/mesh_vpn_fastd.lua | 41 +++++++++++++++++++ .../view/gluon/cbi/mesh-vpn-fastd-mode.htm | 32 +++++++++++++++ package/gluon-luci-mesh-vpn-fastd/i18n/de.po | 38 +++++++++++++++++ .../i18n/gluon-luci-mesh-vpn-fastd.pot | 23 +++++++++++ 7 files changed, 182 insertions(+) create mode 100644 package/gluon-luci-mesh-vpn-fastd/Makefile create mode 100644 package/gluon-luci-mesh-vpn-fastd/check_site.lua create mode 100644 package/gluon-luci-mesh-vpn-fastd/files/usr/lib/lua/luci/controller/admin/mesh_vpn_fastd.lua create mode 100644 package/gluon-luci-mesh-vpn-fastd/files/usr/lib/lua/luci/model/cbi/admin/mesh_vpn_fastd.lua create mode 100644 package/gluon-luci-mesh-vpn-fastd/files/usr/lib/lua/luci/view/gluon/cbi/mesh-vpn-fastd-mode.htm create mode 100644 package/gluon-luci-mesh-vpn-fastd/i18n/de.po create mode 100644 package/gluon-luci-mesh-vpn-fastd/i18n/gluon-luci-mesh-vpn-fastd.pot diff --git a/package/gluon-luci-mesh-vpn-fastd/Makefile b/package/gluon-luci-mesh-vpn-fastd/Makefile new file mode 100644 index 00000000..1be12ccc --- /dev/null +++ b/package/gluon-luci-mesh-vpn-fastd/Makefile @@ -0,0 +1,41 @@ +include $(TOPDIR)/rules.mk + +PKG_NAME:=gluon-luci-mesh-vpn-fastd +PKG_VERSION:=1 +PKG_RELEASE:=1 + +PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME) + +include $(GLUONDIR)/include/package.mk + +PKG_CONFIG_DEPENDS += $(GLUON_I18N_CONFIG) + +define Package/gluon-luci-mesh-vpn-fastd + SECTION:=gluon + CATEGORY:=Gluon + TITLE:=Luci module to enable and disable encryption for the mesh VPN + DEPENDS:=+gluon-luci-admin +gluon-mesh-vpn-fastd +endef + +define Build/Prepare + mkdir -p $(PKG_BUILD_DIR) +endef + +define Build/Configure +endef + +define Build/Compile + $(call GluonBuildI18N,gluon-mesh-vpn-fastd,i18n) +endef + +define Package/gluon-luci-mesh-vpn-fastd/install + $(CP) ./files/* $(1)/ + $(call GluonInstallI18N,gluon-mesh-vpn-fastd,$(1)) +endef + +define Package/gluon-luci-mesh-vpn-fastd/postinst +#!/bin/sh +$(call GluonCheckSite,check_site.lua) +endef + +$(eval $(call BuildPackage,gluon-luci-mesh-vpn-fastd)) diff --git a/package/gluon-luci-mesh-vpn-fastd/check_site.lua b/package/gluon-luci-mesh-vpn-fastd/check_site.lua new file mode 100644 index 00000000..42ff5a50 --- /dev/null +++ b/package/gluon-luci-mesh-vpn-fastd/check_site.lua @@ -0,0 +1,2 @@ +assert(need_boolean('fastd_mesh_vpn.configurable') == true, + "site.conf error: expected `fastd_mesh_vpn.configurable' to be true") 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/files/usr/lib/lua/luci/controller/admin/mesh_vpn_fastd.lua new file mode 100644 index 00000000..8141c44a --- /dev/null +++ b/package/gluon-luci-mesh-vpn-fastd/files/usr/lib/lua/luci/controller/admin/mesh_vpn_fastd.lua @@ -0,0 +1,5 @@ +module("luci.controller.admin.mesh_vpn_fastd", package.seeall) + +function index() + entry({"admin", "mesh_vpn_fastd"}, cbi("admin/mesh_vpn_fastd"), _("Mesh VPN"), 20) +end 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/files/usr/lib/lua/luci/model/cbi/admin/mesh_vpn_fastd.lua new file mode 100644 index 00000000..14bb5783 --- /dev/null +++ b/package/gluon-luci-mesh-vpn-fastd/files/usr/lib/lua/luci/model/cbi/admin/mesh_vpn_fastd.lua @@ -0,0 +1,41 @@ +local uci = luci.model.uci.cursor() +local util = luci.util + +local f = SimpleForm('mesh_vpn', translate('Mesh VPN')) +f.template = "admin/expertmode" + +local s = f:section(SimpleSection) + +local o = s:option(Value, 'mode') +o.template = "gluon/cbi/mesh-vpn-fastd-mode" + +local methods = uci:get('fastd', 'mesh_vpn', 'method') +if util.contains(methods, 'null') then + o.default = 'performance' +else + o.default = 'security' +end + +function f.handle(self, state, data) + if state == FORM_VALID then + local site = require 'gluon.site_config' + + local methods = {} + if data.mode == 'performance' then + table.insert(methods, 'null') + end + + for _, method in ipairs(site.fastd_mesh_vpn.methods) do + if method ~= 'null' then + table.insert(methods, method) + end + end + + uci:set('fastd', 'mesh_vpn', 'method', methods) + + uci:save('fastd') + uci:commit('fastd') + end +end + +return f diff --git a/package/gluon-luci-mesh-vpn-fastd/files/usr/lib/lua/luci/view/gluon/cbi/mesh-vpn-fastd-mode.htm b/package/gluon-luci-mesh-vpn-fastd/files/usr/lib/lua/luci/view/gluon/cbi/mesh-vpn-fastd-mode.htm new file mode 100644 index 00000000..597cef87 --- /dev/null +++ b/package/gluon-luci-mesh-vpn-fastd/files/usr/lib/lua/luci/view/gluon/cbi/mesh-vpn-fastd-mode.htm @@ -0,0 +1,32 @@ +
+
+ /> +
+
+ class="cbi-value-title"><%:Security mode%> +
+ <%= translate( + 'In security mode, the mesh VPN uses an encrypted tunnel to connect to the VPN servers. ' .. + 'The encryption ensures that it is impossible for your internet access provider to see what ' .. + 'data is exchanged over your node.' + ) %> +
+
+
+
+ +
+
+ /> +
+
+ class="cbi-value-title"><%:Performance mode%> +
+ <%= translate( + 'In performance mode, no encryption is used. This usually allows for higher throughput, but the data exchanged over your node is not ' .. + 'protected against eavesdroppers.' + ) %> +
+
+
+
diff --git a/package/gluon-luci-mesh-vpn-fastd/i18n/de.po b/package/gluon-luci-mesh-vpn-fastd/i18n/de.po new file mode 100644 index 00000000..c8d7ecac --- /dev/null +++ b/package/gluon-luci-mesh-vpn-fastd/i18n/de.po @@ -0,0 +1,38 @@ +msgid "" +msgstr "" +"Content-Type: text/plain; charset=UTF-8\n" +"Project-Id-Version: PACKAGE VERSION\n" +"PO-Revision-Date: 2015-05-03 20:39+0200\n" +"Last-Translator: \n" +"Language-Team: German\n" +"Language: de\n" +"MIME-Version: 1.0\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +msgid "" +"In performance mode, no encryption is used. This usually allows for higher " +"throughput, but the data exchanged over your node is not protected against " +"eavesdroppers." +msgstr "" +"Im Modus „Hohe Geschwindigkeit“ wird auf Verschlüsselung verzichtet. " +"Dies erlaubt häufig eine höhere Bandbreite als mit Verschlüsselung, aber die " +"Verbindung ist nicht gegen Abhören geschützt." + +msgid "" +"In security mode, the mesh VPN uses an encrypted tunnel to connect to the " +"VPN servers. The encryption ensures that it is impossible for your internet " +"access provider to see what data is exchanged over your node." +msgstr "" +"Im Modus „Hohe Sicherheit“ wird ein verschlüsselter Tunnel verwendet. " +"Dies schließt aus, dass dein Internetzugangsprovider herausfinden kann, was für " +"Daten über deinen Knoten übertragen werden." + +msgid "Mesh VPN" +msgstr "Mesh-VPN" + +msgid "Performance mode" +msgstr "Hohe Geschwindigkeit" + +msgid "Security mode" +msgstr "Hohe Sicherheit" diff --git a/package/gluon-luci-mesh-vpn-fastd/i18n/gluon-luci-mesh-vpn-fastd.pot b/package/gluon-luci-mesh-vpn-fastd/i18n/gluon-luci-mesh-vpn-fastd.pot new file mode 100644 index 00000000..77f82b68 --- /dev/null +++ b/package/gluon-luci-mesh-vpn-fastd/i18n/gluon-luci-mesh-vpn-fastd.pot @@ -0,0 +1,23 @@ +msgid "" +msgstr "Content-Type: text/plain; charset=UTF-8" + +msgid "" +"In performance mode, no encryption is used. This usually allows for higher " +"throughput, but the data exchanged over your node is not protected against " +"eavesdroppers." +msgstr "" + +msgid "" +"In security mode, the mesh VPN uses an encrypted tunnel to connect to the " +"VPN servers. The encryption ensures that it is impossible for your internet " +"access provider to see what data is exchanged over your node." +msgstr "" + +msgid "Mesh VPN" +msgstr "" + +msgid "Performance mode" +msgstr "" + +msgid "Security mode" +msgstr "" From 2e5c8f39ccc3583ae39382e60cdfe0bd9d54f152 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sun, 3 May 2015 21:11:12 +0200 Subject: [PATCH 33/62] docs: add some explanations regarding the fastd_mesh_vpn "configurable" setting --- docs/site-example/site.conf | 2 ++ docs/user/site.rst | 13 ++++++++++++- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/docs/site-example/site.conf b/docs/site-example/site.conf index a25857a9..845401c6 100644 --- a/docs/site-example/site.conf +++ b/docs/site-example/site.conf @@ -89,6 +89,8 @@ fastd_mesh_vpn = { -- List of crypto-methods to use. methods = {'salsa2012+umac'}, + -- configurable = true, + mtu = 1426, groups = { backbone = { diff --git a/docs/user/site.rst b/docs/user/site.rst index 689dd51d..11351451 100644 --- a/docs/user/site.rst +++ b/docs/user/site.rst @@ -97,11 +97,22 @@ next_node : package fastd_mesh_vpn - Remote server setup for vpn. + Remote server setup for the fastd-based mesh VPN. + + If `configurable` is false or unset, the method list will be replaced on updates + with the list in the site configuration. Setting `configurable` to `true` will allow the user to + add the method ``null`` to the front of the method list or remove ``null`` from it, + and make this change survive updates. Settings configurable is necessary for the + package `gluon-luci-mesh-vpn-fastd`, which adds a UI for this configuration. + + In any case, the ``null`` method should always be the first method in the list + if it is supported at all. You should only set `configurable` to `true` if the + configured peers support both the ``null`` method and methods with encryption. :: fastd_mesh_vpn = { methods = {'salsa2012+umac'}, + -- configurable = true, mtu = 1426, groups = { backbone = { From 6fc1db3a709e2bfd06ab806d4acfad373a641f87 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Mon, 4 May 2015 04:34:23 +0200 Subject: [PATCH 34/62] gluon-luci-wifi-config: add txpower setting Fixes #219 --- package/gluon-luci-wifi-config/Makefile | 2 +- .../lua/luci/model/cbi/admin/wifi-config.lua | 108 +++++++++++++++--- package/gluon-luci-wifi-config/i18n/de.po | 22 +++- .../i18n/gluon-luci-wifi-config.pot | 11 +- 4 files changed, 122 insertions(+), 21 deletions(-) diff --git a/package/gluon-luci-wifi-config/Makefile b/package/gluon-luci-wifi-config/Makefile index 75e70863..462eab9f 100644 --- a/package/gluon-luci-wifi-config/Makefile +++ b/package/gluon-luci-wifi-config/Makefile @@ -13,7 +13,7 @@ PKG_CONFIG_DEPENDS += $(GLUON_I18N_CONFIG) define Package/gluon-luci-wifi-config SECTION:=gluon CATEGORY:=Gluon - DEPENDS:=+gluon-luci-admin + DEPENDS:=+gluon-luci-admin +libiwinfo-lua TITLE:=UI for Wifi Settings endef 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/files/usr/lib/lua/luci/model/cbi/admin/wifi-config.lua index 1b8ef7c4..720346d3 100644 --- a/package/gluon-luci-wifi-config/files/usr/lib/lua/luci/model/cbi/admin/wifi-config.lua +++ b/package/gluon-luci-wifi-config/files/usr/lib/lua/luci/model/cbi/admin/wifi-config.lua @@ -1,13 +1,54 @@ -local f, s, o local uci = luci.model.uci.cursor() +local fs = require 'nixio.fs' -f = SimpleForm("wifi", translate("WLAN")) + +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 luci.util.trim(fs.readfile(file)) == addr then + return file:match("([^/]+)/macaddress$") + end + end +end + +local function txpower_list(iw) + local list = iw.txpwrlist or { } + local off = tonumber(iw.txpower_offset) or 0 + local new = { } + local prev = -1 + local _, val + for _, val in ipairs(list) do + local dbm = val.dbm + off + local mw = math.floor(10 ^ (dbm / 10)) + if mw ~= prev then + prev = mw + table.insert(new, { + display_dbm = dbm, + display_mw = mw, + driver_dbm = val.dbm, + }) + end + end + return new +end + + +local f = SimpleForm("wifi", translate("WLAN")) f.template = "admin/expertmode" -s = f:section(SimpleSection, nil, translate( +local s = f:section(SimpleSection, nil, translate( "You can enable or disable your node's client and mesh network " .. "SSIDs here. Please don't disable the mesh network without " - .. "a good reason, so other nodes can mesh with yours." + .. "a good reason, so other nodes can mesh with yours.

" + .. "It is also possible to configure the WLAN adapters transmission power " + .. "here. Please note that the transmission power values include the antenna gain " + .. "where available, but there are many devices for which the gain is unavailable or inaccurate." )) local radios = {} @@ -21,24 +62,56 @@ uci:foreach('wireless', 'wifi-device', -- add a client and mesh checkbox for each interface for _, radio in ipairs(radios) do - local hwmode = uci:get('wireless', radio, 'hwmode') + local config = uci:get_all('wireless', radio) local p - if hwmode == '11g' or hwmode == '11ng' then + if config.hwmode == '11g' or config.hwmode == '11ng' then p = f:section(SimpleSection, translate("2.4GHz WLAN")) - elseif hwmode == '11a' or hwmode == '11na' then + elseif config.hwmode == '11a' or config.hwmode == '11na' then p = f:section(SimpleSection, translate("5GHz WLAN")) end if p then + local o + --box for the client network - o = p:option(Flag, 'clientbox_' .. radio, translate("Enable client network")) + o = p:option(Flag, radio .. '_client_enabled', translate("Enable client network")) o.default = uci:get_bool('wireless', 'client_' .. radio, "disabled") and o.disabled or o.enabled o.rmempty = false + --box for the mesh network - o = p:option(Flag, 'meshbox_' .. radio, translate("Enable mesh network")) + o = p:option(Flag, radio .. '_mesh_enabled', translate("Enable mesh network")) o.default = uci:get_bool('wireless', 'mesh_' .. radio, "disabled") and o.disabled or o.enabled o.rmempty = false + + local phy + + if config.path then + phy = find_phy_by_path(config.path) + elseif config.macaddr then + phy = find_phy_by_path(config.macaddr) + end + + if phy then + local iw = luci.sys.wifi.getiwinfo(phy) + if iw then + local txpowers = txpower_list(iw) + + if #txpowers > 1 then + local tp = p:option(ListValue, radio .. '_txpower', translate("Transmission power")) + tp.rmempty = true + tp.default = uci:get('wireless', radio, 'txpower') or 'default' + + tp:value('default', translate("(default)")) + + table.sort(txpowers, function(a, b) return a.driver_dbm > b.driver_dbm end) + + for _, entry in ipairs(txpowers) do + tp:value(entry.driver_dbm, "%i dBm (%i mW)" % {entry.display_dbm, entry.display_mw}) + end + end + end + end end end @@ -50,20 +123,25 @@ function f.handle(self, state, data) for _, radio in ipairs(radios) do local clientdisabled = 0 - local meshdisabled = 0 - -- get and invert the data from the boxes - if data["clientbox_"..radio] == '0' then + if data[radio .. '_client_enabled'] == '0' then clientdisabled = 1 end - -- write the data to the config file uci:set('wireless', 'client_' .. radio, "disabled", clientdisabled) - if data["meshbox_"..radio] == '0' then + local meshdisabled = 0 + if data[radio .. '_client_enabled'] == '0' then meshdisabled = 1 end - uci:set('wireless', 'mesh_' .. radio, "disabled", meshdisabled) + if data[radio .. '_txpower'] then + if data[radio .. '_txpower'] == 'default' then + uci:delete('wireless', radio, 'txpower') + else + uci:set('wireless', radio, 'txpower', data[radio .. '_txpower']) + end + end + end uci:save('wireless') diff --git a/package/gluon-luci-wifi-config/i18n/de.po b/package/gluon-luci-wifi-config/i18n/de.po index 6d51ccf1..d633d84c 100644 --- a/package/gluon-luci-wifi-config/i18n/de.po +++ b/package/gluon-luci-wifi-config/i18n/de.po @@ -10,6 +10,9 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" +msgid "(default)" +msgstr "(Standard)" + msgid "2.4GHz WLAN" msgstr "2,4GHz-WLAN" @@ -22,11 +25,22 @@ msgstr "Client-Netz aktivieren" msgid "Enable mesh network" msgstr "Mesh-Netz aktivieren" +msgid "Transmission power" +msgstr "Sendeleistung" + msgid "" "You can enable or disable your node's client and mesh network SSIDs here. " "Please don't disable the mesh network without a good reason, so other nodes " -"can mesh with yours." +"can mesh with yours.

It is also possible to configure the WLAN " +"adapters transmission power here. Please note that the transmission power " +"values include the antenna gain where available, but there are many devices " +"for which the gain is unavailable or inaccurate." msgstr "" -"In diesem Abschnitt hast du die Möglichkeit, die SSIDs des Client- und des " -"Mesh-Netzes zu aktivieren bzw. deaktivieren. Bitte lass die SSID des Mesh-" -"Netzes aktiviert, damit sich andere Knoten mit deinem verbinden können." +"In diesem Abschnitt hast du die Möglichkeit, die SSIDs des Client- und " +"des Mesh-Netzes zu aktivieren bzw. deaktivieren. Bitte lass die SSID des " +"Mesh-Netzes aktiviert, damit sich andere Knoten mit deinem verbinden " +"können.

" +"Außerdem kann hier die Sendeleistung des WLAN-Adapters konfiguriert werden. " +"Wenn möglich, ist in den Werten der Sendeleistung der Antennengewinn " +"enthalten; diese Werte sind allerdings für viele Geräte nicht verfügbar oder " +"fehlerhaft." diff --git a/package/gluon-luci-wifi-config/i18n/gluon-luci-wifi-config.pot b/package/gluon-luci-wifi-config/i18n/gluon-luci-wifi-config.pot index 52dd7b66..fa61df18 100644 --- a/package/gluon-luci-wifi-config/i18n/gluon-luci-wifi-config.pot +++ b/package/gluon-luci-wifi-config/i18n/gluon-luci-wifi-config.pot @@ -1,6 +1,9 @@ msgid "" msgstr "Content-Type: text/plain; charset=UTF-8" +msgid "(default)" +msgstr "" + msgid "2.4GHz WLAN" msgstr "" @@ -13,8 +16,14 @@ msgstr "" msgid "Enable mesh network" msgstr "" +msgid "Transmission power" +msgstr "" + msgid "" "You can enable or disable your node's client and mesh network SSIDs here. " "Please don't disable the mesh network without a good reason, so other nodes " -"can mesh with yours." +"can mesh with yours.

It is also possible to configure the WLAN " +"adapters transmission power here. Please note that the transmission power " +"values include the antenna gain where available, but there are many devices " +"for which the gain is unavailable or inaccurate." msgstr "" From f4a3f73fcb112cf34b17789ad24020837a9457ef Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Mon, 4 May 2015 04:44:12 +0200 Subject: [PATCH 35/62] gluon-luci-private-wifi: various fixes and cleanup It would be nice to generalize this to work with multiple radios, maybe by integrating it into the wifi-config module... --- .../lua/luci/model/cbi/admin/privatewifi.lua | 26 ++++++++++--------- 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/package/gluon-luci-private-wifi/files/usr/lib/lua/luci/model/cbi/admin/privatewifi.lua b/package/gluon-luci-private-wifi/files/usr/lib/lua/luci/model/cbi/admin/privatewifi.lua index f2f00350..d3ddcd72 100644 --- a/package/gluon-luci-private-wifi/files/usr/lib/lua/luci/model/cbi/admin/privatewifi.lua +++ b/package/gluon-luci-private-wifi/files/usr/lib/lua/luci/model/cbi/admin/privatewifi.lua @@ -21,9 +21,11 @@ o.default = (ssid and not uci:get_bool(config, primary_iface, "disabled")) and o o.rmempty = false o = s:option(Value, "ssid", translate("Name (SSID)")) +o:depends("enabled", '1') 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") @@ -36,20 +38,20 @@ function f.handle(self, state, data) if data.enabled == '1' then -- set up WAN wifi-iface - local t = uci:get_all(config, name) or {} - - t.device = device - t.network = "wan" - t.mode = 'ap' - t.encryption = 'psk2' - t.ssid = data.ssid - t.key = data.key - t.disabled = "false" - - uci:section(config, "wifi-iface", name, t) + uci:section(config, "wifi-iface", name, + { + device = device, + network = "wan", + mode = 'ap', + encryption = 'psk2', + ssid = data.ssid, + key = data.key, + disabled = 0, + } + ) else -- disable WAN wifi-iface - uci:set(config, name, "disabled", "true") + uci:set(config, name, "disabled", 1) end end) From fadfc64e16d738f521d974ce24fd3e361dfa1cae Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Mon, 4 May 2015 19:07:33 +0200 Subject: [PATCH 36/62] gluon-luci-wifi-config: don't use luci.sys.wifi.getiwinfo() Directly using libiwinfo is more reliable. --- .../lua/luci/model/cbi/admin/wifi-config.lua | 28 +++++++++---------- 1 file changed, 13 insertions(+), 15 deletions(-) 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/files/usr/lib/lua/luci/model/cbi/admin/wifi-config.lua index 720346d3..591e944e 100644 --- a/package/gluon-luci-wifi-config/files/usr/lib/lua/luci/model/cbi/admin/wifi-config.lua +++ b/package/gluon-luci-wifi-config/files/usr/lib/lua/luci/model/cbi/admin/wifi-config.lua @@ -1,5 +1,6 @@ local uci = luci.model.uci.cursor() local fs = require 'nixio.fs' +local iwinfo = require 'iwinfo' local function find_phy_by_path(path) @@ -17,9 +18,9 @@ local function find_phy_by_macaddr(macaddr) end end -local function txpower_list(iw) - local list = iw.txpwrlist or { } - local off = tonumber(iw.txpower_offset) or 0 +local function txpower_list(phy) + local list = iwinfo.nl80211.txpwrlist(phy) or { } + local off = tonumber(iwinfo.nl80211.txpower_offset(phy)) or 0 local new = { } local prev = -1 local _, val @@ -93,22 +94,19 @@ for _, radio in ipairs(radios) do end if phy then - local iw = luci.sys.wifi.getiwinfo(phy) - if iw then - local txpowers = txpower_list(iw) + local txpowers = txpower_list(phy) - if #txpowers > 1 then - local tp = p:option(ListValue, radio .. '_txpower', translate("Transmission power")) - tp.rmempty = true - tp.default = uci:get('wireless', radio, 'txpower') or 'default' + if #txpowers > 1 then + local tp = p:option(ListValue, radio .. '_txpower', translate("Transmission power")) + tp.rmempty = true + tp.default = uci:get('wireless', radio, 'txpower') or 'default' - tp:value('default', translate("(default)")) + tp:value('default', translate("(default)")) - table.sort(txpowers, function(a, b) return a.driver_dbm > b.driver_dbm end) + table.sort(txpowers, function(a, b) return a.driver_dbm > b.driver_dbm end) - for _, entry in ipairs(txpowers) do - tp:value(entry.driver_dbm, "%i dBm (%i mW)" % {entry.display_dbm, entry.display_mw}) - end + for _, entry in ipairs(txpowers) do + tp:value(entry.driver_dbm, "%i dBm (%i mW)" % {entry.display_dbm, entry.display_mw}) end end end From a349dd07bd1ab2c84e7a7b215ecb5e55a5e5d845 Mon Sep 17 00:00:00 2001 From: Nils Schneider Date: Sun, 26 Apr 2015 15:16:07 +0200 Subject: [PATCH 37/62] nodeinfo: mesh interface classes (wireless, tunnel, other) This will introduce a new nodeinfo object, network.mesh.bat0.interfaces, containing any of the the following subordinated objects: - wireless - tunnel - other Each of these objects contains a (possibly empty) list of MAC addresses (lowercase, colon-notation) corresponding to a interface of the given class. Combined with a batman graph it is thus possible to mark sub-graphs as "wireless" or "vpn". The previously used object mesh_intefaces is superseded by this new object structure and mesh_interfaces will be removed in a future Gluon release. --- .../nodeinfo.d/network/mesh/bat0/interfaces | 52 +++++++++++++++++++ .../lib/gluon/status-page/www/cgi-bin/status | 20 +++++-- 2 files changed, 69 insertions(+), 3 deletions(-) create mode 100644 package/gluon-mesh-batman-adv-core/files/lib/gluon/announce/nodeinfo.d/network/mesh/bat0/interfaces diff --git a/package/gluon-mesh-batman-adv-core/files/lib/gluon/announce/nodeinfo.d/network/mesh/bat0/interfaces b/package/gluon-mesh-batman-adv-core/files/lib/gluon/announce/nodeinfo.d/network/mesh/bat0/interfaces new file mode 100644 index 00000000..97180b81 --- /dev/null +++ b/package/gluon-mesh-batman-adv-core/files/lib/gluon/announce/nodeinfo.d/network/mesh/bat0/interfaces @@ -0,0 +1,52 @@ +local list = util.exec('batctl if') + +local wireless = {} +local tunnel = {} +local other = {} + +local function get_address(t, ifname) + pcall( + function() + table.insert(t, util.trim(fs.readfile('/sys/class/net/' .. ifname .. '/address'))) + end + ) +end + +local function is_wireless(ifname) + local type = fs.stat('/sys/class/net/' .. ifname .. '/wireless', 'type') + + return type == 'directory' +end + +local function is_tuntap(ifname) + local type = fs.stat('/sys/class/net/' .. ifname .. '/tun_flags', 'type') + + return type == 'regular' +end + +local function nil_table(t) + if next(t) ~= nil then + return t + else + return nil + end +end + +for _, line in ipairs(util.split(list)) do + local ifname = line:match('^(.-):') + if ifname ~= nil then + if is_wireless(ifname) then + get_address(wireless, ifname) + elseif is_tuntap(ifname) then + get_address(tunnel, ifname) + else + get_address(other, ifname) + end + end +end + +return { + wireless = nil_table(wireless), + tunnel = nil_table(tunnel), + other = nil_table(other) +} diff --git a/package/gluon-status-page/files/lib/gluon/status-page/www/cgi-bin/status b/package/gluon-status-page/files/lib/gluon/status-page/www/cgi-bin/status index 23e612d3..771bdaba 100755 --- a/package/gluon-status-page/files/lib/gluon/status-page/www/cgi-bin/status +++ b/package/gluon-status-page/files/lib/gluon/status-page/www/cgi-bin/status @@ -22,9 +22,23 @@ function neighbours(ifname) for _, line in ipairs(util.split(info)) do local data = json.decode(line) if data then - if data["network"] and data["network"]["mesh_interfaces"] then - for _, mac in ipairs(data["network"]["mesh_interfaces"]) do - macs[mac] = data + local function add_macs(list) + if list then + for _, mac in ipairs(list) do + macs[mac] = data + end + end + end + + if data["network"] then + add_macs(data["network"]["mesh_interfaces"]) + + if data["network"]["mesh"] and data["network"]["mesh"]["bat0"] and + data["network"]["mesh"]["bat0"]["interfaces"] then + local interfaces = data["network"]["mesh"]["bat0"]["interfaces"] + add_macs(interfaces["other"]) + add_macs(interfaces["wireless"]) + add_macs(interfaces["tunnel"]) end end end From 3f80b6585647dce960325c3df46b4407a00bca7f Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Mon, 4 May 2015 20:47:26 +0200 Subject: [PATCH 38/62] iwinfo: update NanoStation (Loco) txpower offsets --- ...ate-NanoStation-Loco-txpower-offsets.patch | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 patches/openwrt/0035-iwinfo-update-NanoStation-Loco-txpower-offsets.patch diff --git a/patches/openwrt/0035-iwinfo-update-NanoStation-Loco-txpower-offsets.patch b/patches/openwrt/0035-iwinfo-update-NanoStation-Loco-txpower-offsets.patch new file mode 100644 index 00000000..0b5e1861 --- /dev/null +++ b/patches/openwrt/0035-iwinfo-update-NanoStation-Loco-txpower-offsets.patch @@ -0,0 +1,20 @@ +From: Matthias Schiffer +Date: Mon, 4 May 2015 20:38:37 +0200 +Subject: iwinfo: update NanoStation (Loco) txpower offsets + +diff --git a/package/network/utils/iwinfo/src/hardware.txt b/package/network/utils/iwinfo/src/hardware.txt +index 153ffeb..b8dfc51 100644 +--- a/package/network/utils/iwinfo/src/hardware.txt ++++ b/package/network/utils/iwinfo/src/hardware.txt +@@ -42,8 +42,9 @@ + 0x168c 0x0027 0x0777 0x4082 7 0 "Ubiquiti" "SR71" + 0x168c 0x0029 0x0777 0x4005 7 0 "Ubiquiti" "SR71-15" + 0x168c 0x002a 0x0777 0xe302 12 0 "Ubiquiti" "PicoStation M2" /* ToDo: confirm offset */ +-0x168c 0x002a 0x0777 0xe012 12 0 "Ubiquiti" "NanoStation M2" /* ToDo: confirm offset */ +-0x168c 0x002a 0x0777 0xe005 5 0 "Ubiquiti" "NanoStation M5" /* ToDo: confirm offset */ ++0x168c 0x002a 0x0777 0xe012 11 0 "Ubiquiti" "NanoStation M2" ++0x168c 0x002e 0x0777 0xe0a2 8 0 "Ubiquiti" "NanoStation Loco M2" ++0x168c 0x002a 0x0777 0xe005 16 0 "Ubiquiti" "NanoStation M5" + 0x168c 0x002a 0x0777 0xe202 12 0 "Ubiquiti" "Bullet M2" + 0x168c 0x002a 0x0777 0xe805 5 0 "Ubiquiti" "Bullet M5" + 0x168c 0x002a 0x0777 0xe345 0 0 "Ubiquiti" "WispStation M5" /* ToDo: confirm offset */ From 39d0c8f45949b06ece9db05a82341acc4d638980 Mon Sep 17 00:00:00 2001 From: Nils Schneider Date: Mon, 4 May 2015 21:18:58 +0200 Subject: [PATCH 39/62] mesh-batman-adv: mesh_on_lan This adds mesh_on_lan functionality. A new optional site.conf option, mesh_on_lan, has been added. If set to 'true', all LAN ports will be used for meshing instead of being part of the client bridge. --- docs/user/site.rst | 3 +++ .../gluon-mesh-batman-adv-core/check_site.lua | 1 + .../310-gluon-mesh-batman-adv-core-mesh | 3 ++- ...340-gluon-mesh-batman-adv-core-mesh-on-lan | 23 +++++++++++++++++++ 4 files changed, 29 insertions(+), 1 deletion(-) create mode 100755 package/gluon-mesh-batman-adv-core/files/lib/gluon/upgrade/340-gluon-mesh-batman-adv-core-mesh-on-lan diff --git a/docs/user/site.rst b/docs/user/site.rst index 689dd51d..68705ce4 100644 --- a/docs/user/site.rst +++ b/docs/user/site.rst @@ -119,6 +119,9 @@ fastd_mesh_vpn mesh_on_wan : optional Enables the mesh on the WAN port (``true`` or ``false``). +mesh_on_lan : optional + Enables the mesh on the LAN port (``true`` or ``false``). + autoupdater : package Configuration for the autoupdater feature of Gluon. :: diff --git a/package/gluon-mesh-batman-adv-core/check_site.lua b/package/gluon-mesh-batman-adv-core/check_site.lua index baed26cb..e76ca9e9 100644 --- a/package/gluon-mesh-batman-adv-core/check_site.lua +++ b/package/gluon-mesh-batman-adv-core/check_site.lua @@ -13,3 +13,4 @@ for _, config in ipairs({'wifi24', 'wifi5'}) do end need_boolean('mesh_on_wan', false) +need_boolean('mesh_on_lan', false) 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/files/lib/gluon/upgrade/310-gluon-mesh-batman-adv-core-mesh index c9638c4b..a51b20e2 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/files/lib/gluon/upgrade/310-gluon-mesh-batman-adv-core-mesh @@ -2,6 +2,7 @@ local sysconfig = require 'gluon.sysconfig' local sysctl = require 'gluon.sysctl' +local site = require 'gluon.site_config' local uci = require('luci.model.uci').cursor() @@ -20,7 +21,7 @@ uci:commit('batman-adv') if not uci:get('network', 'client') then local ifname - if sysconfig.lan_ifname then + if sysconfig.lan_ifname and not site.mesh_on_lan then ifname = sysconfig.lan_ifname .. ' bat0' else ifname = 'bat0' 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-mesh-batman-adv-core/files/lib/gluon/upgrade/340-gluon-mesh-batman-adv-core-mesh-on-lan new file mode 100755 index 00000000..f9cbde03 --- /dev/null +++ b/package/gluon-mesh-batman-adv-core/files/lib/gluon/upgrade/340-gluon-mesh-batman-adv-core-mesh-on-lan @@ -0,0 +1,23 @@ +#!/usr/bin/lua + +local site = require 'gluon.site_config' +local uci = require 'luci.model.uci' +local util = require 'gluon.util' +local sysconfig = require 'gluon.sysconfig' + +local c = uci.cursor() + +if sysconfig.lan_ifname then + if not c:get('network', 'mesh_lan') then + c:section('network', 'interface', 'mesh_lan', + { ifname = sysconfig.lan_ifname + , proto = 'batadv' + , mesh = 'bat0' + , macaddr = util.generate_mac(1, 1) + , auto = site.mesh_on_lan and 1 or 0 + }) + end +end + +c:save('network') +c:commit('network') From d4c3467bc336581eb9ac9db77277d9d82b8ac9b6 Mon Sep 17 00:00:00 2001 From: Nils Schneider Date: Mon, 4 May 2015 21:18:58 +0200 Subject: [PATCH 40/62] luci-portconfig: allow toggling of mesh_on_lan --- .../lua/luci/model/cbi/admin/portconfig.lua | 18 ++++++++++++++++++ package/gluon-luci-portconfig/i18n/de.po | 3 +++ .../i18n/gluon-luci-portconfig.pot | 3 +++ 3 files changed, 24 insertions(+) diff --git a/package/gluon-luci-portconfig/files/usr/lib/lua/luci/model/cbi/admin/portconfig.lua b/package/gluon-luci-portconfig/files/usr/lib/lua/luci/model/cbi/admin/portconfig.lua index ccade674..8166539c 100644 --- a/package/gluon-luci-portconfig/files/usr/lib/lua/luci/model/cbi/admin/portconfig.lua +++ b/package/gluon-luci-portconfig/files/usr/lib/lua/luci/model/cbi/admin/portconfig.lua @@ -13,6 +13,7 @@ $Id$ ]]-- local uci = luci.model.uci.cursor() +local sysconfig = require 'gluon.sysconfig' local wan = uci:get_all("network", "wan") local wan6 = uci:get_all("network", "wan6") @@ -86,6 +87,13 @@ o = s:option(Flag, "mesh_wan", translate("Enable meshing on the WAN interface")) o.default = uci:get_bool("network", "mesh_wan", "auto") and o.enabled or o.disabled o.rmempty = false +if sysconfig.lan_ifname then + o = s:option(Flag, "mesh_lan", translate("Enable meshing on the LAN interface")) + o.default = uci:get_bool("network", "mesh_lan", "auto") and o.enabled or o.disabled + o.rmempty = false +end + + function f.handle(self, state, data) if state == FORM_VALID then uci:set("network", "wan", "proto", data.ipv4) @@ -110,6 +118,16 @@ function f.handle(self, state, data) uci:set("network", "mesh_wan", "auto", data.mesh_wan) + if sysconfig.lan_ifname then + uci:set("network", "mesh_lan", "auto", data.mesh_lan) + + if data.mesh_lan == '1' then + uci:set("network", "client", "ifname", "bat0") + else + uci:set("network", "client", "ifname", sysconfig.lan_ifname .. " bat0") + end + end + uci:save("network") uci:commit("network") diff --git a/package/gluon-luci-portconfig/i18n/de.po b/package/gluon-luci-portconfig/i18n/de.po index 6cc06e20..2197fdbe 100644 --- a/package/gluon-luci-portconfig/i18n/de.po +++ b/package/gluon-luci-portconfig/i18n/de.po @@ -19,6 +19,9 @@ msgstr "Automatisch (RA/DHCPv6)" msgid "Enable meshing on the WAN interface" msgstr "Mesh auf dem WAN-Port aktivieren" +msgid "Enable meshing on the LAN interface" +msgstr "Mesh auf dem LAN-Port aktivieren" + msgid "Static" msgstr "Statisch" diff --git a/package/gluon-luci-portconfig/i18n/gluon-luci-portconfig.pot b/package/gluon-luci-portconfig/i18n/gluon-luci-portconfig.pot index 1800f8d0..31ac71d3 100644 --- a/package/gluon-luci-portconfig/i18n/gluon-luci-portconfig.pot +++ b/package/gluon-luci-portconfig/i18n/gluon-luci-portconfig.pot @@ -10,6 +10,9 @@ msgstr "" msgid "Enable meshing on the WAN interface" msgstr "" +msgid "Enable meshing on the LAN interface" +msgstr "" + msgid "Static" msgstr "" From 6d2741c0248d67cf3d27743cdb16a7a4f0ed28fb Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Thu, 7 May 2015 02:23:32 +0200 Subject: [PATCH 41/62] gluon-luci-mesh-vpn-fastd: minor text change --- .../luci/view/gluon/cbi/mesh-vpn-fastd-mode.htm | 2 +- package/gluon-luci-mesh-vpn-fastd/i18n/de.po | 16 ++++++++-------- .../i18n/gluon-luci-mesh-vpn-fastd.pot | 2 +- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/package/gluon-luci-mesh-vpn-fastd/files/usr/lib/lua/luci/view/gluon/cbi/mesh-vpn-fastd-mode.htm b/package/gluon-luci-mesh-vpn-fastd/files/usr/lib/lua/luci/view/gluon/cbi/mesh-vpn-fastd-mode.htm index 597cef87..0899fa1d 100644 --- a/package/gluon-luci-mesh-vpn-fastd/files/usr/lib/lua/luci/view/gluon/cbi/mesh-vpn-fastd-mode.htm +++ b/package/gluon-luci-mesh-vpn-fastd/files/usr/lib/lua/luci/view/gluon/cbi/mesh-vpn-fastd-mode.htm @@ -24,7 +24,7 @@
<%= translate( 'In performance mode, no encryption is used. This usually allows for higher throughput, but the data exchanged over your node is not ' .. - 'protected against eavesdroppers.' + 'protected against eavesdropping.' ) %>
diff --git a/package/gluon-luci-mesh-vpn-fastd/i18n/de.po b/package/gluon-luci-mesh-vpn-fastd/i18n/de.po index c8d7ecac..12e48439 100644 --- a/package/gluon-luci-mesh-vpn-fastd/i18n/de.po +++ b/package/gluon-luci-mesh-vpn-fastd/i18n/de.po @@ -1,32 +1,32 @@ msgid "" msgstr "" -"Content-Type: text/plain; charset=UTF-8\n" "Project-Id-Version: PACKAGE VERSION\n" "PO-Revision-Date: 2015-05-03 20:39+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" msgid "" "In performance mode, no encryption is used. This usually allows for higher " "throughput, but the data exchanged over your node is not protected against " -"eavesdroppers." +"eavesdropping." msgstr "" -"Im Modus „Hohe Geschwindigkeit“ wird auf Verschlüsselung verzichtet. " -"Dies erlaubt häufig eine höhere Bandbreite als mit Verschlüsselung, aber die " -"Verbindung ist nicht gegen Abhören geschützt." +"Im Modus „Hohe Geschwindigkeit“ wird auf Verschlüsselung " +"verzichtet. Dies erlaubt häufig eine höhere Bandbreite als mit " +"Verschlüsselung, aber die Verbindung ist nicht gegen Abhören geschützt." msgid "" "In security mode, the mesh VPN uses an encrypted tunnel to connect to the " "VPN servers. The encryption ensures that it is impossible for your internet " "access provider to see what data is exchanged over your node." msgstr "" -"Im Modus „Hohe Sicherheit“ wird ein verschlüsselter Tunnel verwendet. " -"Dies schließt aus, dass dein Internetzugangsprovider herausfinden kann, was für " -"Daten über deinen Knoten übertragen werden." +"Im Modus „Hohe Sicherheit“ wird ein verschlüsselter Tunnel " +"verwendet. Dies schließt aus, dass dein Internetzugangsprovider herausfinden " +"kann, was für Daten über deinen Knoten übertragen werden." msgid "Mesh VPN" msgstr "Mesh-VPN" diff --git a/package/gluon-luci-mesh-vpn-fastd/i18n/gluon-luci-mesh-vpn-fastd.pot b/package/gluon-luci-mesh-vpn-fastd/i18n/gluon-luci-mesh-vpn-fastd.pot index 77f82b68..878a1959 100644 --- a/package/gluon-luci-mesh-vpn-fastd/i18n/gluon-luci-mesh-vpn-fastd.pot +++ b/package/gluon-luci-mesh-vpn-fastd/i18n/gluon-luci-mesh-vpn-fastd.pot @@ -4,7 +4,7 @@ msgstr "Content-Type: text/plain; charset=UTF-8" msgid "" "In performance mode, no encryption is used. This usually allows for higher " "throughput, but the data exchanged over your node is not protected against " -"eavesdroppers." +"eavesdropping." msgstr "" msgid "" From e51560beb70a594c27dd416cd27075697450a61d Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Thu, 7 May 2015 03:08:22 +0200 Subject: [PATCH 42/62] Update OpenWrt base --- modules | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules b/modules index 3e3927fd..4776b64f 100644 --- a/modules +++ b/modules @@ -1,7 +1,7 @@ GLUON_FEEDS='openwrt gluon routing luci' OPENWRT_REPO=git://git.openwrt.org/14.07/openwrt.git -OPENWRT_COMMIT=229d60fdb45c34902d402938e231c006f7c73931 +OPENWRT_COMMIT=179bab8b1700d74b28cc6cd25322f9a1ad670107 PACKAGES_OPENWRT_REPO=git://github.com/openwrt/packages.git PACKAGES_OPENWRT_COMMIT=01fcd1f29174a56d6ddb59901ed8c67ea42c3a8f From e8a483c9a1ac3b7bc33b03a7b4d1fad92e4088ac Mon Sep 17 00:00:00 2001 From: Nils Schneider Date: Sat, 9 May 2015 22:10:32 +0200 Subject: [PATCH 43/62] luci-wifi-config: don't disable mesh interface fixes #365 --- .../files/usr/lib/lua/luci/model/cbi/admin/wifi-config.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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/files/usr/lib/lua/luci/model/cbi/admin/wifi-config.lua index 591e944e..66393961 100644 --- a/package/gluon-luci-wifi-config/files/usr/lib/lua/luci/model/cbi/admin/wifi-config.lua +++ b/package/gluon-luci-wifi-config/files/usr/lib/lua/luci/model/cbi/admin/wifi-config.lua @@ -127,7 +127,7 @@ function f.handle(self, state, data) uci:set('wireless', 'client_' .. radio, "disabled", clientdisabled) local meshdisabled = 0 - if data[radio .. '_client_enabled'] == '0' then + if data[radio .. '_mesh_enabled'] == '0' then meshdisabled = 1 end uci:set('wireless', 'mesh_' .. radio, "disabled", meshdisabled) From dcdb99fb9d337df4f8fb5458f2b6c5b84e3f90b8 Mon Sep 17 00:00:00 2001 From: Alex Date: Sun, 10 May 2015 12:07:52 +0200 Subject: [PATCH 44/62] docs: add WNDRMACv2 to list of supported devices --- docs/index.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/index.rst b/docs/index.rst index bba84aad..46e6cfce 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -87,6 +87,7 @@ ar71xx-generic - WNDR3700 (v1, v2) - WNDR3800 + - WNDRMAC (v2) * TP-Link From 10580d59e84d37cb573c7c3c89136d8846317133 Mon Sep 17 00:00:00 2001 From: hexa- Date: Mon, 11 May 2015 16:26:06 +0200 Subject: [PATCH 45/62] docs/autoupdater: depends on ipv6 reachable update-servers --- docs/features/autoupdater.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/features/autoupdater.rst b/docs/features/autoupdater.rst index 983027de..fdc511d9 100644 --- a/docs/features/autoupdater.rst +++ b/docs/features/autoupdater.rst @@ -54,7 +54,7 @@ We suggest to have following directory tree accessible via http: sysupgrade/ factory/ -The server should be available via IPv6. +The server must be available via IPv6. Command Line ------------ From 548c70d170a66ce82058f53cb11d403439c7324c Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Thu, 14 May 2015 02:13:01 +0200 Subject: [PATCH 46/62] docs: mention fastd_mesh_vpn.enabled setting --- docs/site-example/site.conf | 1 + docs/user/site.rst | 5 ++++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/docs/site-example/site.conf b/docs/site-example/site.conf index 845401c6..310f8bc5 100644 --- a/docs/site-example/site.conf +++ b/docs/site-example/site.conf @@ -89,6 +89,7 @@ fastd_mesh_vpn = { -- List of crypto-methods to use. methods = {'salsa2012+umac'}, + -- enabled = true, -- configurable = true, mtu = 1426, diff --git a/docs/user/site.rst b/docs/user/site.rst index a5b31745..acbcb877 100644 --- a/docs/user/site.rst +++ b/docs/user/site.rst @@ -99,7 +99,9 @@ next_node : package fastd_mesh_vpn Remote server setup for the fastd-based mesh VPN. - If `configurable` is false or unset, the method list will be replaced on updates + The `enabled` option can be set to true to enable the VPN by default. + + If `configurable` is `false` or unset, the method list will be replaced on updates with the list in the site configuration. Setting `configurable` to `true` will allow the user to add the method ``null`` to the front of the method list or remove ``null`` from it, and make this change survive updates. Settings configurable is necessary for the @@ -112,6 +114,7 @@ fastd_mesh_vpn fastd_mesh_vpn = { methods = {'salsa2012+umac'}, + -- enabled = true, -- configurable = true, mtu = 1426, groups = { From acefefd2fafd21f9ca94792f0bd5e0627102a188 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sat, 16 May 2015 00:23:12 +0200 Subject: [PATCH 47/62] docs: hardware support list fixes --- docs/index.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/index.rst b/docs/index.rst index 46e6cfce..5fc679a0 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -77,7 +77,7 @@ ar71xx-generic * GL-Inet - 6408A (v1) - - 6416a (v1) + - 6416A (v1) * Linksys @@ -137,7 +137,7 @@ ar71xx-nand * Netgear - WNDR3700 (v4) - - WNDR3700 (v1) + - WNDR4300 (v1) mpc85xx-generic ^^^^^^^^^^^^^^^ From df4ec226b4cecf24575a08968313cbb8bba40daf Mon Sep 17 00:00:00 2001 From: Nils Schneider Date: Mon, 4 May 2015 19:37:53 +0200 Subject: [PATCH 48/62] docs/site-example: explain how to re-enter configmode Fixes #347 --- docs/site-example/i18n/de.po | 3 +++ docs/site-example/i18n/en.po | 3 +++ 2 files changed, 6 insertions(+) diff --git a/docs/site-example/i18n/de.po b/docs/site-example/i18n/de.po index 271172a4..ce27c813 100644 --- a/docs/site-example/i18n/de.po +++ b/docs/site-example/i18n/de.po @@ -32,4 +32,7 @@ msgstr "" "verbinden. Weitere Informationen zur " "Entenhausener Freifunk-Community findest du auf " "unserer Webseite.

" +"

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

" "

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

" diff --git a/docs/site-example/i18n/en.po b/docs/site-example/i18n/en.po index bfbbc882..dedc06e1 100644 --- a/docs/site-example/i18n/en.po +++ b/docs/site-example/i18n/en.po @@ -30,4 +30,7 @@ msgstr "" "nearby Freifunk nodes after that. " "Your can find lots of information on the Freifunk Duckburg community on " "our homepage.

" +"

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

" "

Have fun with your node and exploring the Freifunk network!

" From 75f4483a6adcb6cac65e271ff1cb9c91f82403b4 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sat, 16 May 2015 13:01:05 +0200 Subject: [PATCH 49/62] Preliminary v2015.1 release notes --- docs/releases/v2015.1.rst | 183 +++++++++++++++++++++++++++++++++++++- docs/user/site.rst | 2 + 2 files changed, 184 insertions(+), 1 deletion(-) diff --git a/docs/releases/v2015.1.rst b/docs/releases/v2015.1.rst index a086dc7e..3ff4d228 100644 --- a/docs/releases/v2015.1.rst +++ b/docs/releases/v2015.1.rst @@ -3,14 +3,157 @@ Gluon 2015.1 (in development) Added (and removed) hardware support ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Gluon v2015.1 is the first release to officially support hardware +that is not handled by the `ar71xx-generic` OpenWrt target. This also +means that `ar71xx-generic` isn't the default target anymore, the ``GLUON_TARGET`` +variable must be set for all runs of ``make`` and ``make clean`` now. + +ar71xx-generic +^^^^^^^^^^^^^^ + +* Allnet + + - ALL0315N + +* D-Link + + - DIR-615 (C1) + +* GL-Inet + + - 6408A (v1) + - 6416A (v1) + + - WRT160NL + +* Netgear + + - WNDR3700 (v1, v2) + - WNDR3800 + - WNDRMAC (v2) + +* TP-Link + + - TL-MR3220 (v2) + - TL-WA701N/ND (v1) + - TL-WA860RE (v1) + - TL-WA901N/ND (v2, v3) + - TL-WR743N/ND (v1, v2) + - TL-WR941N/ND (v5) + - TL-WR2543N/ND (v1) + +* Ubiquiti + + - Nanostation M XW + - Loco M XW + - UniFi AP Pro + +ar71xx-nand +^^^^^^^^^^^ + +* Netgear + + - WNDR3700 (v4) + - WNDR4300 (v1) + +mpc85xx-generic +^^^^^^^^^^^^^^^ + +* TP-Link + + - TL-WDR4900 (v1) + +x86-generic +^^^^^^^^^^^ +* x86-generic +* x86-virtualbox +* x86-vmware + +x86-kvm_guest +^^^^^^^^^^^^^ +* x86-kvm New features ~~~~~~~~~~~~ +Multilingual config mode +^^^^^^^^^^^^^^^^^^^^^^^^ +All config and expert mode modules contain both English and German texts now. The English +locale should always be enabled in ``site.mk`` (as English is the fallback language), +German can be enabled in addition using the ``GLUON_LANGS`` setting. +The language shown is autmatically determined from the headers sent by the user's +browser. + +Mesh-on-LAN +^^^^^^^^^^^ +Gluon now supports meshing using a node's LAN ports. It can be enabled by +default in `site.conf`, and configured by the user using the `gluon-luci-portconfig` +expert mode package. + +Please note that nodes without the `mesh-on-lan` feature enabled must never be connected +via their LAN ports. + +Extended WLAN configuration +^^^^^^^^^^^^^^^^^^^^^^^^^^^ +The new ``client_disabled`` and ``mesh_disabled`` keys in the ``wifi24`` and ``wifi5`` sections allow +to disable the client and mesh networks by default, which may make sense for images for +special installations. + +The new package `gluon-luci-wifi-config` allows the user to change these settings; in addition, +the WLAN adapters' transmission power can be changed in this package. + +fastd "performance mode" +^^^^^^^^^^^^^^^^^^^^^^^^ +The new package `gluon-luci-mesh-vpn-fastd` allows the user to switch between the `security` and +`performance` VPN settions. In `performance mode`, the method `null` will be prepended to the +method list. + +The new option ``configurable`` in the ``fastd_mesh_vpn`` section of ``site.conf`` must be set to `true` +so firmware upgrades don't overwrite the method list completely (non-`null` methods will still +be overwritten). Adding the `gluon-luci-mesh-vpn-fastd` package enforces this setting. + +Altitude setting in `gluon-config-mode-geo-location` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +The `gluon-config-mode-geo-location` config mode module +now contains an optional altitude field. + +`gluon-announced` rework +^^^^^^^^^^^^^^^^^^^^^^^^ +The `gluon-announced` package has been reworked to allow querying it from anywhere in the mesh. +In contrast to `gluon-alfred`, it is based on a query-response model (the master multicasts a query, +the nodes respond), while `gluon-alfred` uses periodic announcements. + +For now, we recommend including both `gluon-alfred` and `gluon-announced` in Gluon-based firmwares, +until `gluon-announced` is ready to replace `gluon-alfred` completely, and software like the +ffmap backend has been adjusted accordingly. + +Nested peer groups +^^^^^^^^^^^^^^^^^^ +Nested peer groups for the `fastd-mesh-vpn-fastd` package can now be configured in ``site.conf``, +each with its own peer limit. This allows to add additional constaints, for example to connect +to 2 peers altogether, but only 1 peer in each data center. + +Autoupdater manual branch override +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +When running the updater manually on the command line, the branch to use can now be +overridden using the ``-b`` option. Bugfixes ~~~~~~~~ +Accidental factory reset fix +^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Pressing a node's reset button for more than 5 seconds would completely reset a node's +configuration under certain conditions. + +WAN IPv6 issues +^^^^^^^^^^^^^^^ +The WAN port would stop to respond to IPv6 packets sometimes, also breaking IPv6 VPN connectivity. + +WDR4900 WAN MAC address +^^^^^^^^^^^^^^^^^^^^^^^ +The MAC address on the WAN port of the WDR4900 was broken, making this device unusable for `mesh-on-wan` +configurations. Site changes @@ -39,6 +182,10 @@ Site changes } } + - ``config_mode``: The config mode messages aren't configured in ``site.conf`` anymore. Instead, they are + defined language-specific gettext files in the ``i18n`` subdirectory of the site configuration (see + :ref:`site-config-mode-texts`). + - ``roles``: The display strings for the node roles aren't configured in the ``site.conf`` anymore, but in the site i18n files. The ``site.conf`` section becomes:: @@ -52,7 +199,6 @@ Site changes The display string use i18n message IDs like ``gluon-luci-node-role:role:foo`` and ``gluon-luci-node-role:role:bar``. - * ``site.mk`` - ``gluon-mesh-batman-adv-15`` is now the recommended batman-adv version for new Gluon deployments. @@ -61,9 +207,44 @@ Site changes added to ``GLUON_SITE_PACKAGES`` explicitly (to allow replacing them with community-specific implementations). + - The new ``GLUON_LANGS`` variable selects the config mode languages to include. It defaults to ``en``, + setting it to ``en de`` will select both the English and German locales. ``en`` must always be + included. + Internals ~~~~~~~~~ +New upgrade script directory +^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +The distinction between `initial` and `invariant` scripts has been removed, +all scripts are now run on each upgrade. Instead of having one script directory +per package, all upgrade scripts lie in ``/lib/gluon/upgrade`` now, so it is +possible to define the run order across packages. +Merged package repository +^^^^^^^^^^^^^^^^^^^^^^^^^ +The Gluon-specific packages have been moved to the ``package`` directory of the Gluon +main repository. The ``packages`` repository now only contains packages that will be +submitted to the OpenWrt upstream eventually. Known Issues ~~~~~~~~~~~~ + +Alfred/respondd crashes +^^^^^^^^^^^^^^^^^^^^^^^ + +https://github.com/freifunk-gluon/gluon/issues/177 + +Occasional alfred crashes may still occur. As this is caused by a kernel issue, +we suspect that respondd, which gluon-announced is based on, is affected +in the same way. + + +Ignored tx-power offset on Ubiquiti AirMax devices +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +https://github.com/freifunk-gluon/gluon/issues/94 + +There is still no OpenWRT support for determining the transmission +power offsets on Ubiquiti AirMax devices (Bullet M2, Picostation +M2, Nanostation (loco) M2, ...). Use Gluon with caution on these +devices! Manual adjustment may be required. diff --git a/docs/user/site.rst b/docs/user/site.rst index acbcb877..bf6c1650 100644 --- a/docs/user/site.rst +++ b/docs/user/site.rst @@ -241,6 +241,8 @@ GLUON_LANGS List of languages (as two-letter-codes) to include for the web interface. Should always contain ``en``. +.. _site-config-mode-texts: + Config mode texts ----------------- From bcae6d073ace7d5b2a0d1bf7da938da3d61b3a07 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sat, 16 May 2015 13:17:25 +0200 Subject: [PATCH 50/62] docs: releases/v2015.1: reword Ubiquiti TX power issue description --- docs/releases/v2015.1.rst | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/docs/releases/v2015.1.rst b/docs/releases/v2015.1.rst index 3ff4d228..d648ff24 100644 --- a/docs/releases/v2015.1.rst +++ b/docs/releases/v2015.1.rst @@ -239,12 +239,14 @@ we suspect that respondd, which gluon-announced is based on, is affected in the same way. -Ignored tx-power offset on Ubiquiti AirMax devices +Ignored TX power offset on Ubiquiti AirMax devices ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ https://github.com/freifunk-gluon/gluon/issues/94 -There is still no OpenWRT support for determining the transmission -power offsets on Ubiquiti AirMax devices (Bullet M2, Picostation -M2, Nanostation (loco) M2, ...). Use Gluon with caution on these -devices! Manual adjustment may be required. +The default transmission power setting on many of these devices +is too high. It may be necessary to make manual adjustments, for example +using the ``gluon-luci-wifi-config`` package. The values shown by +``gluon-luci-wifi-config`` generally include the TX power offset +(amplifier and antenna gain) where available, but on many devices +the offset is inaccurate or unavailable. From 6a318306002b5a0cd47c1dc12bb97246c1ae4c07 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sat, 16 May 2015 14:00:06 +0200 Subject: [PATCH 51/62] gluon-mesh-batman-adv-core: always set hop penalty to 15 15 is the default in batman-adv-legacy, the new default 30 in newer batman-adv versions is too high in larger networks. --- .../files/lib/gluon/upgrade/310-gluon-mesh-batman-adv-core-mesh | 1 + 1 file changed, 1 insertion(+) 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/files/lib/gluon/upgrade/310-gluon-mesh-batman-adv-core-mesh index a51b20e2..43c4e4d4 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/files/lib/gluon/upgrade/310-gluon-mesh-batman-adv-core-mesh @@ -11,6 +11,7 @@ uci:section('batman-adv', 'mesh', 'bat0', { orig_interval = 5000, gw_mode = 'client', + hop_penalty = 15, multicast_mode = 0, } ) From 7f1e2621afe5384532d6209db2cfb03a9cceafe1 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sat, 16 May 2015 14:33:19 +0200 Subject: [PATCH 52/62] docs: add gluon-luci-wifi-config to the example site.mk --- docs/site-example/site.mk | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/site-example/site.mk b/docs/site-example/site.mk index 5e5a9f99..6a16eb53 100644 --- a/docs/site-example/site.mk +++ b/docs/site-example/site.mk @@ -20,6 +20,7 @@ GLUON_SITE_PACKAGES := \ gluon-luci-admin \ gluon-luci-autoupdater \ gluon-luci-portconfig \ + gluon-luci-wifi-config \ gluon-next-node \ gluon-mesh-vpn-fastd \ gluon-radvd \ From 279ac23d8369e709b2b5bcd27d42a28f004aa575 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sat, 16 May 2015 15:02:47 +0200 Subject: [PATCH 53/62] docs: user/x86 Fixes #373 --- docs/index.rst | 5 +++++ docs/user/x86.rst | 29 +++++++++++++++++++++++++++++ 2 files changed, 34 insertions(+) create mode 100644 docs/user/x86.rst diff --git a/docs/index.rst b/docs/index.rst index 5fc679a0..92fb58b7 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -13,6 +13,7 @@ User Documentation user/getting_started user/site + user/x86 user/faq Features @@ -152,10 +153,14 @@ x86-generic * x86-virtualbox * x86-vmware +See also: :doc:`user/x86` + x86-kvm_guest ^^^^^^^^^^^^^ * x86-kvm +See also: :doc:`user/x86` + License ------- diff --git a/docs/user/x86.rst b/docs/user/x86.rst new file mode 100644 index 00000000..b985d6fc --- /dev/null +++ b/docs/user/x86.rst @@ -0,0 +1,29 @@ +x86 support +=========== + +Gluon can run on normal x86 systems, for example virtual machines +and VPN boxes. There is no WLAN support on x86 though. + +Targets +^^^^^^^ + +There are two targets for x86 images: + +`x86-generic` + Generic x86 support with many different ethernet drivers; should run on + most x86 systems. + + There are three images: + + * `generic` (compressed "raw" image, can written to a disk directly or booted with qemu) + * `virtualbox` (VDI image) + * `vmware` (VMDK image) + + These images only differ in the image file format, the content is the same. Therefore there is + only a single `x86-generic` sysupgrade image instead of three. + + Please note that the `x86-generic` image doesn't include VirtIO support, so another virtual NIC + like `pcnet32` must be chosen when using VirtualBox. + +`x86-kvm` + The `x86-kvm` image uses VirtIO as its harddisk and network driver. From dab3dabc0efcf2bac263bdd1c00c1c535527775e Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sat, 16 May 2015 15:19:57 +0200 Subject: [PATCH 54/62] docs: releases/v2015.1: we haven't removed any hardware support --- docs/releases/v2015.1.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/releases/v2015.1.rst b/docs/releases/v2015.1.rst index d648ff24..aac47e6f 100644 --- a/docs/releases/v2015.1.rst +++ b/docs/releases/v2015.1.rst @@ -1,8 +1,8 @@ Gluon 2015.1 (in development) ============================= -Added (and removed) hardware support -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Added hardware support +~~~~~~~~~~~~~~~~~~~~~~ Gluon v2015.1 is the first release to officially support hardware that is not handled by the `ar71xx-generic` OpenWrt target. This also means that `ar71xx-generic` isn't the default target anymore, the ``GLUON_TARGET`` From 80906c2a0c2f3252ce8defb7b62e8c8dc97863e5 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Sat, 16 May 2015 15:34:55 +0200 Subject: [PATCH 55/62] docs, README: change current release to v2015.1 --- README.md | 2 +- docs/conf.py | 4 ++-- docs/releases/v2015.1.rst | 4 ++-- docs/site-example/site.conf | 2 +- docs/user/getting_started.rst | 2 +- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index acb027fb..87750136 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,7 @@ our mailinglist to discuss it first. 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 v2014.4;make update`. +and switch to one by running `git checkout v2015.1 && 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/docs/conf.py b/docs/conf.py index 0856ed6f..4dee07af 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -54,9 +54,9 @@ copyright = '2015, Project Gluon' # built documents. # # The short X.Y version. -version = '2014.4+' +version = '2015.1' # The full version, including alpha/beta/rc tags. -release = '2014.4+' +release = '2015.1' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. diff --git a/docs/releases/v2015.1.rst b/docs/releases/v2015.1.rst index aac47e6f..8e5c8e99 100644 --- a/docs/releases/v2015.1.rst +++ b/docs/releases/v2015.1.rst @@ -1,5 +1,5 @@ -Gluon 2015.1 (in development) -============================= +Gluon 2015.1 +============ Added hardware support ~~~~~~~~~~~~~~~~~~~~~~ diff --git a/docs/site-example/site.conf b/docs/site-example/site.conf index 310f8bc5..0849c07e 100644 --- a/docs/site-example/site.conf +++ b/docs/site-example/site.conf @@ -1,4 +1,4 @@ --- This is an example site configuration for Gluon v2014.4 +-- This is an example site configuration for Gluon v2015.1 -- -- Take a look at the documentation located at -- http://gluon.readthedocs.org/ for details. diff --git a/docs/user/getting_started.rst b/docs/user/getting_started.rst index adbec026..885a3887 100644 --- a/docs/user/getting_started.rst +++ b/docs/user/getting_started.rst @@ -38,7 +38,7 @@ Building the images ------------------- To build Gluon, first check out the repository. Replace *RELEASE* with the -version you'd like to checkout, e.g. *v2014.4*. +version you'd like to checkout, e.g. *v2015.1*. :: From b3f44325c4321af4ccea5c941f778ca90b30bead Mon Sep 17 00:00:00 2001 From: Florian Klink Date: Wed, 20 May 2015 21:23:56 +0200 Subject: [PATCH 56/62] add support for TP-LINK TL-WA830RE v1.0 final image name is shown as tp-link-tl-wa830re-v10 primary mac is the one printed on the case --- targets/ar71xx-generic/profiles.mk | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/targets/ar71xx-generic/profiles.mk b/targets/ar71xx-generic/profiles.mk index 1cc4ce40..27ebf827 100644 --- a/targets/ar71xx-generic/profiles.mk +++ b/targets/ar71xx-generic/profiles.mk @@ -83,9 +83,10 @@ $(eval $(call GluonModel,TLWDR4300,tl-wdr4300-v1,tp-link-tl-wdr4300-v1)) $(eval $(call GluonProfile,TLWA750)) $(eval $(call GluonModel,TLWA750,tl-wa750re-v1,tp-link-tl-wa750re-v1)) -ifeq ($(BROKEN),1) -# TL-WA830RE v2 +# TL-WA830RE v1.0, v2 $(eval $(call GluonProfile,TLWA830)) +$(eval $(call GluonModel,TLWA830,tl-wa830re-v1,tp-link-tl-wa830re-v10)) +ifeq ($(BROKEN),1) $(eval $(call GluonModel,TLWA830,tl-wa830re-v2,tp-link-tl-wa830re-v2)) endif From 8332a49b7808df62e62a34520955f938ef4f077d Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Thu, 21 May 2015 01:06:25 +0200 Subject: [PATCH 57/62] docs: change version to 2015.1+ --- docs/conf.py | 4 ++-- docs/site-example/site.conf | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/conf.py b/docs/conf.py index 4dee07af..090de523 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -54,9 +54,9 @@ copyright = '2015, Project Gluon' # built documents. # # The short X.Y version. -version = '2015.1' +version = '2015.1+' # The full version, including alpha/beta/rc tags. -release = '2015.1' +release = '2015.1+' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. diff --git a/docs/site-example/site.conf b/docs/site-example/site.conf index 0849c07e..6cffded8 100644 --- a/docs/site-example/site.conf +++ b/docs/site-example/site.conf @@ -1,4 +1,4 @@ --- This is an example site configuration for Gluon v2015.1 +-- This is an example site configuration for Gluon v2015.1+ -- -- Take a look at the documentation located at -- http://gluon.readthedocs.org/ for details. From ab10be9f50077e32d6ae0cba5d761a3da9188dc5 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Fri, 22 May 2015 01:09:19 +0200 Subject: [PATCH 58/62] We're on Chaos Calmer now --- Makefile | 15 +- docs/dev/i18n.rst | 6 +- include/Makefile.image | 7 - include/Makefile.target | 3 +- include/config | 2 +- include/gluon.mk | 4 +- include/package.mk | 33 +- modules | 15 +- .../files/usr/lib/lua/gluon/announce.lua | 6 +- .../controller/gluon-config-mode/index.lua | 5 +- .../model/cbi/gluon-config-mode/wizard.lua | 5 +- package/gluon-core/Makefile | 16 +- .../files/lib/gluon/upgrade/001-upgrade | 4 +- .../files/lib/gluon/upgrade/010-primary-mac | 2 +- .../files/lib/gluon/upgrade/999-version | 2 +- .../usr/lib/lua/luci/view/admin/info.htm | 2 +- .../lib/lua/luci/view/themes/gluon/header.htm | 1 - package/gluon-mesh-batman-adv-core/Makefile | 2 +- package/gluon-site/Makefile | 2 +- .../lib/gluon/status-page/www/cgi-bin/status | 2 +- ...le-fix-host-tools-build-dependencies.patch | 32 +- ...revision-on-TP-Link-Archer-C5-and-C7.patch | 31 - ...ndent-of-the-default-router-lifetime.patch | 31 + ...-really-empty-not-when-it-is-locked.patch} | 0 ...ndent-of-the-default-router-lifetime.patch | 26 - ...ty-firmware-as-an-additional-choice.patch} | 16 +- ...NK-Pharos-devices-CPE210-220-510-520.patch | 570 - ...pport-for-TP-LINK-CPE210-220-510-520.patch | 471 - ...files-disable-reset-button-handling.patch} | 0 ...-ar71xx-refactor-ubnt-xw-board-setup.patch | 72 - ...-ncurses-fix-host-build-with-GCC-5.1.patch | 21 + ...add-board-support-for-ubnt-loco-m-xw.patch | 161 - ...11-ath10k-allow-simultaneous-AP-IBSS.patch | 42 + ...ate-NanoStation-Loco-txpower-offsets.patch | 24 + ...ency-on-error.h-in-tplink-safeloader.patch | 43 - ...uild-explicitly-unexport-CONFIG_SITE.patch | 28 - ...ard-detection-for-TP-LINK-TL-WA860RE.patch | 20 - ...iguration-for-D-Link-DIR-615-rev.-C1.patch | 25 - ...ink-DIR-615-rev.-C1-WLAN-MAC-address.patch | 42 - ...upport-for-the-TP-LINK-TL-WR941ND-v5.patch | 229 - ...upport-for-the-UniFi-AP-Outdoor-Plus.patch | 177 - ...ath10k-to-compat-wireless-2015-03-05.patch | 33655 ---------------- ...pdate-firmware-to-the-latest-version.patch | 41 - ...xx-TP-LINK-Archer-add-5GHz-led-entry.patch | 20 - ...ed-WLAN-LEDs-on-TP-LINK-Archer-C5-C7.patch | 34 - ...syscalls-with-6-arguments-on-PowerPC.patch | 24 - ...file-for-the-gl-inet-6416A-and-6408A.patch | 35 - .../0024-ar71xx-detect-GL.iNet-model.patch | 39 - ...ng-a-specific-MBR-signature-to-ptgen.patch | 70 - ...tly-specifying-the-device-by-default.patch | 180 - ...ion-on-NETGEAR-WNDR3700-3800-WNDRMAC.patch | 65 - ...WDR3600-4300-RFKILL-switch-positions.patch | 22 - ...ot-make-it-easier-to-build-all-kmods.patch | 57 - ...-define-STAMP_CONFIGURED-recursively.patch | 26 - ...-from-patch-files-to-files-directory.patch | 1111 - ...nfar-add-add-mtd-mac-address-support.patch | 168 - ...rnet-MAC-address-hack-with-DTS-entry.patch | 41 - ...ate-NanoStation-Loco-txpower-offsets.patch | 20 - ...ue.html-add-label-that-can-be-styled.patch | 6 +- ...none-provided-by-the-browser-matches.patch | 12 +- ...0003-luci-base-depend-on-libubus-lua.patch | 17 + ...fter-initial-setup-and-disable-tests.patch | 33 - .../openwrt/0002-libuecc-update-to-v5.patch | 35 - .../openwrt/0003-fastd-update-to-v17.patch | 213 - ...ate-batman-adv-and-alfred-to-v2014.4.patch | 52 - ...tch => 0001-alfred-adjust-intervals.patch} | 0 ...adv-introduce-no_rebroadcast-option.patch} | 0 targets/ar71xx-generic/profiles.mk | 11 +- targets/ar71xx-generic/vermagic | 2 +- targets/ar71xx-nand/vermagic | 2 +- targets/mpc85xx-generic/vermagic | 2 +- targets/ramips-rt305x/vermagic | 2 +- targets/x86-generic/vermagic | 2 +- targets/x86-kvm_guest/vermagic | 2 +- 74 files changed, 220 insertions(+), 37974 deletions(-) delete mode 100644 include/Makefile.image delete mode 100644 patches/openwrt/0003-ar71xx-correctly-detect-hardware-revision-on-TP-Link-Archer-C5-and-C7.patch create mode 100644 patches/openwrt/0003-odhcp6c-always-accept-RDNSS-independent-of-the-default-router-lifetime.patch rename patches/openwrt/{0009-busybox-enable-telnet-only-when-root-password-is-really-empty-not-when-it-is-locked.patch => 0004-busybox-enable-telnet-only-when-root-password-is-really-empty-not-when-it-is-locked.patch} (100%) delete mode 100644 patches/openwrt/0004-odhcp6c-always-accept-RDNSS-independent-of-the-default-router-lifetime.patch rename patches/openwrt/{0019-ath10k-add-Candelatech-community-firmware-as-an-additional-choice.patch => 0005-ath10k-add-Candelatech-community-firmware-as-an-additional-choice.patch} (82%) delete mode 100644 patches/openwrt/0005-firmware-utils-add-new-tool-tplink-safeloader-for-the-new-TP-LINK-Pharos-devices-CPE210-220-510-520.patch delete mode 100644 patches/openwrt/0006-ar71xx-add-support-for-TP-LINK-CPE210-220-510-520.patch rename patches/openwrt/{0031-base-files-disable-reset-button-handling.patch => 0006-base-files-disable-reset-button-handling.patch} (100%) delete mode 100644 patches/openwrt/0007-ar71xx-refactor-ubnt-xw-board-setup.patch create mode 100644 patches/openwrt/0007-ncurses-fix-host-build-with-GCC-5.1.patch delete mode 100644 patches/openwrt/0008-ar71xx-add-board-support-for-ubnt-loco-m-xw.patch create mode 100644 patches/openwrt/0008-mac80211-ath10k-allow-simultaneous-AP-IBSS.patch create mode 100644 patches/openwrt/0009-iwinfo-update-NanoStation-Loco-txpower-offsets.patch delete mode 100644 patches/openwrt/0010-firmware-utils-remove-dependency-on-error.h-in-tplink-safeloader.patch delete mode 100644 patches/openwrt/0011-build-explicitly-unexport-CONFIG_SITE.patch delete mode 100644 patches/openwrt/0012-ar71xx-fix-board-detection-for-TP-LINK-TL-WA860RE.patch delete mode 100644 patches/openwrt/0013-ar71xx-add-default-LED-configuration-for-D-Link-DIR-615-rev.-C1.patch delete mode 100644 patches/openwrt/0014-ar71xx-fix-D-Link-DIR-615-rev.-C1-WLAN-MAC-address.patch delete mode 100644 patches/openwrt/0015-Add-support-for-the-TP-LINK-TL-WR941ND-v5.patch delete mode 100644 patches/openwrt/0016-ar71xx-add-support-for-the-UniFi-AP-Outdoor-Plus.patch delete mode 100644 patches/openwrt/0017-mac80211-update-ath10k-to-compat-wireless-2015-03-05.patch delete mode 100644 patches/openwrt/0018-ath10k-update-firmware-to-the-latest-version.patch delete mode 100644 patches/openwrt/0020-at71xx-TP-LINK-Archer-add-5GHz-led-entry.patch delete mode 100644 patches/openwrt/0021-ar71xx-fix-switched-WLAN-LEDs-on-TP-LINK-Archer-C5-C7.patch delete mode 100644 patches/openwrt/0022-uClibc-fix-syscall-for-syscalls-with-6-arguments-on-PowerPC.patch delete mode 100644 patches/openwrt/0023-ar71xx-Add-build-profile-for-the-gl-inet-6416A-and-6408A.patch delete mode 100644 patches/openwrt/0024-ar71xx-detect-GL.iNet-model.patch delete mode 100644 patches/openwrt/0025-firmware-utils-allow-passing-a-specific-MBR-signature-to-ptgen.patch delete mode 100644 patches/openwrt/0026-x86-use-PARTUUID-instead-explicitly-specifying-the-device-by-default.patch delete mode 100644 patches/openwrt/0027-ar71xx-fix-model-string-detection-on-NETGEAR-WNDR3700-3800-WNDRMAC.patch delete mode 100644 patches/openwrt/0028-ar71xx-fix-TP-LINK-TL-WDR3600-4300-RFKILL-switch-positions.patch delete mode 100644 patches/openwrt/0029-buildroot-make-it-easier-to-build-all-kmods.patch delete mode 100644 patches/openwrt/0030-build-define-STAMP_CONFIGURED-recursively.patch delete mode 100644 patches/openwrt/0032-mpc85xx-move-newly-created-files-from-patch-files-to-files-directory.patch delete mode 100644 patches/openwrt/0033-mpc85xx-gianfar-add-add-mtd-mac-address-support.patch delete mode 100644 patches/openwrt/0034-mpc85xx-replace-WDR4900-uci-defaults-ethernet-MAC-address-hack-with-DTS-entry.patch delete mode 100644 patches/openwrt/0035-iwinfo-update-NanoStation-Loco-txpower-offsets.patch create mode 100644 patches/packages/luci/0003-luci-base-depend-on-libubus-lua.patch delete mode 100644 patches/packages/openwrt/0001-haveged-start-directly-after-initial-setup-and-disable-tests.patch delete mode 100644 patches/packages/openwrt/0002-libuecc-update-to-v5.patch delete mode 100644 patches/packages/openwrt/0003-fastd-update-to-v17.patch delete mode 100644 patches/packages/routing/0001-Update-batman-adv-and-alfred-to-v2014.4.patch rename patches/packages/routing/{0002-alfred-adjust-intervals.patch => 0001-alfred-adjust-intervals.patch} (100%) rename patches/packages/routing/{0003-batman-adv-introduce-no_rebroadcast-option.patch => 0002-batman-adv-introduce-no_rebroadcast-option.patch} (100%) diff --git a/Makefile b/Makefile index 7f5fd437..a4fe82b8 100644 --- a/Makefile +++ b/Makefile @@ -212,7 +212,7 @@ config: FORCE echo 'CONFIG_BUILD_SUFFIX="gluon-$(GLUON_TARGET)"'; \ echo '$(patsubst %,CONFIG_PACKAGE_%=m,$(sort $(filter-out -%,$(GLUON_DEFAULT_PACKAGES) $(GLUON_SITE_PACKAGES) $(PROFILE_PACKAGES))))' \ | sed -e 's/ /\n/g'; \ - echo '$(patsubst %,CONFIG_GLUON_LANG_%=y,$(GLUON_LANGS))' \ + echo '$(patsubst %,CONFIG_LUCI_LANG_%=y,$(GLUON_LANGS))' \ | sed -e 's/ /\n/g'; \ ) > $(BOARD_BUILDDIR)/config.tmp scripts/config/conf --defconfig=$(BOARD_BUILDDIR)/config.tmp Config.in @@ -281,8 +281,11 @@ packages: $(package/stamp-compile) prepare-image: FORCE rm -rf $(BOARD_KDIR) mkdir -p $(BOARD_KDIR) - cp $(KERNEL_BUILD_DIR)/vmlinux $(KERNEL_BUILD_DIR)/vmlinux.elf $(BOARD_KDIR)/ - +$(SUBMAKE) -C $(TOPDIR)/target/linux/$(BOARD)/image -f $(GLUONDIR)/include/Makefile.image prepare KDIR="$(BOARD_KDIR)" + $(foreach k, vmlinux vmlinux.elf \ + $(if $(KERNEL_IMAGES),$(KERNEL_IMAGES),$(filter-out dtbs,$(KERNELNAME))), \ + $(CP) $(KERNEL_BUILD_DIR)/$(k) $(BOARD_KDIR)/$(k); \ + ) + +$(SUBMAKE) -C $(TOPDIR)/target/linux/$(BOARD)/image image_prepare KDIR="$(BOARD_KDIR)" prepare: FORCE @$(STAGING_DIR_HOST)/bin/lua $(GLUONDIR)/package/gluon-core/files/usr/lib/lua/gluon/site_config.lua \ @@ -346,7 +349,7 @@ $(eval $(call merge-lists,INSTALL_PACKAGES,DEFAULT_PACKAGES GLUON_DEFAULT_PACKAG package_install: FORCE $(OPKG) update - $(OPKG) install $(PACKAGE_DIR)/libc_*.ipk + $(OPKG) install $(PACKAGE_DIR)/base-files_*.ipk $(PACKAGE_DIR)/libc_*.ipk $(OPKG) install $(PACKAGE_DIR)/kernel_*.ipk $(OPKG) install $(INSTALL_PACKAGES) @@ -354,6 +357,10 @@ package_install: FORCE rm -f $(TARGET_DIR)/usr/lib/opkg/lists/* $(TARGET_DIR)/tmp/opkg.lock +# Remove opkg database when opkg is not intalled + if [ ! -x $(TARGET_DIR)/bin/opkg ]; then rm -rf $(TARGET_DIR)/usr/lib/opkg; fi + + ifeq ($(GLUON_OPKG_CONFIG),1) include $(INCLUDE_DIR)/version.mk endif diff --git a/docs/dev/i18n.rst b/docs/dev/i18n.rst index 536baf1a..b51bfdee 100644 --- a/docs/dev/i18n.rst +++ b/docs/dev/i18n.rst @@ -80,9 +80,9 @@ instead). Adding support for new languages -------------------------------- -A list of all languages supported by LuCI can be found in the ``include/package.mk`` file of -the Gluon repository. Adding translations for these languages is straightforward using the ``msginit`` -command. +A list of all languages supported by LuCI can be found in the ``packages/luci/luci.mk`` file after +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. diff --git a/include/Makefile.image b/include/Makefile.image deleted file mode 100644 index d6a627c6..00000000 --- a/include/Makefile.image +++ /dev/null @@ -1,7 +0,0 @@ -override define BuildImage -prepare: FORCE - $(call Image/Prepare) -endef - -# The Makefile included here is $(TOPDIR)/target/linux/$(BOARD)/image/Makefile -include Makefile diff --git a/include/Makefile.target b/include/Makefile.target index 19370e52..a78a4044 100644 --- a/include/Makefile.target +++ b/include/Makefile.target @@ -7,8 +7,7 @@ override define Kernel/Configure echo "# CONFIG_KALLSYMS_EXTRA_PASS is not set" >> $(LINUX_DIR)/.config.target echo "# CONFIG_KALLSYMS_ALL is not set" >> $(LINUX_DIR)/.config.target echo "# CONFIG_KALLSYMS_UNCOMPRESSED is not set" >> $(LINUX_DIR)/.config.target - echo "# CONFIG_KPROBES is not set" >> $(LINUX_DIR)/.config.target - $(SCRIPT_DIR)/metadata.pl kconfig $(TMP_DIR)/.packageinfo $(BOARD_BUILDDIR)/config-allmods > $(LINUX_DIR)/.config.override + $(SCRIPT_DIR)/metadata.pl kconfig $(TMP_DIR)/.packageinfo $(BOARD_BUILDDIR)/config-allmods $(KERNEL_PATCHVER) > $(LINUX_DIR)/.config.override $(SCRIPT_DIR)/kconfig.pl 'm+' '+' $(LINUX_DIR)/.config.target /dev/null $(LINUX_DIR)/.config.override > $(LINUX_DIR)/.config $(call Kernel/SetNoInitramfs) rm -rf $(KERNEL_BUILD_DIR)/modules diff --git a/include/config b/include/config index faab30c8..ac1a4f8d 100644 --- a/include/config +++ b/include/config @@ -19,4 +19,4 @@ CONFIG_ATH_USER_REGD=y CONFIG_PACKAGE_ATH_DEBUG=y CONFIG_ATH10K_CT_COMMUNITY_FW=y -CONFIG_PACKAGE_luci-base_srcdiet=y +CONFIG_LUCI_SRCDIET=y diff --git a/include/gluon.mk b/include/gluon.mk index 88db6f42..fdccef20 100644 --- a/include/gluon.mk +++ b/include/gluon.mk @@ -35,7 +35,7 @@ export GLUON_LANGS ifeq ($(OPENWRT_BUILD),1) ifeq ($(GLUON_TOOLS),1) -CONFIG_VERSION_REPO := $(shell $(GLUONDIR)/scripts/site.sh opkg_repo || echo http://downloads.openwrt.org/barrier_breaker/14.07/%S/packages) +CONFIG_VERSION_REPO := $(shell $(GLUONDIR)/scripts/site.sh opkg_repo || echo http://downloads.openwrt.org/chaos_calmer/15.05-rc1/%S/packages) export CONFIG_VERSION_REPO GLUON_SITE_CODE := $(shell $(GLUONDIR)/scripts/site.sh site_code) @@ -65,7 +65,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 +GLUON_DEFAULT_PACKAGES := gluon-core kmod-ipv6 firewall ip6tables -uboot-envtools -wpad-mini hostapd-mini override DEFAULT_PACKAGES.router := diff --git a/include/package.mk b/include/package.mk index 271d1de0..76e109e2 100644 --- a/include/package.mk +++ b/include/package.mk @@ -7,45 +7,20 @@ $(shell cat $(1) | sed -ne '1h; 1!H; $$ {g; s/@/+@/g; s/\n/-@/g; p}') END__GLUON__CHECK__SITE endef - # Languages supported by LuCi GLUON_SUPPORTED_LANGS := ca zh_cn en fr de el he hu it ja ms no pl pt_br pt ro ru es sv uk vi -GLUON_LANG_ca := catalan -GLUON_LANG_zh_cn := chinese -GLUON_LANG_en := english -GLUON_LANG_fr := french -GLUON_LANG_de := german -GLUON_LANG_el := greek -GLUON_LANG_he := hebrew -GLUON_LANG_hu := hungarian -GLUON_LANG_it := italian -GLUON_LANG_ja := japanese -GLUON_LANG_ms := malay -GLUON_LANG_no := norwegian -GLUON_LANG_pl := polish -GLUON_LANG_pt_br := portuguese-brazilian -GLUON_LANG_pt := portuguese -GLUON_LANG_ro := romanian -GLUON_LANG_ru := russian -GLUON_LANG_es := spanish -GLUON_LANG_sv := swedish -GLUON_LANG_uk := ukrainian -GLUON_LANG_vi := vietnamese +GLUON_I18N_PACKAGES := $(foreach lang,$(GLUON_SUPPORTED_LANGS),+LUCI_LANG_$(lang):luci-i18n-base-$(lang)) +GLUON_I18N_CONFIG := $(foreach lang,$(GLUON_SUPPORTED_LANGS),CONFIG_LUCI_LANG_$(lang)) +GLUON_ENABLED_LANGS := $(foreach lang,$(GLUON_SUPPORTED_LANGS),$(if $(CONFIG_LUCI_LANG_$(lang)),$(lang))) -GLUON_I18N_PACKAGES := $(foreach lang,$(GLUON_SUPPORTED_LANGS),+GLUON_LANG_$(lang):luci-i18n-$(GLUON_LANG_$(lang))) -GLUON_I18N_CONFIG := $(foreach lang,$(GLUON_SUPPORTED_LANGS),CONFIG_GLUON_LANG_$(lang)) -GLUON_ENABLED_LANGS := $(foreach lang,$(GLUON_SUPPORTED_LANGS),$(if $(CONFIG_GLUON_LANG_$(lang)),$(lang))) - - -GLUON_PO2LMO := $(BUILD_DIR)/luci/build/po2lmo define GluonBuildI18N mkdir -p $$(PKG_BUILD_DIR)/i18n for lang in $$(GLUON_ENABLED_LANGS); do \ if [ -e $(2)/$$$$lang.po ]; then \ rm -f $$(PKG_BUILD_DIR)/i18n/$(1).$$$$lang.lmo; \ - $(GLUON_PO2LMO) $(2)/$$$$lang.po $$(PKG_BUILD_DIR)/i18n/$(1).$$$$lang.lmo; \ + po2lmo $(2)/$$$$lang.po $$(PKG_BUILD_DIR)/i18n/$(1).$$$$lang.lmo; \ fi; \ done endef diff --git a/modules b/modules index 4776b64f..8c31b718 100644 --- a/modules +++ b/modules @@ -1,18 +1,19 @@ GLUON_FEEDS='openwrt gluon routing luci' -OPENWRT_REPO=git://git.openwrt.org/14.07/openwrt.git -OPENWRT_COMMIT=179bab8b1700d74b28cc6cd25322f9a1ad670107 +OPENWRT_REPO=git://git.openwrt.org/openwrt.git +OPENWRT_COMMIT=53a178af743eb1a463c806ee79d1e622969ad6ef PACKAGES_OPENWRT_REPO=git://github.com/openwrt/packages.git -PACKAGES_OPENWRT_COMMIT=01fcd1f29174a56d6ddb59901ed8c67ea42c3a8f -PACKAGES_OPENWRT_BRANCH=for-14.07 +PACKAGES_OPENWRT_COMMIT=914beae80e848c161214464fba7a9826c66bbf26 +PACKAGES_OPENWRT_BRANCH=for-15.05 PACKAGES_GLUON_REPO=git://github.com/freifunk-gluon/packages.git PACKAGES_GLUON_COMMIT=e8ee21d116a0abc2e328b0ee181d79845654582e PACKAGES_ROUTING_REPO=git://github.com/openwrt-routing/packages.git -PACKAGES_ROUTING_COMMIT=5d4ad63897b435d5df0f39a49bd58962c22c33b8 -PACKAGES_ROUTING_BRANCH=for-14.07 +PACKAGES_ROUTING_COMMIT=b1c3bdfbf47003088198bf8ef699a94cc29e3eca +PACKAGES_ROUTING_BRANCH=for-15.05 PACKAGES_LUCI_REPO=git://github.com/openwrt/luci.git -PACKAGES_LUCI_COMMIT=f81be49ae756dab82e1758a6c9de145f0d36960e +PACKAGES_LUCI_COMMIT=7a54785ea616df1e72f20b9cad2f1a6b3097f7b5 +PACKAGES_LUCI_BRANCH=for-15.05 diff --git a/package/gluon-announce/files/usr/lib/lua/gluon/announce.lua b/package/gluon-announce/files/usr/lib/lua/gluon/announce.lua index 7f3f62e2..17109785 100644 --- a/package/gluon-announce/files/usr/lib/lua/gluon/announce.lua +++ b/package/gluon-announce/files/usr/lib/lua/gluon/announce.lua @@ -2,12 +2,12 @@ module('gluon.announce', package.seeall) -fs = require 'luci.fs' +fs = require 'nixio.fs' uci = require('luci.model.uci').cursor() util = require 'luci.util' local function collect_entry(entry) - if fs.isdirectory(entry) then + if fs.stat(entry, 'type') == 'dir' then return collect_dir(entry) else return setfenv(loadfile(entry), _M)() @@ -17,7 +17,7 @@ end function collect_dir(dir) local ret = {} - for _, entry in ipairs(fs.dir(dir)) do + for entry in fs.dir(dir) do if entry:sub(1, 1) ~= '.' then local ok, val = pcall(collect_entry, dir .. '/' .. entry) if ok then 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/files/usr/lib/lua/luci/controller/gluon-config-mode/index.lua index c3ab070d..39ba00a9 100644 --- a/package/gluon-config-mode-core/files/usr/lib/lua/luci/controller/gluon-config-mode/index.lua +++ b/package/gluon-config-mode-core/files/usr/lib/lua/luci/controller/gluon-config-mode/index.lua @@ -49,10 +49,11 @@ function action_reboot() uci:commit("gluon-setup-mode") if nixio.fork() ~= 0 then - local fs = require "luci.fs" + local fs = require "nixio.fs" + local util = require "nixio.util" local parts_dir = "/lib/gluon/config-mode/reboot/" - local files = fs.dir(parts_dir) + local files = util.consume(fs.dir(parts_dir)) table.sort(files) 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/files/usr/lib/lua/luci/model/cbi/gluon-config-mode/wizard.lua index 101a02e3..dda5e58c 100644 --- a/package/gluon-config-mode-core/files/usr/lib/lua/luci/model/cbi/gluon-config-mode/wizard.lua +++ b/package/gluon-config-mode-core/files/usr/lib/lua/luci/model/cbi/gluon-config-mode/wizard.lua @@ -1,11 +1,12 @@ local wizard_dir = "/lib/gluon/config-mode/wizard/" local i18n = luci.i18n local uci = luci.model.uci.cursor() -local fs = require "luci.fs" +local fs = require "nixio.fs" +local util = require "nixio.util" local f, s local wizard = {} -local files = fs.dir(wizard_dir) +local files = util.consume(fs.dir(wizard_dir)) table.sort(files) diff --git a/package/gluon-core/Makefile b/package/gluon-core/Makefile index 2c632a00..bf9768e2 100644 --- a/package/gluon-core/Makefile +++ b/package/gluon-core/Makefile @@ -12,21 +12,7 @@ define Package/gluon-core SECTION:=gluon CATEGORY:=Gluon TITLE:=Base files of Gluon - DEPENDS:=+gluon-site +lua-platform-info +luci-lib-nixio +odhcp6c +firewall -endef - - -define LangConfig -config GLUON_LANG_$(1) - bool "$(GLUON_LANG_$(1)) language support" - depends on PACKAGE_gluon-core - default n - -endef - - -define Package/gluon-core/config -$(foreach lang,$(GLUON_SUPPORTED_LANGS),$(call LangConfig,$(lang))) + DEPENDS:=+gluon-site +lua-platform-info +luci-base +odhcp6c +firewall endef diff --git a/package/gluon-core/files/lib/gluon/upgrade/001-upgrade b/package/gluon-core/files/lib/gluon/upgrade/001-upgrade index 6caba148..5d53398c 100755 --- a/package/gluon-core/files/lib/gluon/upgrade/001-upgrade +++ b/package/gluon-core/files/lib/gluon/upgrade/001-upgrade @@ -1,10 +1,10 @@ #!/usr/bin/lua -local fs = require 'luci.fs' +local fs = require 'nixio.fs' local sysconfig = require 'gluon.sysconfig' -if fs.isfile('/lib/gluon/version/core') and not sysconfig.gluon_version then +if fs.stat('/lib/gluon/version/core') and not sysconfig.gluon_version then -- This isn't an initial upgrade, so set gluon_version sysconfig.gluon_version = '' end diff --git a/package/gluon-core/files/lib/gluon/upgrade/010-primary-mac b/package/gluon-core/files/lib/gluon/upgrade/010-primary-mac index 70aee39d..d7c6e968 100755 --- a/package/gluon-core/files/lib/gluon/upgrade/010-primary-mac +++ b/package/gluon-core/files/lib/gluon/upgrade/010-primary-mac @@ -10,7 +10,7 @@ end local platform = require 'gluon.platform' -local fs = require 'luci.fs' +local fs = require 'nixio.fs' local util = require 'luci.util' diff --git a/package/gluon-core/files/lib/gluon/upgrade/999-version b/package/gluon-core/files/lib/gluon/upgrade/999-version index 62f08206..9731692e 100755 --- a/package/gluon-core/files/lib/gluon/upgrade/999-version +++ b/package/gluon-core/files/lib/gluon/upgrade/999-version @@ -2,7 +2,7 @@ local sysconfig = require 'gluon.sysconfig' -local fs = require 'luci.fs' +local fs = require 'nixio.fs' local util = require 'luci.util' 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 a04a834d..da403c1b 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,5 +1,5 @@ <%- - local fs = require 'luci.fs' + local fs = require 'nixio.fs' local uci = require('luci.model.uci').cursor() local util = require 'luci.util' local i18n = require 'luci.i18n' 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 730647bc..2fe1004b 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 @@ -20,7 +20,6 @@ $Id$ local hostname = sys.hostname() local release = fs.readfile("/lib/gluon/release") - local load1, load5, load15 = sys.loadavg() local request = disp.context.path local request2 = disp.context.request diff --git a/package/gluon-mesh-batman-adv-core/Makefile b/package/gluon-mesh-batman-adv-core/Makefile index fc4bc224..8358089c 100644 --- a/package/gluon-mesh-batman-adv-core/Makefile +++ b/package/gluon-mesh-batman-adv-core/Makefile @@ -11,7 +11,7 @@ define Package/gluon-mesh-batman-adv-core SECTION:=gluon CATEGORY:=Gluon TITLE:=Support for batman-adv meshing (core) - DEPENDS:=+gluon-core +firewall +kmod-ipt-nathelper +libiwinfo-lua + DEPENDS:=+gluon-core +firewall +libiwinfo-lua endef define Build/Prepare diff --git a/package/gluon-site/Makefile b/package/gluon-site/Makefile index fc9f58ce..7816c9d3 100644 --- a/package/gluon-site/Makefile +++ b/package/gluon-site/Makefile @@ -5,7 +5,7 @@ PKG_VERSION:=$(if $(GLUON_SITE_CODE),$(GLUON_SITE_CODE),1) PKG_RELEASE:=$(GLUON_RELEASE) PKG_FILE_DEPENDS := $(GLUON_SITEDIR)/ -PKG_BUILD_DEPENDS := luci +PKG_BUILD_DEPENDS := luci-base/host PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME) diff --git a/package/gluon-status-page/files/lib/gluon/status-page/www/cgi-bin/status b/package/gluon-status-page/files/lib/gluon/status-page/www/cgi-bin/status index 771bdaba..b31e2f73 100755 --- a/package/gluon-status-page/files/lib/gluon/status-page/www/cgi-bin/status +++ b/package/gluon-status-page/files/lib/gluon/status-page/www/cgi-bin/status @@ -1,7 +1,7 @@ #!/usr/bin/lua local util = require("luci.util") -local fs = require("luci.fs") +local fs = require("nixio.fs") local ltn12 = require 'luci.ltn12' local sys = require("luci.sys") local json = require("luci.json") diff --git a/patches/openwrt/0001-tools-Makefile-fix-host-tools-build-dependencies.patch b/patches/openwrt/0001-tools-Makefile-fix-host-tools-build-dependencies.patch index 1a39c7bd..e400f28b 100644 --- a/patches/openwrt/0001-tools-Makefile-fix-host-tools-build-dependencies.patch +++ b/patches/openwrt/0001-tools-Makefile-fix-host-tools-build-dependencies.patch @@ -3,10 +3,10 @@ Date: Sat, 26 Jul 2014 06:10:23 +0200 Subject: tools/Makefile: fix host tools build dependencies diff --git a/tools/Makefile b/tools/Makefile -index 13bb028..137ad61 100644 +index 2f516d2..9416069 100644 --- a/tools/Makefile +++ b/tools/Makefile -@@ -97,10 +97,16 @@ define PrepareStaging +@@ -95,10 +95,16 @@ define PrepareStaging endef # preparatory work @@ -23,32 +23,14 @@ index 13bb028..137ad61 100644 $(STAGING_DIR_HOST)/.prepared: $(TMP_DIR)/.build $(call PrepareStaging,$(STAGING_DIR_HOST)) -@@ -112,7 +118,7 @@ $(STAGING_DIR_HOST)/.prepared: $(TMP_DIR)/.build +@@ -110,8 +116,8 @@ $(STAGING_DIR_HOST)/.prepared: $(TMP_DIR)/.build - - define PrepareCommand --$(STAGING_DIR_HOST)/bin/$(1): $(STAGING_DIR)/.prepared -+$(STAGING_DIR_HOST)/bin/$(1): $(STAGING_DIR_HOST)/.prepared - @mkdir -p "$$(dir $$@)"; rm -f "$$@" - @export FILE="$$$$(which $(2) 2>/dev/null | grep -v 'not found' | head -n1)"; [ -n "$$$$FILE" ] || { \ - echo "Command $(1) not found."; false; \ -@@ -121,7 +127,7 @@ $(STAGING_DIR_HOST)/bin/$(1): $(STAGING_DIR)/.prepared - endef endif --$(STAGING_DIR_HOST)/bin/stat: $(STAGING_DIR)/.prepared -+$(STAGING_DIR_HOST)/bin/stat: $(STAGING_DIR_HOST)/.prepared - @rm -f $@ - @if stat --version > /dev/null 2>&1; then \ - ln -s `which stat` $@; \ -@@ -145,8 +151,8 @@ $(eval $(call PrepareCommand,tar,gtar tar)) - $(eval $(call PrepareCommand,diff,gdiff diff)) - - $(curdir)/cmddeps = $(patsubst %,$(STAGING_DIR_HOST)/bin/%,md5sum cp stat seq python awk getopt grep tar diff) --$(curdir)//prepare = $(STAGING_DIR)/.prepared $(STAGING_DIR_HOST)/.prepared $($(curdir)/cmddeps) --$(curdir)//compile = $(STAGING_DIR)/.prepared $(STAGING_DIR_HOST)/.prepared $($(curdir)/cmddeps) -+$(curdir)//prepare = $(staging_prepared) $(STAGING_DIR_HOST)/.prepared $($(curdir)/cmddeps) -+$(curdir)//compile = $(staging_prepared) $(STAGING_DIR_HOST)/.prepared $($(curdir)/cmddeps) +-$(curdir)//prepare = $(STAGING_DIR)/.prepared $(STAGING_DIR_HOST)/.prepared +-$(curdir)//compile = $(STAGING_DIR)/.prepared $(STAGING_DIR_HOST)/.prepared ++$(curdir)//prepare = $(staging_prepared) $(STAGING_DIR_HOST)/.prepared ++$(curdir)//compile = $(staging_prepared) $(STAGING_DIR_HOST)/.prepared # prerequisites for the individual targets $(curdir)/ := .config prereq diff --git a/patches/openwrt/0003-ar71xx-correctly-detect-hardware-revision-on-TP-Link-Archer-C5-and-C7.patch b/patches/openwrt/0003-ar71xx-correctly-detect-hardware-revision-on-TP-Link-Archer-C5-and-C7.patch deleted file mode 100644 index 7b85d1e7..00000000 --- a/patches/openwrt/0003-ar71xx-correctly-detect-hardware-revision-on-TP-Link-Archer-C5-and-C7.patch +++ /dev/null @@ -1,31 +0,0 @@ -From: Matthias Schiffer -Date: Sat, 16 Aug 2014 17:52:34 +0200 -Subject: ar71xx: correctly detect hardware revision on TP-Link Archer C5 and C7 - -diff --git a/target/linux/ar71xx/base-files/lib/ar71xx.sh b/target/linux/ar71xx/base-files/lib/ar71xx.sh -index 18da356..1709356 100755 ---- a/target/linux/ar71xx/base-files/lib/ar71xx.sh -+++ b/target/linux/ar71xx/base-files/lib/ar71xx.sh -@@ -214,6 +214,13 @@ tplink_board_detect() { - "934100"*) - model="NC-LINK SMART-300" - ;; -+ "c50000"*) -+ model="TP-Link Archer C5" -+ ;; -+ "750000"*|\ -+ "c70000"*) -+ model="TP-Link Archer C7" -+ ;; - *) - hwver="" - ;; -@@ -748,7 +755,7 @@ ar71xx_board_detect() { - esac - - case "$machine" in -- *TL-WR* | *TL-WA* | *TL-MR* | *TL-WD*) -+ *TL-WR* | *TL-WA* | *TL-MR* | *TL-WD* | *Archer*) - tplink_board_detect "$machine" - ;; - esac diff --git a/patches/openwrt/0003-odhcp6c-always-accept-RDNSS-independent-of-the-default-router-lifetime.patch b/patches/openwrt/0003-odhcp6c-always-accept-RDNSS-independent-of-the-default-router-lifetime.patch new file mode 100644 index 00000000..82de5300 --- /dev/null +++ b/patches/openwrt/0003-odhcp6c-always-accept-RDNSS-independent-of-the-default-router-lifetime.patch @@ -0,0 +1,31 @@ +From: Matthias Schiffer +Date: Thu, 13 Nov 2014 01:17:24 +0100 +Subject: odhcp6c: always accept RDNSS, independent of the default router lifetime + +diff --git a/package/network/ipv6/odhcp6c/patches/001-always_accept_rdnss.patch b/package/network/ipv6/odhcp6c/patches/001-always_accept_rdnss.patch +new file mode 100644 +index 0000000..cb694ca +--- /dev/null ++++ b/package/network/ipv6/odhcp6c/patches/001-always_accept_rdnss.patch +@@ -0,0 +1,21 @@ ++--- a/src/ra.c +++++ b/src/ra.c ++@@ -438,18 +438,6 @@ bool ra_process(void) ++ } ++ } ++ } ++- ++- int states[2] = {STATE_RA_DNS, STATE_RA_SEARCH}; ++- for (size_t i = 0; i < 2; ++i) { ++- size_t ra_dns_len; ++- uint8_t *start = odhcp6c_get_state(states[i], &ra_dns_len); ++- for (struct odhcp6c_entry *c = (struct odhcp6c_entry*)start; ++- (uint8_t*)c < &start[ra_dns_len] && &c->auxtarget[c->auxlen] <= &start[ra_dns_len]; ++- c = (struct odhcp6c_entry*)(&c->auxtarget[c->auxlen])) ++- if (IN6_ARE_ADDR_EQUAL(&c->router, &from.sin6_addr) && ++- c->valid > router_valid) ++- c->valid = router_valid; ++- } ++ } ++ ++ if (found) diff --git a/patches/openwrt/0009-busybox-enable-telnet-only-when-root-password-is-really-empty-not-when-it-is-locked.patch b/patches/openwrt/0004-busybox-enable-telnet-only-when-root-password-is-really-empty-not-when-it-is-locked.patch similarity index 100% rename from patches/openwrt/0009-busybox-enable-telnet-only-when-root-password-is-really-empty-not-when-it-is-locked.patch rename to patches/openwrt/0004-busybox-enable-telnet-only-when-root-password-is-really-empty-not-when-it-is-locked.patch diff --git a/patches/openwrt/0004-odhcp6c-always-accept-RDNSS-independent-of-the-default-router-lifetime.patch b/patches/openwrt/0004-odhcp6c-always-accept-RDNSS-independent-of-the-default-router-lifetime.patch deleted file mode 100644 index 21c81918..00000000 --- a/patches/openwrt/0004-odhcp6c-always-accept-RDNSS-independent-of-the-default-router-lifetime.patch +++ /dev/null @@ -1,26 +0,0 @@ -From: Matthias Schiffer -Date: Thu, 13 Nov 2014 01:17:24 +0100 -Subject: odhcp6c: always accept RDNSS, independent of the default router lifetime - -diff --git a/package/network/ipv6/odhcp6c/patches/001-always_accept_rdnss.patch b/package/network/ipv6/odhcp6c/patches/001-always_accept_rdnss.patch -new file mode 100644 -index 0000000..ae4e18d ---- /dev/null -+++ b/package/network/ipv6/odhcp6c/patches/001-always_accept_rdnss.patch -@@ -0,0 +1,16 @@ -+--- a/src/ra.c -++++ b/src/ra.c -+@@ -409,13 +409,6 @@ bool ra_process(void) -+ } -+ } -+ } -+- -+- size_t ra_dns_len; -+- struct odhcp6c_entry *entry = odhcp6c_get_state(STATE_RA_DNS, &ra_dns_len); -+- for (size_t i = 0; i < ra_dns_len / sizeof(*entry); ++i) -+- if (IN6_ARE_ADDR_EQUAL(&entry[i].router, &from.sin6_addr) && -+- entry[i].valid > router_valid) -+- entry[i].valid = router_valid; -+ } -+ -+ if (found) diff --git a/patches/openwrt/0019-ath10k-add-Candelatech-community-firmware-as-an-additional-choice.patch b/patches/openwrt/0005-ath10k-add-Candelatech-community-firmware-as-an-additional-choice.patch similarity index 82% rename from patches/openwrt/0019-ath10k-add-Candelatech-community-firmware-as-an-additional-choice.patch rename to patches/openwrt/0005-ath10k-add-Candelatech-community-firmware-as-an-additional-choice.patch index 0fa623f4..e662cbe5 100644 --- a/patches/openwrt/0019-ath10k-add-Candelatech-community-firmware-as-an-additional-choice.patch +++ b/patches/openwrt/0005-ath10k-add-Candelatech-community-firmware-as-an-additional-choice.patch @@ -3,10 +3,10 @@ Date: Tue, 10 Mar 2015 13:17:14 +0100 Subject: ath10k: add Candelatech community firmware as an additional choice diff --git a/package/kernel/mac80211/Makefile b/package/kernel/mac80211/Makefile -index 629692d..d77842a 100644 +index 2a40bb1..17dbe03 100644 --- a/package/kernel/mac80211/Makefile +++ b/package/kernel/mac80211/Makefile -@@ -605,6 +605,14 @@ This module adds support for wireless adapters based on +@@ -604,6 +604,14 @@ This module adds support for wireless adapters based on Atheros USB AR9271 and AR7010 family of chipsets. endef @@ -21,7 +21,7 @@ index 629692d..d77842a 100644 define KernelPackage/ath10k $(call KernelPackage/mac80211/Default) TITLE:=Atheros 802.11ac wireless cards support -@@ -625,13 +633,31 @@ endef +@@ -624,13 +632,31 @@ endef define KernelPackage/ath10k/config if PACKAGE_kmod-ath10k @@ -55,14 +55,14 @@ index 629692d..d77842a 100644 endif endef -@@ -1824,14 +1850,20 @@ define KernelPackage/ath10k/install +@@ -1858,14 +1884,20 @@ define KernelPackage/ath10k/install $(INSTALL_DATA) \ $(PKG_BUILD_DIR)/$(PKG_ATH10K_LINUX_FIRMWARE_SUBDIR)/ath10k/QCA988X/hw2.0/board.bin \ $(1)/lib/firmware/ath10k/QCA988X/hw2.0/ +ifeq ($(CONFIG_ATH10K_AP_FW),y) + $(INSTALL_DATA) \ -+ $(PKG_BUILD_DIR)/$(PKG_ATH10K_LINUX_FIRMWARE_SUBDIR)/10.2/firmware-3.bin_10.2-00082-4-2 \ -+ $(1)/lib/firmware/ath10k/QCA988X/hw2.0/firmware-3.bin ++ $(PKG_BUILD_DIR)/$(PKG_ATH10K_LINUX_FIRMWARE_SUBDIR)/10.2.4/firmware-4.bin_10.2.4.45 \ ++ $(1)/lib/firmware/ath10k/QCA988X/hw2.0/firmware-4.bin +endif ifeq ($(CONFIG_ATH10K_STA_FW),y) $(INSTALL_DATA) \ @@ -72,8 +72,8 @@ index 629692d..d77842a 100644 +endif +ifeq ($(CONFIG_ATH10K_CT_COMMUNITY_FW),y) $(INSTALL_DATA) \ -- $(PKG_BUILD_DIR)/$(PKG_ATH10K_LINUX_FIRMWARE_SUBDIR)/10.2/firmware-3.bin_10.2-00082-4-2 \ -- $(1)/lib/firmware/ath10k/QCA988X/hw2.0/firmware-3.bin +- $(PKG_BUILD_DIR)/$(PKG_ATH10K_LINUX_FIRMWARE_SUBDIR)/10.2.4/firmware-4.bin_10.2.4.45 \ +- $(1)/lib/firmware/ath10k/QCA988X/hw2.0/firmware-4.bin + $(DL_DIR)/$(ATH10K_CT_COMMUNITY_FW) \ + $(1)/lib/firmware/ath10k/QCA988X/hw2.0/firmware-2.bin endif diff --git a/patches/openwrt/0005-firmware-utils-add-new-tool-tplink-safeloader-for-the-new-TP-LINK-Pharos-devices-CPE210-220-510-520.patch b/patches/openwrt/0005-firmware-utils-add-new-tool-tplink-safeloader-for-the-new-TP-LINK-Pharos-devices-CPE210-220-510-520.patch deleted file mode 100644 index 9cc72b6b..00000000 --- a/patches/openwrt/0005-firmware-utils-add-new-tool-tplink-safeloader-for-the-new-TP-LINK-Pharos-devices-CPE210-220-510-520.patch +++ /dev/null @@ -1,570 +0,0 @@ -From: Matthias Schiffer -Date: Wed, 26 Nov 2014 19:57:39 +0100 -Subject: firmware-utils: add new tool tplink-safeloader for the new TP-LINK Pharos devices (CPE210/220/510/520) - -The new TP-LINK Pharos series uses a new bootloader, the "TP-LINK Safeloader". -It uses an advanced firmware image format, containing an image partition table -and a flash partition table (and image partitions are mapped to the -corresponding flash partitions). The exact image format is documented in the -source code. - -Furthermore, the bootloader expects the kernel image as an ELF executable. - -Signed-off-by: Matthias Schiffer - -diff --git a/tools/firmware-utils/Makefile b/tools/firmware-utils/Makefile -index 4bb53cb..3f9eb56 100644 ---- a/tools/firmware-utils/Makefile -+++ b/tools/firmware-utils/Makefile -@@ -41,6 +41,7 @@ define Host/Compile - $(call cc,mkplanexfw sha1) - $(call cc,mktplinkfw md5) - $(call cc,mktplinkfw2 md5) -+ $(call cc,tplink-safeloader md5, -Wall) - $(call cc,pc1crypt) - $(call cc,osbridge-crc) - $(call cc,wrt400n cyg_crc32) -diff --git a/tools/firmware-utils/src/tplink-safeloader.c b/tools/firmware-utils/src/tplink-safeloader.c -new file mode 100644 -index 0000000..23d703f ---- /dev/null -+++ b/tools/firmware-utils/src/tplink-safeloader.c -@@ -0,0 +1,538 @@ -+/* -+ Copyright (c) 2014, Matthias Schiffer -+ All rights reserved. -+ -+ Redistribution and use in source and binary forms, with or without -+ modification, are permitted provided that the following conditions are met: -+ -+ 1. Redistributions of source code must retain the above copyright notice, -+ this list of conditions and the following disclaimer. -+ 2. Redistributions in binary form must reproduce the above copyright notice, -+ this list of conditions and the following disclaimer in the documentation -+ and/or other materials provided with the distribution. -+ -+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE -+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+*/ -+ -+ -+/* -+ tplink-safeloader -+ -+ Image generation tool for the TP-LINK SafeLoader as seen on -+ TP-LINK Pharos devices (CPE210/220/510/520) -+*/ -+ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+ -+#include -+#include -+ -+#include "md5.h" -+ -+ -+#define ALIGN(x,a) ({ typeof(a) __a = (a); (((x) + __a - 1) & ~(__a - 1)); }) -+ -+ -+/** An image partition table entry */ -+struct image_partition_entry { -+ const char *name; -+ size_t size; -+ uint8_t *data; -+}; -+ -+/** A flash partition table entry */ -+struct flash_partition_entry { -+ const char *name; -+ uint32_t base; -+ uint32_t size; -+}; -+ -+ -+/** The content of the soft-version structure */ -+struct __attribute__((__packed__)) soft_version { -+ uint32_t magic; -+ uint32_t zero; -+ uint8_t pad1; -+ uint8_t version_major; -+ uint8_t version_minor; -+ uint8_t version_patch; -+ uint8_t year_hi; -+ uint8_t year_lo; -+ uint8_t month; -+ uint8_t day; -+ uint32_t rev; -+ uint8_t pad2; -+}; -+ -+ -+static const uint8_t jffs2_eof_mark[4] = {0xde, 0xad, 0xc0, 0xde}; -+ -+ -+/** -+ Salt for the MD5 hash -+ -+ Fortunately, TP-LINK seems to use the same salt for most devices which use -+ the new image format. -+*/ -+static const uint8_t md5_salt[16] = { -+ 0x7a, 0x2b, 0x15, 0xed, -+ 0x9b, 0x98, 0x59, 0x6d, -+ 0xe5, 0x04, 0xab, 0x44, -+ 0xac, 0x2a, 0x9f, 0x4e, -+}; -+ -+ -+/** Vendor information for CPE210/220/510/520 */ -+static const unsigned char cpe510_vendor[] = "\x00\x00\x00\x1f""CPE510(TP-LINK|UN|N300-5):1.0\r\n"; -+ -+ -+/** -+ The flash partition table for CPE210/220/510/520; -+ it is the same as the one used by the stock images. -+*/ -+static const struct flash_partition_entry cpe510_partitions[] = { -+ {"fs-uboot", 0x00000, 0x20000}, -+ {"partition-table", 0x20000, 0x02000}, -+ {"default-mac", 0x30000, 0x00020}, -+ {"product-info", 0x31100, 0x00100}, -+ {"signature", 0x32000, 0x00400}, -+ {"os-image", 0x40000, 0x170000}, -+ {"soft-version", 0x1b0000, 0x00100}, -+ {"support-list", 0x1b1000, 0x00400}, -+ {"file-system", 0x1c0000, 0x600000}, -+ {"user-config", 0x7c0000, 0x10000}, -+ {"default-config", 0x7d0000, 0x10000}, -+ {"log", 0x7e0000, 0x10000}, -+ {"radio", 0x7f0000, 0x10000}, -+ {NULL, 0, 0} -+}; -+ -+/** -+ The support list for CPE210/220/510/520 -+ -+ The stock images also contain strings for two more devices: BS510 and BS210. -+ At the moment, there exists no public information about these devices. -+*/ -+static const unsigned char cpe510_support_list[] = -+ "\x00\x00\x00\xc8\x00\x00\x00\x00" -+ "SupportList:\r\n" -+ "CPE510(TP-LINK|UN|N300-5):1.0\r\n" -+ "CPE520(TP-LINK|UN|N300-5):1.0\r\n" -+ "CPE210(TP-LINK|UN|N300-2):1.0\r\n" -+ "CPE220(TP-LINK|UN|N300-2):1.0\r\n" -+ "\r\n\xff"; -+ -+ -+/** Allocates a new image partition */ -+struct image_partition_entry alloc_image_partition(const char *name, size_t len) { -+ struct image_partition_entry entry = {name, len, malloc(len)}; -+ if (!entry.data) -+ error(1, errno, "malloc"); -+ -+ return entry; -+} -+ -+/** Frees an image partition */ -+void free_image_partition(struct image_partition_entry entry) { -+ free(entry.data); -+} -+ -+/** Generates the partition-table partition */ -+struct image_partition_entry make_partition_table(const struct flash_partition_entry *p) { -+ struct image_partition_entry entry = alloc_image_partition("partition-table", 0x800); -+ -+ char *s = (char *)entry.data, *end = (char *)(s+entry.size); -+ -+ *(s++) = 0x00; -+ *(s++) = 0x04; -+ *(s++) = 0x00; -+ *(s++) = 0x00; -+ -+ size_t i; -+ for (i = 0; p[i].name; i++) { -+ size_t len = end-s; -+ size_t w = snprintf(s, len, "partition %s base 0x%05x size 0x%05x\n", p[i].name, p[i].base, p[i].size); -+ -+ if (w > len-1) -+ error(1, 0, "flash partition table overflow?"); -+ -+ s += w; -+ } -+ -+ s++; -+ -+ memset(s, 0xff, end-s); -+ -+ return entry; -+} -+ -+ -+/** Generates a binary-coded decimal representation of an integer in the range [0, 99] */ -+static inline uint8_t bcd(uint8_t v) { -+ return 0x10 * (v/10) + v%10; -+} -+ -+ -+/** Generates the soft-version partition */ -+struct image_partition_entry make_soft_version(uint32_t rev) { -+ struct image_partition_entry entry = alloc_image_partition("soft-version", sizeof(struct soft_version)); -+ struct soft_version *s = (struct soft_version *)entry.data; -+ -+ time_t t; -+ if (time(&t) == (time_t)(-1)) -+ error(1, errno, "time"); -+ -+ struct tm *tm = localtime(&t); -+ -+ s->magic = htonl(0x0000000c); -+ s->zero = 0; -+ s->pad1 = 0xff; -+ -+ s->version_major = 0; -+ s->version_minor = 0; -+ s->version_patch = 0; -+ -+ s->year_hi = bcd((1900+tm->tm_year)/100); -+ s->year_lo = bcd(tm->tm_year%100); -+ s->month = bcd(tm->tm_mon+1); -+ s->day = bcd(tm->tm_mday); -+ s->rev = htonl(rev); -+ -+ s->pad2 = 0xff; -+ -+ return entry; -+} -+ -+/** Generates the support-list partition */ -+struct image_partition_entry make_support_list(const unsigned char *support_list, size_t len) { -+ struct image_partition_entry entry = alloc_image_partition("support-list", len); -+ memcpy(entry.data, support_list, len); -+ return entry; -+} -+ -+/** Creates a new image partition with an arbitrary name from a file */ -+struct image_partition_entry read_file(const char *part_name, const char *filename, bool add_jffs2_eof) { -+ struct stat statbuf; -+ -+ if (stat(filename, &statbuf) < 0) -+ error(1, errno, "unable to stat file `%s'", filename); -+ -+ size_t len = statbuf.st_size; -+ -+ if (add_jffs2_eof) -+ len = ALIGN(len, 0x10000) + sizeof(jffs2_eof_mark); -+ -+ struct image_partition_entry entry = alloc_image_partition(part_name, len); -+ -+ FILE *file = fopen(filename, "rb"); -+ if (!file) -+ error(1, errno, "unable to open file `%s'", filename); -+ -+ if (fread(entry.data, statbuf.st_size, 1, file) != 1) -+ error(1, errno, "unable to read file `%s'", filename); -+ -+ if (add_jffs2_eof) { -+ uint8_t *eof = entry.data + statbuf.st_size, *end = entry.data+entry.size; -+ -+ memset(eof, 0xff, end - eof - sizeof(jffs2_eof_mark)); -+ memcpy(end - sizeof(jffs2_eof_mark), jffs2_eof_mark, sizeof(jffs2_eof_mark)); -+ } -+ -+ fclose(file); -+ -+ return entry; -+} -+ -+ -+/** -+ Copies a list of image partitions into an image buffer and generates the image partition table while doing so -+ -+ Example image partition table: -+ -+ fwup-ptn partition-table base 0x00800 size 0x00800 -+ fwup-ptn os-image base 0x01000 size 0x113b45 -+ fwup-ptn file-system base 0x114b45 size 0x1d0004 -+ fwup-ptn support-list base 0x2e4b49 size 0x000d1 -+ -+ Each line of the partition table is terminated with the bytes 09 0d 0a ("\t\r\n"), -+ the end of the partition table is marked with a zero byte. -+ -+ The firmware image must contain at least the partition-table and support-list partitions -+ to be accepted. There aren't any alignment constraints for the image partitions. -+ -+ The partition-table partition contains the actual flash layout; partitions -+ from the image partition table are mapped to the corresponding flash partitions during -+ the firmware upgrade. The support-list partition contains a list of devices supported by -+ the firmware image. -+ -+ The base offsets in the firmware partition table are relative to the end -+ of the vendor information block, so the partition-table partition will -+ actually start at offset 0x1814 of the image. -+ -+ I think partition-table must be the first partition in the firmware image. -+*/ -+void put_partitions(uint8_t *buffer, const struct image_partition_entry *parts) { -+ size_t i; -+ char *image_pt = (char *)buffer, *end = image_pt + 0x800; -+ -+ size_t base = 0x800; -+ for (i = 0; parts[i].name; i++) { -+ memcpy(buffer + base, parts[i].data, parts[i].size); -+ -+ size_t len = end-image_pt; -+ size_t w = snprintf(image_pt, len, "fwup-ptn %s base 0x%05x size 0x%05x\t\r\n", parts[i].name, (unsigned)base, (unsigned)parts[i].size); -+ -+ if (w > len-1) -+ error(1, 0, "image partition table overflow?"); -+ -+ image_pt += w; -+ -+ base += parts[i].size; -+ } -+ -+ image_pt++; -+ -+ memset(image_pt, 0xff, end-image_pt); -+} -+ -+/** Generates and writes the image MD5 checksum */ -+void put_md5(uint8_t *md5, uint8_t *buffer, unsigned int len) { -+ MD5_CTX ctx; -+ -+ MD5_Init(&ctx); -+ MD5_Update(&ctx, md5_salt, (unsigned int)sizeof(md5_salt)); -+ MD5_Update(&ctx, buffer, len); -+ MD5_Final(md5, &ctx); -+} -+ -+ -+/** -+ Generates the firmware image in factory format -+ -+ Image format: -+ -+ Bytes (hex) Usage -+ ----------- ----- -+ 0000-0003 Image size (4 bytes, big endian) -+ 0004-0013 MD5 hash (hash of a 16 byte salt and the image data starting with byte 0x14) -+ 0014-1013 Vendor information (4096 bytes, padded with 0xff; there seem to be older -+ (VxWorks-based) TP-LINK devices which use a smaller vendor information block) -+ 1014-1813 Image partition table (2048 bytes, padded with 0xff) -+ 1814-xxxx Firmware partitions -+*/ -+void * generate_factory_image(const unsigned char *vendor, size_t vendor_len, const struct image_partition_entry *parts, size_t *len) { -+ *len = 0x1814; -+ -+ size_t i; -+ for (i = 0; parts[i].name; i++) -+ *len += parts[i].size; -+ -+ uint8_t *image = malloc(*len); -+ if (!image) -+ error(1, errno, "malloc"); -+ -+ image[0] = *len >> 24; -+ image[1] = *len >> 16; -+ image[2] = *len >> 8; -+ image[3] = *len; -+ -+ memcpy(image+0x14, vendor, vendor_len); -+ memset(image+0x14+vendor_len, 0xff, 4096-vendor_len); -+ -+ put_partitions(image + 0x1014, parts); -+ put_md5(image+0x04, image+0x14, *len-0x14); -+ -+ return image; -+} -+ -+/** -+ Generates the firmware image in sysupgrade format -+ -+ This makes some assumptions about the provided flash and image partition tables and -+ should be generalized when TP-LINK starts building its safeloader into hardware with -+ different flash layouts. -+*/ -+void * generate_sysupgrade_image(const struct flash_partition_entry *flash_parts, const struct image_partition_entry *image_parts, size_t *len) { -+ const struct flash_partition_entry *flash_os_image = &flash_parts[5]; -+ const struct flash_partition_entry *flash_soft_version = &flash_parts[6]; -+ const struct flash_partition_entry *flash_support_list = &flash_parts[7]; -+ const struct flash_partition_entry *flash_file_system = &flash_parts[8]; -+ -+ const struct image_partition_entry *image_os_image = &image_parts[3]; -+ const struct image_partition_entry *image_soft_version = &image_parts[1]; -+ const struct image_partition_entry *image_support_list = &image_parts[2]; -+ const struct image_partition_entry *image_file_system = &image_parts[4]; -+ -+ assert(strcmp(flash_os_image->name, "os-image") == 0); -+ assert(strcmp(flash_soft_version->name, "soft-version") == 0); -+ assert(strcmp(flash_support_list->name, "support-list") == 0); -+ assert(strcmp(flash_file_system->name, "file-system") == 0); -+ -+ assert(strcmp(image_os_image->name, "os-image") == 0); -+ assert(strcmp(image_soft_version->name, "soft-version") == 0); -+ assert(strcmp(image_support_list->name, "support-list") == 0); -+ assert(strcmp(image_file_system->name, "file-system") == 0); -+ -+ if (image_os_image->size > flash_os_image->size) -+ error(1, 0, "kernel image too big (more than %u bytes)", (unsigned)flash_os_image->size); -+ if (image_file_system->size > flash_file_system->size) -+ error(1, 0, "rootfs image too big (more than %u bytes)", (unsigned)flash_file_system->size); -+ -+ *len = flash_file_system->base - flash_os_image->base + image_file_system->size; -+ -+ uint8_t *image = malloc(*len); -+ if (!image) -+ error(1, errno, "malloc"); -+ -+ memset(image, 0xff, *len); -+ -+ memcpy(image, image_os_image->data, image_os_image->size); -+ memcpy(image + flash_soft_version->base - flash_os_image->base, image_soft_version->data, image_soft_version->size); -+ memcpy(image + flash_support_list->base - flash_os_image->base, image_support_list->data, image_support_list->size); -+ memcpy(image + flash_file_system->base - flash_os_image->base, image_file_system->data, image_file_system->size); -+ -+ return image; -+} -+ -+ -+/** Generates an image for CPE210/220/510/520 and writes it to a file */ -+static void do_cpe510(const char *output, const char *kernel_image, const char *rootfs_image, uint32_t rev, bool add_jffs2_eof, bool sysupgrade) { -+ struct image_partition_entry parts[6] = {}; -+ -+ parts[0] = make_partition_table(cpe510_partitions); -+ parts[1] = make_soft_version(rev); -+ parts[2] = make_support_list(cpe510_support_list, sizeof(cpe510_support_list)-1); -+ parts[3] = read_file("os-image", kernel_image, false); -+ parts[4] = read_file("file-system", rootfs_image, add_jffs2_eof); -+ -+ size_t len; -+ void *image; -+ if (sysupgrade) -+ image = generate_sysupgrade_image(cpe510_partitions, parts, &len); -+ else -+ image = generate_factory_image(cpe510_vendor, sizeof(cpe510_vendor)-1, parts, &len); -+ -+ FILE *file = fopen(output, "wb"); -+ if (!file) -+ error(1, errno, "unable to open output file"); -+ -+ if (fwrite(image, len, 1, file) != 1) -+ error(1, 0, "unable to write output file"); -+ -+ fclose(file); -+ -+ free(image); -+ -+ size_t i; -+ for (i = 0; parts[i].name; i++) -+ free_image_partition(parts[i]); -+} -+ -+ -+/** Usage output */ -+void usage(const char *argv0) { -+ fprintf(stderr, -+ "Usage: %s [OPTIONS...]\n" -+ "\n" -+ "Options:\n" -+ " -B create image for the board specified with \n" -+ " -k read kernel image from the file \n" -+ " -r read rootfs image from the file \n" -+ " -o write output to the file \n" -+ " -V sets the revision number to \n" -+ " -j add jffs2 end-of-filesystem markers\n" -+ " -S create sysupgrade instead of factory image\n" -+ " -h show this help\n", -+ argv0 -+ ); -+}; -+ -+ -+int main(int argc, char *argv[]) { -+ const char *board = NULL, *kernel_image = NULL, *rootfs_image = NULL, *output = NULL; -+ bool add_jffs2_eof = false, sysupgrade = false; -+ unsigned rev = 0; -+ -+ while (true) { -+ int c; -+ -+ c = getopt(argc, argv, "B:k:r:o:V:jSh"); -+ if (c == -1) -+ break; -+ -+ switch (c) { -+ case 'B': -+ board = optarg; -+ break; -+ -+ case 'k': -+ kernel_image = optarg; -+ break; -+ -+ case 'r': -+ rootfs_image = optarg; -+ break; -+ -+ case 'o': -+ output = optarg; -+ break; -+ -+ case 'V': -+ sscanf(optarg, "r%u", &rev); -+ break; -+ -+ case 'j': -+ add_jffs2_eof = true; -+ break; -+ -+ case 'S': -+ sysupgrade = true; -+ break; -+ -+ case 'h': -+ usage(argv[0]); -+ return 0; -+ -+ default: -+ usage(argv[0]); -+ return 1; -+ } -+ } -+ -+ if (!board) -+ error(1, 0, "no board has been specified"); -+ if (!kernel_image) -+ error(1, 0, "no kernel image has been specified"); -+ if (!rootfs_image) -+ error(1, 0, "no rootfs image has been specified"); -+ if (!output) -+ error(1, 0, "no output filename has been specified"); -+ -+ if (strcmp(board, "CPE510") == 0) -+ do_cpe510(output, kernel_image, rootfs_image, rev, add_jffs2_eof, sysupgrade); -+ else -+ error(1, 0, "unsupported board %s", board); -+ -+ return 0; -+} diff --git a/patches/openwrt/0006-ar71xx-add-support-for-TP-LINK-CPE210-220-510-520.patch b/patches/openwrt/0006-ar71xx-add-support-for-TP-LINK-CPE210-220-510-520.patch deleted file mode 100644 index 8e109662..00000000 --- a/patches/openwrt/0006-ar71xx-add-support-for-TP-LINK-CPE210-220-510-520.patch +++ /dev/null @@ -1,471 +0,0 @@ -From: Matthias Schiffer -Date: Wed, 26 Nov 2014 19:57:50 +0100 -Subject: ar71xx: add support for TP-LINK CPE210/220/510/520 - -This adds support for the TP-LINK CPE210/220/510/520 (Pharos series). These -devices are very similar to the Ubiquiti NanoStations, but with better specs: -faster CPU, more RAM, 2x2 MIMO. - -Signed-off-by: Matthias Schiffer - -diff --git a/target/linux/ar71xx/base-files/etc/diag.sh b/target/linux/ar71xx/base-files/etc/diag.sh -index eb96338..d9c7328 100755 ---- a/target/linux/ar71xx/base-files/etc/diag.sh -+++ b/target/linux/ar71xx/base-files/etc/diag.sh -@@ -43,6 +43,9 @@ get_status_led() { - cap4200ag) - status_led="senao:green:pwr" - ;; -+ cpe510) -+ status_led="tp-link:green:link4" -+ ;; - db120) - status_led="db120:green:status" - ;; -diff --git a/target/linux/ar71xx/base-files/etc/uci-defaults/01_leds b/target/linux/ar71xx/base-files/etc/uci-defaults/01_leds -index 0d085be..a6e6721 100755 ---- a/target/linux/ar71xx/base-files/etc/uci-defaults/01_leds -+++ b/target/linux/ar71xx/base-files/etc/uci-defaults/01_leds -@@ -61,6 +61,16 @@ carambola2) - ucidef_set_led_wlan "wlan" "WLAN" "carambola2:green:wlan" "phy0tpt" - ;; - -+cpe510) -+ ucidef_set_led_switch "lan0" "LAN0" "tp-link:green:lan0" "switch0" "0x20" -+ ucidef_set_led_switch "lan1" "LAN1" "tp-link:green:lan1" "switch0" "0x10" -+ ucidef_set_rssimon "wlan0" "40000" "1" -+ ucidef_set_led_rssi "rssilow" "RSSILOW" "tp-link:green:link1" "wlan0" "1" "100" "0" "13" -+ ucidef_set_led_rssi "rssimediumlow" "RSSIMEDIUMLOW" "tp-link:green:link2" "wlan0" "26" "100" "-25" "13" -+ ucidef_set_led_rssi "rssimediumhigh" "RSSIMEDIUMHIGH" "tp-link:green:link3" "wlan0" "51" "100" "-50" "13" -+ ucidef_set_led_rssi "rssihigh" "RSSIHIGH" "tp-link:green:link4" "wlan0" "76" "100" "-75" "13" -+ ;; -+ - db120) - ucidef_set_led_usbdev "usb" "USB" "db120:green:usb" "1-1" - ;; -diff --git a/target/linux/ar71xx/base-files/etc/uci-defaults/02_network b/target/linux/ar71xx/base-files/etc/uci-defaults/02_network -index 4be30b8..78f4992 100755 ---- a/target/linux/ar71xx/base-files/etc/uci-defaults/02_network -+++ b/target/linux/ar71xx/base-files/etc/uci-defaults/02_network -@@ -62,6 +62,13 @@ tl-wdr4900-v2) - ucidef_add_switch_vlan "switch0" "2" "1 6" - ;; - -+cpe510) -+ ucidef_set_interfaces_lan_wan "eth0.1" "eth0.2" -+ ucidef_add_switch "switch0" "1" "1" -+ ucidef_add_switch_vlan "switch0" "1" "0t 5" -+ ucidef_add_switch_vlan "switch0" "2" "0t 4" -+ ;; -+ - db120 |\ - rb-2011l | \ - rb-2011uas |\ -diff --git a/target/linux/ar71xx/base-files/lib/ar71xx.sh b/target/linux/ar71xx/base-files/lib/ar71xx.sh -index 1709356..9fb4102 100755 ---- a/target/linux/ar71xx/base-files/lib/ar71xx.sh -+++ b/target/linux/ar71xx/base-files/lib/ar71xx.sh -@@ -229,6 +229,39 @@ tplink_board_detect() { - AR71XX_MODEL="$model $hwver" - } - -+tplink_pharos_get_model_string() { -+ local part -+ part=$(find_mtd_part 'product-info') -+ [ -z "$part" ] && return 1 -+ -+ # The returned string will end with \r\n, but we don't remove it here -+ # to simplify matching against it in the sysupgrade image check -+ dd if=$part bs=1 skip=4360 2>/dev/null | head -n 1 -+} -+ -+tplink_pharos_board_detect() { -+ local model_string="$(tplink_pharos_get_model_string | tr -d '\r')" -+ local oIFS="$IFS"; IFS=":"; set -- $model_string; IFS="$oIFS" -+ local model -+ -+ case "$1" in -+ 'CPE210(TP-LINK|UN|N300-2)') -+ model='TP-Link CPE210' -+ ;; -+ 'CPE220(TP-LINK|UN|N300-2)') -+ model='TP-Link CPE220' -+ ;; -+ 'CPE510(TP-LINK|UN|N300-5)') -+ model='TP-Link CPE510' -+ ;; -+ 'CPE520(TP-LINK|UN|N300-5)') -+ model='TP-Link CPE520' -+ ;; -+ esac -+ -+ [ -n "$model" ] && AR71XX_MODEL="$model v$2" -+} -+ - ar71xx_board_detect() { - local machine - local name -@@ -302,6 +335,10 @@ ar71xx_board_detect() { - *CAP4200AG) - name="cap4200ag" - ;; -+ *"CPE210/220/510/520") -+ name="cpe510" -+ tplink_pharos_board_detect -+ ;; - *"DB120 reference board") - name="db120" - ;; -@@ -754,11 +791,8 @@ ar71xx_board_detect() { - ;; - esac - -- case "$machine" in -- *TL-WR* | *TL-WA* | *TL-MR* | *TL-WD* | *Archer*) -+ [ -z "$AR71XX_MODEL" ] && [ "${machine:0:8}" = 'TP-LINK ' ] && \ - tplink_board_detect "$machine" -- ;; -- esac - - [ -z "$name" ] && name="unknown" - -diff --git a/target/linux/ar71xx/base-files/lib/upgrade/platform.sh b/target/linux/ar71xx/base-files/lib/upgrade/platform.sh -index eeaac6a..c583215 100755 ---- a/target/linux/ar71xx/base-files/lib/upgrade/platform.sh -+++ b/target/linux/ar71xx/base-files/lib/upgrade/platform.sh -@@ -70,6 +70,33 @@ tplink_get_image_boot_size() { - get_image "$@" | dd bs=4 count=1 skip=37 2>/dev/null | hexdump -v -n 4 -e '1/1 "%02x"' - } - -+tplink_pharos_check_image() { -+ local magic_long="$(get_magic_long "$1")" -+ [ "$magic_long" != "7f454c46" ] && { -+ echo "Invalid image magic '$magic_long'" -+ return 1 -+ } -+ -+ local model_string="$(tplink_pharos_get_model_string)" -+ local line -+ -+ # Here $1 is given to dd directly instead of get_image as otherwise the skip -+ # will take almost a second (as dd can't seek then) -+ # -+ # This will fail if the image isn't local, but that's fine: as the -+ # read loop won't be executed at all, it will return true, so the image -+ # is accepted (loading the first 1.5M of a remote image for this check seems -+ # a bit extreme) -+ dd if="$1" bs=1 skip=1511432 count=1024 2>/dev/null | while read line; do -+ [ "$line" == "$model_string" ] && break -+ done || { -+ echo "Unsupported image (model not in support-list)" -+ return 1 -+ } -+ -+ return 0 -+} -+ - seama_get_type_magic() { - get_image "$@" | dd bs=1 count=4 skip=53 2>/dev/null | hexdump -v -n 4 -e '1/1 "%02x"' - } -@@ -214,6 +241,11 @@ platform_check_image() { - return 0 - ;; - -+ cpe510) -+ tplink_pharos_check_image "$1" && return 0 -+ return 1 -+ ;; -+ - dir-825-b1 | \ - tew-673gru) - dir825b_check_image "$1" && return 0 -diff --git a/target/linux/ar71xx/config-3.10 b/target/linux/ar71xx/config-3.10 -index 482914a..14b59f7 100644 ---- a/target/linux/ar71xx/config-3.10 -+++ b/target/linux/ar71xx/config-3.10 -@@ -39,6 +39,7 @@ CONFIG_ATH79_MACH_AW_NR580=y - CONFIG_ATH79_MACH_BHU_BXU2000N2_A=y - CONFIG_ATH79_MACH_CAP4200AG=y - CONFIG_ATH79_MACH_CARAMBOLA2=y -+CONFIG_ATH79_MACH_CPE510=y - CONFIG_ATH79_MACH_DB120=y - CONFIG_ATH79_MACH_DIR_505_A1=y - CONFIG_ATH79_MACH_DIR_600_A1=y -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-cpe510.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-cpe510.c -new file mode 100644 -index 0000000..8bf5c0f ---- /dev/null -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-cpe510.c -@@ -0,0 +1,107 @@ -+/* -+ * TP-LINK CPE210/220/510/520 board support -+ * -+ * Copyright (C) 2014 Matthias Schiffer -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include -+#include -+ -+#include -+#include -+ -+#include "common.h" -+#include "dev-eth.h" -+#include "dev-gpio-buttons.h" -+#include "dev-leds-gpio.h" -+#include "dev-m25p80.h" -+#include "dev-wmac.h" -+#include "machtypes.h" -+ -+ -+#define CPE510_GPIO_LED_LAN0 11 -+#define CPE510_GPIO_LED_LAN1 12 -+#define CPE510_GPIO_LED_L1 13 -+#define CPE510_GPIO_LED_L2 14 -+#define CPE510_GPIO_LED_L3 15 -+#define CPE510_GPIO_LED_L4 16 -+ -+#define CPE510_GPIO_BTN_RESET 4 -+ -+#define CPE510_KEYS_POLL_INTERVAL 20 /* msecs */ -+#define CPE510_KEYS_DEBOUNCE_INTERVAL (3 * CPE510_KEYS_POLL_INTERVAL) -+ -+ -+static struct gpio_led cpe510_leds_gpio[] __initdata = { -+ { -+ .name = "tp-link:green:lan0", -+ .gpio = CPE510_GPIO_LED_LAN0, -+ .active_low = 1, -+ }, { -+ .name = "tp-link:green:lan1", -+ .gpio = CPE510_GPIO_LED_LAN1, -+ .active_low = 1, -+ }, { -+ .name = "tp-link:green:link1", -+ .gpio = CPE510_GPIO_LED_L1, -+ .active_low = 1, -+ }, { -+ .name = "tp-link:green:link2", -+ .gpio = CPE510_GPIO_LED_L2, -+ .active_low = 1, -+ }, { -+ .name = "tp-link:green:link3", -+ .gpio = CPE510_GPIO_LED_L3, -+ .active_low = 1, -+ }, { -+ .name = "tp-link:green:link4", -+ .gpio = CPE510_GPIO_LED_L4, -+ .active_low = 1, -+ }, -+}; -+ -+static struct gpio_keys_button cpe510_gpio_keys[] __initdata = { -+ { -+ .desc = "Reset button", -+ .type = EV_KEY, -+ .code = KEY_RESTART, -+ .debounce_interval = CPE510_KEYS_DEBOUNCE_INTERVAL, -+ .gpio = CPE510_GPIO_BTN_RESET, -+ .active_low = 1, -+ } -+}; -+ -+ -+static void __init cpe510_setup(void) -+{ -+ u8 *mac = (u8 *) KSEG1ADDR(0x1f830008); -+ u8 *ee = (u8 *) KSEG1ADDR(0x1fff1000); -+ -+ /* Disable JTAG, enabling GPIOs 0-3 */ -+ /* Configure OBS4 line, for GPIO 4*/ -+ ath79_gpio_function_setup(AR934X_GPIO_FUNC_JTAG_DISABLE, -+ AR934X_GPIO_FUNC_CLK_OBS4_EN); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(cpe510_leds_gpio), -+ cpe510_leds_gpio); -+ -+ ath79_register_gpio_keys_polled(1, CPE510_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(cpe510_gpio_keys), -+ cpe510_gpio_keys); -+ -+ ath79_register_m25p80(NULL); -+ -+ ath79_register_mdio(1, 0); -+ ath79_init_mac(ath79_eth1_data.mac_addr, mac, 0); -+ ath79_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_GMII; -+ ath79_register_eth(1); -+ -+ ath79_register_wmac(ee, mac); -+} -+ -+MIPS_MACHINE(ATH79_MACH_CPE510, "CPE510", "TP-LINK CPE210/220/510/520", -+ cpe510_setup); -diff --git a/target/linux/ar71xx/generic/profiles/tp-link.mk b/target/linux/ar71xx/generic/profiles/tp-link.mk -index 78333be..a9d170c 100644 ---- a/target/linux/ar71xx/generic/profiles/tp-link.mk -+++ b/target/linux/ar71xx/generic/profiles/tp-link.mk -@@ -16,6 +16,17 @@ endef - $(eval $(call Profile,ARCHERC7)) - - -+define Profile/CPE510 -+ NAME:=TP-LINK CPE210/220/510/520 -+ PACKAGES:=rssileds -+endef -+ -+define Profile/CPE510/Description -+ Package set optimized for the TP-LINK CPE210/220/510/520. -+endef -+$(eval $(call Profile,CPE510)) -+ -+ - define Profile/TLMR10U - NAME:=TP-LINK TL-MR10U - PACKAGES:=kmod-usb-core kmod-usb2 -diff --git a/target/linux/ar71xx/image/Makefile b/target/linux/ar71xx/image/Makefile -index 425fcc5..55f11dc 100644 ---- a/target/linux/ar71xx/image/Makefile -+++ b/target/linux/ar71xx/image/Makefile -@@ -261,6 +261,7 @@ cameo_ap121_mtdlayout_8M=mtdparts=spi0.0:64k(u-boot)ro,64k(art)ro,64k(mac)ro,64k - cameo_db120_mtdlayout=mtdparts=spi0.0:64k(uboot)ro,64k(nvram)ro,15936k(firmware),192k(lang)ro,64k(mac)ro,64k(art)ro - cameo_db120_mtdlayout_8M=mtdparts=spi0.0:64k(uboot)ro,64k(nvram)ro,7872k(firmware),128k(lang)ro,64k(art)ro - cap4200ag_mtdlayout=mtdparts=spi0.0:256k(u-boot),64k(u-boot-env),320k(custom)ro,1536k(kernel),12096k(rootfs),2048k(failsafe),64k(art),13632k@0xa0000(firmware) -+cpe510_mtdlayout=mtdparts=spi0.0:128k(u-boot)ro,64k(pation-table)ro,64k(product-info)ro,1536k(kernel),6144k(rootfs),192k(config)ro,64k(ART)ro,7680k@0x40000(firmware) - eap300v2_mtdlayout=mtdparts=spi0.0:256k(u-boot)ro,64k(u-boot-env),320k(custom),13632k(firmware),2048k(failsafe),64k(art)ro - db120_mtdlayout=mtdparts=spi0.0:256k(u-boot)ro,64k(u-boot-env)ro,6336k(rootfs),1408k(kernel),64k(nvram),64k(art)ro,7744k@0x50000(firmware) - cameo_ap94_mtdlayout=mtdparts=spi0.0:256k(uboot)ro,64k(config)ro,6208k(firmware),64k(caldata)ro,1600k(unknown)ro,64k@0x7f0000(caldata_copy) -@@ -811,6 +812,32 @@ define Image/Build/TPLINK-LZMA/initramfs - endef - - -+Image/Build/TPLINK-SAFELOADER/buildkernel=$(call PatchKernelLzma,$(2),$(3) $(4)) -+ -+define Image/Build/TPLINK-SAFELOADER -+ -rm -rf $(KDIR)/lzma-loader -+ $(LOADER_MAKE) LOADER=loader-$(2).elf\ -+ LZMA_TEXT_START=0x80a00000 LOADADDR=0x80060000 \ -+ LOADER_DATA="$(KDIR_TMP)/vmlinux-$(2).bin.lzma" BOARD="$(2)" \ -+ compile loader.elf -+ -+ -$(STAGING_DIR_HOST)/bin/tplink-safeloader \ -+ -B $(5) \ -+ -k $(KDIR)/loader-$(2).elf \ -+ -r $(KDIR)/root.$(1) \ -+ -V $(REVISION) \ -+ -j \ -+ -o $(call factoryname,$(1),$(2)) -+ -$(STAGING_DIR_HOST)/bin/tplink-safeloader \ -+ -B $(5) \ -+ -k $(KDIR)/loader-$(2).elf \ -+ -r $(KDIR)/root.$(1) \ -+ -V $(REVISION) \ -+ -j -S \ -+ -o $(call sysupname,$(1),$(2)) -+endef -+ -+ - define Image/Build/CyberTAN - echo -n '' > $(KDIR_TMP)/empty.bin - $(STAGING_DIR_HOST)/bin/trx -o $(KDIR)/image.tmp \ -@@ -1227,6 +1254,8 @@ $(eval $(call SingleProfile,TPLINK-LZMA,64kraw,TLWDR4310V1,tl-wdr4310-v1,TL-WDR4 - $(eval $(call SingleProfile,TPLINK-LZMA,64kraw,TLWDR4900V2,tl-wdr4900-v2,TL-WDR4900-v2,ttyS0,115200,0x49000002,1,8Mlzma)) - $(eval $(call SingleProfile,TPLINK-LZMA,64kraw,MW4530RV1,mw4530r-v1,TL-WDR4300,ttyS0,115200,0x45300001,1,8Mlzma)) - -+$(eval $(call SingleProfile,TPLINK-SAFELOADER,64kraw,CPE510,cpe210-220-510-520,CPE510,ttyS0,115200,$$(cpe510_mtdlayout),CPE510)) -+ - $(eval $(call SingleProfile,TPLINK-LZMA,64kraw,SMART-300,smart-300,SMART-300,ttyS0,115200,0x93410001,1,8Mlzma)) - - $(eval $(call SingleProfile,TPLINK-LZMA,64kraw,OOLITE,oolite,GS-OOLITE,ttyATH0,115200,0x3C000101,1,16Mlzma)) -diff --git a/target/linux/ar71xx/patches-3.10/610-MIPS-ath79-openwrt-machines.patch b/target/linux/ar71xx/patches-3.10/610-MIPS-ath79-openwrt-machines.patch -index 3669f26..516d52d 100644 ---- a/target/linux/ar71xx/patches-3.10/610-MIPS-ath79-openwrt-machines.patch -+++ b/target/linux/ar71xx/patches-3.10/610-MIPS-ath79-openwrt-machines.patch -@@ -1,6 +1,6 @@ - --- a/arch/mips/ath79/machtypes.h - +++ b/arch/mips/ath79/machtypes.h --@@ -16,22 +16,144 @@ -+@@ -16,22 +16,145 @@ - - enum ath79_mach_type { - ATH79_MACH_GENERIC = 0, -@@ -24,6 +24,7 @@ - + ATH79_MACH_BHU_BXU2000N2_A1, /* BHU BXU2000n-2 A1 */ - + ATH79_MACH_CAP4200AG, /* Senao CAP4200AG */ - + ATH79_MACH_CARAMBOLA2, /* 8devices Carambola2 */ -++ ATH79_MACH_CPE510, /* TP-LINK CPE510 */ - ATH79_MACH_DB120, /* Atheros DB120 reference board */ - ATH79_MACH_PB44, /* Atheros PB44 reference board */ - + ATH79_MACH_DIR_505_A1, /* D-Link DIR-505 rev. A1 */ -@@ -209,7 +210,7 @@ - config ATH79_MACH_AP121 - bool "Atheros AP121 reference board" - select SOC_AR933X --@@ -9,64 +64,736 @@ config ATH79_MACH_AP121 -+@@ -9,64 +64,745 @@ config ATH79_MACH_AP121 - select ATH79_DEV_GPIO_BUTTONS - select ATH79_DEV_LEDS_GPIO - select ATH79_DEV_M25P80 -@@ -709,6 +710,15 @@ - - -config ATH79_MACH_AP81 - - bool "Atheros AP81 reference board" -++config ATH79_MACH_CPE510 -++ bool "TP-LINK CPE510 support" -++ select SOC_AR934X -++ select ATH79_DEV_ETH -++ select ATH79_DEV_GPIO_BUTTONS -++ select ATH79_DEV_LEDS_GPIO -++ select ATH79_DEV_M25P80 -++ select ATH79_DEV_WMAC -++ - +config ATH79_MACH_TL_MR11U - + bool "TP-LINK TL-MR11U/TL-MR3040 support" - + select SOC_AR933X -@@ -972,7 +982,7 @@ - - config ATH79_MACH_UBNT_XM - bool "Ubiquiti Networks XM/UniFi boards" --@@ -83,6 +810,65 @@ config ATH79_MACH_UBNT_XM -+@@ -83,6 +819,65 @@ config ATH79_MACH_UBNT_XM - Say 'Y' here if you want your kernel to support the - Ubiquiti Networks XM (rev 1.0) board. - -@@ -1038,7 +1048,7 @@ - endmenu - - config SOC_AR71XX --@@ -132,7 +918,10 @@ config ATH79_DEV_DSA -+@@ -132,7 +927,10 @@ config ATH79_DEV_DSA - config ATH79_DEV_ETH - def_bool n - -@@ -1050,7 +1060,7 @@ - def_bool n - - config ATH79_DEV_GPIO_BUTTONS --@@ -164,4 +953,7 @@ config ATH79_PCI_ATH9K_FIXUP -+@@ -164,4 +962,7 @@ config ATH79_PCI_ATH9K_FIXUP - config ATH79_ROUTERBOOT - def_bool n - -@@ -1060,7 +1070,7 @@ - endif - --- a/arch/mips/ath79/Makefile - +++ b/arch/mips/ath79/Makefile --@@ -38,9 +38,90 @@ obj-$(CONFIG_ATH79_ROUTERBOOT) += route -+@@ -38,9 +38,91 @@ obj-$(CONFIG_ATH79_ROUTERBOOT) += route - # - # Machines - # -@@ -1079,6 +1089,7 @@ - +obj-$(CONFIG_ATH79_MACH_AW_NR580) += mach-aw-nr580.o - +obj-$(CONFIG_ATH79_MACH_BHU_BXU2000N2_A)+= mach-bhu-bxu2000n2-a.o - +obj-$(CONFIG_ATH79_MACH_CAP4200AG) += mach-cap4200ag.o -++obj-$(CONFIG_ATH79_MACH_CPE510) += mach-cpe510.o - obj-$(CONFIG_ATH79_MACH_DB120) += mach-db120.o - +obj-$(CONFIG_ATH79_MACH_DIR_505_A1) += mach-dir-505-a1.o - +obj-$(CONFIG_ATH79_MACH_DIR_600_A1) += mach-dir-600-a1.o diff --git a/patches/openwrt/0031-base-files-disable-reset-button-handling.patch b/patches/openwrt/0006-base-files-disable-reset-button-handling.patch similarity index 100% rename from patches/openwrt/0031-base-files-disable-reset-button-handling.patch rename to patches/openwrt/0006-base-files-disable-reset-button-handling.patch diff --git a/patches/openwrt/0007-ar71xx-refactor-ubnt-xw-board-setup.patch b/patches/openwrt/0007-ar71xx-refactor-ubnt-xw-board-setup.patch deleted file mode 100644 index 208e1766..00000000 --- a/patches/openwrt/0007-ar71xx-refactor-ubnt-xw-board-setup.patch +++ /dev/null @@ -1,72 +0,0 @@ -From: Matthias Schiffer -Date: Wed, 26 Nov 2014 23:20:33 +0100 -Subject: ar71xx: refactor ubnt xw board setup - -Signed-off-by: Alexander Couzens - -diff --git a/target/linux/ar71xx/patches-3.10/616-MIPS-ath79-ubnt-xw.patch b/target/linux/ar71xx/patches-3.10/616-MIPS-ath79-ubnt-xw.patch -index ed2fd24..9413bd8 100644 ---- a/target/linux/ar71xx/patches-3.10/616-MIPS-ath79-ubnt-xw.patch -+++ b/target/linux/ar71xx/patches-3.10/616-MIPS-ath79-ubnt-xw.patch -@@ -1,6 +1,8 @@ ----- a/arch/mips/ath79/mach-ubnt-xm.c --+++ b/arch/mips/ath79/mach-ubnt-xm.c --@@ -332,3 +332,60 @@ static void __init ubnt_uap_pro_setup(vo -+Index: linux-3.10.49/arch/mips/ath79/mach-ubnt-xm.c -+=================================================================== -+--- linux-3.10.49.orig/arch/mips/ath79/mach-ubnt-xm.c 2014-08-15 22:55:37.890080659 +0200 -++++ linux-3.10.49/arch/mips/ath79/mach-ubnt-xm.c 2014-08-15 22:58:31.061570912 +0200 -+@@ -332,3 +332,67 @@ - MIPS_MACHINE(ATH79_MACH_UBNT_UAP_PRO, "UAP-PRO", "Ubiquiti UniFi AP Pro", - ubnt_uap_pro_setup); - -@@ -29,7 +31,7 @@ - + }, - +}; - + --+static void __init ubnt_nano_m_xw_setup(void) -++static void __init ubnt_xw_init(void) - +{ - + u8 *eeprom = (u8 *) KSEG1ADDR(0x1fff0000); - + -@@ -44,26 +46,36 @@ - + ath79_register_wmac(eeprom + UAP_PRO_WMAC_CALDATA_OFFSET, NULL); - + ap91_pci_init(eeprom + UAP_PRO_PCI_CALDATA_OFFSET, NULL); - + --+ ath79_register_mdio(0, ~(BIT(0) | BIT(1) | BIT(5))); - + - + ath79_setup_ar934x_eth_cfg(AR934X_ETH_CFG_MII_GMAC0 | AR934X_ETH_CFG_MII_GMAC0_SLAVE); - + ath79_init_mac(ath79_eth0_data.mac_addr, - + eeprom + UAP_PRO_MAC0_OFFSET, 0); - + --+ /* GMAC0 is connected to an AR8326 switch */ - + ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_MII; -++ ath79_eth0_data.mii_bus_dev = &ath79_mdio0_device.dev; -++} -++ -++static void __init ubnt_nano_m_xw_setup(void) -++{ -++ ubnt_xw_init(); -++ -++ /* GMAC0 is connected to an AR8326 switch */ -++ ath79_register_mdio(0, ~(BIT(0) | BIT(1) | BIT(5))); - + ath79_eth0_data.phy_mask = (BIT(0) | BIT(1) | BIT(5)); - + ath79_eth0_data.speed = SPEED_100; - + ath79_eth0_data.duplex = DUPLEX_FULL; --+ ath79_eth0_data.mii_bus_dev = &ath79_mdio0_device.dev; - + ath79_register_eth(0); - +} - + - +MIPS_MACHINE(ATH79_MACH_UBNT_NANO_M_XW, "UBNT-NM-XW", "Ubiquiti Nanostation M XW", - + ubnt_nano_m_xw_setup); -++ - --- a/arch/mips/ath79/machtypes.h - +++ b/arch/mips/ath79/machtypes.h --@@ -124,6 +124,7 @@ enum ath79_mach_type { -+@@ -121,9 +121,10 @@ enum ath79_mach_type { -+ ATH79_MACH_TL_WR941ND, /* TP-LINK TL-WR941ND */ -+ ATH79_MACH_UBNT_AIRROUTER, /* Ubiquiti AirRouter */ -+ ATH79_MACH_UBNT_BULLET_M, /* Ubiquiti Bullet M */ - ATH79_MACH_UBNT_LSSR71, /* Ubiquiti LS-SR71 */ - ATH79_MACH_UBNT_LSX, /* Ubiquiti LSX */ - ATH79_MACH_UBNT_NANO_M, /* Ubiquiti NanoStation M */ diff --git a/patches/openwrt/0007-ncurses-fix-host-build-with-GCC-5.1.patch b/patches/openwrt/0007-ncurses-fix-host-build-with-GCC-5.1.patch new file mode 100644 index 00000000..366039ff --- /dev/null +++ b/patches/openwrt/0007-ncurses-fix-host-build-with-GCC-5.1.patch @@ -0,0 +1,21 @@ +From: Matthias Schiffer +Date: Wed, 20 May 2015 21:56:14 +0200 +Subject: ncurses: fix host build with GCC 5.1 + +diff --git a/package/libs/ncurses/Makefile b/package/libs/ncurses/Makefile +index 13c7962..39851a6 100644 +--- a/package/libs/ncurses/Makefile ++++ b/package/libs/ncurses/Makefile +@@ -82,6 +82,12 @@ HOST_CONFIGURE_ARGS += \ + --without-tests \ + --without-curses-h + ++HOST_CONFIGURE_VARS = \ ++ CC="$(HOSTCC)" \ ++ CFLAGS="$(HOST_CFLAGS)" \ ++ CPPFLAGS="$(HOST_CPPFLAGS) -P" \ ++ LDFLAGS="$(HOST_LDFLAGS)" \ ++ SHELL="$(SHELL)" + + ifeq ($(HOST_OS),FreeBSD) + CONFIGURE_ARGS += diff --git a/patches/openwrt/0008-ar71xx-add-board-support-for-ubnt-loco-m-xw.patch b/patches/openwrt/0008-ar71xx-add-board-support-for-ubnt-loco-m-xw.patch deleted file mode 100644 index f3e496d1..00000000 --- a/patches/openwrt/0008-ar71xx-add-board-support-for-ubnt-loco-m-xw.patch +++ /dev/null @@ -1,161 +0,0 @@ -From: Matthias Schiffer -Date: Wed, 26 Nov 2014 23:20:46 +0100 -Subject: ar71xx: add board support for ubnt loco m xw - -Signed-off-by: Alexander Couzens - -diff --git a/target/linux/ar71xx/base-files/etc/diag.sh b/target/linux/ar71xx/base-files/etc/diag.sh -index d9c7328..924766d 100755 ---- a/target/linux/ar71xx/base-files/etc/diag.sh -+++ b/target/linux/ar71xx/base-files/etc/diag.sh -@@ -34,7 +34,7 @@ get_status_led() { - aw-nr580) - status_led="aw-nr580:green:ready" - ;; -- bullet-m | rocket-m | nano-m | nanostation-m | nanostation-m-xw) -+ bullet-m | rocket-m | nano-m | nanostation-m | nanostation-m-xw | loco-m-xw) - status_led="ubnt:green:link4" - ;; - bxu2000n-2-a1) -diff --git a/target/linux/ar71xx/base-files/etc/uci-defaults/01_leds b/target/linux/ar71xx/base-files/etc/uci-defaults/01_leds -index a6e6721..2676b48 100755 ---- a/target/linux/ar71xx/base-files/etc/uci-defaults/01_leds -+++ b/target/linux/ar71xx/base-files/etc/uci-defaults/01_leds -@@ -38,7 +38,8 @@ ap113) - bullet-m | \ - nanostation-m | \ - rocket-m | \ --nanostation-m-xw) -+nanostation-m-xw | \ -+loco-m-xw) - ucidef_set_led_rssi "rssilow" "RSSILOW" "ubnt:red:link1" "wlan0" "1" "100" "0" "13" - ucidef_set_led_rssi "rssimediumlow" "RSSIMEDIUMLOW" "ubnt:orange:link2" "wlan0" "26" "100" "-25" "13" - ucidef_set_led_rssi "rssimediumhigh" "RSSIMEDIUMHIGH" "ubnt:green:link3" "wlan0" "51" "100" "-50" "13" -diff --git a/target/linux/ar71xx/base-files/etc/uci-defaults/02_network b/target/linux/ar71xx/base-files/etc/uci-defaults/02_network -index 78f4992..c494310 100755 ---- a/target/linux/ar71xx/base-files/etc/uci-defaults/02_network -+++ b/target/linux/ar71xx/base-files/etc/uci-defaults/02_network -@@ -293,6 +293,7 @@ bullet-m |\ - cap4200ag |\ - eap300v2 |\ - eap7660d |\ -+loco-m-xw |\ - mr600 |\ - mr600v2 |\ - rb-411 |\ -diff --git a/target/linux/ar71xx/base-files/lib/ar71xx.sh b/target/linux/ar71xx/base-files/lib/ar71xx.sh -index 9fb4102..79b6073 100755 ---- a/target/linux/ar71xx/base-files/lib/ar71xx.sh -+++ b/target/linux/ar71xx/base-files/lib/ar71xx.sh -@@ -396,6 +396,9 @@ ar71xx_board_detect() { - *"Bullet M") - name="bullet-m" - ;; -+ *"Loco M XW") -+ name="loco-m-xw" -+ ;; - *"Nanostation M") - name="nanostation-m" - ;; -diff --git a/target/linux/ar71xx/base-files/lib/upgrade/platform.sh b/target/linux/ar71xx/base-files/lib/upgrade/platform.sh -index c583215..a566b62 100755 ---- a/target/linux/ar71xx/base-files/lib/upgrade/platform.sh -+++ b/target/linux/ar71xx/base-files/lib/upgrade/platform.sh -@@ -217,6 +217,7 @@ platform_check_image() { - airgateway | \ - airrouter | \ - bullet-m | \ -+ loco-m-xw | \ - nanostation-m | \ - rocket-m | \ - nanostation-m-xw | \ -diff --git a/target/linux/ar71xx/image/Makefile b/target/linux/ar71xx/image/Makefile -index 55f11dc..3fdaf47 100644 ---- a/target/linux/ar71xx/image/Makefile -+++ b/target/linux/ar71xx/image/Makefile -@@ -1276,6 +1276,7 @@ $(eval $(call SingleProfile,UBNTXM,64kraw,UBNTNANOM,ubnt-nano-m,UBNT-NM,ttyS0,11 - $(eval $(call SingleProfile,UBNTXM,64kraw,UBNTUNIFI,ubnt-unifi,UBNT-UF,ttyS0,115200,XM,BZ,ar7240)) - $(eval $(call SingleProfile,UBNTXM,64kraw,UBNTUNIFIOUTDOOR,ubnt-unifi-outdoor,UBNT-U20,ttyS0,115200,XM,BZ,ar7240)) - $(eval $(call SingleProfile,UBNTXM,64kraw,UBNTNANOMXW,ubnt-nano-m-xw,UBNT-NM-XW,ttyS0,115200,XM,XW,ar934x)) -+$(eval $(call SingleProfile,UBNTXM,64kraw,UBNTLOCOXW,ubnt-loco-m-xw,UBNT-LOCO-XW,ttyS0,115200,XM,XW,ar934x)) - $(eval $(call SingleProfile,UBNTXM,64kraw,UBNTAIRGW,ubnt-air-gateway,UBNT-AGW,ttyATH0,115200,XM,AirGW,ar933x)) - - $(eval $(call SingleProfile,WHRHPG300N,64kraw,WHRG301N,whr-g301n,WHR-G301N,ttyS0,115200,$$(whrhpg300n_mtdlayout),WHR-G301N)) -@@ -1322,7 +1323,7 @@ $(eval $(call MultiProfile,TLWR941,TLWR941NV2 TLWR941NV3 TLWR941NV4 TLWR941NV6)) - $(eval $(call MultiProfile,TLWR1043,TLWR1043V1 TLWR1043V2)) - $(eval $(call MultiProfile,TLWDR4300,TLWDR3500V1 TLWDR3600V1 TLWDR4300V1 TLWDR4300V1IL TLWDR4310V1 MW4530RV1)) - $(eval $(call MultiProfile,TUBE2H,TUBE2H8M TUBE2H16M)) --$(eval $(call MultiProfile,UBNT,UBNTAIRROUTER UBNTRS UBNTRSPRO UBNTLSSR71 UBNTBULLETM UBNTROCKETM UBNTNANOM UBNTNANOMXW UBNTUNIFI UBNTUNIFIOUTDOOR UAPPRO UBNTAIRGW)) -+$(eval $(call MultiProfile,UBNT,UBNTAIRROUTER UBNTRS UBNTRSPRO UBNTLSSR71 UBNTBULLETM UBNTROCKETM UBNTNANOM UBNTNANOMXW UBNTLOCOXW UBNTUNIFI UBNTUNIFIOUTDOOR UAPPRO UBNTAIRGW)) - $(eval $(call MultiProfile,WNDR3700,WNDR3700V1 WNDR3700V2 WNDR3800 WNDR3800CH WNDRMAC WNDRMACV2)) - $(eval $(call MultiProfile,WNR612V2,REALWNR612V2 N150R)) - $(eval $(call MultiProfile,WP543,WP543_2M WP543_4M WP543_8M WP543_16M)) -diff --git a/target/linux/ar71xx/patches-3.10/616-MIPS-ath79-ubnt-xw.patch b/target/linux/ar71xx/patches-3.10/616-MIPS-ath79-ubnt-xw.patch -index 9413bd8..5e3d4d4 100644 ---- a/target/linux/ar71xx/patches-3.10/616-MIPS-ath79-ubnt-xw.patch -+++ b/target/linux/ar71xx/patches-3.10/616-MIPS-ath79-ubnt-xw.patch -@@ -1,8 +1,6 @@ --Index: linux-3.10.49/arch/mips/ath79/mach-ubnt-xm.c --=================================================================== ----- linux-3.10.49.orig/arch/mips/ath79/mach-ubnt-xm.c 2014-08-15 22:55:37.890080659 +0200 --+++ linux-3.10.49/arch/mips/ath79/mach-ubnt-xm.c 2014-08-15 22:58:31.061570912 +0200 --@@ -332,3 +332,67 @@ -+--- a/arch/mips/ath79/mach-ubnt-xm.c -++++ b/arch/mips/ath79/mach-ubnt-xm.c -+@@ -332,3 +332,78 @@ static void __init ubnt_uap_pro_setup(vo - MIPS_MACHINE(ATH79_MACH_UBNT_UAP_PRO, "UAP-PRO", "Ubiquiti UniFi AP Pro", - ubnt_uap_pro_setup); - -@@ -67,15 +65,27 @@ Index: linux-3.10.49/arch/mips/ath79/mach-ubnt-xm.c - + ath79_register_eth(0); - +} - + -++static void __init ubnt_loco_m_xw_setup(void) -++{ -++ ubnt_xw_init(); -++ -++ ath79_register_mdio(0, ~BIT(1)); -++ ath79_eth0_data.phy_mask = BIT(1); -++ ath79_register_eth(0); -++} -++ - +MIPS_MACHINE(ATH79_MACH_UBNT_NANO_M_XW, "UBNT-NM-XW", "Ubiquiti Nanostation M XW", - + ubnt_nano_m_xw_setup); - + -++MIPS_MACHINE(ATH79_MACH_UBNT_LOCO_M_XW, "UBNT-LOCO-XW", "Ubiquiti Loco M XW", -++ ubnt_loco_m_xw_setup); - --- a/arch/mips/ath79/machtypes.h - +++ b/arch/mips/ath79/machtypes.h --@@ -121,9 +121,10 @@ enum ath79_mach_type { -+@@ -121,9 +121,11 @@ enum ath79_mach_type { - ATH79_MACH_TL_WR941ND, /* TP-LINK TL-WR941ND */ - ATH79_MACH_UBNT_AIRROUTER, /* Ubiquiti AirRouter */ - ATH79_MACH_UBNT_BULLET_M, /* Ubiquiti Bullet M */ -++ ATH79_MACH_UBNT_LOCO_M_XW, /* Ubiquiti Loco M XW */ - ATH79_MACH_UBNT_LSSR71, /* Ubiquiti LS-SR71 */ - ATH79_MACH_UBNT_LSX, /* Ubiquiti LSX */ - ATH79_MACH_UBNT_NANO_M, /* Ubiquiti NanoStation M */ -diff --git a/target/linux/ar71xx/patches-3.10/722-MIPS-ath79-add-airGateway-support.patch b/target/linux/ar71xx/patches-3.10/722-MIPS-ath79-add-airGateway-support.patch -index 0fe62d9..c9d1e1e 100644 ---- a/target/linux/ar71xx/patches-3.10/722-MIPS-ath79-add-airGateway-support.patch -+++ b/target/linux/ar71xx/patches-3.10/722-MIPS-ath79-add-airGateway-support.patch -@@ -12,10 +12,10 @@ - #include "dev-ap9x-pci.h" - #include "dev-eth.h" - #include "dev-gpio-buttons.h" --@@ -389,3 +391,65 @@ static void __init ubnt_nano_m_xw_setup( -+@@ -406,3 +408,65 @@ MIPS_MACHINE(ATH79_MACH_UBNT_NANO_M_XW, - -- MIPS_MACHINE(ATH79_MACH_UBNT_NANO_M_XW, "UBNT-NM-XW", "Ubiquiti Nanostation M XW", -- ubnt_nano_m_xw_setup); -+ MIPS_MACHINE(ATH79_MACH_UBNT_LOCO_M_XW, "UBNT-LOCO-XW", "Ubiquiti Loco M XW", -+ ubnt_loco_m_xw_setup); - + - +static struct gpio_led ubnt_airgateway_gpio_leds[] __initdata = { - + { -@@ -87,4 +87,4 @@ - + ATH79_MACH_UBNT_AIRGW, /* Ubiquiti AirGateway */ - ATH79_MACH_UBNT_AIRROUTER, /* Ubiquiti AirRouter */ - ATH79_MACH_UBNT_BULLET_M, /* Ubiquiti Bullet M */ -- ATH79_MACH_UBNT_LSSR71, /* Ubiquiti LS-SR71 */ -+ ATH79_MACH_UBNT_LOCO_M_XW, /* Ubiquiti Loco M XW */ diff --git a/patches/openwrt/0008-mac80211-ath10k-allow-simultaneous-AP-IBSS.patch b/patches/openwrt/0008-mac80211-ath10k-allow-simultaneous-AP-IBSS.patch new file mode 100644 index 00000000..7586d3a2 --- /dev/null +++ b/patches/openwrt/0008-mac80211-ath10k-allow-simultaneous-AP-IBSS.patch @@ -0,0 +1,42 @@ +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/0009-iwinfo-update-NanoStation-Loco-txpower-offsets.patch b/patches/openwrt/0009-iwinfo-update-NanoStation-Loco-txpower-offsets.patch new file mode 100644 index 00000000..b45cf4e7 --- /dev/null +++ b/patches/openwrt/0009-iwinfo-update-NanoStation-Loco-txpower-offsets.patch @@ -0,0 +1,24 @@ +From: Matthias Schiffer +Date: Wed, 20 May 2015 23:15:20 +0200 +Subject: iwinfo: update NanoStation (Loco) txpower offsets + +diff --git a/package/network/utils/iwinfo/patches/001-update_nanostation_offsets.patch b/package/network/utils/iwinfo/patches/001-update_nanostation_offsets.patch +new file mode 100644 +index 0000000..1e13570 +--- /dev/null ++++ b/package/network/utils/iwinfo/patches/001-update_nanostation_offsets.patch +@@ -0,0 +1,14 @@ ++--- a/hardware.txt +++++ b/hardware.txt ++@@ -42,8 +42,9 @@ ++ 0x168c 0x0027 0x0777 0x4082 7 0 "Ubiquiti" "SR71" ++ 0x168c 0x0029 0x0777 0x4005 7 0 "Ubiquiti" "SR71-15" ++ 0x168c 0x002a 0x0777 0xe302 12 0 "Ubiquiti" "PicoStation M2" /* ToDo: confirm offset */ ++-0x168c 0x002a 0x0777 0xe012 12 0 "Ubiquiti" "NanoStation M2" /* ToDo: confirm offset */ ++-0x168c 0x002a 0x0777 0xe005 5 0 "Ubiquiti" "NanoStation M5" /* ToDo: confirm offset */ +++0x168c 0x002a 0x0777 0xe012 11 0 "Ubiquiti" "NanoStation M2" +++0x168c 0x002e 0x0777 0xe0a2 8 0 "Ubiquiti" "NanoStation Loco M2" +++0x168c 0x002a 0x0777 0xe005 16 0 "Ubiquiti" "NanoStation M5" ++ 0x168c 0x002a 0x0777 0xe202 12 0 "Ubiquiti" "Bullet M2" ++ 0x168c 0x002a 0x0777 0xe805 5 0 "Ubiquiti" "Bullet M5" ++ 0x168c 0x002a 0x0777 0xe345 0 0 "Ubiquiti" "WispStation M5" /* ToDo: confirm offset */ diff --git a/patches/openwrt/0010-firmware-utils-remove-dependency-on-error.h-in-tplink-safeloader.patch b/patches/openwrt/0010-firmware-utils-remove-dependency-on-error.h-in-tplink-safeloader.patch deleted file mode 100644 index c9c3b05b..00000000 --- a/patches/openwrt/0010-firmware-utils-remove-dependency-on-error.h-in-tplink-safeloader.patch +++ /dev/null @@ -1,43 +0,0 @@ -From: Matthias Schiffer -Date: Sun, 11 Jan 2015 09:14:34 +0100 -Subject: firmware-utils: remove dependency on error.h in tplink-safeloader - -Fixes build on Mac OS X - -Signed-off-by: Felix Fietkau - -diff --git a/tools/firmware-utils/src/tplink-safeloader.c b/tools/firmware-utils/src/tplink-safeloader.c -index 23d703f..9c5bb54 100644 ---- a/tools/firmware-utils/src/tplink-safeloader.c -+++ b/tools/firmware-utils/src/tplink-safeloader.c -@@ -34,7 +34,6 @@ - - #include - #include --#include - #include - #include - #include -@@ -143,6 +142,14 @@ static const unsigned char cpe510_support_list[] = - "CPE220(TP-LINK|UN|N300-2):1.0\r\n" - "\r\n\xff"; - -+#define error(_ret, _errno, _str, ...) \ -+ do { \ -+ fprintf(stderr, _str ": %s\n", ## __VA_ARGS__, \ -+ strerror(_errno)); \ -+ if (_ret) \ -+ exit(_ret); \ -+ } while (0) -+ - - /** Allocates a new image partition */ - struct image_partition_entry alloc_image_partition(const char *name, size_t len) { -@@ -200,6 +207,7 @@ struct image_partition_entry make_soft_version(uint32_t rev) { - struct soft_version *s = (struct soft_version *)entry.data; - - time_t t; -+ - if (time(&t) == (time_t)(-1)) - error(1, errno, "time"); - diff --git a/patches/openwrt/0011-build-explicitly-unexport-CONFIG_SITE.patch b/patches/openwrt/0011-build-explicitly-unexport-CONFIG_SITE.patch deleted file mode 100644 index c40d6b5d..00000000 --- a/patches/openwrt/0011-build-explicitly-unexport-CONFIG_SITE.patch +++ /dev/null @@ -1,28 +0,0 @@ -From: Matthias Schiffer -Date: Fri, 16 Jan 2015 03:49:40 +0100 -Subject: build: explicitly unexport CONFIG_SITE - -On systems with CONFIG_SITE in the environment (e.g. OpenSUSE) make will export -the CONFIG_SITE set in include/package.mk by default. This will cause host -builds to get the target site configuration, leading to all kinds of weirdness -(wrong pointer size, wrong endianess). - -Fix this by explicitly unexporting CONFIG_SITE. The explicit export for the -target builds overrides the unexport, so the target builds will still correctly -get the site config. - -Signed-off-by: Matthias Schiffer - -diff --git a/include/package.mk b/include/package.mk -index 88ec3ef..53ca6de 100644 ---- a/include/package.mk -+++ b/include/package.mk -@@ -93,7 +93,7 @@ CONFIG_SITE:=$(INCLUDE_DIR)/site/$(REAL_GNU_TARGET_NAME) - CUR_MAKEFILE:=$(filter-out Makefile,$(firstword $(MAKEFILE_LIST))) - SUBMAKE:=$(NO_TRACE_MAKE) $(if $(CUR_MAKEFILE),-f $(CUR_MAKEFILE)) - PKG_CONFIG_PATH=$(STAGING_DIR)/usr/lib/pkgconfig:$(STAGING_DIR)/usr/share/pkgconfig --unexport QUIET -+unexport QUIET CONFIG_SITE - - ifeq ($(DUMP)$(filter prereq clean refresh update,$(MAKECMDGOALS)),) - ifneq ($(if $(QUILT),,$(CONFIG_AUTOREBUILD)),) diff --git a/patches/openwrt/0012-ar71xx-fix-board-detection-for-TP-LINK-TL-WA860RE.patch b/patches/openwrt/0012-ar71xx-fix-board-detection-for-TP-LINK-TL-WA860RE.patch deleted file mode 100644 index 31c4304c..00000000 --- a/patches/openwrt/0012-ar71xx-fix-board-detection-for-TP-LINK-TL-WA860RE.patch +++ /dev/null @@ -1,20 +0,0 @@ -From: Matthias Schiffer -Date: Fri, 16 Jan 2015 19:56:39 +0100 -Subject: ar71xx: fix board detection for TP-LINK TL-WA860RE - -Signed-off-by: Matthias Schiffer - -diff --git a/target/linux/ar71xx/base-files/lib/ar71xx.sh b/target/linux/ar71xx/base-files/lib/ar71xx.sh -index 79b6073..13c5bf2 100755 ---- a/target/linux/ar71xx/base-files/lib/ar71xx.sh -+++ b/target/linux/ar71xx/base-files/lib/ar71xx.sh -@@ -630,6 +630,9 @@ ar71xx_board_detect() { - *TL-WA850RE) - name="tl-wa850re" - ;; -+ *TL-WA860RE) -+ name="tl-wa860re" -+ ;; - *"TL-WA830RE v2") - name="tl-wa830re-v2" - ;; diff --git a/patches/openwrt/0013-ar71xx-add-default-LED-configuration-for-D-Link-DIR-615-rev.-C1.patch b/patches/openwrt/0013-ar71xx-add-default-LED-configuration-for-D-Link-DIR-615-rev.-C1.patch deleted file mode 100644 index e283375d..00000000 --- a/patches/openwrt/0013-ar71xx-add-default-LED-configuration-for-D-Link-DIR-615-rev.-C1.patch +++ /dev/null @@ -1,25 +0,0 @@ -From: Matthias Schiffer -Date: Wed, 28 Jan 2015 15:02:54 +0100 -Subject: ar71xx: add default LED configuration for D-Link DIR-615 rev. C1 - -This patch adds an entry in the uci-defaults' led-file to configure the -WAN and WLAN LEDs by default. - -Signed-off-by: Vincent Wiemann - -diff --git a/target/linux/ar71xx/base-files/etc/uci-defaults/01_leds b/target/linux/ar71xx/base-files/etc/uci-defaults/01_leds -index 2676b48..ee90c52 100755 ---- a/target/linux/ar71xx/base-files/etc/uci-defaults/01_leds -+++ b/target/linux/ar71xx/base-files/etc/uci-defaults/01_leds -@@ -122,6 +122,11 @@ dir-615-e4) - ucidef_set_led_switch "lan4" "LAN4" "d-link:green:lan4" "switch0" "0x10" - ;; - -+dir-615-c1) -+ ucidef_set_led_netdev "wan" "WAN" "d-link:green:wan" "eth1" -+ ucidef_set_led_wlan "wlan" "WLAN" "d-link:green:wlan" "phy0tpt" -+ ;; -+ - dir-825-b1) - ucidef_set_led_usbdev "usb" "USB" "d-link:blue:usb" "1-1" - ;; diff --git a/patches/openwrt/0014-ar71xx-fix-D-Link-DIR-615-rev.-C1-WLAN-MAC-address.patch b/patches/openwrt/0014-ar71xx-fix-D-Link-DIR-615-rev.-C1-WLAN-MAC-address.patch deleted file mode 100644 index 964e3b71..00000000 --- a/patches/openwrt/0014-ar71xx-fix-D-Link-DIR-615-rev.-C1-WLAN-MAC-address.patch +++ /dev/null @@ -1,42 +0,0 @@ -From: Matthias Schiffer -Date: Wed, 28 Jan 2015 14:56:03 +0100 -Subject: ar71xx: fix D-Link DIR-615 rev. C1 WLAN MAC address - -Fix the WLAN MAC address to match the one printed on the label by using the -correct address from the ART instead of the address of the LAN interface. - -Signed-off-by: Matthias Schiffer - -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-dir-615-c1.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-dir-615-c1.c -index 425be30..e55a43f 100644 ---- a/target/linux/ar71xx/files/arch/mips/ath79/mach-dir-615-c1.c -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-dir-615-c1.c -@@ -38,6 +38,8 @@ - #define DIR_615C1_CONFIG_ADDR 0x1f020000 - #define DIR_615C1_CONFIG_SIZE 0x10000 - -+#define DIR_615C1_WLAN_MAC_ADDR 0x1f3fffb4 -+ - static struct gpio_led dir_615c1_leds_gpio[] __initdata = { - { - .name = "d-link:orange:status", -@@ -96,16 +98,16 @@ static void __init dir_615c1_setup(void) - { - const char *config = (char *) KSEG1ADDR(DIR_615C1_CONFIG_ADDR); - u8 *eeprom = (u8 *) KSEG1ADDR(0x1fff1000); -- u8 mac[6]; -- u8 *wlan_mac = NULL; -+ u8 mac[ETH_ALEN], wlan_mac[ETH_ALEN]; - - if (ath79_nvram_parse_mac_addr(config, DIR_615C1_CONFIG_SIZE, - "lan_mac=", mac) == 0) { - ath79_init_mac(ath79_eth0_data.mac_addr, mac, 0); - ath79_init_mac(ath79_eth1_data.mac_addr, mac, 1); -- wlan_mac = mac; - } - -+ ath79_parse_ascii_mac((char *) KSEG1ADDR(DIR_615C1_WLAN_MAC_ADDR), wlan_mac); -+ - ath79_register_mdio(0, DIR_615C1_MDIO_MASK); - - ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RMII; diff --git a/patches/openwrt/0015-Add-support-for-the-TP-LINK-TL-WR941ND-v5.patch b/patches/openwrt/0015-Add-support-for-the-TP-LINK-TL-WR941ND-v5.patch deleted file mode 100644 index 48079fc6..00000000 --- a/patches/openwrt/0015-Add-support-for-the-TP-LINK-TL-WR941ND-v5.patch +++ /dev/null @@ -1,229 +0,0 @@ -From: Matthias Schiffer -Date: Tue, 3 Feb 2015 16:54:22 +0100 -Subject: Add support for the TP-LINK TL-WR941ND v5 - -This device is very similar to the TL-WR841N v8, only two LED GPIOs are -different. - -Signed-off-by: Matthias Schiffer - -diff --git a/target/linux/ar71xx/base-files/etc/diag.sh b/target/linux/ar71xx/base-files/etc/diag.sh -index 924766d..f0d5d70 100755 ---- a/target/linux/ar71xx/base-files/etc/diag.sh -+++ b/target/linux/ar71xx/base-files/etc/diag.sh -@@ -214,7 +214,8 @@ get_status_led() { - tl-wr841n-v8 | \ - tl-wa830re-v2 | \ - tl-wr842n-v2 | \ -- tl-wr941nd) -+ tl-wr941nd | \ -+ tl-wr941nd-v5) - status_led="tp-link:green:system" - ;; - archer-c5 | \ -diff --git a/target/linux/ar71xx/base-files/etc/uci-defaults/01_leds b/target/linux/ar71xx/base-files/etc/uci-defaults/01_leds -index ee90c52..a74b8f4 100755 ---- a/target/linux/ar71xx/base-files/etc/uci-defaults/01_leds -+++ b/target/linux/ar71xx/base-files/etc/uci-defaults/01_leds -@@ -345,7 +345,8 @@ tl-wr741nd-v4) - ucidef_set_led_wlan "wlan" "WLAN" "tp-link:green:wlan" "phy0tpt" - ;; - --tl-wr841n-v8) -+tl-wr841n-v8 | \ -+tl-wr941nd-v5) - ucidef_set_led_netdev "wan" "WAN" "tp-link:green:wan" "eth0" - ucidef_set_led_switch "lan1" "LAN1" "tp-link:green:lan1" "switch0" "0x04" - ucidef_set_led_switch "lan2" "LAN2" "tp-link:green:lan2" "switch0" "0x08" -diff --git a/target/linux/ar71xx/base-files/etc/uci-defaults/02_network b/target/linux/ar71xx/base-files/etc/uci-defaults/02_network -index c494310..3ccb917 100755 ---- a/target/linux/ar71xx/base-files/etc/uci-defaults/02_network -+++ b/target/linux/ar71xx/base-files/etc/uci-defaults/02_network -@@ -211,6 +211,7 @@ smart-300 | \ - tl-mr3420-v2 |\ - tl-wr841n-v8 |\ - tl-wr842n-v2 |\ -+tl-wr941nd-v5 |\ - wnr2000-v3 |\ - wnr2200 |\ - wnr612-v2) -diff --git a/target/linux/ar71xx/base-files/lib/ar71xx.sh b/target/linux/ar71xx/base-files/lib/ar71xx.sh -index 13c5bf2..5fbca92 100755 ---- a/target/linux/ar71xx/base-files/lib/ar71xx.sh -+++ b/target/linux/ar71xx/base-files/lib/ar71xx.sh -@@ -681,6 +681,9 @@ ar71xx_board_detect() { - *TL-WR941ND) - name="tl-wr941nd" - ;; -+ *"TL-WR941N/ND v5") -+ name="tl-wr941nd-v5" -+ ;; - *"TL-WR703N v1") - name="tl-wr703n" - ;; -diff --git a/target/linux/ar71xx/base-files/lib/upgrade/platform.sh b/target/linux/ar71xx/base-files/lib/upgrade/platform.sh -index a566b62..e512f41 100755 ---- a/target/linux/ar71xx/base-files/lib/upgrade/platform.sh -+++ b/target/linux/ar71xx/base-files/lib/upgrade/platform.sh -@@ -326,6 +326,7 @@ platform_check_image() { - tl-wr841n-v9 | \ - tl-wr842n-v2 | \ - tl-wr941nd | \ -+ tl-wr941nd-v5 | \ - tl-wr1041n-v2 | \ - tl-wr1043nd | \ - tl-wr1043nd-v2 | \ -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-tl-wr841n-v8.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-tl-wr841n-v8.c -index 0099b15..73cfdd9 100644 ---- a/target/linux/ar71xx/files/arch/mips/ath79/mach-tl-wr841n-v8.c -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-tl-wr841n-v8.c -@@ -38,6 +38,15 @@ - #define TL_MR3420V2_GPIO_LED_3G 11 - #define TL_MR3420V2_GPIO_USB_POWER 4 - -+#define TL_WR941NDV5_GPIO_LED_WLAN 13 -+#define TL_WR941NDV5_GPIO_LED_QSS 15 -+#define TL_WR941NDV5_GPIO_LED_WAN 18 -+#define TL_WR941NDV5_GPIO_LED_LAN1 19 -+#define TL_WR941NDV5_GPIO_LED_LAN2 20 -+#define TL_WR941NDV5_GPIO_LED_LAN3 2 -+#define TL_WR941NDV5_GPIO_LED_LAN4 3 -+#define TL_WR941NDV5_GPIO_LED_SYSTEM 14 -+ - #define TL_WR841NV8_KEYS_POLL_INTERVAL 20 /* msecs */ - #define TL_WR841NV8_KEYS_DEBOUNCE_INTERVAL (3 * TL_WR841NV8_KEYS_POLL_INTERVAL) - -@@ -127,6 +136,42 @@ static struct gpio_keys_button tl_mr3420v2_gpio_keys[] __initdata = { - } - }; - -+static struct gpio_led tl_wr941nd_v5_leds_gpio[] __initdata = { -+ { -+ .name = "tp-link:green:lan1", -+ .gpio = TL_WR941NDV5_GPIO_LED_LAN1, -+ .active_low = 1, -+ }, { -+ .name = "tp-link:green:lan2", -+ .gpio = TL_WR941NDV5_GPIO_LED_LAN2, -+ .active_low = 1, -+ }, { -+ .name = "tp-link:green:lan3", -+ .gpio = TL_WR941NDV5_GPIO_LED_LAN3, -+ .active_low = 1, -+ }, { -+ .name = "tp-link:green:lan4", -+ .gpio = TL_WR941NDV5_GPIO_LED_LAN4, -+ .active_low = 1, -+ }, { -+ .name = "tp-link:green:qss", -+ .gpio = TL_WR941NDV5_GPIO_LED_QSS, -+ .active_low = 1, -+ }, { -+ .name = "tp-link:green:system", -+ .gpio = TL_WR941NDV5_GPIO_LED_SYSTEM, -+ .active_low = 1, -+ }, { -+ .name = "tp-link:green:wan", -+ .gpio = TL_WR941NDV5_GPIO_LED_WAN, -+ .active_low = 1, -+ }, { -+ .name = "tp-link:green:wlan", -+ .gpio = TL_WR941NDV5_GPIO_LED_WLAN, -+ .active_low = 1, -+ }, -+}; -+ - static void __init tl_ap123_setup(void) - { - u8 *mac = (u8 *) KSEG1ADDR(0x1f01fc00); -@@ -223,3 +268,19 @@ static void __init tl_mr3420v2_setup(void) - - MIPS_MACHINE(ATH79_MACH_TL_MR3420_V2, "TL-MR3420-v2", "TP-LINK TL-MR3420 v2", - tl_mr3420v2_setup); -+ -+ -+static void __init tl_wr941nd_v5_setup(void) -+{ -+ tl_ap123_setup(); -+ -+ ath79_register_leds_gpio(-1, ARRAY_SIZE(tl_wr941nd_v5_leds_gpio), -+ tl_wr941nd_v5_leds_gpio); -+ -+ ath79_register_gpio_keys_polled(1, TL_WR841NV8_KEYS_POLL_INTERVAL, -+ ARRAY_SIZE(tl_wr841n_v8_gpio_keys), -+ tl_wr841n_v8_gpio_keys); -+} -+ -+MIPS_MACHINE(ATH79_MACH_TL_WR941ND_V5, "TL-WR941ND-v5", "TP-LINK TL-WR941N/ND v5", -+ tl_wr941nd_v5_setup); -diff --git a/target/linux/ar71xx/image/Makefile b/target/linux/ar71xx/image/Makefile -index 3fdaf47..ba16c7b 100644 ---- a/target/linux/ar71xx/image/Makefile -+++ b/target/linux/ar71xx/image/Makefile -@@ -1242,6 +1242,7 @@ $(eval $(call SingleProfile,TPLINK-LZMA,64kraw,TLWA801NV2,tl-wa801nd-v2,TL-WA801 - $(eval $(call SingleProfile,TPLINK-LZMA,64kraw,TLWA850,tl-wa850re-v1,TL-WA850RE,ttyS0,115200,0x08500001,1,4Mlzma)) - $(eval $(call SingleProfile,TPLINK-LZMA,64kraw,TLWA860,tl-wa860re-v1,TL-WA860RE,ttyS0,115200,0x08600001,1,4Mlzma)) - $(eval $(call SingleProfile,TPLINK-LZMA,64kraw,TLWA901NV3,tl-wa901nd-v3,TL-WA901ND-v3,ttyS0,115200,0x09010003,1,4Mlzma)) -+$(eval $(call SingleProfile,TPLINK-LZMA,64kraw,TLWR941NV5,tl-wr941nd-v5,TL-WR941ND-v5,ttyS0,115200,0x09410005,1,4Mlzma)) - $(eval $(call SingleProfile,TPLINK-LZMA,64kraw,TLWR941NV6,tl-wr941nd-v6,TL-WDR3500,ttyS0,115200,0x09410006,1,4Mlzma)) - $(eval $(call SingleProfile,TPLINK-LZMA,64kraw,TLWR1041,tl-wr1041n-v2,TL-WR1041N-v2,ttyS0,115200,0x10410002,1,4Mlzma)) - $(eval $(call SingleProfile,TPLINK-LZMA,64kraw,TLWR1043V2,tl-wr1043nd-v2,TL-WR1043ND-v2,ttyS0,115200,0x10430002,1,8M)) -@@ -1319,7 +1320,7 @@ $(eval $(call MultiProfile,TLWR741,TLWR741NV1 TLWR741NV2 TLWR741NV4)) - $(eval $(call MultiProfile,TLWR743,TLWR743NV1 TLWR743NV2)) - $(eval $(call MultiProfile,TLWR841,TLWR841NV15 TLWR841NV3 TLWR841NV5 TLWR841NV7 TLWR841NV8 TLWR841NV9)) - $(eval $(call MultiProfile,TLWR842,TLWR842V1 TLWR842V2)) --$(eval $(call MultiProfile,TLWR941,TLWR941NV2 TLWR941NV3 TLWR941NV4 TLWR941NV6)) -+$(eval $(call MultiProfile,TLWR941,TLWR941NV2 TLWR941NV3 TLWR941NV4 TLWR941NV5 TLWR941NV6)) - $(eval $(call MultiProfile,TLWR1043,TLWR1043V1 TLWR1043V2)) - $(eval $(call MultiProfile,TLWDR4300,TLWDR3500V1 TLWDR3600V1 TLWDR4300V1 TLWDR4300V1IL TLWDR4310V1 MW4530RV1)) - $(eval $(call MultiProfile,TUBE2H,TUBE2H8M TUBE2H16M)) -diff --git a/target/linux/ar71xx/patches-3.10/610-MIPS-ath79-openwrt-machines.patch b/target/linux/ar71xx/patches-3.10/610-MIPS-ath79-openwrt-machines.patch -index 516d52d..3722519 100644 ---- a/target/linux/ar71xx/patches-3.10/610-MIPS-ath79-openwrt-machines.patch -+++ b/target/linux/ar71xx/patches-3.10/610-MIPS-ath79-openwrt-machines.patch -@@ -1,6 +1,6 @@ - --- a/arch/mips/ath79/machtypes.h - +++ b/arch/mips/ath79/machtypes.h --@@ -16,22 +16,145 @@ -+@@ -16,22 +16,146 @@ - - enum ath79_mach_type { - ATH79_MACH_GENERIC = 0, -@@ -108,6 +108,7 @@ - + ATH79_MACH_TL_WR841N_V8, /* TP-LINK TL-WR841N/ND v8 */ - + ATH79_MACH_TL_WR842N_V2, /* TP-LINK TL-WR842N/ND v2 */ - + ATH79_MACH_TL_WR941ND, /* TP-LINK TL-WR941ND */ -++ ATH79_MACH_TL_WR941ND_V5, /* TP-LINK TL-WR941ND v5 */ - ATH79_MACH_UBNT_AIRROUTER, /* Ubiquiti AirRouter */ - ATH79_MACH_UBNT_BULLET_M, /* Ubiquiti Bullet M */ - + ATH79_MACH_UBNT_LSSR71, /* Ubiquiti LS-SR71 */ -diff --git a/target/linux/ar71xx/patches-3.10/720-MIPS-ath79-add-Tube2H-support.patch b/target/linux/ar71xx/patches-3.10/720-MIPS-ath79-add-Tube2H-support.patch -index c4aa70c..7a3754b 100644 ---- a/target/linux/ar71xx/patches-3.10/720-MIPS-ath79-add-Tube2H-support.patch -+++ b/target/linux/ar71xx/patches-3.10/720-MIPS-ath79-add-Tube2H-support.patch -@@ -1,13 +1,13 @@ - --- a/arch/mips/ath79/machtypes.h - +++ b/arch/mips/ath79/machtypes.h --@@ -141,6 +141,7 @@ enum ath79_mach_type { -- ATH79_MACH_TL_WR841N_V9, /* TP-LINK TL-WR841N/ND v9 */ -+@@ -143,6 +143,7 @@ enum ath79_mach_type { - ATH79_MACH_TL_WR842N_V2, /* TP-LINK TL-WR842N/ND v2 */ - ATH79_MACH_TL_WR941ND, /* TP-LINK TL-WR941ND */ -+ ATH79_MACH_TL_WR941ND_V5, /* TP-LINK TL-WR941ND v5 */ - + ATH79_MACH_TUBE2H, /* Alfa Network Tube2H */ - ATH79_MACH_UBNT_AIRROUTER, /* Ubiquiti AirRouter */ - ATH79_MACH_UBNT_BULLET_M, /* Ubiquiti Bullet M */ -- ATH79_MACH_UBNT_LSSR71, /* Ubiquiti LS-SR71 */ -+ ATH79_MACH_UBNT_LOCO_M_XW, /* Ubiquiti Loco M XW */ - --- a/arch/mips/ath79/Kconfig - +++ b/arch/mips/ath79/Kconfig - @@ -29,6 +29,15 @@ config ATH79_MACH_ALFA_NX -@@ -28,7 +28,7 @@ - select SOC_AR724X - --- a/arch/mips/ath79/Makefile - +++ b/arch/mips/ath79/Makefile --@@ -116,6 +116,7 @@ obj-$(CONFIG_ATH79_MACH_TL_WR1043ND_V2) -+@@ -117,6 +117,7 @@ obj-$(CONFIG_ATH79_MACH_TL_WR1043ND_V2) - obj-$(CONFIG_ATH79_MACH_TL_WR2543N) += mach-tl-wr2543n.o - obj-$(CONFIG_ATH79_MACH_TL_WR703N) += mach-tl-wr703n.o - obj-$(CONFIG_ATH79_MACH_TL_WR720N_V3) += mach-tl-wr720n-v3.o diff --git a/patches/openwrt/0016-ar71xx-add-support-for-the-UniFi-AP-Outdoor-Plus.patch b/patches/openwrt/0016-ar71xx-add-support-for-the-UniFi-AP-Outdoor-Plus.patch deleted file mode 100644 index c5d18bf6..00000000 --- a/patches/openwrt/0016-ar71xx-add-support-for-the-UniFi-AP-Outdoor-Plus.patch +++ /dev/null @@ -1,177 +0,0 @@ -From: blogic -Date: Thu, 22 Jan 2015 09:35:46 +0000 -Subject: ar71xx: add support for the UniFi AP Outdoor Plus - -Signed-off-by: Matthias Schiffer - -diff --git a/target/linux/ar71xx/base-files/etc/diag.sh b/target/linux/ar71xx/base-files/etc/diag.sh -index f0d5d70..6aac86a 100755 ---- a/target/linux/ar71xx/base-files/etc/diag.sh -+++ b/target/linux/ar71xx/base-files/etc/diag.sh -@@ -244,6 +244,9 @@ get_status_led() { - uap-pro) - status_led="ubnt:white:dome" - ;; -+ unifi-outdoor-plus) -+ status_led="ubnt:white:front" -+ ;; - airgateway) - status_led="ubnt:white:status" - ;; -diff --git a/target/linux/ar71xx/base-files/lib/ar71xx.sh b/target/linux/ar71xx/base-files/lib/ar71xx.sh -index 5fbca92..61a7936 100755 ---- a/target/linux/ar71xx/base-files/lib/ar71xx.sh -+++ b/target/linux/ar71xx/base-files/lib/ar71xx.sh -@@ -723,6 +723,9 @@ ar71xx_board_detect() { - *"UniFiAP Outdoor") - name="unifi-outdoor" - ;; -+ *"UniFiAP Outdoor+") -+ name="unifi-outdoor-plus" -+ ;; - *WP543) - name="wp543" - ;; -diff --git a/target/linux/ar71xx/base-files/lib/upgrade/platform.sh b/target/linux/ar71xx/base-files/lib/upgrade/platform.sh -index e512f41..49746c4 100755 ---- a/target/linux/ar71xx/base-files/lib/upgrade/platform.sh -+++ b/target/linux/ar71xx/base-files/lib/upgrade/platform.sh -@@ -363,6 +363,7 @@ platform_check_image() { - return 1 - ;; - -+ unifi-outdoor-plus | \ - uap-pro) - [ "$magic_long" != "19852003" ] && { - echo "Invalid image type." -@@ -467,6 +468,7 @@ platform_do_upgrade() { - om5p) - platform_do_upgrade_openmesh "$ARGV" - ;; -+ unifi-outdoor-plus | \ - uap-pro) - MTD_CONFIG_ARGS="-s 0x180000" - default_do_upgrade "$ARGV" -diff --git a/target/linux/ar71xx/image/Makefile b/target/linux/ar71xx/image/Makefile -index ba16c7b..8505ac4 100644 ---- a/target/linux/ar71xx/image/Makefile -+++ b/target/linux/ar71xx/image/Makefile -@@ -1262,6 +1262,7 @@ $(eval $(call SingleProfile,TPLINK-LZMA,64kraw,SMART-300,smart-300,SMART-300,tty - $(eval $(call SingleProfile,TPLINK-LZMA,64kraw,OOLITE,oolite,GS-OOLITE,ttyATH0,115200,0x3C000101,1,16Mlzma)) - - $(eval $(call SingleProfile,UAPPRO,64k,UAPPRO,ubnt-uap-pro,UAP-PRO,ttyS0,115200,BZ,BZ,ar934x)) -+$(eval $(call SingleProfile,UAPPRO,64k,UBNTUNIFIOUTDOORPLUS,ubnt-unifi-outdoor-plus,UBNT-UOP,ttyS0,115200,BZ,BZ,ar7240)) - - $(eval $(call SingleProfile,UBDEV,64kraw,UBDEV01,ubdev01,UBNT-UF,ttyS0,115200,XM,XM,ar7240)) - -@@ -1324,7 +1325,7 @@ $(eval $(call MultiProfile,TLWR941,TLWR941NV2 TLWR941NV3 TLWR941NV4 TLWR941NV5 T - $(eval $(call MultiProfile,TLWR1043,TLWR1043V1 TLWR1043V2)) - $(eval $(call MultiProfile,TLWDR4300,TLWDR3500V1 TLWDR3600V1 TLWDR4300V1 TLWDR4300V1IL TLWDR4310V1 MW4530RV1)) - $(eval $(call MultiProfile,TUBE2H,TUBE2H8M TUBE2H16M)) --$(eval $(call MultiProfile,UBNT,UBNTAIRROUTER UBNTRS UBNTRSPRO UBNTLSSR71 UBNTBULLETM UBNTROCKETM UBNTNANOM UBNTNANOMXW UBNTLOCOXW UBNTUNIFI UBNTUNIFIOUTDOOR UAPPRO UBNTAIRGW)) -+$(eval $(call MultiProfile,UBNT,UBNTAIRROUTER UBNTRS UBNTRSPRO UBNTLSSR71 UBNTBULLETM UBNTROCKETM UBNTNANOM UBNTNANOMXW UBNTLOCOXW UBNTUNIFI UBNTUNIFIOUTDOOR UBNTUNIFIOUTDOORPLUS UAPPRO UBNTAIRGW)) - $(eval $(call MultiProfile,WNDR3700,WNDR3700V1 WNDR3700V2 WNDR3800 WNDR3800CH WNDRMAC WNDRMACV2)) - $(eval $(call MultiProfile,WNR612V2,REALWNR612V2 N150R)) - $(eval $(call MultiProfile,WP543,WP543_2M WP543_4M WP543_8M WP543_16M)) -diff --git a/target/linux/ar71xx/patches-3.10/610-MIPS-ath79-openwrt-machines.patch b/target/linux/ar71xx/patches-3.10/610-MIPS-ath79-openwrt-machines.patch -index 3722519..6bb8884 100644 ---- a/target/linux/ar71xx/patches-3.10/610-MIPS-ath79-openwrt-machines.patch -+++ b/target/linux/ar71xx/patches-3.10/610-MIPS-ath79-openwrt-machines.patch -@@ -1,6 +1,6 @@ - --- a/arch/mips/ath79/machtypes.h - +++ b/arch/mips/ath79/machtypes.h --@@ -16,22 +16,146 @@ -+@@ -16,22 +16,147 @@ - - enum ath79_mach_type { - ATH79_MACH_GENERIC = 0, -@@ -120,6 +120,7 @@ - ATH79_MACH_UBNT_UAP_PRO, /* Ubiquiti UniFi AP Pro */ - ATH79_MACH_UBNT_UNIFI, /* Ubiquiti Unifi */ - ATH79_MACH_UBNT_UNIFI_OUTDOOR, /* Ubiquiti UnifiAP Outdoor */ -++ ATH79_MACH_UBNT_UNIFI_OUTDOOR_PLUS, /* Ubiquiti UnifiAP Outdoor+ */ - ATH79_MACH_UBNT_XM, /* Ubiquiti Networks XM board rev 1.0 */ - + ATH79_MACH_WHR_G301N, /* Buffalo WHR-G301N */ - + ATH79_MACH_WHR_HP_G300N, /* Buffalo WHR-HP-G300N */ -diff --git a/target/linux/ar71xx/patches-3.10/616-MIPS-ath79-ubnt-xw.patch b/target/linux/ar71xx/patches-3.10/616-MIPS-ath79-ubnt-xw.patch -index 5e3d4d4..3c3c273 100644 ---- a/target/linux/ar71xx/patches-3.10/616-MIPS-ath79-ubnt-xw.patch -+++ b/target/linux/ar71xx/patches-3.10/616-MIPS-ath79-ubnt-xw.patch -@@ -1,6 +1,65 @@ - --- a/arch/mips/ath79/mach-ubnt-xm.c - +++ b/arch/mips/ath79/mach-ubnt-xm.c --@@ -332,3 +332,78 @@ static void __init ubnt_uap_pro_setup(vo -+@@ -186,6 +186,19 @@ static struct gpio_led ubnt_unifi_outdoo -+ } -+ }; -+ -++static struct gpio_led ubnt_unifi_outdoor_plus_leds_gpio[] __initdata = { -++ { -++ .name = "ubnt:white:front", -++ .gpio = 1, -++ .active_low = 0, -++ }, { -++ .name = "ubnt:blue:front", -++ .gpio = 0, -++ .active_low = 0, -++ } -++}; -++ -++ -+ static void __init ubnt_unifi_setup(void) -+ { -+ u8 *mac = (u8 *) KSEG1ADDR(0x1fff0000); -+@@ -245,6 +258,38 @@ MIPS_MACHINE(ATH79_MACH_UBNT_UNIFI_OUTDO -+ "Ubiquiti UniFiAP Outdoor", -+ ubnt_unifi_outdoor_setup); -+ -++ -++static void __init ubnt_unifi_outdoor_plus_setup(void) -++{ -++ u8 *mac1 = (u8 *) KSEG1ADDR(0x1fff0000); -++ u8 *mac2 = (u8 *) KSEG1ADDR(0x1fff0000 + ETH_ALEN); -++ u8 *ee = (u8 *) KSEG1ADDR(0x1fff1000); -++ -++ ath79_register_m25p80(NULL); -++ -++ ath79_register_mdio(0, ~(UBNT_UNIFIOD_PRI_PHYMASK | -++ UBNT_UNIFIOD_2ND_PHYMASK)); -++ -++ ath79_init_mac(ath79_eth0_data.mac_addr, mac1, 0); -++ ath79_init_mac(ath79_eth1_data.mac_addr, mac2, 0); -++ ath79_register_eth(0); -++ ath79_register_eth(1); -++ -++ ap91_pci_init(ee, NULL); -++ -++ ath79_register_leds_gpio(-1, ARRAY_SIZE(ubnt_unifi_outdoor_plus_leds_gpio), -++ ubnt_unifi_outdoor_plus_leds_gpio); -++ -++ ath79_register_gpio_keys_polled(-1, UBNT_XM_KEYS_POLL_INTERVAL, -++ ARRAY_SIZE(ubnt_xm_gpio_keys), -++ ubnt_xm_gpio_keys); -++} -++ -++MIPS_MACHINE(ATH79_MACH_UBNT_UNIFI_OUTDOOR_PLUS, "UBNT-UOP", -++ "Ubiquiti UniFiAP Outdoor+", -++ ubnt_unifi_outdoor_plus_setup); -++ -++ -+ static struct gpio_led ubnt_uap_pro_gpio_leds[] __initdata = { -+ { -+ .name = "ubnt:white:dome", -+@@ -332,3 +377,78 @@ static void __init ubnt_uap_pro_setup(vo - MIPS_MACHINE(ATH79_MACH_UBNT_UAP_PRO, "UAP-PRO", "Ubiquiti UniFi AP Pro", - ubnt_uap_pro_setup); - -@@ -81,8 +140,8 @@ - + ubnt_loco_m_xw_setup); - --- a/arch/mips/ath79/machtypes.h - +++ b/arch/mips/ath79/machtypes.h --@@ -121,9 +121,11 @@ enum ath79_mach_type { -- ATH79_MACH_TL_WR941ND, /* TP-LINK TL-WR941ND */ -+@@ -123,9 +123,11 @@ enum ath79_mach_type { -+ ATH79_MACH_TL_WR941ND_V5, /* TP-LINK TL-WR941ND v5 */ - ATH79_MACH_UBNT_AIRROUTER, /* Ubiquiti AirRouter */ - ATH79_MACH_UBNT_BULLET_M, /* Ubiquiti Bullet M */ - + ATH79_MACH_UBNT_LOCO_M_XW, /* Ubiquiti Loco M XW */ diff --git a/patches/openwrt/0017-mac80211-update-ath10k-to-compat-wireless-2015-03-05.patch b/patches/openwrt/0017-mac80211-update-ath10k-to-compat-wireless-2015-03-05.patch deleted file mode 100644 index 387ea9cf..00000000 --- a/patches/openwrt/0017-mac80211-update-ath10k-to-compat-wireless-2015-03-05.patch +++ /dev/null @@ -1,33655 +0,0 @@ -From: Matthias Schiffer -Date: Tue, 10 Mar 2015 12:40:53 +0100 -Subject: mac80211: update ath10k to compat-wireless-2015-03-05 - -Taken from http://openwrt.reigndropsfall.net/ - -diff --git a/package/kernel/mac80211/patches/917-mac80211-rx-reordering.patch b/package/kernel/mac80211/patches/917-mac80211-rx-reordering.patch -new file mode 100644 -index 0000000..1d0c559 ---- /dev/null -+++ b/package/kernel/mac80211/patches/917-mac80211-rx-reordering.patch -@@ -0,0 +1,271 @@ -+commit 08cf42e843f9a7e253502011c81677f61f7e5c42 -+Author: Michal Kazior -+Date: Wed Jul 16 12:12:15 2014 +0200 -+ -+ mac80211: add support for Rx reordering offloading -+ -+ Some drivers may be performing most of Tx/Rx -+ aggregation on their own (e.g. in firmware) -+ including AddBa/DelBa negotiations but may -+ otherwise require Rx reordering assistance. -+ -+ The patch exports 2 new functions for establishing -+ Rx aggregation sessions in assumption device -+ driver has taken care of the necessary -+ negotiations. -+ -+ Signed-off-by: Michal Kazior -+ [fix endian bug] -+ Signed-off-by: Johannes Berg -+ -+--- a/include/net/mac80211.h -++++ b/include/net/mac80211.h -+@@ -4481,6 +4481,40 @@ void ieee80211_stop_rx_ba_session(struct -+ */ -+ void ieee80211_send_bar(struct ieee80211_vif *vif, u8 *ra, u16 tid, u16 ssn); -+ -++/** -++ * ieee80211_start_rx_ba_session_offl - start a Rx BA session -++ * -++ * Some device drivers may offload part of the Rx aggregation flow including -++ * AddBa/DelBa negotiation but may otherwise be incapable of full Rx -++ * reordering. -++ * -++ * Create structures responsible for reordering so device drivers may call here -++ * when they complete AddBa negotiation. -++ * -++ * @vif: &struct ieee80211_vif pointer from the add_interface callback -++ * @addr: station mac address -++ * @tid: the rx tid -++ */ -++void ieee80211_start_rx_ba_session_offl(struct ieee80211_vif *vif, -++ const u8 *addr, u16 tid); -++ -++/** -++ * ieee80211_stop_rx_ba_session_offl - stop a Rx BA session -++ * -++ * Some device drivers may offload part of the Rx aggregation flow including -++ * AddBa/DelBa negotiation but may otherwise be incapable of full Rx -++ * reordering. -++ * -++ * Destroy structures responsible for reordering so device drivers may call here -++ * when they complete DelBa negotiation. -++ * -++ * @vif: &struct ieee80211_vif pointer from the add_interface callback -++ * @addr: station mac address -++ * @tid: the rx tid -++ */ -++void ieee80211_stop_rx_ba_session_offl(struct ieee80211_vif *vif, -++ const u8 *addr, u16 tid); -++ -+ /* Rate control API */ -+ -+ /** -+--- a/net/mac80211/agg-rx.c -++++ b/net/mac80211/agg-rx.c -+@@ -224,28 +224,15 @@ static void ieee80211_send_addba_resp(st -+ ieee80211_tx_skb(sdata, skb); -+ } -+ -+-void ieee80211_process_addba_request(struct ieee80211_local *local, -+- struct sta_info *sta, -+- struct ieee80211_mgmt *mgmt, -+- size_t len) -++void __ieee80211_start_rx_ba_session(struct sta_info *sta, -++ u8 dialog_token, u16 timeout, -++ u16 start_seq_num, u16 ba_policy, u16 tid, -++ u16 buf_size, bool tx) -+ { -++ struct ieee80211_local *local = sta->sdata->local; -+ struct tid_ampdu_rx *tid_agg_rx; -+- u16 capab, tid, timeout, ba_policy, buf_size, start_seq_num, status; -+- u8 dialog_token; -+ int ret = -EOPNOTSUPP; -+- -+- /* extract session parameters from addba request frame */ -+- dialog_token = mgmt->u.action.u.addba_req.dialog_token; -+- timeout = le16_to_cpu(mgmt->u.action.u.addba_req.timeout); -+- start_seq_num = -+- le16_to_cpu(mgmt->u.action.u.addba_req.start_seq_num) >> 4; -+- -+- capab = le16_to_cpu(mgmt->u.action.u.addba_req.capab); -+- ba_policy = (capab & IEEE80211_ADDBA_PARAM_POLICY_MASK) >> 1; -+- tid = (capab & IEEE80211_ADDBA_PARAM_TID_MASK) >> 2; -+- buf_size = (capab & IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK) >> 6; -+- -+- status = WLAN_STATUS_REQUEST_DECLINED; -++ u16 status = WLAN_STATUS_REQUEST_DECLINED; -+ -+ if (test_sta_flag(sta, WLAN_STA_BLOCK_BA)) { -+ ht_dbg(sta->sdata, -+@@ -264,7 +251,7 @@ void ieee80211_process_addba_request(str -+ status = WLAN_STATUS_INVALID_QOS_PARAM; -+ ht_dbg_ratelimited(sta->sdata, -+ "AddBA Req with bad params from %pM on tid %u. policy %d, buffer size %d\n", -+- mgmt->sa, tid, ba_policy, buf_size); -++ sta->sta.addr, tid, ba_policy, buf_size); -+ goto end_no_lock; -+ } -+ /* determine default buffer size */ -+@@ -281,7 +268,7 @@ void ieee80211_process_addba_request(str -+ if (sta->ampdu_mlme.tid_rx[tid]) { -+ ht_dbg_ratelimited(sta->sdata, -+ "unexpected AddBA Req from %pM on tid %u\n", -+- mgmt->sa, tid); -++ sta->sta.addr, tid); -+ -+ /* delete existing Rx BA session on the same tid */ -+ ___ieee80211_stop_rx_ba_session(sta, tid, WLAN_BACK_RECIPIENT, -+@@ -350,6 +337,74 @@ end: -+ mutex_unlock(&sta->ampdu_mlme.mtx); -+ -+ end_no_lock: -+- ieee80211_send_addba_resp(sta->sdata, sta->sta.addr, tid, -+- dialog_token, status, 1, buf_size, timeout); -++ if (tx) -++ ieee80211_send_addba_resp(sta->sdata, sta->sta.addr, tid, -++ dialog_token, status, 1, buf_size, -++ timeout); -++} -++ -++void ieee80211_process_addba_request(struct ieee80211_local *local, -++ struct sta_info *sta, -++ struct ieee80211_mgmt *mgmt, -++ size_t len) -++{ -++ u16 capab, tid, timeout, ba_policy, buf_size, start_seq_num; -++ u8 dialog_token; -++ -++ /* extract session parameters from addba request frame */ -++ dialog_token = mgmt->u.action.u.addba_req.dialog_token; -++ timeout = le16_to_cpu(mgmt->u.action.u.addba_req.timeout); -++ start_seq_num = -++ le16_to_cpu(mgmt->u.action.u.addba_req.start_seq_num) >> 4; -++ -++ capab = le16_to_cpu(mgmt->u.action.u.addba_req.capab); -++ ba_policy = (capab & IEEE80211_ADDBA_PARAM_POLICY_MASK) >> 1; -++ tid = (capab & IEEE80211_ADDBA_PARAM_TID_MASK) >> 2; -++ buf_size = (capab & IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK) >> 6; -++ -++ __ieee80211_start_rx_ba_session(sta, dialog_token, timeout, -++ start_seq_num, ba_policy, tid, -++ buf_size, true); -++} -++ -++void ieee80211_start_rx_ba_session_offl(struct ieee80211_vif *vif, -++ const u8 *addr, u16 tid) -++{ -++ struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif); -++ struct ieee80211_local *local = sdata->local; -++ struct ieee80211_rx_agg *rx_agg; -++ struct sk_buff *skb = dev_alloc_skb(0); -++ -++ if (unlikely(!skb)) -++ return; -++ -++ rx_agg = (struct ieee80211_rx_agg *) &skb->cb; -++ memcpy(&rx_agg->addr, addr, ETH_ALEN); -++ rx_agg->tid = tid; -++ -++ skb->pkt_type = IEEE80211_SDATA_QUEUE_RX_AGG_START; -++ skb_queue_tail(&sdata->skb_queue, skb); -++ ieee80211_queue_work(&local->hw, &sdata->work); -++} -++EXPORT_SYMBOL(ieee80211_start_rx_ba_session_offl); -++ -++void ieee80211_stop_rx_ba_session_offl(struct ieee80211_vif *vif, -++ const u8 *addr, u16 tid) -++{ -++ struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif); -++ struct ieee80211_local *local = sdata->local; -++ struct ieee80211_rx_agg *rx_agg; -++ struct sk_buff *skb = dev_alloc_skb(0); -++ -++ if (unlikely(!skb)) -++ return; -++ -++ rx_agg = (struct ieee80211_rx_agg *) &skb->cb; -++ memcpy(&rx_agg->addr, addr, ETH_ALEN); -++ rx_agg->tid = tid; -++ -++ skb->pkt_type = IEEE80211_SDATA_QUEUE_RX_AGG_STOP; -++ skb_queue_tail(&sdata->skb_queue, skb); -++ ieee80211_queue_work(&local->hw, &sdata->work); -+ } -++EXPORT_SYMBOL(ieee80211_stop_rx_ba_session_offl); -+--- a/net/mac80211/ieee80211_i.h -++++ b/net/mac80211/ieee80211_i.h -+@@ -902,10 +902,17 @@ ieee80211_vif_get_shift(struct ieee80211 -+ return shift; -+ } -+ -++struct ieee80211_rx_agg { -++ u8 addr[ETH_ALEN]; -++ u16 tid; -++}; -++ -+ enum sdata_queue_type { -+ IEEE80211_SDATA_QUEUE_TYPE_FRAME = 0, -+ IEEE80211_SDATA_QUEUE_AGG_START = 1, -+ IEEE80211_SDATA_QUEUE_AGG_STOP = 2, -++ IEEE80211_SDATA_QUEUE_RX_AGG_START = 3, -++ IEEE80211_SDATA_QUEUE_RX_AGG_STOP = 4, -+ }; -+ -+ enum { -+@@ -1554,6 +1561,10 @@ void ___ieee80211_stop_rx_ba_session(str -+ u16 initiator, u16 reason, bool stop); -+ void __ieee80211_stop_rx_ba_session(struct sta_info *sta, u16 tid, -+ u16 initiator, u16 reason, bool stop); -++void __ieee80211_start_rx_ba_session(struct sta_info *sta, -++ u8 dialog_token, u16 timeout, -++ u16 start_seq_num, u16 ba_policy, u16 tid, -++ u16 buf_size, bool tx); -+ void ieee80211_sta_tear_down_BA_sessions(struct sta_info *sta, -+ enum ieee80211_agg_stop_reason reason); -+ void ieee80211_process_delba(struct ieee80211_sub_if_data *sdata, -+--- a/net/mac80211/iface.c -++++ b/net/mac80211/iface.c -+@@ -1154,6 +1154,7 @@ static void ieee80211_iface_work(struct -+ struct sk_buff *skb; -+ struct sta_info *sta; -+ struct ieee80211_ra_tid *ra_tid; -++ struct ieee80211_rx_agg *rx_agg; -+ -+ if (!ieee80211_sdata_running(sdata)) -+ return; -+@@ -1181,6 +1182,34 @@ static void ieee80211_iface_work(struct -+ ra_tid = (void *)&skb->cb; -+ ieee80211_stop_tx_ba_cb(&sdata->vif, ra_tid->ra, -+ ra_tid->tid); -++ } else if (skb->pkt_type == IEEE80211_SDATA_QUEUE_RX_AGG_START) { -++ rx_agg = (void *)&skb->cb; -++ mutex_lock(&local->sta_mtx); -++ sta = sta_info_get_bss(sdata, rx_agg->addr); -++ if (sta) { -++ u16 last_seq; -++ -++ last_seq = le16_to_cpu( -++ sta->last_seq_ctrl[rx_agg->tid]); -++ -++ __ieee80211_start_rx_ba_session(sta, -++ 0, 0, -++ ieee80211_sn_inc(last_seq), -++ 1, rx_agg->tid, -++ IEEE80211_MAX_AMPDU_BUF, -++ false); -++ } -++ mutex_unlock(&local->sta_mtx); -++ } else if (skb->pkt_type == IEEE80211_SDATA_QUEUE_RX_AGG_STOP) { -++ rx_agg = (void *)&skb->cb; -++ mutex_lock(&local->sta_mtx); -++ sta = sta_info_get_bss(sdata, rx_agg->addr); -++ if (sta) -++ __ieee80211_stop_rx_ba_session(sta, -++ rx_agg->tid, -++ WLAN_BACK_RECIPIENT, 0, -++ false); -++ mutex_unlock(&local->sta_mtx); -+ } else if (ieee80211_is_action(mgmt->frame_control) && -+ mgmt->u.action.category == WLAN_CATEGORY_BACK) { -+ int len = skb->len; -diff --git a/package/kernel/mac80211/patches/918-ath-spectral-debugfs.patch b/package/kernel/mac80211/patches/918-ath-spectral-debugfs.patch -new file mode 100644 -index 0000000..d0c1bbd ---- /dev/null -+++ b/package/kernel/mac80211/patches/918-ath-spectral-debugfs.patch -@@ -0,0 +1,192 @@ -+--- a/drivers/net/wireless/ath/ath9k/spectral.h -++++ b/drivers/net/wireless/ath/ath9k/spectral.h -+@@ -17,6 +17,8 @@ -+ #ifndef SPECTRAL_H -+ #define SPECTRAL_H -+ -++#include "../spectral_common.h" -++ -+ /* enum spectral_mode: -+ * -+ * @SPECTRAL_DISABLED: spectral mode is disabled -+@@ -54,8 +56,6 @@ struct ath_ht20_mag_info { -+ u8 max_exp; -+ } __packed; -+ -+-#define SPECTRAL_HT20_NUM_BINS 56 -+- -+ /* WARNING: don't actually use this struct! MAC may vary the amount of -+ * data by -1/+2. This struct is for reference only. -+ */ -+@@ -83,8 +83,6 @@ struct ath_ht20_40_mag_info { -+ u8 max_exp; -+ } __packed; -+ -+-#define SPECTRAL_HT20_40_NUM_BINS 128 -+- -+ /* WARNING: don't actually use this struct! MAC may vary the amount of -+ * data. This struct is for reference only. -+ */ -+@@ -125,71 +123,6 @@ static inline u8 spectral_bitmap_weight( -+ return bins[0] & 0x3f; -+ } -+ -+-/* FFT sample format given to userspace via debugfs. -+- * -+- * Please keep the type/length at the front position and change -+- * other fields after adding another sample type -+- * -+- * TODO: this might need rework when switching to nl80211-based -+- * interface. -+- */ -+-enum ath_fft_sample_type { -+- ATH_FFT_SAMPLE_HT20 = 1, -+- ATH_FFT_SAMPLE_HT20_40, -+-}; -+- -+-struct fft_sample_tlv { -+- u8 type; /* see ath_fft_sample */ -+- __be16 length; -+- /* type dependent data follows */ -+-} __packed; -+- -+-struct fft_sample_ht20 { -+- struct fft_sample_tlv tlv; -+- -+- u8 max_exp; -+- -+- __be16 freq; -+- s8 rssi; -+- s8 noise; -+- -+- __be16 max_magnitude; -+- u8 max_index; -+- u8 bitmap_weight; -+- -+- __be64 tsf; -+- -+- u8 data[SPECTRAL_HT20_NUM_BINS]; -+-} __packed; -+- -+-struct fft_sample_ht20_40 { -+- struct fft_sample_tlv tlv; -+- -+- u8 channel_type; -+- __be16 freq; -+- -+- s8 lower_rssi; -+- s8 upper_rssi; -+- -+- __be64 tsf; -+- -+- s8 lower_noise; -+- s8 upper_noise; -+- -+- __be16 lower_max_magnitude; -+- __be16 upper_max_magnitude; -+- -+- u8 lower_max_index; -+- u8 upper_max_index; -+- -+- u8 lower_bitmap_weight; -+- u8 upper_bitmap_weight; -+- -+- u8 max_exp; -+- -+- u8 data[SPECTRAL_HT20_40_NUM_BINS]; -+-} __packed; -+- -+ void ath9k_spectral_init_debug(struct ath_softc *sc); -+ void ath9k_spectral_deinit_debug(struct ath_softc *sc); -+ -+--- /dev/null -++++ b/drivers/net/wireless/ath/spectral_common.h -+@@ -0,0 +1,88 @@ -++/* -++ * Copyright (c) 2013 Qualcomm Atheros, Inc. -++ * -++ * Permission to use, copy, modify, and/or distribute this software for any -++ * purpose with or without fee is hereby granted, provided that the above -++ * copyright notice and this permission notice appear in all copies. -++ * -++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -++ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -++ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -++ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -++ */ -++ -++#ifndef SPECTRAL_COMMON_H -++#define SPECTRAL_COMMON_H -++ -++#define SPECTRAL_HT20_NUM_BINS 56 -++#define SPECTRAL_HT20_40_NUM_BINS 128 -++ -++/* FFT sample format given to userspace via debugfs. -++ * -++ * Please keep the type/length at the front position and change -++ * other fields after adding another sample type -++ * -++ * TODO: this might need rework when switching to nl80211-based -++ * interface. -++ */ -++enum ath_fft_sample_type { -++ ATH_FFT_SAMPLE_HT20 = 1, -++ ATH_FFT_SAMPLE_HT20_40, -++}; -++ -++struct fft_sample_tlv { -++ u8 type; /* see ath_fft_sample */ -++ __be16 length; -++ /* type dependent data follows */ -++} __packed; -++ -++struct fft_sample_ht20 { -++ struct fft_sample_tlv tlv; -++ -++ u8 max_exp; -++ -++ __be16 freq; -++ s8 rssi; -++ s8 noise; -++ -++ __be16 max_magnitude; -++ u8 max_index; -++ u8 bitmap_weight; -++ -++ __be64 tsf; -++ -++ u8 data[SPECTRAL_HT20_NUM_BINS]; -++} __packed; -++ -++struct fft_sample_ht20_40 { -++ struct fft_sample_tlv tlv; -++ -++ u8 channel_type; -++ __be16 freq; -++ -++ s8 lower_rssi; -++ s8 upper_rssi; -++ -++ __be64 tsf; -++ -++ s8 lower_noise; -++ s8 upper_noise; -++ -++ __be16 lower_max_magnitude; -++ __be16 upper_max_magnitude; -++ -++ u8 lower_max_index; -++ u8 upper_max_index; -++ -++ u8 lower_bitmap_weight; -++ u8 upper_bitmap_weight; -++ -++ u8 max_exp; -++ -++ u8 data[SPECTRAL_HT20_40_NUM_BINS]; -++} __packed; -++ -++#endif /* SPECTRAL_COMMON_H */ -diff --git a/package/kernel/mac80211/patches/919-update-ath10k.patch b/package/kernel/mac80211/patches/919-update-ath10k.patch -new file mode 100644 -index 0000000..45fccb8 ---- /dev/null -+++ b/package/kernel/mac80211/patches/919-update-ath10k.patch -@@ -0,0 +1,33023 @@ -+--- a/drivers/net/wireless/ath/ath10k/Kconfig -++++ b/drivers/net/wireless/ath/ath10k/Kconfig -+@@ -26,13 +26,15 @@ config ATH10K_DEBUG -+ -+ config ATH10K_DEBUGFS -+ bool "Atheros ath10k debugfs support" -+- depends on ATH10K -++ depends on ATH10K && DEBUG_FS -++ depends on RELAY -+ ---help--- -+ Enabled debugfs support -+ -+ If unsure, say Y to make it easier to debug problems. -+ -+ config ATH10K_TRACING -++ depends on !KERNEL_3_4 -+ bool "Atheros ath10k tracing support" -+ depends on ATH10K -+ depends on EVENT_TRACING -+--- a/drivers/net/wireless/ath/ath10k/Makefile -++++ b/drivers/net/wireless/ath/ath10k/Makefile -+@@ -8,9 +8,15 @@ ath10k_core-y += mac.o \ -+ htt_tx.o \ -+ txrx.o \ -+ wmi.o \ -+- bmi.o -++ wmi-tlv.o \ -++ bmi.o \ -++ hw.o -+ -++ath10k_core-$(CPTCFG_ATH10K_DEBUGFS) += spectral.o -++ath10k_core-$(CPTCFG_NL80211_TESTMODE) += testmode.o -+ ath10k_core-$(CPTCFG_ATH10K_TRACING) += trace.o -++ath10k_core-$(CONFIG_THERMAL) += thermal.o -++ath10k_core-$(CPTCFG_MAC80211_DEBUGFS) += debugfs_sta.o -+ -+ obj-$(CPTCFG_ATH10K_PCI) += ath10k_pci.o -+ ath10k_pci-y += pci.o \ -+--- a/drivers/net/wireless/ath/ath10k/bmi.c -++++ b/drivers/net/wireless/ath/ath10k/bmi.c -+@@ -22,7 +22,7 @@ -+ -+ void ath10k_bmi_start(struct ath10k *ar) -+ { -+- ath10k_dbg(ATH10K_DBG_BMI, "bmi start\n"); -++ ath10k_dbg(ar, ATH10K_DBG_BMI, "bmi start\n"); -+ -+ ar->bmi.done_sent = false; -+ } -+@@ -33,10 +33,10 @@ int ath10k_bmi_done(struct ath10k *ar) -+ u32 cmdlen = sizeof(cmd.id) + sizeof(cmd.done); -+ int ret; -+ -+- ath10k_dbg(ATH10K_DBG_BMI, "bmi done\n"); -++ ath10k_dbg(ar, ATH10K_DBG_BMI, "bmi done\n"); -+ -+ if (ar->bmi.done_sent) { -+- ath10k_dbg(ATH10K_DBG_BMI, "bmi skipped\n"); -++ ath10k_dbg(ar, ATH10K_DBG_BMI, "bmi skipped\n"); -+ return 0; -+ } -+ -+@@ -45,7 +45,7 @@ int ath10k_bmi_done(struct ath10k *ar) -+ -+ ret = ath10k_hif_exchange_bmi_msg(ar, &cmd, cmdlen, NULL, NULL); -+ if (ret) { -+- ath10k_warn("unable to write to the device: %d\n", ret); -++ ath10k_warn(ar, "unable to write to the device: %d\n", ret); -+ return ret; -+ } -+ -+@@ -61,10 +61,10 @@ int ath10k_bmi_get_target_info(struct at -+ u32 resplen = sizeof(resp.get_target_info); -+ int ret; -+ -+- ath10k_dbg(ATH10K_DBG_BMI, "bmi get target info\n"); -++ ath10k_dbg(ar, ATH10K_DBG_BMI, "bmi get target info\n"); -+ -+ if (ar->bmi.done_sent) { -+- ath10k_warn("BMI Get Target Info Command disallowed\n"); -++ ath10k_warn(ar, "BMI Get Target Info Command disallowed\n"); -+ return -EBUSY; -+ } -+ -+@@ -72,12 +72,12 @@ int ath10k_bmi_get_target_info(struct at -+ -+ ret = ath10k_hif_exchange_bmi_msg(ar, &cmd, cmdlen, &resp, &resplen); -+ if (ret) { -+- ath10k_warn("unable to get target info from device\n"); -++ ath10k_warn(ar, "unable to get target info from device\n"); -+ return ret; -+ } -+ -+ if (resplen < sizeof(resp.get_target_info)) { -+- ath10k_warn("invalid get_target_info response length (%d)\n", -++ ath10k_warn(ar, "invalid get_target_info response length (%d)\n", -+ resplen); -+ return -EIO; -+ } -+@@ -97,11 +97,11 @@ int ath10k_bmi_read_memory(struct ath10k -+ u32 rxlen; -+ int ret; -+ -+- ath10k_dbg(ATH10K_DBG_BMI, "bmi read address 0x%x length %d\n", -++ ath10k_dbg(ar, ATH10K_DBG_BMI, "bmi read address 0x%x length %d\n", -+ address, length); -+ -+ if (ar->bmi.done_sent) { -+- ath10k_warn("command disallowed\n"); -++ ath10k_warn(ar, "command disallowed\n"); -+ return -EBUSY; -+ } -+ -+@@ -115,7 +115,7 @@ int ath10k_bmi_read_memory(struct ath10k -+ ret = ath10k_hif_exchange_bmi_msg(ar, &cmd, cmdlen, -+ &resp, &rxlen); -+ if (ret) { -+- ath10k_warn("unable to read from the device (%d)\n", -++ ath10k_warn(ar, "unable to read from the device (%d)\n", -+ ret); -+ return ret; -+ } -+@@ -137,11 +137,11 @@ int ath10k_bmi_write_memory(struct ath10 -+ u32 txlen; -+ int ret; -+ -+- ath10k_dbg(ATH10K_DBG_BMI, "bmi write address 0x%x length %d\n", -++ ath10k_dbg(ar, ATH10K_DBG_BMI, "bmi write address 0x%x length %d\n", -+ address, length); -+ -+ if (ar->bmi.done_sent) { -+- ath10k_warn("command disallowed\n"); -++ ath10k_warn(ar, "command disallowed\n"); -+ return -EBUSY; -+ } -+ -+@@ -159,7 +159,7 @@ int ath10k_bmi_write_memory(struct ath10 -+ ret = ath10k_hif_exchange_bmi_msg(ar, &cmd, hdrlen + txlen, -+ NULL, NULL); -+ if (ret) { -+- ath10k_warn("unable to write to the device (%d)\n", -++ ath10k_warn(ar, "unable to write to the device (%d)\n", -+ ret); -+ return ret; -+ } -+@@ -183,11 +183,11 @@ int ath10k_bmi_execute(struct ath10k *ar -+ u32 resplen = sizeof(resp.execute); -+ int ret; -+ -+- ath10k_dbg(ATH10K_DBG_BMI, "bmi execute address 0x%x param 0x%x\n", -++ ath10k_dbg(ar, ATH10K_DBG_BMI, "bmi execute address 0x%x param 0x%x\n", -+ address, param); -+ -+ if (ar->bmi.done_sent) { -+- ath10k_warn("command disallowed\n"); -++ ath10k_warn(ar, "command disallowed\n"); -+ return -EBUSY; -+ } -+ -+@@ -197,19 +197,19 @@ int ath10k_bmi_execute(struct ath10k *ar -+ -+ ret = ath10k_hif_exchange_bmi_msg(ar, &cmd, cmdlen, &resp, &resplen); -+ if (ret) { -+- ath10k_warn("unable to read from the device\n"); -++ ath10k_warn(ar, "unable to read from the device\n"); -+ return ret; -+ } -+ -+ if (resplen < sizeof(resp.execute)) { -+- ath10k_warn("invalid execute response length (%d)\n", -++ ath10k_warn(ar, "invalid execute response length (%d)\n", -+ resplen); -+ return -EIO; -+ } -+ -+ *result = __le32_to_cpu(resp.execute.result); -+ -+- ath10k_dbg(ATH10K_DBG_BMI, "bmi execute result 0x%x\n", *result); -++ ath10k_dbg(ar, ATH10K_DBG_BMI, "bmi execute result 0x%x\n", *result); -+ -+ return 0; -+ } -+@@ -221,11 +221,11 @@ int ath10k_bmi_lz_data(struct ath10k *ar -+ u32 txlen; -+ int ret; -+ -+- ath10k_dbg(ATH10K_DBG_BMI, "bmi lz data buffer 0x%p length %d\n", -++ ath10k_dbg(ar, ATH10K_DBG_BMI, "bmi lz data buffer 0x%p length %d\n", -+ buffer, length); -+ -+ if (ar->bmi.done_sent) { -+- ath10k_warn("command disallowed\n"); -++ ath10k_warn(ar, "command disallowed\n"); -+ return -EBUSY; -+ } -+ -+@@ -241,7 +241,7 @@ int ath10k_bmi_lz_data(struct ath10k *ar -+ ret = ath10k_hif_exchange_bmi_msg(ar, &cmd, hdrlen + txlen, -+ NULL, NULL); -+ if (ret) { -+- ath10k_warn("unable to write to the device\n"); -++ ath10k_warn(ar, "unable to write to the device\n"); -+ return ret; -+ } -+ -+@@ -258,11 +258,11 @@ int ath10k_bmi_lz_stream_start(struct at -+ u32 cmdlen = sizeof(cmd.id) + sizeof(cmd.lz_start); -+ int ret; -+ -+- ath10k_dbg(ATH10K_DBG_BMI, "bmi lz stream start address 0x%x\n", -++ ath10k_dbg(ar, ATH10K_DBG_BMI, "bmi lz stream start address 0x%x\n", -+ address); -+ -+ if (ar->bmi.done_sent) { -+- ath10k_warn("command disallowed\n"); -++ ath10k_warn(ar, "command disallowed\n"); -+ return -EBUSY; -+ } -+ -+@@ -271,7 +271,7 @@ int ath10k_bmi_lz_stream_start(struct at -+ -+ ret = ath10k_hif_exchange_bmi_msg(ar, &cmd, cmdlen, NULL, NULL); -+ if (ret) { -+- ath10k_warn("unable to Start LZ Stream to the device\n"); -++ ath10k_warn(ar, "unable to Start LZ Stream to the device\n"); -+ return ret; -+ } -+ -+@@ -286,7 +286,7 @@ int ath10k_bmi_fast_download(struct ath1 -+ u32 trailer_len = length - head_len; -+ int ret; -+ -+- ath10k_dbg(ATH10K_DBG_BMI, -++ ath10k_dbg(ar, ATH10K_DBG_BMI, -+ "bmi fast download address 0x%x buffer 0x%p length %d\n", -+ address, buffer, length); -+ -+--- a/drivers/net/wireless/ath/ath10k/bmi.h -++++ b/drivers/net/wireless/ath/ath10k/bmi.h -+@@ -177,7 +177,6 @@ struct bmi_target_info { -+ u32 type; -+ }; -+ -+- -+ /* in msec */ -+ #define BMI_COMMUNICATION_TIMEOUT_HZ (1*HZ) -+ -+@@ -201,7 +200,8 @@ int ath10k_bmi_write_memory(struct ath10 -+ \ -+ addr = host_interest_item_address(HI_ITEM(item)); \ -+ ret = ath10k_bmi_read_memory(ar, addr, (u8 *)&tmp, 4); \ -+- *val = __le32_to_cpu(tmp); \ -++ if (!ret) \ -++ *val = __le32_to_cpu(tmp); \ -+ ret; \ -+ }) -+ -+--- a/drivers/net/wireless/ath/ath10k/ce.c -++++ b/drivers/net/wireless/ath/ath10k/ce.c -+@@ -260,7 +260,6 @@ static inline void ath10k_ce_engine_int_ -+ ath10k_pci_write32(ar, ce_ctrl_addr + HOST_IS_ADDRESS, mask); -+ } -+ -+- -+ /* -+ * Guts of ath10k_ce_send, used by both ath10k_ce_send and -+ * ath10k_ce_sendlist_send. -+@@ -284,13 +283,9 @@ int ath10k_ce_send_nolock(struct ath10k_ -+ int ret = 0; -+ -+ if (nbytes > ce_state->src_sz_max) -+- ath10k_warn("%s: send more we can (nbytes: %d, max: %d)\n", -++ ath10k_warn(ar, "%s: send more we can (nbytes: %d, max: %d)\n", -+ __func__, nbytes, ce_state->src_sz_max); -+ -+- ret = ath10k_pci_wake(ar); -+- if (ret) -+- return ret; -+- -+ if (unlikely(CE_RING_DELTA(nentries_mask, -+ write_index, sw_index - 1) <= 0)) { -+ ret = -ENOSR; -+@@ -325,10 +320,36 @@ int ath10k_ce_send_nolock(struct ath10k_ -+ -+ src_ring->write_index = write_index; -+ exit: -+- ath10k_pci_sleep(ar); -+ return ret; -+ } -+ -++void __ath10k_ce_send_revert(struct ath10k_ce_pipe *pipe) -++{ -++ struct ath10k *ar = pipe->ar; -++ struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); -++ struct ath10k_ce_ring *src_ring = pipe->src_ring; -++ u32 ctrl_addr = pipe->ctrl_addr; -++ -++ lockdep_assert_held(&ar_pci->ce_lock); -++ -++ /* -++ * This function must be called only if there is an incomplete -++ * scatter-gather transfer (before index register is updated) -++ * that needs to be cleaned up. -++ */ -++ if (WARN_ON_ONCE(src_ring->write_index == src_ring->sw_index)) -++ return; -++ -++ if (WARN_ON_ONCE(src_ring->write_index == -++ ath10k_ce_src_ring_write_index_get(ar, ctrl_addr))) -++ return; -++ -++ src_ring->write_index--; -++ src_ring->write_index &= src_ring->nentries_mask; -++ -++ src_ring->per_transfer_context[src_ring->write_index] = NULL; -++} -++ -+ int ath10k_ce_send(struct ath10k_ce_pipe *ce_state, -+ void *per_transfer_context, -+ u32 buffer, -+@@ -363,49 +384,56 @@ int ath10k_ce_num_free_src_entries(struc -+ return delta; -+ } -+ -+-int ath10k_ce_recv_buf_enqueue(struct ath10k_ce_pipe *ce_state, -+- void *per_recv_context, -+- u32 buffer) -++int __ath10k_ce_rx_num_free_bufs(struct ath10k_ce_pipe *pipe) -+ { -+- struct ath10k_ce_ring *dest_ring = ce_state->dest_ring; -+- u32 ctrl_addr = ce_state->ctrl_addr; -+- struct ath10k *ar = ce_state->ar; -++ struct ath10k *ar = pipe->ar; -+ struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); -++ struct ath10k_ce_ring *dest_ring = pipe->dest_ring; -+ unsigned int nentries_mask = dest_ring->nentries_mask; -+- unsigned int write_index; -+- unsigned int sw_index; -+- int ret; -++ unsigned int write_index = dest_ring->write_index; -++ unsigned int sw_index = dest_ring->sw_index; -+ -+- spin_lock_bh(&ar_pci->ce_lock); -+- write_index = dest_ring->write_index; -+- sw_index = dest_ring->sw_index; -++ lockdep_assert_held(&ar_pci->ce_lock); -+ -+- ret = ath10k_pci_wake(ar); -+- if (ret) -+- goto out; -++ return CE_RING_DELTA(nentries_mask, write_index, sw_index - 1); -++} -+ -+- if (CE_RING_DELTA(nentries_mask, write_index, sw_index - 1) > 0) { -+- struct ce_desc *base = dest_ring->base_addr_owner_space; -+- struct ce_desc *desc = CE_DEST_RING_TO_DESC(base, write_index); -++int __ath10k_ce_rx_post_buf(struct ath10k_ce_pipe *pipe, void *ctx, u32 paddr) -++{ -++ struct ath10k *ar = pipe->ar; -++ struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); -++ struct ath10k_ce_ring *dest_ring = pipe->dest_ring; -++ unsigned int nentries_mask = dest_ring->nentries_mask; -++ unsigned int write_index = dest_ring->write_index; -++ unsigned int sw_index = dest_ring->sw_index; -++ struct ce_desc *base = dest_ring->base_addr_owner_space; -++ struct ce_desc *desc = CE_DEST_RING_TO_DESC(base, write_index); -++ u32 ctrl_addr = pipe->ctrl_addr; -+ -+- /* Update destination descriptor */ -+- desc->addr = __cpu_to_le32(buffer); -+- desc->nbytes = 0; -++ lockdep_assert_held(&ar_pci->ce_lock); -+ -+- dest_ring->per_transfer_context[write_index] = -+- per_recv_context; -++ if (CE_RING_DELTA(nentries_mask, write_index, sw_index - 1) == 0) -++ return -EIO; -+ -+- /* Update Destination Ring Write Index */ -+- write_index = CE_RING_IDX_INCR(nentries_mask, write_index); -+- ath10k_ce_dest_ring_write_index_set(ar, ctrl_addr, write_index); -+- dest_ring->write_index = write_index; -+- ret = 0; -+- } else { -+- ret = -EIO; -+- } -+- ath10k_pci_sleep(ar); -++ desc->addr = __cpu_to_le32(paddr); -++ desc->nbytes = 0; -++ -++ dest_ring->per_transfer_context[write_index] = ctx; -++ write_index = CE_RING_IDX_INCR(nentries_mask, write_index); -++ ath10k_ce_dest_ring_write_index_set(ar, ctrl_addr, write_index); -++ dest_ring->write_index = write_index; -++ -++ return 0; -++} -+ -+-out: -++int ath10k_ce_rx_post_buf(struct ath10k_ce_pipe *pipe, void *ctx, u32 paddr) -++{ -++ struct ath10k *ar = pipe->ar; -++ struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); -++ int ret; -++ -++ spin_lock_bh(&ar_pci->ce_lock); -++ ret = __ath10k_ce_rx_post_buf(pipe, ctx, paddr); -+ spin_unlock_bh(&ar_pci->ce_lock); -+ -+ return ret; -+@@ -415,12 +443,12 @@ out: -+ * Guts of ath10k_ce_completed_recv_next. -+ * The caller takes responsibility for any necessary locking. -+ */ -+-static int ath10k_ce_completed_recv_next_nolock(struct ath10k_ce_pipe *ce_state, -+- void **per_transfer_contextp, -+- u32 *bufferp, -+- unsigned int *nbytesp, -+- unsigned int *transfer_idp, -+- unsigned int *flagsp) -++int ath10k_ce_completed_recv_next_nolock(struct ath10k_ce_pipe *ce_state, -++ void **per_transfer_contextp, -++ u32 *bufferp, -++ unsigned int *nbytesp, -++ unsigned int *transfer_idp, -++ unsigned int *flagsp) -+ { -+ struct ath10k_ce_ring *dest_ring = ce_state->dest_ring; -+ unsigned int nentries_mask = dest_ring->nentries_mask; -+@@ -530,6 +558,7 @@ int ath10k_ce_revoke_recv_next(struct at -+ -+ /* sanity */ -+ dest_ring->per_transfer_context[sw_index] = NULL; -++ desc->nbytes = 0; -+ -+ /* Update sw_index */ -+ sw_index = CE_RING_IDX_INCR(nentries_mask, sw_index); -+@@ -548,11 +577,11 @@ int ath10k_ce_revoke_recv_next(struct at -+ * Guts of ath10k_ce_completed_send_next. -+ * The caller takes responsibility for any necessary locking. -+ */ -+-static int ath10k_ce_completed_send_next_nolock(struct ath10k_ce_pipe *ce_state, -+- void **per_transfer_contextp, -+- u32 *bufferp, -+- unsigned int *nbytesp, -+- unsigned int *transfer_idp) -++int ath10k_ce_completed_send_next_nolock(struct ath10k_ce_pipe *ce_state, -++ void **per_transfer_contextp, -++ u32 *bufferp, -++ unsigned int *nbytesp, -++ unsigned int *transfer_idp) -+ { -+ struct ath10k_ce_ring *src_ring = ce_state->src_ring; -+ u32 ctrl_addr = ce_state->ctrl_addr; -+@@ -561,7 +590,6 @@ static int ath10k_ce_completed_send_next -+ unsigned int sw_index = src_ring->sw_index; -+ struct ce_desc *sdesc, *sbase; -+ unsigned int read_index; -+- int ret; -+ -+ if (src_ring->hw_index == sw_index) { -+ /* -+@@ -572,20 +600,17 @@ static int ath10k_ce_completed_send_next -+ * value of the HW index has become stale. -+ */ -+ -+- ret = ath10k_pci_wake(ar); -+- if (ret) -+- return ret; -+- -+- src_ring->hw_index = -+- ath10k_ce_src_ring_read_index_get(ar, ctrl_addr); -+- src_ring->hw_index &= nentries_mask; -++ read_index = ath10k_ce_src_ring_read_index_get(ar, ctrl_addr); -++ if (read_index == 0xffffffff) -++ return -ENODEV; -+ -+- ath10k_pci_sleep(ar); -++ read_index &= nentries_mask; -++ src_ring->hw_index = read_index; -+ } -+ -+ read_index = src_ring->hw_index; -+ -+- if ((read_index == sw_index) || (read_index == 0xffffffff)) -++ if (read_index == sw_index) -+ return -EIO; -+ -+ sbase = src_ring->shadow_base; -+@@ -701,11 +726,6 @@ void ath10k_ce_per_engine_service(struct -+ struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); -+ struct ath10k_ce_pipe *ce_state = &ar_pci->ce_states[ce_id]; -+ u32 ctrl_addr = ce_state->ctrl_addr; -+- int ret; -+- -+- ret = ath10k_pci_wake(ar); -+- if (ret) -+- return; -+ -+ spin_lock_bh(&ar_pci->ce_lock); -+ -+@@ -730,7 +750,6 @@ void ath10k_ce_per_engine_service(struct -+ ath10k_ce_engine_int_status_clear(ar, ctrl_addr, CE_WATERMARK_MASK); -+ -+ spin_unlock_bh(&ar_pci->ce_lock); -+- ath10k_pci_sleep(ar); -+ } -+ -+ /* -+@@ -741,13 +760,9 @@ void ath10k_ce_per_engine_service(struct -+ -+ void ath10k_ce_per_engine_service_any(struct ath10k *ar) -+ { -+- int ce_id, ret; -++ int ce_id; -+ u32 intr_summary; -+ -+- ret = ath10k_pci_wake(ar); -+- if (ret) -+- return; -+- -+ intr_summary = CE_INTERRUPT_SUMMARY(ar); -+ -+ for (ce_id = 0; intr_summary && (ce_id < CE_COUNT); ce_id++) { -+@@ -759,8 +774,6 @@ void ath10k_ce_per_engine_service_any(st -+ -+ ath10k_ce_per_engine_service(ar, ce_id); -+ } -+- -+- ath10k_pci_sleep(ar); -+ } -+ -+ /* -+@@ -770,16 +783,11 @@ void ath10k_ce_per_engine_service_any(st -+ * -+ * Called with ce_lock held. -+ */ -+-static void ath10k_ce_per_engine_handler_adjust(struct ath10k_ce_pipe *ce_state, -+- int disable_copy_compl_intr) -++static void ath10k_ce_per_engine_handler_adjust(struct ath10k_ce_pipe *ce_state) -+ { -+ u32 ctrl_addr = ce_state->ctrl_addr; -+ struct ath10k *ar = ce_state->ar; -+- int ret; -+- -+- ret = ath10k_pci_wake(ar); -+- if (ret) -+- return; -++ bool disable_copy_compl_intr = ce_state->attr_flags & CE_ATTR_DIS_INTR; -+ -+ if ((!disable_copy_compl_intr) && -+ (ce_state->send_cb || ce_state->recv_cb)) -+@@ -788,54 +796,33 @@ static void ath10k_ce_per_engine_handler -+ ath10k_ce_copy_complete_intr_disable(ar, ctrl_addr); -+ -+ ath10k_ce_watermark_intr_disable(ar, ctrl_addr); -+- -+- ath10k_pci_sleep(ar); -+ } -+ -+ int ath10k_ce_disable_interrupts(struct ath10k *ar) -+ { -+- int ce_id, ret; -+- -+- ret = ath10k_pci_wake(ar); -+- if (ret) -+- return ret; -++ int ce_id; -+ -+ for (ce_id = 0; ce_id < CE_COUNT; ce_id++) { -+- u32 ctrl_addr = ath10k_ce_base_address(ce_id); -++ u32 ctrl_addr = ath10k_ce_base_address(ar, ce_id); -+ -+ ath10k_ce_copy_complete_intr_disable(ar, ctrl_addr); -+ ath10k_ce_error_intr_disable(ar, ctrl_addr); -+ ath10k_ce_watermark_intr_disable(ar, ctrl_addr); -+ } -+ -+- ath10k_pci_sleep(ar); -+- -+ return 0; -+ } -+ -+-void ath10k_ce_send_cb_register(struct ath10k_ce_pipe *ce_state, -+- void (*send_cb)(struct ath10k_ce_pipe *), -+- int disable_interrupts) -++void ath10k_ce_enable_interrupts(struct ath10k *ar) -+ { -+- struct ath10k *ar = ce_state->ar; -+ struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); -++ int ce_id; -+ -+- spin_lock_bh(&ar_pci->ce_lock); -+- ce_state->send_cb = send_cb; -+- ath10k_ce_per_engine_handler_adjust(ce_state, disable_interrupts); -+- spin_unlock_bh(&ar_pci->ce_lock); -+-} -+- -+-void ath10k_ce_recv_cb_register(struct ath10k_ce_pipe *ce_state, -+- void (*recv_cb)(struct ath10k_ce_pipe *)) -+-{ -+- struct ath10k *ar = ce_state->ar; -+- struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); -+- -+- spin_lock_bh(&ar_pci->ce_lock); -+- ce_state->recv_cb = recv_cb; -+- ath10k_ce_per_engine_handler_adjust(ce_state, 0); -+- spin_unlock_bh(&ar_pci->ce_lock); -++ /* Skip the last copy engine, CE7 the diagnostic window, as that -++ * uses polling and isn't initialized for interrupts. -++ */ -++ for (ce_id = 0; ce_id < CE_COUNT - 1; ce_id++) -++ ath10k_ce_per_engine_handler_adjust(&ar_pci->ce_states[ce_id]); -+ } -+ -+ static int ath10k_ce_init_src_ring(struct ath10k *ar, -+@@ -845,12 +832,12 @@ static int ath10k_ce_init_src_ring(struc -+ struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); -+ struct ath10k_ce_pipe *ce_state = &ar_pci->ce_states[ce_id]; -+ struct ath10k_ce_ring *src_ring = ce_state->src_ring; -+- u32 nentries, ctrl_addr = ath10k_ce_base_address(ce_id); -++ u32 nentries, ctrl_addr = ath10k_ce_base_address(ar, ce_id); -+ -+ nentries = roundup_pow_of_two(attr->src_nentries); -+ -+- memset(src_ring->per_transfer_context, 0, -+- nentries * sizeof(*src_ring->per_transfer_context)); -++ memset(src_ring->base_addr_owner_space, 0, -++ nentries * sizeof(struct ce_desc)); -+ -+ src_ring->sw_index = ath10k_ce_src_ring_read_index_get(ar, ctrl_addr); -+ src_ring->sw_index &= src_ring->nentries_mask; -+@@ -868,7 +855,7 @@ static int ath10k_ce_init_src_ring(struc -+ ath10k_ce_src_ring_lowmark_set(ar, ctrl_addr, 0); -+ ath10k_ce_src_ring_highmark_set(ar, ctrl_addr, nentries); -+ -+- ath10k_dbg(ATH10K_DBG_BOOT, -++ ath10k_dbg(ar, ATH10K_DBG_BOOT, -+ "boot init ce src ring id %d entries %d base_addr %p\n", -+ ce_id, nentries, src_ring->base_addr_owner_space); -+ -+@@ -882,12 +869,12 @@ static int ath10k_ce_init_dest_ring(stru -+ struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); -+ struct ath10k_ce_pipe *ce_state = &ar_pci->ce_states[ce_id]; -+ struct ath10k_ce_ring *dest_ring = ce_state->dest_ring; -+- u32 nentries, ctrl_addr = ath10k_ce_base_address(ce_id); -++ u32 nentries, ctrl_addr = ath10k_ce_base_address(ar, ce_id); -+ -+ nentries = roundup_pow_of_two(attr->dest_nentries); -+ -+- memset(dest_ring->per_transfer_context, 0, -+- nentries * sizeof(*dest_ring->per_transfer_context)); -++ memset(dest_ring->base_addr_owner_space, 0, -++ nentries * sizeof(struct ce_desc)); -+ -+ dest_ring->sw_index = ath10k_ce_dest_ring_read_index_get(ar, ctrl_addr); -+ dest_ring->sw_index &= dest_ring->nentries_mask; -+@@ -902,7 +889,7 @@ static int ath10k_ce_init_dest_ring(stru -+ ath10k_ce_dest_ring_lowmark_set(ar, ctrl_addr, 0); -+ ath10k_ce_dest_ring_highmark_set(ar, ctrl_addr, nentries); -+ -+- ath10k_dbg(ATH10K_DBG_BOOT, -++ ath10k_dbg(ar, ATH10K_DBG_BOOT, -+ "boot ce dest ring id %d entries %d base_addr %p\n", -+ ce_id, nentries, dest_ring->base_addr_owner_space); -+ -+@@ -1039,59 +1026,32 @@ ath10k_ce_alloc_dest_ring(struct ath10k -+ int ath10k_ce_init_pipe(struct ath10k *ar, unsigned int ce_id, -+ const struct ce_attr *attr) -+ { -+- struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); -+- struct ath10k_ce_pipe *ce_state = &ar_pci->ce_states[ce_id]; -+ int ret; -+ -+- /* -+- * Make sure there's enough CE ringbuffer entries for HTT TX to avoid -+- * additional TX locking checks. -+- * -+- * For the lack of a better place do the check here. -+- */ -+- BUILD_BUG_ON(2*TARGET_NUM_MSDU_DESC > -+- (CE_HTT_H2T_MSG_SRC_NENTRIES - 1)); -+- BUILD_BUG_ON(2*TARGET_10X_NUM_MSDU_DESC > -+- (CE_HTT_H2T_MSG_SRC_NENTRIES - 1)); -+- -+- ret = ath10k_pci_wake(ar); -+- if (ret) -+- return ret; -+- -+- spin_lock_bh(&ar_pci->ce_lock); -+- ce_state->ar = ar; -+- ce_state->id = ce_id; -+- ce_state->ctrl_addr = ath10k_ce_base_address(ce_id); -+- ce_state->attr_flags = attr->flags; -+- ce_state->src_sz_max = attr->src_sz_max; -+- spin_unlock_bh(&ar_pci->ce_lock); -+- -+ if (attr->src_nentries) { -+ ret = ath10k_ce_init_src_ring(ar, ce_id, attr); -+ if (ret) { -+- ath10k_err("Failed to initialize CE src ring for ID: %d (%d)\n", -++ ath10k_err(ar, "Failed to initialize CE src ring for ID: %d (%d)\n", -+ ce_id, ret); -+- goto out; -++ return ret; -+ } -+ } -+ -+ if (attr->dest_nentries) { -+ ret = ath10k_ce_init_dest_ring(ar, ce_id, attr); -+ if (ret) { -+- ath10k_err("Failed to initialize CE dest ring for ID: %d (%d)\n", -++ ath10k_err(ar, "Failed to initialize CE dest ring for ID: %d (%d)\n", -+ ce_id, ret); -+- goto out; -++ return ret; -+ } -+ } -+ -+-out: -+- ath10k_pci_sleep(ar); -+- return ret; -++ return 0; -+ } -+ -+ static void ath10k_ce_deinit_src_ring(struct ath10k *ar, unsigned int ce_id) -+ { -+- u32 ctrl_addr = ath10k_ce_base_address(ce_id); -++ u32 ctrl_addr = ath10k_ce_base_address(ar, ce_id); -+ -+ ath10k_ce_src_ring_base_addr_set(ar, ctrl_addr, 0); -+ ath10k_ce_src_ring_size_set(ar, ctrl_addr, 0); -+@@ -1101,7 +1061,7 @@ static void ath10k_ce_deinit_src_ring(st -+ -+ static void ath10k_ce_deinit_dest_ring(struct ath10k *ar, unsigned int ce_id) -+ { -+- u32 ctrl_addr = ath10k_ce_base_address(ce_id); -++ u32 ctrl_addr = ath10k_ce_base_address(ar, ce_id); -+ -+ ath10k_ce_dest_ring_base_addr_set(ar, ctrl_addr, 0); -+ ath10k_ce_dest_ring_size_set(ar, ctrl_addr, 0); -+@@ -1110,30 +1070,49 @@ static void ath10k_ce_deinit_dest_ring(s -+ -+ void ath10k_ce_deinit_pipe(struct ath10k *ar, unsigned int ce_id) -+ { -+- int ret; -+- -+- ret = ath10k_pci_wake(ar); -+- if (ret) -+- return; -+- -+ ath10k_ce_deinit_src_ring(ar, ce_id); -+ ath10k_ce_deinit_dest_ring(ar, ce_id); -+- -+- ath10k_pci_sleep(ar); -+ } -+ -+ int ath10k_ce_alloc_pipe(struct ath10k *ar, int ce_id, -+- const struct ce_attr *attr) -++ const struct ce_attr *attr, -++ void (*send_cb)(struct ath10k_ce_pipe *), -++ void (*recv_cb)(struct ath10k_ce_pipe *)) -+ { -+ struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); -+ struct ath10k_ce_pipe *ce_state = &ar_pci->ce_states[ce_id]; -+ int ret; -+ -++ /* -++ * Make sure there's enough CE ringbuffer entries for HTT TX to avoid -++ * additional TX locking checks. -++ * -++ * For the lack of a better place do the check here. -++ */ -++ BUILD_BUG_ON(2*TARGET_NUM_MSDU_DESC > -++ (CE_HTT_H2T_MSG_SRC_NENTRIES - 1)); -++ BUILD_BUG_ON(2*TARGET_10X_NUM_MSDU_DESC > -++ (CE_HTT_H2T_MSG_SRC_NENTRIES - 1)); -++ BUILD_BUG_ON(2*TARGET_TLV_NUM_MSDU_DESC > -++ (CE_HTT_H2T_MSG_SRC_NENTRIES - 1)); -++ -++ ce_state->ar = ar; -++ ce_state->id = ce_id; -++ ce_state->ctrl_addr = ath10k_ce_base_address(ar, ce_id); -++ ce_state->attr_flags = attr->flags; -++ ce_state->src_sz_max = attr->src_sz_max; -++ -++ if (attr->src_nentries) -++ ce_state->send_cb = send_cb; -++ -++ if (attr->dest_nentries) -++ ce_state->recv_cb = recv_cb; -++ -+ if (attr->src_nentries) { -+ ce_state->src_ring = ath10k_ce_alloc_src_ring(ar, ce_id, attr); -+ if (IS_ERR(ce_state->src_ring)) { -+ ret = PTR_ERR(ce_state->src_ring); -+- ath10k_err("failed to allocate copy engine source ring %d: %d\n", -++ ath10k_err(ar, "failed to allocate copy engine source ring %d: %d\n", -+ ce_id, ret); -+ ce_state->src_ring = NULL; -+ return ret; -+@@ -1145,7 +1124,7 @@ int ath10k_ce_alloc_pipe(struct ath10k * -+ attr); -+ if (IS_ERR(ce_state->dest_ring)) { -+ ret = PTR_ERR(ce_state->dest_ring); -+- ath10k_err("failed to allocate copy engine destination ring %d: %d\n", -++ ath10k_err(ar, "failed to allocate copy engine destination ring %d: %d\n", -+ ce_id, ret); -+ ce_state->dest_ring = NULL; -+ return ret; -+--- a/drivers/net/wireless/ath/ath10k/ce.h -++++ b/drivers/net/wireless/ath/ath10k/ce.h -+@@ -20,7 +20,6 @@ -+ -+ #include "hif.h" -+ -+- -+ /* Maximum number of Copy Engine's supported */ -+ #define CE_COUNT_MAX 8 -+ #define CE_HTT_H2T_MSG_SRC_NENTRIES 4096 -+@@ -37,11 +36,10 @@ -+ -+ struct ath10k_ce_pipe; -+ -+- -+ #define CE_DESC_FLAGS_GATHER (1 << 0) -+ #define CE_DESC_FLAGS_BYTE_SWAP (1 << 1) -+ #define CE_DESC_FLAGS_META_DATA_MASK 0xFFFC -+-#define CE_DESC_FLAGS_META_DATA_LSB 3 -++#define CE_DESC_FLAGS_META_DATA_LSB 2 -+ -+ struct ce_desc { -+ __le32 addr; -+@@ -160,30 +158,15 @@ int ath10k_ce_send_nolock(struct ath10k_ -+ unsigned int transfer_id, -+ unsigned int flags); -+ -+-void ath10k_ce_send_cb_register(struct ath10k_ce_pipe *ce_state, -+- void (*send_cb)(struct ath10k_ce_pipe *), -+- int disable_interrupts); -++void __ath10k_ce_send_revert(struct ath10k_ce_pipe *pipe); -+ -+ int ath10k_ce_num_free_src_entries(struct ath10k_ce_pipe *pipe); -+ -+ /*==================Recv=======================*/ -+ -+-/* -+- * Make a buffer available to receive. The buffer must be at least of a -+- * minimal size appropriate for this copy engine (src_sz_max attribute). -+- * ce - which copy engine to use -+- * per_transfer_recv_context - context passed back to caller's recv_cb -+- * buffer - address of buffer in CE space -+- * Returns 0 on success; otherwise an error status. -+- * -+- * Implemenation note: Pushes a buffer to Dest ring. -+- */ -+-int ath10k_ce_recv_buf_enqueue(struct ath10k_ce_pipe *ce_state, -+- void *per_transfer_recv_context, -+- u32 buffer); -+- -+-void ath10k_ce_recv_cb_register(struct ath10k_ce_pipe *ce_state, -+- void (*recv_cb)(struct ath10k_ce_pipe *)); -++int __ath10k_ce_rx_num_free_bufs(struct ath10k_ce_pipe *pipe); -++int __ath10k_ce_rx_post_buf(struct ath10k_ce_pipe *pipe, void *ctx, u32 paddr); -++int ath10k_ce_rx_post_buf(struct ath10k_ce_pipe *pipe, void *ctx, u32 paddr); -+ -+ /* recv flags */ -+ /* Data is byte-swapped */ -+@@ -204,10 +187,16 @@ int ath10k_ce_completed_recv_next(struct -+ * Pops 1 completed send buffer from Source ring. -+ */ -+ int ath10k_ce_completed_send_next(struct ath10k_ce_pipe *ce_state, -+- void **per_transfer_contextp, -+- u32 *bufferp, -+- unsigned int *nbytesp, -+- unsigned int *transfer_idp); -++ void **per_transfer_contextp, -++ u32 *bufferp, -++ unsigned int *nbytesp, -++ unsigned int *transfer_idp); -++ -++int ath10k_ce_completed_send_next_nolock(struct ath10k_ce_pipe *ce_state, -++ void **per_transfer_contextp, -++ u32 *bufferp, -++ unsigned int *nbytesp, -++ unsigned int *transfer_idp); -+ -+ /*==================CE Engine Initialization=======================*/ -+ -+@@ -215,7 +204,9 @@ int ath10k_ce_init_pipe(struct ath10k *a -+ const struct ce_attr *attr); -+ void ath10k_ce_deinit_pipe(struct ath10k *ar, unsigned int ce_id); -+ int ath10k_ce_alloc_pipe(struct ath10k *ar, int ce_id, -+- const struct ce_attr *attr); -++ const struct ce_attr *attr, -++ void (*send_cb)(struct ath10k_ce_pipe *), -++ void (*recv_cb)(struct ath10k_ce_pipe *)); -+ void ath10k_ce_free_pipe(struct ath10k *ar, int ce_id); -+ -+ /*==================CE Engine Shutdown=======================*/ -+@@ -228,6 +219,13 @@ int ath10k_ce_revoke_recv_next(struct at -+ void **per_transfer_contextp, -+ u32 *bufferp); -+ -++int ath10k_ce_completed_recv_next_nolock(struct ath10k_ce_pipe *ce_state, -++ void **per_transfer_contextp, -++ u32 *bufferp, -++ unsigned int *nbytesp, -++ unsigned int *transfer_idp, -++ unsigned int *flagsp); -++ -+ /* -+ * Support clean shutdown by allowing the caller to cancel -+ * pending sends. Target DMA must be stopped before using -+@@ -243,6 +241,7 @@ int ath10k_ce_cancel_send_next(struct at -+ void ath10k_ce_per_engine_service_any(struct ath10k *ar); -+ void ath10k_ce_per_engine_service(struct ath10k *ar, unsigned int ce_id); -+ int ath10k_ce_disable_interrupts(struct ath10k *ar); -++void ath10k_ce_enable_interrupts(struct ath10k *ar); -+ -+ /* ce_attr.flags values */ -+ /* Use NonSnooping PCIe accesses? */ -+@@ -395,8 +394,7 @@ struct ce_attr { -+ #define DST_WATERMARK_HIGH_RESET 0 -+ #define DST_WATERMARK_ADDRESS 0x0050 -+ -+- -+-static inline u32 ath10k_ce_base_address(unsigned int ce_id) -++static inline u32 ath10k_ce_base_address(struct ath10k *ar, unsigned int ce_id) -+ { -+ return CE0_BASE_ADDRESS + (CE1_BASE_ADDRESS - CE0_BASE_ADDRESS) * ce_id; -+ } -+--- a/drivers/net/wireless/ath/ath10k/core.c -++++ b/drivers/net/wireless/ath/ath10k/core.c -+@@ -17,6 +17,7 @@ -+ -+ #include -+ #include -++#include -+ -+ #include "core.h" -+ #include "mac.h" -+@@ -26,68 +27,88 @@ -+ #include "bmi.h" -+ #include "debug.h" -+ #include "htt.h" -++#include "testmode.h" -++#include "wmi-ops.h" -+ -+ unsigned int ath10k_debug_mask; -+ static bool uart_print; -+-static unsigned int ath10k_p2p; -++static bool skip_otp; -++ -+ module_param_named(debug_mask, ath10k_debug_mask, uint, 0644); -+ module_param(uart_print, bool, 0644); -+-module_param_named(p2p, ath10k_p2p, uint, 0644); -++module_param(skip_otp, bool, 0644); -++ -+ MODULE_PARM_DESC(debug_mask, "Debugging mask"); -+ MODULE_PARM_DESC(uart_print, "Uart target debugging"); -+-MODULE_PARM_DESC(p2p, "Enable ath10k P2P support"); -++MODULE_PARM_DESC(skip_otp, "Skip otp failure for calibration in testmode"); -+ -+ static const struct ath10k_hw_params ath10k_hw_params_list[] = { -+ { -+ .id = QCA988X_HW_2_0_VERSION, -+ .name = "qca988x hw2.0", -+ .patch_load_addr = QCA988X_HW_2_0_PATCH_LOAD_ADDR, -++ .uart_pin = 7, -+ .fw = { -+ .dir = QCA988X_HW_2_0_FW_DIR, -+ .fw = QCA988X_HW_2_0_FW_FILE, -+ .otp = QCA988X_HW_2_0_OTP_FILE, -+ .board = QCA988X_HW_2_0_BOARD_DATA_FILE, -++ .board_size = QCA988X_BOARD_DATA_SZ, -++ .board_ext_size = QCA988X_BOARD_EXT_DATA_SZ, -++ }, -++ }, -++ { -++ .id = QCA6174_HW_2_1_VERSION, -++ .name = "qca6174 hw2.1", -++ .patch_load_addr = QCA6174_HW_2_1_PATCH_LOAD_ADDR, -++ .uart_pin = 6, -++ .fw = { -++ .dir = QCA6174_HW_2_1_FW_DIR, -++ .fw = QCA6174_HW_2_1_FW_FILE, -++ .otp = QCA6174_HW_2_1_OTP_FILE, -++ .board = QCA6174_HW_2_1_BOARD_DATA_FILE, -++ .board_size = QCA6174_BOARD_DATA_SZ, -++ .board_ext_size = QCA6174_BOARD_EXT_DATA_SZ, -++ }, -++ }, -++ { -++ .id = QCA6174_HW_3_0_VERSION, -++ .name = "qca6174 hw3.0", -++ .patch_load_addr = QCA6174_HW_3_0_PATCH_LOAD_ADDR, -++ .uart_pin = 6, -++ .fw = { -++ .dir = QCA6174_HW_3_0_FW_DIR, -++ .fw = QCA6174_HW_3_0_FW_FILE, -++ .otp = QCA6174_HW_3_0_OTP_FILE, -++ .board = QCA6174_HW_3_0_BOARD_DATA_FILE, -++ .board_size = QCA6174_BOARD_DATA_SZ, -++ .board_ext_size = QCA6174_BOARD_EXT_DATA_SZ, -++ }, -++ }, -++ { -++ .id = QCA6174_HW_3_2_VERSION, -++ .name = "qca6174 hw3.2", -++ .patch_load_addr = QCA6174_HW_3_0_PATCH_LOAD_ADDR, -++ .uart_pin = 6, -++ .fw = { -++ /* uses same binaries as hw3.0 */ -++ .dir = QCA6174_HW_3_0_FW_DIR, -++ .fw = QCA6174_HW_3_0_FW_FILE, -++ .otp = QCA6174_HW_3_0_OTP_FILE, -++ .board = QCA6174_HW_3_0_BOARD_DATA_FILE, -++ .board_size = QCA6174_BOARD_DATA_SZ, -++ .board_ext_size = QCA6174_BOARD_EXT_DATA_SZ, -+ }, -+ }, -+ }; -+ -+ static void ath10k_send_suspend_complete(struct ath10k *ar) -+ { -+- ath10k_dbg(ATH10K_DBG_BOOT, "boot suspend complete\n"); -++ ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot suspend complete\n"); -+ -+ complete(&ar->target_suspend); -+ } -+ -+-static int ath10k_init_connect_htc(struct ath10k *ar) -+-{ -+- int status; -+- -+- status = ath10k_wmi_connect_htc_service(ar); -+- if (status) -+- goto conn_fail; -+- -+- /* Start HTC */ -+- status = ath10k_htc_start(&ar->htc); -+- if (status) -+- goto conn_fail; -+- -+- /* Wait for WMI event to be ready */ -+- status = ath10k_wmi_wait_for_service_ready(ar); -+- if (status <= 0) { -+- ath10k_warn("wmi service ready event not received"); -+- status = -ETIMEDOUT; -+- goto timeout; -+- } -+- -+- ath10k_dbg(ATH10K_DBG_BOOT, "boot wmi ready\n"); -+- return 0; -+- -+-timeout: -+- ath10k_htc_stop(&ar->htc); -+-conn_fail: -+- return status; -+-} -+- -+ static int ath10k_init_configure_target(struct ath10k *ar) -+ { -+ u32 param_host; -+@@ -97,14 +118,14 @@ static int ath10k_init_configure_target( -+ ret = ath10k_bmi_write32(ar, hi_app_host_interest, -+ HTC_PROTOCOL_VERSION); -+ if (ret) { -+- ath10k_err("settings HTC version failed\n"); -++ ath10k_err(ar, "settings HTC version failed\n"); -+ return ret; -+ } -+ -+ /* set the firmware mode to STA/IBSS/AP */ -+ ret = ath10k_bmi_read32(ar, hi_option_flag, ¶m_host); -+ if (ret) { -+- ath10k_err("setting firmware mode (1/2) failed\n"); -++ ath10k_err(ar, "setting firmware mode (1/2) failed\n"); -+ return ret; -+ } -+ -+@@ -123,14 +144,14 @@ static int ath10k_init_configure_target( -+ -+ ret = ath10k_bmi_write32(ar, hi_option_flag, param_host); -+ if (ret) { -+- ath10k_err("setting firmware mode (2/2) failed\n"); -++ ath10k_err(ar, "setting firmware mode (2/2) failed\n"); -+ return ret; -+ } -+ -+ /* We do all byte-swapping on the host */ -+ ret = ath10k_bmi_write32(ar, hi_be, 0); -+ if (ret) { -+- ath10k_err("setting host CPU BE mode failed\n"); -++ ath10k_err(ar, "setting host CPU BE mode failed\n"); -+ return ret; -+ } -+ -+@@ -138,7 +159,7 @@ static int ath10k_init_configure_target( -+ ret = ath10k_bmi_write32(ar, hi_fw_swap, 0); -+ -+ if (ret) { -+- ath10k_err("setting FW data/desc swap flags failed\n"); -++ ath10k_err(ar, "setting FW data/desc swap flags failed\n"); -+ return ret; -+ } -+ -+@@ -167,79 +188,83 @@ static const struct firmware *ath10k_fet -+ return fw; -+ } -+ -+-static int ath10k_push_board_ext_data(struct ath10k *ar) -++static int ath10k_push_board_ext_data(struct ath10k *ar, const void *data, -++ size_t data_len) -+ { -+- u32 board_data_size = QCA988X_BOARD_DATA_SZ; -+- u32 board_ext_data_size = QCA988X_BOARD_EXT_DATA_SZ; -++ u32 board_data_size = ar->hw_params.fw.board_size; -++ u32 board_ext_data_size = ar->hw_params.fw.board_ext_size; -+ u32 board_ext_data_addr; -+ int ret; -+ -+ ret = ath10k_bmi_read32(ar, hi_board_ext_data, &board_ext_data_addr); -+ if (ret) { -+- ath10k_err("could not read board ext data addr (%d)\n", ret); -++ ath10k_err(ar, "could not read board ext data addr (%d)\n", -++ ret); -+ return ret; -+ } -+ -+- ath10k_dbg(ATH10K_DBG_BOOT, -++ ath10k_dbg(ar, ATH10K_DBG_BOOT, -+ "boot push board extended data addr 0x%x\n", -+ board_ext_data_addr); -+ -+ if (board_ext_data_addr == 0) -+ return 0; -+ -+- if (ar->board_len != (board_data_size + board_ext_data_size)) { -+- ath10k_err("invalid board (ext) data sizes %zu != %d+%d\n", -+- ar->board_len, board_data_size, board_ext_data_size); -++ if (data_len != (board_data_size + board_ext_data_size)) { -++ ath10k_err(ar, "invalid board (ext) data sizes %zu != %d+%d\n", -++ data_len, board_data_size, board_ext_data_size); -+ return -EINVAL; -+ } -+ -+ ret = ath10k_bmi_write_memory(ar, board_ext_data_addr, -+- ar->board_data + board_data_size, -++ data + board_data_size, -+ board_ext_data_size); -+ if (ret) { -+- ath10k_err("could not write board ext data (%d)\n", ret); -++ ath10k_err(ar, "could not write board ext data (%d)\n", ret); -+ return ret; -+ } -+ -+ ret = ath10k_bmi_write32(ar, hi_board_ext_data_config, -+ (board_ext_data_size << 16) | 1); -+ if (ret) { -+- ath10k_err("could not write board ext data bit (%d)\n", ret); -++ ath10k_err(ar, "could not write board ext data bit (%d)\n", -++ ret); -+ return ret; -+ } -+ -+ return 0; -+ } -+ -+-static int ath10k_download_board_data(struct ath10k *ar) -++static int ath10k_download_board_data(struct ath10k *ar, const void *data, -++ size_t data_len) -+ { -+- u32 board_data_size = QCA988X_BOARD_DATA_SZ; -++ u32 board_data_size = ar->hw_params.fw.board_size; -+ u32 address; -+ int ret; -+ -+- ret = ath10k_push_board_ext_data(ar); -++ ret = ath10k_push_board_ext_data(ar, data, data_len); -+ if (ret) { -+- ath10k_err("could not push board ext data (%d)\n", ret); -++ ath10k_err(ar, "could not push board ext data (%d)\n", ret); -+ goto exit; -+ } -+ -+ ret = ath10k_bmi_read32(ar, hi_board_data, &address); -+ if (ret) { -+- ath10k_err("could not read board data addr (%d)\n", ret); -++ ath10k_err(ar, "could not read board data addr (%d)\n", ret); -+ goto exit; -+ } -+ -+- ret = ath10k_bmi_write_memory(ar, address, ar->board_data, -++ ret = ath10k_bmi_write_memory(ar, address, data, -+ min_t(u32, board_data_size, -+- ar->board_len)); -++ data_len)); -+ if (ret) { -+- ath10k_err("could not write board data (%d)\n", ret); -++ ath10k_err(ar, "could not write board data (%d)\n", ret); -+ goto exit; -+ } -+ -+ ret = ath10k_bmi_write32(ar, hi_board_data_initialized, 1); -+ if (ret) { -+- ath10k_err("could not write board data bit (%d)\n", ret); -++ ath10k_err(ar, "could not write board data bit (%d)\n", ret); -+ goto exit; -+ } -+ -+@@ -247,73 +272,182 @@ exit: -+ return ret; -+ } -+ -++static int ath10k_download_cal_file(struct ath10k *ar) -++{ -++ int ret; -++ -++ if (!ar->cal_file) -++ return -ENOENT; -++ -++ if (IS_ERR(ar->cal_file)) -++ return PTR_ERR(ar->cal_file); -++ -++ ret = ath10k_download_board_data(ar, ar->cal_file->data, -++ ar->cal_file->size); -++ if (ret) { -++ ath10k_err(ar, "failed to download cal_file data: %d\n", ret); -++ return ret; -++ } -++ -++ ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot cal file downloaded\n"); -++ -++ return 0; -++} -++ -++static int ath10k_download_cal_dt(struct ath10k *ar) -++{ -++ struct device_node *node; -++ int data_len; -++ void *data; -++ int ret; -++ -++ node = ar->dev->of_node; -++ if (!node) -++ /* Device Tree is optional, don't print any warnings if -++ * there's no node for ath10k. -++ */ -++ return -ENOENT; -++ -++ if (!of_get_property(node, "qcom,ath10k-calibration-data", -++ &data_len)) { -++ /* The calibration data node is optional */ -++ return -ENOENT; -++ } -++ -++ if (data_len != QCA988X_CAL_DATA_LEN) { -++ ath10k_warn(ar, "invalid calibration data length in DT: %d\n", -++ data_len); -++ ret = -EMSGSIZE; -++ goto out; -++ } -++ -++ data = kmalloc(data_len, GFP_KERNEL); -++ if (!data) { -++ ret = -ENOMEM; -++ goto out; -++ } -++ -++ ret = of_property_read_u8_array(node, "qcom,ath10k-calibration-data", -++ data, data_len); -++ if (ret) { -++ ath10k_warn(ar, "failed to read calibration data from DT: %d\n", -++ ret); -++ goto out_free; -++ } -++ -++ ret = ath10k_download_board_data(ar, data, data_len); -++ if (ret) { -++ ath10k_warn(ar, "failed to download calibration data from Device Tree: %d\n", -++ ret); -++ goto out_free; -++ } -++ -++ ret = 0; -++ -++out_free: -++ kfree(data); -++ -++out: -++ return ret; -++} -++ -+ static int ath10k_download_and_run_otp(struct ath10k *ar) -+ { -+ u32 result, address = ar->hw_params.patch_load_addr; -+ int ret; -+ -++ ret = ath10k_download_board_data(ar, ar->board_data, ar->board_len); -++ if (ret) { -++ ath10k_err(ar, "failed to download board data: %d\n", ret); -++ return ret; -++ } -++ -+ /* OTP is optional */ -+ -+ if (!ar->otp_data || !ar->otp_len) { -+- ath10k_warn("Not running otp, calibration will be incorrect (otp-data %p otp_len %zd)!\n", -++ ath10k_warn(ar, "Not running otp, calibration will be incorrect (otp-data %p otp_len %zd)!\n", -+ ar->otp_data, ar->otp_len); -+ return 0; -+ } -+ -+- ath10k_dbg(ATH10K_DBG_BOOT, "boot upload otp to 0x%x len %zd\n", -++ ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot upload otp to 0x%x len %zd\n", -+ address, ar->otp_len); -+ -+ ret = ath10k_bmi_fast_download(ar, address, ar->otp_data, ar->otp_len); -+ if (ret) { -+- ath10k_err("could not write otp (%d)\n", ret); -++ ath10k_err(ar, "could not write otp (%d)\n", ret); -+ return ret; -+ } -+ -+ ret = ath10k_bmi_execute(ar, address, 0, &result); -+ if (ret) { -+- ath10k_err("could not execute otp (%d)\n", ret); -++ ath10k_err(ar, "could not execute otp (%d)\n", ret); -+ return ret; -+ } -+ -+- ath10k_dbg(ATH10K_DBG_BOOT, "boot otp execute result %d\n", result); -++ ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot otp execute result %d\n", result); -+ -+- if (result != 0) { -+- ath10k_err("otp calibration failed: %d", result); -++ if (!skip_otp && result != 0) { -++ ath10k_err(ar, "otp calibration failed: %d", result); -+ return -EINVAL; -+ } -+ -+ return 0; -+ } -+ -+-static int ath10k_download_fw(struct ath10k *ar) -++static int ath10k_download_fw(struct ath10k *ar, enum ath10k_firmware_mode mode) -+ { -+- u32 address; -++ u32 address, data_len; -++ const char *mode_name; -++ const void *data; -+ int ret; -+ -+ address = ar->hw_params.patch_load_addr; -+ -+- ret = ath10k_bmi_fast_download(ar, address, ar->firmware_data, -+- ar->firmware_len); -++ switch (mode) { -++ case ATH10K_FIRMWARE_MODE_NORMAL: -++ data = ar->firmware_data; -++ data_len = ar->firmware_len; -++ mode_name = "normal"; -++ break; -++ case ATH10K_FIRMWARE_MODE_UTF: -++ data = ar->testmode.utf->data; -++ data_len = ar->testmode.utf->size; -++ mode_name = "utf"; -++ break; -++ default: -++ ath10k_err(ar, "unknown firmware mode: %d\n", mode); -++ return -EINVAL; -++ } -++ -++ ath10k_dbg(ar, ATH10K_DBG_BOOT, -++ "boot uploading firmware image %p len %d mode %s\n", -++ data, data_len, mode_name); -++ -++ ret = ath10k_bmi_fast_download(ar, address, data, data_len); -+ if (ret) { -+- ath10k_err("could not write fw (%d)\n", ret); -+- goto exit; -++ ath10k_err(ar, "failed to download %s firmware: %d\n", -++ mode_name, ret); -++ return ret; -+ } -+ -+-exit: -+ return ret; -+ } -+ -+ static void ath10k_core_free_firmware_files(struct ath10k *ar) -+ { -+- if (ar->board && !IS_ERR(ar->board)) -++ if (!IS_ERR(ar->board)) -+ release_firmware(ar->board); -+ -+- if (ar->otp && !IS_ERR(ar->otp)) -++ if (!IS_ERR(ar->otp)) -+ release_firmware(ar->otp); -+ -+- if (ar->firmware && !IS_ERR(ar->firmware)) -++ if (!IS_ERR(ar->firmware)) -+ release_firmware(ar->firmware); -+ -++ if (!IS_ERR(ar->cal_file)) -++ release_firmware(ar->cal_file); -++ -+ ar->board = NULL; -+ ar->board_data = NULL; -+ ar->board_len = 0; -+@@ -325,6 +459,27 @@ static void ath10k_core_free_firmware_fi -+ ar->firmware = NULL; -+ ar->firmware_data = NULL; -+ ar->firmware_len = 0; -++ -++ ar->cal_file = NULL; -++} -++ -++static int ath10k_fetch_cal_file(struct ath10k *ar) -++{ -++ char filename[100]; -++ -++ /* cal--.bin */ -++ scnprintf(filename, sizeof(filename), "cal-%s-%s.bin", -++ ath10k_bus_str(ar->hif.bus), dev_name(ar->dev)); -++ -++ ar->cal_file = ath10k_fetch_fw_file(ar, ATH10K_FW_DIR, filename); -++ if (IS_ERR(ar->cal_file)) -++ /* calibration file is optional, don't print any warnings */ -++ return PTR_ERR(ar->cal_file); -++ -++ ath10k_dbg(ar, ATH10K_DBG_BOOT, "found calibration file %s/%s\n", -++ ATH10K_FW_DIR, filename); -++ -++ return 0; -+ } -+ -+ static int ath10k_core_fetch_firmware_api_1(struct ath10k *ar) -+@@ -332,12 +487,12 @@ static int ath10k_core_fetch_firmware_ap -+ int ret = 0; -+ -+ if (ar->hw_params.fw.fw == NULL) { -+- ath10k_err("firmware file not defined\n"); -++ ath10k_err(ar, "firmware file not defined\n"); -+ return -EINVAL; -+ } -+ -+ if (ar->hw_params.fw.board == NULL) { -+- ath10k_err("board data file not defined"); -++ ath10k_err(ar, "board data file not defined"); -+ return -EINVAL; -+ } -+ -+@@ -346,7 +501,7 @@ static int ath10k_core_fetch_firmware_ap -+ ar->hw_params.fw.board); -+ if (IS_ERR(ar->board)) { -+ ret = PTR_ERR(ar->board); -+- ath10k_err("could not fetch board data (%d)\n", ret); -++ ath10k_err(ar, "could not fetch board data (%d)\n", ret); -+ goto err; -+ } -+ -+@@ -358,7 +513,7 @@ static int ath10k_core_fetch_firmware_ap -+ ar->hw_params.fw.fw); -+ if (IS_ERR(ar->firmware)) { -+ ret = PTR_ERR(ar->firmware); -+- ath10k_err("could not fetch firmware (%d)\n", ret); -++ ath10k_err(ar, "could not fetch firmware (%d)\n", ret); -+ goto err; -+ } -+ -+@@ -374,7 +529,7 @@ static int ath10k_core_fetch_firmware_ap -+ ar->hw_params.fw.otp); -+ if (IS_ERR(ar->otp)) { -+ ret = PTR_ERR(ar->otp); -+- ath10k_err("could not fetch otp (%d)\n", ret); -++ ath10k_err(ar, "could not fetch otp (%d)\n", ret); -+ goto err; -+ } -+ -+@@ -394,12 +549,12 @@ static int ath10k_core_fetch_firmware_ap -+ int ie_id, i, index, bit, ret; -+ struct ath10k_fw_ie *hdr; -+ const u8 *data; -+- __le32 *timestamp; -++ __le32 *timestamp, *version; -+ -+ /* first fetch the firmware file (firmware-*.bin) */ -+ ar->firmware = ath10k_fetch_fw_file(ar, ar->hw_params.fw.dir, name); -+ if (IS_ERR(ar->firmware)) { -+- ath10k_err("could not fetch firmware file '%s/%s': %ld\n", -++ ath10k_err(ar, "could not fetch firmware file '%s/%s': %ld\n", -+ ar->hw_params.fw.dir, name, PTR_ERR(ar->firmware)); -+ return PTR_ERR(ar->firmware); -+ } -+@@ -411,14 +566,14 @@ static int ath10k_core_fetch_firmware_ap -+ magic_len = strlen(ATH10K_FIRMWARE_MAGIC) + 1; -+ -+ if (len < magic_len) { -+- ath10k_err("firmware file '%s/%s' too small to contain magic: %zu\n", -++ ath10k_err(ar, "firmware file '%s/%s' too small to contain magic: %zu\n", -+ ar->hw_params.fw.dir, name, len); -+ ret = -EINVAL; -+ goto err; -+ } -+ -+ if (memcmp(data, ATH10K_FIRMWARE_MAGIC, magic_len) != 0) { -+- ath10k_err("invalid firmware magic\n"); -++ ath10k_err(ar, "invalid firmware magic\n"); -+ ret = -EINVAL; -+ goto err; -+ } -+@@ -440,7 +595,7 @@ static int ath10k_core_fetch_firmware_ap -+ data += sizeof(*hdr); -+ -+ if (len < ie_len) { -+- ath10k_err("invalid length for FW IE %d (%zu < %zu)\n", -++ ath10k_err(ar, "invalid length for FW IE %d (%zu < %zu)\n", -+ ie_id, len, ie_len); -+ ret = -EINVAL; -+ goto err; -+@@ -454,7 +609,7 @@ static int ath10k_core_fetch_firmware_ap -+ memcpy(ar->hw->wiphy->fw_version, data, ie_len); -+ ar->hw->wiphy->fw_version[ie_len] = '\0'; -+ -+- ath10k_dbg(ATH10K_DBG_BOOT, -++ ath10k_dbg(ar, ATH10K_DBG_BOOT, -+ "found fw version %s\n", -+ ar->hw->wiphy->fw_version); -+ break; -+@@ -464,11 +619,11 @@ static int ath10k_core_fetch_firmware_ap -+ -+ timestamp = (__le32 *)data; -+ -+- ath10k_dbg(ATH10K_DBG_BOOT, "found fw timestamp %d\n", -++ ath10k_dbg(ar, ATH10K_DBG_BOOT, "found fw timestamp %d\n", -+ le32_to_cpup(timestamp)); -+ break; -+ case ATH10K_FW_IE_FEATURES: -+- ath10k_dbg(ATH10K_DBG_BOOT, -++ ath10k_dbg(ar, ATH10K_DBG_BOOT, -+ "found firmware features ie (%zd B)\n", -+ ie_len); -+ -+@@ -480,19 +635,19 @@ static int ath10k_core_fetch_firmware_ap -+ break; -+ -+ if (data[index] & (1 << bit)) { -+- ath10k_dbg(ATH10K_DBG_BOOT, -++ ath10k_dbg(ar, ATH10K_DBG_BOOT, -+ "Enabling feature bit: %i\n", -+ i); -+ __set_bit(i, ar->fw_features); -+ } -+ } -+ -+- ath10k_dbg_dump(ATH10K_DBG_BOOT, "features", "", -++ ath10k_dbg_dump(ar, ATH10K_DBG_BOOT, "features", "", -+ ar->fw_features, -+ sizeof(ar->fw_features)); -+ break; -+ case ATH10K_FW_IE_FW_IMAGE: -+- ath10k_dbg(ATH10K_DBG_BOOT, -++ ath10k_dbg(ar, ATH10K_DBG_BOOT, -+ "found fw image ie (%zd B)\n", -+ ie_len); -+ -+@@ -501,7 +656,7 @@ static int ath10k_core_fetch_firmware_ap -+ -+ break; -+ case ATH10K_FW_IE_OTP_IMAGE: -+- ath10k_dbg(ATH10K_DBG_BOOT, -++ ath10k_dbg(ar, ATH10K_DBG_BOOT, -+ "found otp image ie (%zd B)\n", -+ ie_len); -+ -+@@ -509,8 +664,19 @@ static int ath10k_core_fetch_firmware_ap -+ ar->otp_len = ie_len; -+ -+ break; -++ case ATH10K_FW_IE_WMI_OP_VERSION: -++ if (ie_len != sizeof(u32)) -++ break; -++ -++ version = (__le32 *)data; -++ -++ ar->wmi.op_version = le32_to_cpup(version); -++ -++ ath10k_dbg(ar, ATH10K_DBG_BOOT, "found fw ie wmi op version %d\n", -++ ar->wmi.op_version); -++ break; -+ default: -+- ath10k_warn("Unknown FW IE: %u\n", -++ ath10k_warn(ar, "Unknown FW IE: %u\n", -+ le32_to_cpu(hdr->id)); -+ break; -+ } -+@@ -523,7 +689,7 @@ static int ath10k_core_fetch_firmware_ap -+ } -+ -+ if (!ar->firmware_data || !ar->firmware_len) { -+- ath10k_warn("No ATH10K_FW_IE_FW_IMAGE found from '%s/%s', skipping\n", -++ ath10k_warn(ar, "No ATH10K_FW_IE_FW_IMAGE found from '%s/%s', skipping\n", -+ ar->hw_params.fw.dir, name); -+ ret = -ENOMEDIUM; -+ goto err; -+@@ -531,7 +697,7 @@ static int ath10k_core_fetch_firmware_ap -+ -+ /* now fetch the board file */ -+ if (ar->hw_params.fw.board == NULL) { -+- ath10k_err("board data file not defined"); -++ ath10k_err(ar, "board data file not defined"); -+ ret = -EINVAL; -+ goto err; -+ } -+@@ -541,7 +707,7 @@ static int ath10k_core_fetch_firmware_ap -+ ar->hw_params.fw.board); -+ if (IS_ERR(ar->board)) { -+ ret = PTR_ERR(ar->board); -+- ath10k_err("could not fetch board data '%s/%s' (%d)\n", -++ ath10k_err(ar, "could not fetch board data '%s/%s' (%d)\n", -+ ar->hw_params.fw.dir, ar->hw_params.fw.board, -+ ret); -+ goto err; -+@@ -561,49 +727,79 @@ static int ath10k_core_fetch_firmware_fi -+ { -+ int ret; -+ -++ /* calibration file is optional, don't check for any errors */ -++ ath10k_fetch_cal_file(ar); -++ -++ ar->fw_api = 4; -++ ath10k_dbg(ar, ATH10K_DBG_BOOT, "trying fw api %d\n", ar->fw_api); -++ -++ ret = ath10k_core_fetch_firmware_api_n(ar, ATH10K_FW_API4_FILE); -++ if (ret == 0) -++ goto success; -++ -++ ar->fw_api = 3; -++ ath10k_dbg(ar, ATH10K_DBG_BOOT, "trying fw api %d\n", ar->fw_api); -++ -++ ret = ath10k_core_fetch_firmware_api_n(ar, ATH10K_FW_API3_FILE); -++ if (ret == 0) -++ goto success; -++ -+ ar->fw_api = 2; -+- ath10k_dbg(ATH10K_DBG_BOOT, "trying fw api %d\n", ar->fw_api); -++ ath10k_dbg(ar, ATH10K_DBG_BOOT, "trying fw api %d\n", ar->fw_api); -+ -+ ret = ath10k_core_fetch_firmware_api_n(ar, ATH10K_FW_API2_FILE); -+ if (ret == 0) -+ goto success; -+ -+ ar->fw_api = 1; -+- ath10k_dbg(ATH10K_DBG_BOOT, "trying fw api %d\n", ar->fw_api); -++ ath10k_dbg(ar, ATH10K_DBG_BOOT, "trying fw api %d\n", ar->fw_api); -+ -+ ret = ath10k_core_fetch_firmware_api_1(ar); -+ if (ret) -+ return ret; -+ -+ success: -+- ath10k_dbg(ATH10K_DBG_BOOT, "using fw api %d\n", ar->fw_api); -++ ath10k_dbg(ar, ATH10K_DBG_BOOT, "using fw api %d\n", ar->fw_api); -+ -+ return 0; -+ } -+ -+-static int ath10k_init_download_firmware(struct ath10k *ar) -++static int ath10k_download_cal_data(struct ath10k *ar) -+ { -+ int ret; -+ -+- ret = ath10k_download_board_data(ar); -+- if (ret) { -+- ath10k_err("failed to download board data: %d\n", ret); -+- return ret; -++ ret = ath10k_download_cal_file(ar); -++ if (ret == 0) { -++ ar->cal_mode = ATH10K_CAL_MODE_FILE; -++ goto done; -+ } -+ -+- ret = ath10k_download_and_run_otp(ar); -+- if (ret) { -+- ath10k_err("failed to run otp: %d\n", ret); -+- return ret; -++ ath10k_dbg(ar, ATH10K_DBG_BOOT, -++ "boot did not find a calibration file, try DT next: %d\n", -++ ret); -++ -++ ret = ath10k_download_cal_dt(ar); -++ if (ret == 0) { -++ ar->cal_mode = ATH10K_CAL_MODE_DT; -++ goto done; -+ } -+ -+- ret = ath10k_download_fw(ar); -++ ath10k_dbg(ar, ATH10K_DBG_BOOT, -++ "boot did not find DT entry, try OTP next: %d\n", -++ ret); -++ -++ ret = ath10k_download_and_run_otp(ar); -+ if (ret) { -+- ath10k_err("failed to download firmware: %d\n", ret); -++ ath10k_err(ar, "failed to run otp: %d\n", ret); -+ return ret; -+ } -+ -+- return ret; -++ ar->cal_mode = ATH10K_CAL_MODE_OTP; -++ -++done: -++ ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot using calibration mode %s\n", -++ ath10k_cal_mode_str(ar->cal_mode)); -++ return 0; -+ } -+ -+ static int ath10k_init_uart(struct ath10k *ar) -+@@ -616,33 +812,33 @@ static int ath10k_init_uart(struct ath10 -+ */ -+ ret = ath10k_bmi_write32(ar, hi_serial_enable, 0); -+ if (ret) { -+- ath10k_warn("could not disable UART prints (%d)\n", ret); -++ ath10k_warn(ar, "could not disable UART prints (%d)\n", ret); -+ return ret; -+ } -+ -+ if (!uart_print) -+ return 0; -+ -+- ret = ath10k_bmi_write32(ar, hi_dbg_uart_txpin, 7); -++ ret = ath10k_bmi_write32(ar, hi_dbg_uart_txpin, ar->hw_params.uart_pin); -+ if (ret) { -+- ath10k_warn("could not enable UART prints (%d)\n", ret); -++ ath10k_warn(ar, "could not enable UART prints (%d)\n", ret); -+ return ret; -+ } -+ -+ ret = ath10k_bmi_write32(ar, hi_serial_enable, 1); -+ if (ret) { -+- ath10k_warn("could not enable UART prints (%d)\n", ret); -++ ath10k_warn(ar, "could not enable UART prints (%d)\n", ret); -+ return ret; -+ } -+ -+ /* Set the UART baud rate to 19200. */ -+ ret = ath10k_bmi_write32(ar, hi_desired_baud_rate, 19200); -+ if (ret) { -+- ath10k_warn("could not set the baud rate (%d)\n", ret); -++ ath10k_warn(ar, "could not set the baud rate (%d)\n", ret); -+ return ret; -+ } -+ -+- ath10k_info("UART prints enabled\n"); -++ ath10k_info(ar, "UART prints enabled\n"); -+ return 0; -+ } -+ -+@@ -659,14 +855,14 @@ static int ath10k_init_hw_params(struct -+ } -+ -+ if (i == ARRAY_SIZE(ath10k_hw_params_list)) { -+- ath10k_err("Unsupported hardware version: 0x%x\n", -++ ath10k_err(ar, "Unsupported hardware version: 0x%x\n", -+ ar->target_version); -+ return -EINVAL; -+ } -+ -+ ar->hw_params = *hw_params; -+ -+- ath10k_dbg(ATH10K_DBG_BOOT, "Hardware name %s version 0x%x\n", -++ ath10k_dbg(ar, ATH10K_DBG_BOOT, "Hardware name %s version 0x%x\n", -+ ar->hw_params.name, ar->target_version); -+ -+ return 0; -+@@ -676,101 +872,124 @@ static void ath10k_core_restart(struct w -+ { -+ struct ath10k *ar = container_of(work, struct ath10k, restart_work); -+ -++ set_bit(ATH10K_FLAG_CRASH_FLUSH, &ar->dev_flags); -++ -++ /* Place a barrier to make sure the compiler doesn't reorder -++ * CRASH_FLUSH and calling other functions. -++ */ -++ barrier(); -++ -++ ieee80211_stop_queues(ar->hw); -++ ath10k_drain_tx(ar); -++ complete_all(&ar->scan.started); -++ complete_all(&ar->scan.completed); -++ complete_all(&ar->scan.on_channel); -++ complete_all(&ar->offchan_tx_completed); -++ complete_all(&ar->install_key_done); -++ complete_all(&ar->vdev_setup_done); -++ complete_all(&ar->thermal.wmi_sync); -++ wake_up(&ar->htt.empty_tx_wq); -++ wake_up(&ar->wmi.tx_credits_wq); -++ wake_up(&ar->peer_mapping_wq); -++ -+ mutex_lock(&ar->conf_mutex); -+ -+ switch (ar->state) { -+ case ATH10K_STATE_ON: -+ ar->state = ATH10K_STATE_RESTARTING; -+- ath10k_halt(ar); -++ ath10k_hif_stop(ar); -++ ath10k_scan_finish(ar); -+ ieee80211_restart_hw(ar->hw); -+ break; -+ case ATH10K_STATE_OFF: -+ /* this can happen if driver is being unloaded -+ * or if the crash happens during FW probing */ -+- ath10k_warn("cannot restart a device that hasn't been started\n"); -++ ath10k_warn(ar, "cannot restart a device that hasn't been started\n"); -+ break; -+ case ATH10K_STATE_RESTARTING: -++ /* hw restart might be requested from multiple places */ -++ break; -+ case ATH10K_STATE_RESTARTED: -+ ar->state = ATH10K_STATE_WEDGED; -+ /* fall through */ -+ case ATH10K_STATE_WEDGED: -+- ath10k_warn("device is wedged, will not restart\n"); -++ ath10k_warn(ar, "device is wedged, will not restart\n"); -++ break; -++ case ATH10K_STATE_UTF: -++ ath10k_warn(ar, "firmware restart in UTF mode not supported\n"); -+ break; -+ } -+ -+ mutex_unlock(&ar->conf_mutex); -+ } -+ -+-struct ath10k *ath10k_core_create(void *hif_priv, struct device *dev, -+- const struct ath10k_hif_ops *hif_ops) -++static int ath10k_core_init_firmware_features(struct ath10k *ar) -+ { -+- struct ath10k *ar; -+- -+- ar = ath10k_mac_create(); -+- if (!ar) -+- return NULL; -+- -+- ar->ath_common.priv = ar; -+- ar->ath_common.hw = ar->hw; -+- -+- ar->p2p = !!ath10k_p2p; -+- ar->dev = dev; -+- -+- ar->hif.priv = hif_priv; -+- ar->hif.ops = hif_ops; -+- -+- init_completion(&ar->scan.started); -+- init_completion(&ar->scan.completed); -+- init_completion(&ar->scan.on_channel); -+- init_completion(&ar->target_suspend); -+- -+- init_completion(&ar->install_key_done); -+- init_completion(&ar->vdev_setup_done); -+- -+- setup_timer(&ar->scan.timeout, ath10k_reset_scan, (unsigned long)ar); -+- -+- ar->workqueue = create_singlethread_workqueue("ath10k_wq"); -+- if (!ar->workqueue) -+- goto err_wq; -+- -+- mutex_init(&ar->conf_mutex); -+- spin_lock_init(&ar->data_lock); -+- -+- INIT_LIST_HEAD(&ar->peers); -+- init_waitqueue_head(&ar->peer_mapping_wq); -+- -+- init_completion(&ar->offchan_tx_completed); -+- INIT_WORK(&ar->offchan_tx_work, ath10k_offchan_tx_work); -+- skb_queue_head_init(&ar->offchan_tx_queue); -+- -+- INIT_WORK(&ar->wmi_mgmt_tx_work, ath10k_mgmt_over_wmi_tx_work); -+- skb_queue_head_init(&ar->wmi_mgmt_tx_queue); -+- -+- INIT_WORK(&ar->restart_work, ath10k_core_restart); -++ if (test_bit(ATH10K_FW_FEATURE_WMI_10_2, ar->fw_features) && -++ !test_bit(ATH10K_FW_FEATURE_WMI_10X, ar->fw_features)) { -++ ath10k_err(ar, "feature bits corrupted: 10.2 feature requires 10.x feature to be set as well"); -++ return -EINVAL; -++ } -+ -+- return ar; -++ if (ar->wmi.op_version >= ATH10K_FW_WMI_OP_VERSION_MAX) { -++ ath10k_err(ar, "unsupported WMI OP version (max %d): %d\n", -++ ATH10K_FW_WMI_OP_VERSION_MAX, ar->wmi.op_version); -++ return -EINVAL; -++ } -+ -+-err_wq: -+- ath10k_mac_destroy(ar); -+- return NULL; -+-} -+-EXPORT_SYMBOL(ath10k_core_create); -++ /* Backwards compatibility for firmwares without -++ * ATH10K_FW_IE_WMI_OP_VERSION. -++ */ -++ if (ar->wmi.op_version == ATH10K_FW_WMI_OP_VERSION_UNSET) { -++ if (test_bit(ATH10K_FW_FEATURE_WMI_10X, ar->fw_features)) { -++ if (test_bit(ATH10K_FW_FEATURE_WMI_10_2, -++ ar->fw_features)) -++ ar->wmi.op_version = ATH10K_FW_WMI_OP_VERSION_10_2; -++ else -++ ar->wmi.op_version = ATH10K_FW_WMI_OP_VERSION_10_1; -++ } else { -++ ar->wmi.op_version = ATH10K_FW_WMI_OP_VERSION_MAIN; -++ } -++ } -+ -+-void ath10k_core_destroy(struct ath10k *ar) -+-{ -+- flush_workqueue(ar->workqueue); -+- destroy_workqueue(ar->workqueue); -++ switch (ar->wmi.op_version) { -++ case ATH10K_FW_WMI_OP_VERSION_MAIN: -++ ar->max_num_peers = TARGET_NUM_PEERS; -++ ar->max_num_stations = TARGET_NUM_STATIONS; -++ ar->max_num_vdevs = TARGET_NUM_VDEVS; -++ ar->htt.max_num_pending_tx = TARGET_NUM_MSDU_DESC; -++ break; -++ case ATH10K_FW_WMI_OP_VERSION_10_1: -++ case ATH10K_FW_WMI_OP_VERSION_10_2: -++ case ATH10K_FW_WMI_OP_VERSION_10_2_4: -++ ar->max_num_peers = TARGET_10X_NUM_PEERS; -++ ar->max_num_stations = TARGET_10X_NUM_STATIONS; -++ ar->max_num_vdevs = TARGET_10X_NUM_VDEVS; -++ ar->htt.max_num_pending_tx = TARGET_10X_NUM_MSDU_DESC; -++ break; -++ case ATH10K_FW_WMI_OP_VERSION_TLV: -++ ar->max_num_peers = TARGET_TLV_NUM_PEERS; -++ ar->max_num_stations = TARGET_TLV_NUM_STATIONS; -++ ar->max_num_vdevs = TARGET_TLV_NUM_VDEVS; -++ ar->htt.max_num_pending_tx = TARGET_TLV_NUM_MSDU_DESC; -++ break; -++ case ATH10K_FW_WMI_OP_VERSION_UNSET: -++ case ATH10K_FW_WMI_OP_VERSION_MAX: -++ WARN_ON(1); -++ return -EINVAL; -++ } -+ -+- ath10k_mac_destroy(ar); -++ return 0; -+ } -+-EXPORT_SYMBOL(ath10k_core_destroy); -+ -+-int ath10k_core_start(struct ath10k *ar) -++int ath10k_core_start(struct ath10k *ar, enum ath10k_firmware_mode mode) -+ { -+ int status; -+ -+ lockdep_assert_held(&ar->conf_mutex); -+ -++ clear_bit(ATH10K_FLAG_CRASH_FLUSH, &ar->dev_flags); -++ -+ ath10k_bmi_start(ar); -+ -+ if (ath10k_init_configure_target(ar)) { -+@@ -778,7 +997,11 @@ int ath10k_core_start(struct ath10k *ar) -+ goto err; -+ } -+ -+- status = ath10k_init_download_firmware(ar); -++ status = ath10k_download_cal_data(ar); -++ if (status) -++ goto err; -++ -++ status = ath10k_download_fw(ar, mode); -+ if (status) -+ goto err; -+ -+@@ -791,7 +1014,7 @@ int ath10k_core_start(struct ath10k *ar) -+ -+ status = ath10k_htc_init(ar); -+ if (status) { -+- ath10k_err("could not init HTC (%d)\n", status); -++ ath10k_err(ar, "could not init HTC (%d)\n", status); -+ goto err; -+ } -+ -+@@ -801,79 +1024,123 @@ int ath10k_core_start(struct ath10k *ar) -+ -+ status = ath10k_wmi_attach(ar); -+ if (status) { -+- ath10k_err("WMI attach failed: %d\n", status); -++ ath10k_err(ar, "WMI attach failed: %d\n", status); -+ goto err; -+ } -+ -+- status = ath10k_hif_start(ar); -++ status = ath10k_htt_init(ar); -++ if (status) { -++ ath10k_err(ar, "failed to init htt: %d\n", status); -++ goto err_wmi_detach; -++ } -++ -++ status = ath10k_htt_tx_alloc(&ar->htt); -+ if (status) { -+- ath10k_err("could not start HIF: %d\n", status); -++ ath10k_err(ar, "failed to alloc htt tx: %d\n", status); -+ goto err_wmi_detach; -+ } -+ -++ status = ath10k_htt_rx_alloc(&ar->htt); -++ if (status) { -++ ath10k_err(ar, "failed to alloc htt rx: %d\n", status); -++ goto err_htt_tx_detach; -++ } -++ -++ status = ath10k_hif_start(ar); -++ if (status) { -++ ath10k_err(ar, "could not start HIF: %d\n", status); -++ goto err_htt_rx_detach; -++ } -++ -+ status = ath10k_htc_wait_target(&ar->htc); -+ if (status) { -+- ath10k_err("failed to connect to HTC: %d\n", status); -++ ath10k_err(ar, "failed to connect to HTC: %d\n", status); -+ goto err_hif_stop; -+ } -+ -+- status = ath10k_htt_attach(ar); -++ if (mode == ATH10K_FIRMWARE_MODE_NORMAL) { -++ status = ath10k_htt_connect(&ar->htt); -++ if (status) { -++ ath10k_err(ar, "failed to connect htt (%d)\n", status); -++ goto err_hif_stop; -++ } -++ } -++ -++ status = ath10k_wmi_connect(ar); -+ if (status) { -+- ath10k_err("could not attach htt (%d)\n", status); -++ ath10k_err(ar, "could not connect wmi: %d\n", status); -+ goto err_hif_stop; -+ } -+ -+- status = ath10k_init_connect_htc(ar); -+- if (status) -+- goto err_htt_detach; -++ status = ath10k_htc_start(&ar->htc); -++ if (status) { -++ ath10k_err(ar, "failed to start htc: %d\n", status); -++ goto err_hif_stop; -++ } -+ -+- ath10k_dbg(ATH10K_DBG_BOOT, "firmware %s booted\n", -++ if (mode == ATH10K_FIRMWARE_MODE_NORMAL) { -++ status = ath10k_wmi_wait_for_service_ready(ar); -++ if (status <= 0) { -++ ath10k_warn(ar, "wmi service ready event not received"); -++ status = -ETIMEDOUT; -++ goto err_hif_stop; -++ } -++ } -++ -++ ath10k_dbg(ar, ATH10K_DBG_BOOT, "firmware %s booted\n", -+ ar->hw->wiphy->fw_version); -+ -+ status = ath10k_wmi_cmd_init(ar); -+ if (status) { -+- ath10k_err("could not send WMI init command (%d)\n", status); -+- goto err_disconnect_htc; -++ ath10k_err(ar, "could not send WMI init command (%d)\n", -++ status); -++ goto err_hif_stop; -+ } -+ -+ status = ath10k_wmi_wait_for_unified_ready(ar); -+ if (status <= 0) { -+- ath10k_err("wmi unified ready event not received\n"); -++ ath10k_err(ar, "wmi unified ready event not received\n"); -+ status = -ETIMEDOUT; -+- goto err_disconnect_htc; -++ goto err_hif_stop; -+ } -+ -+- status = ath10k_htt_attach_target(&ar->htt); -+- if (status) -+- goto err_disconnect_htc; -++ /* If firmware indicates Full Rx Reorder support it must be used in a -++ * slightly different manner. Let HTT code know. -++ */ -++ ar->htt.rx_ring.in_ord_rx = !!(test_bit(WMI_SERVICE_RX_FULL_REORDER, -++ ar->wmi.svc_map)); -++ -++ status = ath10k_htt_rx_ring_refill(ar); -++ if (status) { -++ ath10k_err(ar, "failed to refill htt rx ring: %d\n", status); -++ goto err_hif_stop; -++ } -++ -++ /* we don't care about HTT in UTF mode */ -++ if (mode == ATH10K_FIRMWARE_MODE_NORMAL) { -++ status = ath10k_htt_setup(&ar->htt); -++ if (status) { -++ ath10k_err(ar, "failed to setup htt: %d\n", status); -++ goto err_hif_stop; -++ } -++ } -+ -+ status = ath10k_debug_start(ar); -+ if (status) -+- goto err_disconnect_htc; -+- -+- ar->free_vdev_map = (1 << TARGET_NUM_VDEVS) - 1; -+- INIT_LIST_HEAD(&ar->arvifs); -++ goto err_hif_stop; -+ -+- if (!test_bit(ATH10K_FLAG_FIRST_BOOT_DONE, &ar->dev_flags)) -+- ath10k_info("%s (0x%08x, 0x%08x) fw %s api %d htt %d.%d\n", -+- ar->hw_params.name, -+- ar->target_version, -+- ar->chip_id, -+- ar->hw->wiphy->fw_version, -+- ar->fw_api, -+- ar->htt.target_version_major, -+- ar->htt.target_version_minor); -++ ar->free_vdev_map = (1LL << ar->max_num_vdevs) - 1; -+ -+- __set_bit(ATH10K_FLAG_FIRST_BOOT_DONE, &ar->dev_flags); -++ INIT_LIST_HEAD(&ar->arvifs); -+ -+ return 0; -+ -+-err_disconnect_htc: -+- ath10k_htc_stop(&ar->htc); -+-err_htt_detach: -+- ath10k_htt_detach(&ar->htt); -+ err_hif_stop: -+ ath10k_hif_stop(ar); -++err_htt_rx_detach: -++ ath10k_htt_rx_free(&ar->htt); -++err_htt_tx_detach: -++ ath10k_htt_tx_free(&ar->htt); -+ err_wmi_detach: -+ ath10k_wmi_detach(ar); -+ err: -+@@ -889,14 +1156,14 @@ int ath10k_wait_for_suspend(struct ath10 -+ -+ ret = ath10k_wmi_pdev_suspend_target(ar, suspend_opt); -+ if (ret) { -+- ath10k_warn("could not suspend target (%d)\n", ret); -++ ath10k_warn(ar, "could not suspend target (%d)\n", ret); -+ return ret; -+ } -+ -+ ret = wait_for_completion_timeout(&ar->target_suspend, 1 * HZ); -+ -+ if (ret == 0) { -+- ath10k_warn("suspend timed out - target pause event never came\n"); -++ ath10k_warn(ar, "suspend timed out - target pause event never came\n"); -+ return -ETIMEDOUT; -+ } -+ -+@@ -908,12 +1175,14 @@ void ath10k_core_stop(struct ath10k *ar) -+ lockdep_assert_held(&ar->conf_mutex); -+ -+ /* try to suspend target */ -+- if (ar->state != ATH10K_STATE_RESTARTING) -++ if (ar->state != ATH10K_STATE_RESTARTING && -++ ar->state != ATH10K_STATE_UTF) -+ ath10k_wait_for_suspend(ar, WMI_PDEV_SUSPEND_AND_DISABLE_INTR); -+ -+ ath10k_debug_stop(ar); -+- ath10k_htc_stop(&ar->htc); -+- ath10k_htt_detach(&ar->htt); -++ ath10k_hif_stop(ar); -++ ath10k_htt_tx_free(&ar->htt); -++ ath10k_htt_rx_free(&ar->htt); -+ ath10k_wmi_detach(ar); -+ } -+ EXPORT_SYMBOL(ath10k_core_stop); -+@@ -929,16 +1198,15 @@ static int ath10k_core_probe_fw(struct a -+ -+ ret = ath10k_hif_power_up(ar); -+ if (ret) { -+- ath10k_err("could not start pci hif (%d)\n", ret); -++ ath10k_err(ar, "could not start pci hif (%d)\n", ret); -+ return ret; -+ } -+ -+ memset(&target_info, 0, sizeof(target_info)); -+ ret = ath10k_bmi_get_target_info(ar, &target_info); -+ if (ret) { -+- ath10k_err("could not get target info (%d)\n", ret); -+- ath10k_hif_power_down(ar); -+- return ret; -++ ath10k_err(ar, "could not get target info (%d)\n", ret); -++ goto err_power_down; -+ } -+ -+ ar->target_version = target_info.version; -+@@ -946,118 +1214,233 @@ static int ath10k_core_probe_fw(struct a -+ -+ ret = ath10k_init_hw_params(ar); -+ if (ret) { -+- ath10k_err("could not get hw params (%d)\n", ret); -+- ath10k_hif_power_down(ar); -+- return ret; -++ ath10k_err(ar, "could not get hw params (%d)\n", ret); -++ goto err_power_down; -+ } -+ -+ ret = ath10k_core_fetch_firmware_files(ar); -+ if (ret) { -+- ath10k_err("could not fetch firmware files (%d)\n", ret); -+- ath10k_hif_power_down(ar); -+- return ret; -++ ath10k_err(ar, "could not fetch firmware files (%d)\n", ret); -++ goto err_power_down; -++ } -++ -++ ret = ath10k_core_init_firmware_features(ar); -++ if (ret) { -++ ath10k_err(ar, "fatal problem with firmware features: %d\n", -++ ret); -++ goto err_free_firmware_files; -+ } -+ -+ mutex_lock(&ar->conf_mutex); -+ -+- ret = ath10k_core_start(ar); -++ ret = ath10k_core_start(ar, ATH10K_FIRMWARE_MODE_NORMAL); -+ if (ret) { -+- ath10k_err("could not init core (%d)\n", ret); -+- ath10k_core_free_firmware_files(ar); -+- ath10k_hif_power_down(ar); -+- mutex_unlock(&ar->conf_mutex); -+- return ret; -++ ath10k_err(ar, "could not init core (%d)\n", ret); -++ goto err_unlock; -+ } -+ -++ ath10k_print_driver_info(ar); -+ ath10k_core_stop(ar); -+ -+ mutex_unlock(&ar->conf_mutex); -+ -+ ath10k_hif_power_down(ar); -+ return 0; -+-} -+- -+-static int ath10k_core_check_chip_id(struct ath10k *ar) -+-{ -+- u32 hw_revision = MS(ar->chip_id, SOC_CHIP_ID_REV); -+- -+- ath10k_dbg(ATH10K_DBG_BOOT, "boot chip_id 0x%08x hw_revision 0x%x\n", -+- ar->chip_id, hw_revision); -+ -+- /* Check that we are not using hw1.0 (some of them have same pci id -+- * as hw2.0) before doing anything else as ath10k crashes horribly -+- * due to missing hw1.0 workarounds. */ -+- switch (hw_revision) { -+- case QCA988X_HW_1_0_CHIP_ID_REV: -+- ath10k_err("ERROR: qca988x hw1.0 is not supported\n"); -+- return -EOPNOTSUPP; -++err_unlock: -++ mutex_unlock(&ar->conf_mutex); -+ -+- case QCA988X_HW_2_0_CHIP_ID_REV: -+- /* known hardware revision, continue normally */ -+- return 0; -++err_free_firmware_files: -++ ath10k_core_free_firmware_files(ar); -+ -+- default: -+- ath10k_warn("Warning: hardware revision unknown (0x%x), expect problems\n", -+- ar->chip_id); -+- return 0; -+- } -++err_power_down: -++ ath10k_hif_power_down(ar); -+ -+- return 0; -++ return ret; -+ } -+ -+-int ath10k_core_register(struct ath10k *ar, u32 chip_id) -++static void ath10k_core_register_work(struct work_struct *work) -+ { -++ struct ath10k *ar = container_of(work, struct ath10k, register_work); -+ int status; -+ -+- ar->chip_id = chip_id; -+- -+- status = ath10k_core_check_chip_id(ar); -+- if (status) { -+- ath10k_err("Unsupported chip id 0x%08x\n", ar->chip_id); -+- return status; -+- } -+- -+ status = ath10k_core_probe_fw(ar); -+ if (status) { -+- ath10k_err("could not probe fw (%d)\n", status); -+- return status; -++ ath10k_err(ar, "could not probe fw (%d)\n", status); -++ goto err; -+ } -+ -+ status = ath10k_mac_register(ar); -+ if (status) { -+- ath10k_err("could not register to mac80211 (%d)\n", status); -++ ath10k_err(ar, "could not register to mac80211 (%d)\n", status); -+ goto err_release_fw; -+ } -+ -+- status = ath10k_debug_create(ar); -++ status = ath10k_debug_register(ar); -+ if (status) { -+- ath10k_err("unable to initialize debugfs\n"); -++ ath10k_err(ar, "unable to initialize debugfs\n"); -+ goto err_unregister_mac; -+ } -+ -+- return 0; -++ status = ath10k_spectral_create(ar); -++ if (status) { -++ ath10k_err(ar, "failed to initialize spectral\n"); -++ goto err_debug_destroy; -++ } -+ -++ status = ath10k_thermal_register(ar); -++ if (status) { -++ ath10k_err(ar, "could not register thermal device: %d\n", -++ status); -++ goto err_spectral_destroy; -++ } -++ -++ set_bit(ATH10K_FLAG_CORE_REGISTERED, &ar->dev_flags); -++ return; -++ -++err_spectral_destroy: -++ ath10k_spectral_destroy(ar); -++err_debug_destroy: -++ ath10k_debug_destroy(ar); -+ err_unregister_mac: -+ ath10k_mac_unregister(ar); -+ err_release_fw: -+ ath10k_core_free_firmware_files(ar); -+- return status; -++err: -++ /* TODO: It's probably a good idea to release device from the driver -++ * but calling device_release_driver() here will cause a deadlock. -++ */ -++ return; -++} -++ -++int ath10k_core_register(struct ath10k *ar, u32 chip_id) -++{ -++ ar->chip_id = chip_id; -++ queue_work(ar->workqueue, &ar->register_work); -++ -++ return 0; -+ } -+ EXPORT_SYMBOL(ath10k_core_register); -+ -+ void ath10k_core_unregister(struct ath10k *ar) -+ { -++ cancel_work_sync(&ar->register_work); -++ -++ if (!test_bit(ATH10K_FLAG_CORE_REGISTERED, &ar->dev_flags)) -++ return; -++ -++ ath10k_thermal_unregister(ar); -++ /* Stop spectral before unregistering from mac80211 to remove the -++ * relayfs debugfs file cleanly. Otherwise the parent debugfs tree -++ * would be already be free'd recursively, leading to a double free. -++ */ -++ ath10k_spectral_destroy(ar); -++ -+ /* We must unregister from mac80211 before we stop HTC and HIF. -+ * Otherwise we will fail to submit commands to FW and mac80211 will be -+ * unhappy about callback failures. */ -+ ath10k_mac_unregister(ar); -+ -++ ath10k_testmode_destroy(ar); -++ -+ ath10k_core_free_firmware_files(ar); -+ -+- ath10k_debug_destroy(ar); -++ ath10k_debug_unregister(ar); -+ } -+ EXPORT_SYMBOL(ath10k_core_unregister); -+ -++struct ath10k *ath10k_core_create(size_t priv_size, struct device *dev, -++ enum ath10k_bus bus, -++ enum ath10k_hw_rev hw_rev, -++ const struct ath10k_hif_ops *hif_ops) -++{ -++ struct ath10k *ar; -++ int ret; -++ -++ ar = ath10k_mac_create(priv_size); -++ if (!ar) -++ return NULL; -++ -++ ar->ath_common.priv = ar; -++ ar->ath_common.hw = ar->hw; -++ ar->dev = dev; -++ ar->hw_rev = hw_rev; -++ ar->hif.ops = hif_ops; -++ ar->hif.bus = bus; -++ -++ switch (hw_rev) { -++ case ATH10K_HW_QCA988X: -++ ar->regs = &qca988x_regs; -++ break; -++ case ATH10K_HW_QCA6174: -++ ar->regs = &qca6174_regs; -++ break; -++ default: -++ ath10k_err(ar, "unsupported core hardware revision %d\n", -++ hw_rev); -++ ret = -ENOTSUPP; -++ goto err_free_mac; -++ } -++ -++ init_completion(&ar->scan.started); -++ init_completion(&ar->scan.completed); -++ init_completion(&ar->scan.on_channel); -++ init_completion(&ar->target_suspend); -++ -++ init_completion(&ar->install_key_done); -++ init_completion(&ar->vdev_setup_done); -++ init_completion(&ar->thermal.wmi_sync); -++ -++ INIT_DELAYED_WORK(&ar->scan.timeout, ath10k_scan_timeout_work); -++ -++ ar->workqueue = create_singlethread_workqueue("ath10k_wq"); -++ if (!ar->workqueue) -++ goto err_free_mac; -++ -++ mutex_init(&ar->conf_mutex); -++ spin_lock_init(&ar->data_lock); -++ -++ INIT_LIST_HEAD(&ar->peers); -++ init_waitqueue_head(&ar->peer_mapping_wq); -++ init_waitqueue_head(&ar->htt.empty_tx_wq); -++ init_waitqueue_head(&ar->wmi.tx_credits_wq); -++ -++ init_completion(&ar->offchan_tx_completed); -++ INIT_WORK(&ar->offchan_tx_work, ath10k_offchan_tx_work); -++ skb_queue_head_init(&ar->offchan_tx_queue); -++ -++ INIT_WORK(&ar->wmi_mgmt_tx_work, ath10k_mgmt_over_wmi_tx_work); -++ skb_queue_head_init(&ar->wmi_mgmt_tx_queue); -++ -++ INIT_WORK(&ar->register_work, ath10k_core_register_work); -++ INIT_WORK(&ar->restart_work, ath10k_core_restart); -++ -++ ret = ath10k_debug_create(ar); -++ if (ret) -++ goto err_free_wq; -++ -++ return ar; -++ -++err_free_wq: -++ destroy_workqueue(ar->workqueue); -++ -++err_free_mac: -++ ath10k_mac_destroy(ar); -++ -++ return NULL; -++} -++EXPORT_SYMBOL(ath10k_core_create); -++ -++void ath10k_core_destroy(struct ath10k *ar) -++{ -++ flush_workqueue(ar->workqueue); -++ destroy_workqueue(ar->workqueue); -++ -++ ath10k_debug_destroy(ar); -++ ath10k_mac_destroy(ar); -++} -++EXPORT_SYMBOL(ath10k_core_destroy); -++ -+ MODULE_AUTHOR("Qualcomm Atheros"); -+ MODULE_DESCRIPTION("Core module for QCA988X PCIe devices."); -+ MODULE_LICENSE("Dual BSD/GPL"); -+--- a/drivers/net/wireless/ath/ath10k/core.h -++++ b/drivers/net/wireless/ath/ath10k/core.h -+@@ -22,6 +22,8 @@ -+ #include -+ #include -+ #include -++#include -++#include -+ -+ #include "htt.h" -+ #include "htc.h" -+@@ -31,6 +33,8 @@ -+ #include "../ath.h" -+ #include "../regd.h" -+ #include "../dfs_pattern_detector.h" -++#include "spectral.h" -++#include "thermal.h" -+ -+ #define MS(_v, _f) (((_v) & _f##_MASK) >> _f##_LSB) -+ #define SM(_v, _f) (((_v) << _f##_LSB) & _f##_MASK) -+@@ -60,12 +64,28 @@ -+ -+ struct ath10k; -+ -++enum ath10k_bus { -++ ATH10K_BUS_PCI, -++}; -++ -++static inline const char *ath10k_bus_str(enum ath10k_bus bus) -++{ -++ switch (bus) { -++ case ATH10K_BUS_PCI: -++ return "pci"; -++ } -++ -++ return "unknown"; -++} -++ -+ struct ath10k_skb_cb { -+ dma_addr_t paddr; -++ u8 eid; -+ u8 vdev_id; -+ -+ struct { -+ u8 tid; -++ u16 freq; -+ bool is_offchan; -+ struct ath10k_htt_txbuf *txbuf; -+ u32 txbuf_paddr; -+@@ -77,6 +97,11 @@ struct ath10k_skb_cb { -+ } bcn; -+ } __packed; -+ -++struct ath10k_skb_rxcb { -++ dma_addr_t paddr; -++ struct hlist_node hlist; -++}; -++ -+ static inline struct ath10k_skb_cb *ATH10K_SKB_CB(struct sk_buff *skb) -+ { -+ BUILD_BUG_ON(sizeof(struct ath10k_skb_cb) > -+@@ -84,6 +109,15 @@ static inline struct ath10k_skb_cb *ATH1 -+ return (struct ath10k_skb_cb *)&IEEE80211_SKB_CB(skb)->driver_data; -+ } -+ -++static inline struct ath10k_skb_rxcb *ATH10K_SKB_RXCB(struct sk_buff *skb) -++{ -++ BUILD_BUG_ON(sizeof(struct ath10k_skb_rxcb) > sizeof(skb->cb)); -++ return (struct ath10k_skb_rxcb *)skb->cb; -++} -++ -++#define ATH10K_RXCB_SKB(rxcb) \ -++ container_of((void *)rxcb, struct sk_buff, cb) -++ -+ static inline u32 host_interest_item_address(u32 item_offset) -+ { -+ return QCA988X_HOST_INTEREST_ADDRESS + item_offset; -+@@ -93,8 +127,6 @@ struct ath10k_bmi { -+ bool done_sent; -+ }; -+ -+-#define ATH10K_MAX_MEM_REQS 16 -+- -+ struct ath10k_mem_chunk { -+ void *vaddr; -+ dma_addr_t paddr; -+@@ -103,26 +135,52 @@ struct ath10k_mem_chunk { -+ }; -+ -+ struct ath10k_wmi { -++ enum ath10k_fw_wmi_op_version op_version; -+ enum ath10k_htc_ep_id eid; -+ struct completion service_ready; -+ struct completion unified_ready; -+ wait_queue_head_t tx_credits_wq; -++ DECLARE_BITMAP(svc_map, WMI_SERVICE_MAX); -+ struct wmi_cmd_map *cmd; -+ struct wmi_vdev_param_map *vdev_param; -+ struct wmi_pdev_param_map *pdev_param; -++ const struct wmi_ops *ops; -+ -+ u32 num_mem_chunks; -+- struct ath10k_mem_chunk mem_chunks[ATH10K_MAX_MEM_REQS]; -++ struct ath10k_mem_chunk mem_chunks[WMI_MAX_MEM_REQS]; -+ }; -+ -+-struct ath10k_peer_stat { -++struct ath10k_fw_stats_peer { -++ struct list_head list; -++ -+ u8 peer_macaddr[ETH_ALEN]; -+ u32 peer_rssi; -+ u32 peer_tx_rate; -+ u32 peer_rx_rate; /* 10x only */ -+ }; -+ -+-struct ath10k_target_stats { -++struct ath10k_fw_stats_vdev { -++ struct list_head list; -++ -++ u32 vdev_id; -++ u32 beacon_snr; -++ u32 data_snr; -++ u32 num_tx_frames[4]; -++ u32 num_rx_frames; -++ u32 num_tx_frames_retries[4]; -++ u32 num_tx_frames_failures[4]; -++ u32 num_rts_fail; -++ u32 num_rts_success; -++ u32 num_rx_err; -++ u32 num_rx_discard; -++ u32 num_tx_not_acked; -++ u32 tx_rate_history[10]; -++ u32 beacon_rssi_history[10]; -++}; -++ -++struct ath10k_fw_stats_pdev { -++ struct list_head list; -++ -+ /* PDEV stats */ -+ s32 ch_noise_floor; -+ u32 tx_frame_count; -+@@ -177,15 +235,12 @@ struct ath10k_target_stats { -+ s32 phy_errs; -+ s32 phy_err_drop; -+ s32 mpdu_errs; -++}; -+ -+- /* VDEV STATS */ -+- -+- /* PEER STATS */ -+- u8 peers; -+- struct ath10k_peer_stat peer_stat[TARGET_NUM_PEERS]; -+- -+- /* TODO: Beacon filter stats */ -+- -++struct ath10k_fw_stats { -++ struct list_head pdevs; -++ struct list_head vdevs; -++ struct list_head peers; -+ }; -+ -+ struct ath10k_dfs_stats { -+@@ -203,6 +258,8 @@ struct ath10k_peer { -+ int vdev_id; -+ u8 addr[ETH_ALEN]; -+ DECLARE_BITMAP(peer_ids, ATH10K_MAX_NUM_PEER_IDS); -++ -++ /* protected by ar->data_lock */ -+ struct ieee80211_key_conf *keys[WMI_MAX_KEY_INDEX + 1]; -+ }; -+ -+@@ -216,10 +273,21 @@ struct ath10k_sta { -+ u32 smps; -+ -+ struct work_struct update_wk; -++ -++#ifdef CPTCFG_MAC80211_DEBUGFS -++ /* protected by conf_mutex */ -++ bool aggr_mode; -++#endif -+ }; -+ -+ #define ATH10K_VDEV_SETUP_TIMEOUT_HZ (5*HZ) -+ -++enum ath10k_beacon_state { -++ ATH10K_BEACON_SCHEDULED = 0, -++ ATH10K_BEACON_SENDING, -++ ATH10K_BEACON_SENT, -++}; -++ -+ struct ath10k_vif { -+ struct list_head list; -+ -+@@ -230,20 +298,22 @@ struct ath10k_vif { -+ u32 dtim_period; -+ struct sk_buff *beacon; -+ /* protected by data_lock */ -+- bool beacon_sent; -++ enum ath10k_beacon_state beacon_state; -++ void *beacon_buf; -++ dma_addr_t beacon_paddr; -+ -+ struct ath10k *ar; -+ struct ieee80211_vif *vif; -+ -+ bool is_started; -+ bool is_up; -++ bool spectral_enabled; -++ bool ps; -+ u32 aid; -+ u8 bssid[ETH_ALEN]; -+ -+- struct work_struct wep_key_work; -+ struct ieee80211_key_conf *wep_keys[WMI_MAX_KEY_INDEX + 1]; -+- u8 def_wep_key_idx; -+- u8 def_wep_key_newidx; -++ s8 def_wep_key_idx; -+ -+ u16 tx_seq_no; -+ -+@@ -269,6 +339,8 @@ struct ath10k_vif { -+ u8 force_sgi; -+ bool use_cts_prot; -+ int num_legacy_stations; -++ int txpower; -++ struct wmi_wmm_params_all_arg wmm_params; -+ }; -+ -+ struct ath10k_vif_iter { -+@@ -276,20 +348,38 @@ struct ath10k_vif_iter { -+ struct ath10k_vif *arvif; -+ }; -+ -++/* used for crash-dump storage, protected by data-lock */ -++struct ath10k_fw_crash_data { -++ bool crashed_since_read; -++ -++ uuid_le uuid; -++ struct timespec timestamp; -++ __le32 registers[REG_DUMP_COUNT_QCA988X]; -++}; -++ -+ struct ath10k_debug { -+ struct dentry *debugfs_phy; -+ -+- struct ath10k_target_stats target_stats; -+- u32 wmi_service_bitmap[WMI_SERVICE_BM_SIZE]; -+- -+- struct completion event_stats_compl; -++ struct ath10k_fw_stats fw_stats; -++ struct completion fw_stats_complete; -++ bool fw_stats_done; -+ -+ unsigned long htt_stats_mask; -+ struct delayed_work htt_stats_dwork; -+ struct ath10k_dfs_stats dfs_stats; -+ struct ath_dfs_pool_stats dfs_pool_stats; -+ -++ /* protected by conf_mutex */ -+ u32 fw_dbglog_mask; -++ u32 fw_dbglog_level; -++ u32 pktlog_filter; -++ u32 reg_addr; -++ u32 nf_cal_period; -++ -++ u8 htt_max_amsdu; -++ u8 htt_max_ampdu; -++ -++ struct ath10k_fw_crash_data *fw_crash_data; -+ }; -+ -+ enum ath10k_state { -+@@ -312,13 +402,24 @@ enum ath10k_state { -+ * prevents completion timeouts and makes the driver more responsive to -+ * userspace commands. This is also prevents recursive recovery. */ -+ ATH10K_STATE_WEDGED, -++ -++ /* factory tests */ -++ ATH10K_STATE_UTF, -++}; -++ -++enum ath10k_firmware_mode { -++ /* the default mode, standard 802.11 functionality */ -++ ATH10K_FIRMWARE_MODE_NORMAL, -++ -++ /* factory tests etc */ -++ ATH10K_FIRMWARE_MODE_UTF, -+ }; -+ -+ enum ath10k_fw_features { -+ /* wmi_mgmt_rx_hdr contains extra RSSI information */ -+ ATH10K_FW_FEATURE_EXT_WMI_MGMT_RX = 0, -+ -+- /* firmware from 10X branch */ -++ /* Firmware from 10X branch. Deprecated, don't use in new code. */ -+ ATH10K_FW_FEATURE_WMI_10X = 1, -+ -+ /* firmware support tx frame management over WMI, otherwise it's HTT */ -+@@ -327,6 +428,18 @@ enum ath10k_fw_features { -+ /* Firmware does not support P2P */ -+ ATH10K_FW_FEATURE_NO_P2P = 3, -+ -++ /* Firmware 10.2 feature bit. The ATH10K_FW_FEATURE_WMI_10X feature -++ * bit is required to be set as well. Deprecated, don't use in new -++ * code. -++ */ -++ ATH10K_FW_FEATURE_WMI_10_2 = 4, -++ -++ /* Some firmware revisions lack proper multi-interface client powersave -++ * implementation. Enabling PS could result in connection drops, -++ * traffic stalls, etc. -++ */ -++ ATH10K_FW_FEATURE_MULTI_VIF_PS_SUPPORT = 5, -++ -+ /* keep last */ -+ ATH10K_FW_FEATURE_COUNT, -+ }; -+@@ -334,15 +447,64 @@ enum ath10k_fw_features { -+ enum ath10k_dev_flags { -+ /* Indicates that ath10k device is during CAC phase of DFS */ -+ ATH10K_CAC_RUNNING, -+- ATH10K_FLAG_FIRST_BOOT_DONE, -++ ATH10K_FLAG_CORE_REGISTERED, -++ -++ /* Device has crashed and needs to restart. This indicates any pending -++ * waiters should immediately cancel instead of waiting for a time out. -++ */ -++ ATH10K_FLAG_CRASH_FLUSH, -++}; -++ -++enum ath10k_cal_mode { -++ ATH10K_CAL_MODE_FILE, -++ ATH10K_CAL_MODE_OTP, -++ ATH10K_CAL_MODE_DT, -++}; -++ -++static inline const char *ath10k_cal_mode_str(enum ath10k_cal_mode mode) -++{ -++ switch (mode) { -++ case ATH10K_CAL_MODE_FILE: -++ return "file"; -++ case ATH10K_CAL_MODE_OTP: -++ return "otp"; -++ case ATH10K_CAL_MODE_DT: -++ return "dt"; -++ } -++ -++ return "unknown"; -++} -++ -++enum ath10k_scan_state { -++ ATH10K_SCAN_IDLE, -++ ATH10K_SCAN_STARTING, -++ ATH10K_SCAN_RUNNING, -++ ATH10K_SCAN_ABORTING, -+ }; -+ -++static inline const char *ath10k_scan_state_str(enum ath10k_scan_state state) -++{ -++ switch (state) { -++ case ATH10K_SCAN_IDLE: -++ return "idle"; -++ case ATH10K_SCAN_STARTING: -++ return "starting"; -++ case ATH10K_SCAN_RUNNING: -++ return "running"; -++ case ATH10K_SCAN_ABORTING: -++ return "aborting"; -++ } -++ -++ return "unknown"; -++} -++ -+ struct ath10k { -+ struct ath_common ath_common; -+ struct ieee80211_hw *hw; -+ struct device *dev; -+ u8 mac_addr[ETH_ALEN]; -+ -++ enum ath10k_hw_rev hw_rev; -+ u32 chip_id; -+ u32 target_version; -+ u8 fw_version_major; -+@@ -358,18 +520,16 @@ struct ath10k { -+ -+ DECLARE_BITMAP(fw_features, ATH10K_FW_FEATURE_COUNT); -+ -+- struct targetdef *targetdef; -+- struct hostdef *hostdef; -+- -+ bool p2p; -+ -+ struct { -+- void *priv; -++ enum ath10k_bus bus; -+ const struct ath10k_hif_ops *ops; -+ } hif; -+ -+ struct completion target_suspend; -+ -++ const struct ath10k_hw_regs *regs; -+ struct ath10k_bmi bmi; -+ struct ath10k_wmi wmi; -+ struct ath10k_htc htc; -+@@ -379,12 +539,15 @@ struct ath10k { -+ u32 id; -+ const char *name; -+ u32 patch_load_addr; -++ int uart_pin; -+ -+ struct ath10k_hw_params_fw { -+ const char *dir; -+ const char *fw; -+ const char *otp; -+ const char *board; -++ size_t board_size; -++ size_t board_ext_size; -+ } fw; -+ } hw_params; -+ -+@@ -400,16 +563,18 @@ struct ath10k { -+ const void *firmware_data; -+ size_t firmware_len; -+ -++ const struct firmware *cal_file; -++ -+ int fw_api; -++ enum ath10k_cal_mode cal_mode; -+ -+ struct { -+ struct completion started; -+ struct completion completed; -+ struct completion on_channel; -+- struct timer_list timeout; -++ struct delayed_work timeout; -++ enum ath10k_scan_state state; -+ bool is_roc; -+- bool in_progress; -+- bool aborting; -+ int vdev_id; -+ int roc_freq; -+ } scan; -+@@ -427,8 +592,7 @@ struct ath10k { -+ /* current operating channel definition */ -+ struct cfg80211_chan_def chandef; -+ -+- int free_vdev_map; -+- bool promisc; -++ unsigned long long free_vdev_map; -+ bool monitor; -+ int monitor_vdev_id; -+ bool monitor_started; -+@@ -440,7 +604,12 @@ struct ath10k { -+ bool radar_enabled; -+ int num_started_vdevs; -+ -+- struct wmi_pdev_set_wmm_params_arg wmm_params; -++ /* Protected by conf-mutex */ -++ u8 supp_tx_chainmask; -++ u8 supp_rx_chainmask; -++ u8 cfg_tx_chainmask; -++ u8 cfg_rx_chainmask; -++ -+ struct completion install_key_done; -+ -+ struct completion vdev_setup_done; -+@@ -457,8 +626,13 @@ struct ath10k { -+ struct list_head peers; -+ wait_queue_head_t peer_mapping_wq; -+ -+- /* number of created peers; protected by data_lock */ -++ /* protected by conf_mutex */ -+ int num_peers; -++ int num_stations; -++ -++ int max_num_peers; -++ int max_num_stations; -++ int max_num_vdevs; -+ -+ struct work_struct offchan_tx_work; -+ struct sk_buff_head offchan_tx_queue; -+@@ -470,6 +644,7 @@ struct ath10k { -+ -+ enum ath10k_state state; -+ -++ struct work_struct register_work; -+ struct work_struct restart_work; -+ -+ /* cycle count is reported twice for each visited channel during scan. -+@@ -483,13 +658,46 @@ struct ath10k { -+ #ifdef CPTCFG_ATH10K_DEBUGFS -+ struct ath10k_debug debug; -+ #endif -++ -++ struct { -++ /* relay(fs) channel for spectral scan */ -++ struct rchan *rfs_chan_spec_scan; -++ -++ /* spectral_mode and spec_config are protected by conf_mutex */ -++ enum ath10k_spectral_mode mode; -++ struct ath10k_spec_scan config; -++ } spectral; -++ -++ struct { -++ /* protected by conf_mutex */ -++ const struct firmware *utf; -++ DECLARE_BITMAP(orig_fw_features, ATH10K_FW_FEATURE_COUNT); -++ enum ath10k_fw_wmi_op_version orig_wmi_op_version; -++ -++ /* protected by data_lock */ -++ bool utf_monitor; -++ } testmode; -++ -++ struct { -++ /* protected by data_lock */ -++ u32 fw_crash_counter; -++ u32 fw_warm_reset_counter; -++ u32 fw_cold_reset_counter; -++ } stats; -++ -++ struct ath10k_thermal thermal; -++ -++ /* must be last */ -++ u8 drv_priv[0] __aligned(sizeof(void *)); -+ }; -+ -+-struct ath10k *ath10k_core_create(void *hif_priv, struct device *dev, -++struct ath10k *ath10k_core_create(size_t priv_size, struct device *dev, -++ enum ath10k_bus bus, -++ enum ath10k_hw_rev hw_rev, -+ const struct ath10k_hif_ops *hif_ops); -+ void ath10k_core_destroy(struct ath10k *ar); -+ -+-int ath10k_core_start(struct ath10k *ar); -++int ath10k_core_start(struct ath10k *ar, enum ath10k_firmware_mode mode); -+ int ath10k_wait_for_suspend(struct ath10k *ar, u32 suspend_opt); -+ void ath10k_core_stop(struct ath10k *ar); -+ int ath10k_core_register(struct ath10k *ar, u32 chip_id); -+--- a/drivers/net/wireless/ath/ath10k/debug.c -++++ b/drivers/net/wireless/ath/ath10k/debug.c -+@@ -17,107 +17,176 @@ -+ -+ #include -+ #include -++#include -++#include -+ -+ #include "core.h" -+ #include "debug.h" -++#include "hif.h" -++#include "wmi-ops.h" -+ -+ /* ms */ -+ #define ATH10K_DEBUG_HTT_STATS_INTERVAL 1000 -+ -+-static int ath10k_printk(const char *level, const char *fmt, ...) -+-{ -+- struct va_format vaf; -+- va_list args; -+- int rtn; -++#define ATH10K_FW_CRASH_DUMP_VERSION 1 -+ -+- va_start(args, fmt); -++/** -++ * enum ath10k_fw_crash_dump_type - types of data in the dump file -++ * @ATH10K_FW_CRASH_DUMP_REGDUMP: Register crash dump in binary format -++ */ -++enum ath10k_fw_crash_dump_type { -++ ATH10K_FW_CRASH_DUMP_REGISTERS = 0, -+ -+- vaf.fmt = fmt; -+- vaf.va = &args; -++ ATH10K_FW_CRASH_DUMP_MAX, -++}; -+ -+- rtn = printk("%sath10k: %pV", level, &vaf); -++struct ath10k_tlv_dump_data { -++ /* see ath10k_fw_crash_dump_type above */ -++ __le32 type; -+ -+- va_end(args); -++ /* in bytes */ -++ __le32 tlv_len; -+ -+- return rtn; -+-} -++ /* pad to 32-bit boundaries as needed */ -++ u8 tlv_data[]; -++} __packed; -++ -++struct ath10k_dump_file_data { -++ /* dump file information */ -++ -++ /* "ATH10K-FW-DUMP" */ -++ char df_magic[16]; -++ -++ __le32 len; -++ -++ /* file dump version */ -++ __le32 version; -++ -++ /* some info we can get from ath10k struct that might help */ -++ -++ u8 uuid[16]; -++ -++ __le32 chip_id; -++ -++ /* 0 for now, in place for later hardware */ -++ __le32 bus_type; -++ -++ __le32 target_version; -++ __le32 fw_version_major; -++ __le32 fw_version_minor; -++ __le32 fw_version_release; -++ __le32 fw_version_build; -++ __le32 phy_capability; -++ __le32 hw_min_tx_power; -++ __le32 hw_max_tx_power; -++ __le32 ht_cap_info; -++ __le32 vht_cap_info; -++ __le32 num_rf_chains; -++ -++ /* firmware version string */ -++ char fw_ver[ETHTOOL_FWVERS_LEN]; -++ -++ /* Kernel related information */ -++ -++ /* time-of-day stamp */ -++ __le64 tv_sec; -++ -++ /* time-of-day stamp, nano-seconds */ -++ __le64 tv_nsec; -++ -++ /* LINUX_VERSION_CODE */ -++ __le32 kernel_ver_code; -++ -++ /* VERMAGIC_STRING */ -++ char kernel_ver[64]; -+ -+-int ath10k_info(const char *fmt, ...) -++ /* room for growth w/out changing binary format */ -++ u8 unused[128]; -++ -++ /* struct ath10k_tlv_dump_data + more */ -++ u8 data[0]; -++} __packed; -++ -++void ath10k_info(struct ath10k *ar, const char *fmt, ...) -+ { -+ struct va_format vaf = { -+ .fmt = fmt, -+ }; -+ va_list args; -+- int ret; -+ -+ va_start(args, fmt); -+ vaf.va = &args; -+- ret = ath10k_printk(KERN_INFO, "%pV", &vaf); -+- trace_ath10k_log_info(&vaf); -++ dev_info(ar->dev, "%pV", &vaf); -++ trace_ath10k_log_info(ar, &vaf); -+ va_end(args); -+- -+- return ret; -+ } -+ EXPORT_SYMBOL(ath10k_info); -+ -+-int ath10k_err(const char *fmt, ...) -++void ath10k_print_driver_info(struct ath10k *ar) -++{ -++ ath10k_info(ar, "%s (0x%08x, 0x%08x) fw %s api %d htt %d.%d wmi %d cal %s max_sta %d\n", -++ ar->hw_params.name, -++ ar->target_version, -++ ar->chip_id, -++ ar->hw->wiphy->fw_version, -++ ar->fw_api, -++ ar->htt.target_version_major, -++ ar->htt.target_version_minor, -++ ar->wmi.op_version, -++ ath10k_cal_mode_str(ar->cal_mode), -++ ar->max_num_stations); -++ ath10k_info(ar, "debug %d debugfs %d tracing %d dfs %d testmode %d\n", -++ config_enabled(CPTCFG_ATH10K_DEBUG), -++ config_enabled(CPTCFG_ATH10K_DEBUGFS), -++ config_enabled(CPTCFG_ATH10K_TRACING), -++ config_enabled(CPTCFG_ATH10K_DFS_CERTIFIED), -++ config_enabled(CPTCFG_NL80211_TESTMODE)); -++} -++EXPORT_SYMBOL(ath10k_print_driver_info); -++ -++void ath10k_err(struct ath10k *ar, const char *fmt, ...) -+ { -+ struct va_format vaf = { -+ .fmt = fmt, -+ }; -+ va_list args; -+- int ret; -+ -+ va_start(args, fmt); -+ vaf.va = &args; -+- ret = ath10k_printk(KERN_ERR, "%pV", &vaf); -+- trace_ath10k_log_err(&vaf); -++ dev_err(ar->dev, "%pV", &vaf); -++ trace_ath10k_log_err(ar, &vaf); -+ va_end(args); -+- -+- return ret; -+ } -+ EXPORT_SYMBOL(ath10k_err); -+ -+-int ath10k_warn(const char *fmt, ...) -++void ath10k_warn(struct ath10k *ar, const char *fmt, ...) -+ { -+ struct va_format vaf = { -+ .fmt = fmt, -+ }; -+ va_list args; -+- int ret = 0; -+ -+ va_start(args, fmt); -+ vaf.va = &args; -+- -+- if (net_ratelimit()) -+- ret = ath10k_printk(KERN_WARNING, "%pV", &vaf); -+- -+- trace_ath10k_log_warn(&vaf); -++ dev_warn_ratelimited(ar->dev, "%pV", &vaf); -++ trace_ath10k_log_warn(ar, &vaf); -+ -+ va_end(args); -+- -+- return ret; -+ } -+ EXPORT_SYMBOL(ath10k_warn); -+ -+ #ifdef CPTCFG_ATH10K_DEBUGFS -+ -+-void ath10k_debug_read_service_map(struct ath10k *ar, -+- void *service_map, -+- size_t map_size) -+-{ -+- memcpy(ar->debug.wmi_service_bitmap, service_map, map_size); -+-} -+- -+ static ssize_t ath10k_read_wmi_services(struct file *file, -+ char __user *user_buf, -+ size_t count, loff_t *ppos) -+ { -+ struct ath10k *ar = file->private_data; -+ char *buf; -+- unsigned int len = 0, buf_len = 1500; -+- const char *status; -++ unsigned int len = 0, buf_len = 4096; -++ const char *name; -+ ssize_t ret_cnt; -++ bool enabled; -+ int i; -+ -+ buf = kzalloc(buf_len, GFP_KERNEL); -+@@ -129,16 +198,25 @@ static ssize_t ath10k_read_wmi_services( -+ if (len > buf_len) -+ len = buf_len; -+ -+- for (i = 0; i < WMI_SERVICE_LAST; i++) { -+- if (WMI_SERVICE_IS_ENABLED(ar->debug.wmi_service_bitmap, i)) -+- status = "enabled"; -+- else -+- status = "disabled"; -++ spin_lock_bh(&ar->data_lock); -++ for (i = 0; i < WMI_SERVICE_MAX; i++) { -++ enabled = test_bit(i, ar->wmi.svc_map); -++ name = wmi_service_name(i); -++ -++ if (!name) { -++ if (enabled) -++ len += scnprintf(buf + len, buf_len - len, -++ "%-40s %s (bit %d)\n", -++ "unknown", "enabled", i); -++ -++ continue; -++ } -+ -+ len += scnprintf(buf + len, buf_len - len, -+- "0x%02x - %20s - %s\n", -+- i, wmi_service_name(i), status); -++ "%-40s %s\n", -++ name, enabled ? "enabled" : "-"); -+ } -++ spin_unlock_bh(&ar->data_lock); -+ -+ ret_cnt = simple_read_from_buffer(user_buf, count, ppos, buf, len); -+ -+@@ -155,169 +233,221 @@ static const struct file_operations fops -+ .llseek = default_llseek, -+ }; -+ -+-void ath10k_debug_read_target_stats(struct ath10k *ar, -+- struct wmi_stats_event *ev) -++static void ath10k_debug_fw_stats_pdevs_free(struct list_head *head) -+ { -+- u8 *tmp = ev->data; -+- struct ath10k_target_stats *stats; -+- int num_pdev_stats, num_vdev_stats, num_peer_stats; -+- struct wmi_pdev_stats_10x *ps; -+- int i; -++ struct ath10k_fw_stats_pdev *i, *tmp; -+ -++ list_for_each_entry_safe(i, tmp, head, list) { -++ list_del(&i->list); -++ kfree(i); -++ } -++} -++ -++static void ath10k_debug_fw_stats_vdevs_free(struct list_head *head) -++{ -++ struct ath10k_fw_stats_vdev *i, *tmp; -++ -++ list_for_each_entry_safe(i, tmp, head, list) { -++ list_del(&i->list); -++ kfree(i); -++ } -++} -++ -++static void ath10k_debug_fw_stats_peers_free(struct list_head *head) -++{ -++ struct ath10k_fw_stats_peer *i, *tmp; -++ -++ list_for_each_entry_safe(i, tmp, head, list) { -++ list_del(&i->list); -++ kfree(i); -++ } -++} -++ -++static void ath10k_debug_fw_stats_reset(struct ath10k *ar) -++{ -+ spin_lock_bh(&ar->data_lock); -++ ar->debug.fw_stats_done = false; -++ ath10k_debug_fw_stats_pdevs_free(&ar->debug.fw_stats.pdevs); -++ ath10k_debug_fw_stats_vdevs_free(&ar->debug.fw_stats.vdevs); -++ ath10k_debug_fw_stats_peers_free(&ar->debug.fw_stats.peers); -++ spin_unlock_bh(&ar->data_lock); -++} -+ -+- stats = &ar->debug.target_stats; -++static size_t ath10k_debug_fw_stats_num_peers(struct list_head *head) -++{ -++ struct ath10k_fw_stats_peer *i; -++ size_t num = 0; -+ -+- num_pdev_stats = __le32_to_cpu(ev->num_pdev_stats); /* 0 or 1 */ -+- num_vdev_stats = __le32_to_cpu(ev->num_vdev_stats); /* 0 or max vdevs */ -+- num_peer_stats = __le32_to_cpu(ev->num_peer_stats); /* 0 or max peers */ -+- -+- if (num_pdev_stats) { -+- ps = (struct wmi_pdev_stats_10x *)tmp; -+- -+- stats->ch_noise_floor = __le32_to_cpu(ps->chan_nf); -+- stats->tx_frame_count = __le32_to_cpu(ps->tx_frame_count); -+- stats->rx_frame_count = __le32_to_cpu(ps->rx_frame_count); -+- stats->rx_clear_count = __le32_to_cpu(ps->rx_clear_count); -+- stats->cycle_count = __le32_to_cpu(ps->cycle_count); -+- stats->phy_err_count = __le32_to_cpu(ps->phy_err_count); -+- stats->chan_tx_power = __le32_to_cpu(ps->chan_tx_pwr); -+- -+- stats->comp_queued = __le32_to_cpu(ps->wal.tx.comp_queued); -+- stats->comp_delivered = -+- __le32_to_cpu(ps->wal.tx.comp_delivered); -+- stats->msdu_enqued = __le32_to_cpu(ps->wal.tx.msdu_enqued); -+- stats->mpdu_enqued = __le32_to_cpu(ps->wal.tx.mpdu_enqued); -+- stats->wmm_drop = __le32_to_cpu(ps->wal.tx.wmm_drop); -+- stats->local_enqued = __le32_to_cpu(ps->wal.tx.local_enqued); -+- stats->local_freed = __le32_to_cpu(ps->wal.tx.local_freed); -+- stats->hw_queued = __le32_to_cpu(ps->wal.tx.hw_queued); -+- stats->hw_reaped = __le32_to_cpu(ps->wal.tx.hw_reaped); -+- stats->underrun = __le32_to_cpu(ps->wal.tx.underrun); -+- stats->tx_abort = __le32_to_cpu(ps->wal.tx.tx_abort); -+- stats->mpdus_requed = __le32_to_cpu(ps->wal.tx.mpdus_requed); -+- stats->tx_ko = __le32_to_cpu(ps->wal.tx.tx_ko); -+- stats->data_rc = __le32_to_cpu(ps->wal.tx.data_rc); -+- stats->self_triggers = __le32_to_cpu(ps->wal.tx.self_triggers); -+- stats->sw_retry_failure = -+- __le32_to_cpu(ps->wal.tx.sw_retry_failure); -+- stats->illgl_rate_phy_err = -+- __le32_to_cpu(ps->wal.tx.illgl_rate_phy_err); -+- stats->pdev_cont_xretry = -+- __le32_to_cpu(ps->wal.tx.pdev_cont_xretry); -+- stats->pdev_tx_timeout = -+- __le32_to_cpu(ps->wal.tx.pdev_tx_timeout); -+- stats->pdev_resets = __le32_to_cpu(ps->wal.tx.pdev_resets); -+- stats->phy_underrun = __le32_to_cpu(ps->wal.tx.phy_underrun); -+- stats->txop_ovf = __le32_to_cpu(ps->wal.tx.txop_ovf); -+- -+- stats->mid_ppdu_route_change = -+- __le32_to_cpu(ps->wal.rx.mid_ppdu_route_change); -+- stats->status_rcvd = __le32_to_cpu(ps->wal.rx.status_rcvd); -+- stats->r0_frags = __le32_to_cpu(ps->wal.rx.r0_frags); -+- stats->r1_frags = __le32_to_cpu(ps->wal.rx.r1_frags); -+- stats->r2_frags = __le32_to_cpu(ps->wal.rx.r2_frags); -+- stats->r3_frags = __le32_to_cpu(ps->wal.rx.r3_frags); -+- stats->htt_msdus = __le32_to_cpu(ps->wal.rx.htt_msdus); -+- stats->htt_mpdus = __le32_to_cpu(ps->wal.rx.htt_mpdus); -+- stats->loc_msdus = __le32_to_cpu(ps->wal.rx.loc_msdus); -+- stats->loc_mpdus = __le32_to_cpu(ps->wal.rx.loc_mpdus); -+- stats->oversize_amsdu = -+- __le32_to_cpu(ps->wal.rx.oversize_amsdu); -+- stats->phy_errs = __le32_to_cpu(ps->wal.rx.phy_errs); -+- stats->phy_err_drop = __le32_to_cpu(ps->wal.rx.phy_err_drop); -+- stats->mpdu_errs = __le32_to_cpu(ps->wal.rx.mpdu_errs); -+- -+- if (test_bit(ATH10K_FW_FEATURE_WMI_10X, -+- ar->fw_features)) { -+- stats->ack_rx_bad = __le32_to_cpu(ps->ack_rx_bad); -+- stats->rts_bad = __le32_to_cpu(ps->rts_bad); -+- stats->rts_good = __le32_to_cpu(ps->rts_good); -+- stats->fcs_bad = __le32_to_cpu(ps->fcs_bad); -+- stats->no_beacons = __le32_to_cpu(ps->no_beacons); -+- stats->mib_int_count = __le32_to_cpu(ps->mib_int_count); -+- tmp += sizeof(struct wmi_pdev_stats_10x); -+- } else { -+- tmp += sizeof(struct wmi_pdev_stats_old); -+- } -++ list_for_each_entry(i, head, list) -++ ++num; -++ -++ return num; -++} -++ -++static size_t ath10k_debug_fw_stats_num_vdevs(struct list_head *head) -++{ -++ struct ath10k_fw_stats_vdev *i; -++ size_t num = 0; -++ -++ list_for_each_entry(i, head, list) -++ ++num; -++ -++ return num; -++} -++ -++void ath10k_debug_fw_stats_process(struct ath10k *ar, struct sk_buff *skb) -++{ -++ struct ath10k_fw_stats stats = {}; -++ bool is_start, is_started, is_end; -++ size_t num_peers; -++ size_t num_vdevs; -++ int ret; -++ -++ INIT_LIST_HEAD(&stats.pdevs); -++ INIT_LIST_HEAD(&stats.vdevs); -++ INIT_LIST_HEAD(&stats.peers); -++ -++ spin_lock_bh(&ar->data_lock); -++ ret = ath10k_wmi_pull_fw_stats(ar, skb, &stats); -++ if (ret) { -++ ath10k_warn(ar, "failed to pull fw stats: %d\n", ret); -++ goto unlock; -+ } -+ -+- /* 0 or max vdevs */ -+- /* Currently firmware does not support VDEV stats */ -+- if (num_vdev_stats) { -+- struct wmi_vdev_stats *vdev_stats; -+- -+- for (i = 0; i < num_vdev_stats; i++) { -+- vdev_stats = (struct wmi_vdev_stats *)tmp; -+- tmp += sizeof(struct wmi_vdev_stats); -+- } -++ /* Stat data may exceed htc-wmi buffer limit. In such case firmware -++ * splits the stats data and delivers it in a ping-pong fashion of -++ * request cmd-update event. -++ * -++ * However there is no explicit end-of-data. Instead start-of-data is -++ * used as an implicit one. This works as follows: -++ * a) discard stat update events until one with pdev stats is -++ * delivered - this skips session started at end of (b) -++ * b) consume stat update events until another one with pdev stats is -++ * delivered which is treated as end-of-data and is itself discarded -++ */ -++ -++ if (ar->debug.fw_stats_done) { -++ ath10k_warn(ar, "received unsolicited stats update event\n"); -++ goto free; -+ } -+ -+- if (num_peer_stats) { -+- struct wmi_peer_stats_10x *peer_stats; -+- struct ath10k_peer_stat *s; -+- -+- stats->peers = num_peer_stats; -+- -+- for (i = 0; i < num_peer_stats; i++) { -+- peer_stats = (struct wmi_peer_stats_10x *)tmp; -+- s = &stats->peer_stat[i]; -+- -+- memcpy(s->peer_macaddr, &peer_stats->peer_macaddr.addr, -+- ETH_ALEN); -+- s->peer_rssi = __le32_to_cpu(peer_stats->peer_rssi); -+- s->peer_tx_rate = -+- __le32_to_cpu(peer_stats->peer_tx_rate); -+- if (test_bit(ATH10K_FW_FEATURE_WMI_10X, -+- ar->fw_features)) { -+- s->peer_rx_rate = -+- __le32_to_cpu(peer_stats->peer_rx_rate); -+- tmp += sizeof(struct wmi_peer_stats_10x); -+- -+- } else { -+- tmp += sizeof(struct wmi_peer_stats_old); -+- } -++ num_peers = ath10k_debug_fw_stats_num_peers(&ar->debug.fw_stats.peers); -++ num_vdevs = ath10k_debug_fw_stats_num_vdevs(&ar->debug.fw_stats.vdevs); -++ is_start = (list_empty(&ar->debug.fw_stats.pdevs) && -++ !list_empty(&stats.pdevs)); -++ is_end = (!list_empty(&ar->debug.fw_stats.pdevs) && -++ !list_empty(&stats.pdevs)); -++ -++ if (is_start) -++ list_splice_tail_init(&stats.pdevs, &ar->debug.fw_stats.pdevs); -++ -++ if (is_end) -++ ar->debug.fw_stats_done = true; -++ -++ is_started = !list_empty(&ar->debug.fw_stats.pdevs); -++ -++ if (is_started && !is_end) { -++ if (num_peers >= ATH10K_MAX_NUM_PEER_IDS) { -++ /* Although this is unlikely impose a sane limit to -++ * prevent firmware from DoS-ing the host. -++ */ -++ ath10k_warn(ar, "dropping fw peer stats\n"); -++ goto free; -+ } -++ -++ if (num_vdevs >= BITS_PER_LONG) { -++ ath10k_warn(ar, "dropping fw vdev stats\n"); -++ goto free; -++ } -++ -++ list_splice_tail_init(&stats.peers, &ar->debug.fw_stats.peers); -++ list_splice_tail_init(&stats.vdevs, &ar->debug.fw_stats.vdevs); -+ } -+ -++ complete(&ar->debug.fw_stats_complete); -++ -++free: -++ /* In some cases lists have been spliced and cleared. Free up -++ * resources if that is not the case. -++ */ -++ ath10k_debug_fw_stats_pdevs_free(&stats.pdevs); -++ ath10k_debug_fw_stats_vdevs_free(&stats.vdevs); -++ ath10k_debug_fw_stats_peers_free(&stats.peers); -++ -++unlock: -+ spin_unlock_bh(&ar->data_lock); -+- complete(&ar->debug.event_stats_compl); -+ } -+ -+-static ssize_t ath10k_read_fw_stats(struct file *file, char __user *user_buf, -+- size_t count, loff_t *ppos) -++static int ath10k_debug_fw_stats_request(struct ath10k *ar) -+ { -+- struct ath10k *ar = file->private_data; -+- struct ath10k_target_stats *fw_stats; -+- char *buf = NULL; -+- unsigned int len = 0, buf_len = 8000; -+- ssize_t ret_cnt = 0; -+- long left; -+- int i; -++ unsigned long timeout; -+ int ret; -+ -+- fw_stats = &ar->debug.target_stats; -++ lockdep_assert_held(&ar->conf_mutex); -+ -+- mutex_lock(&ar->conf_mutex); -++ timeout = jiffies + msecs_to_jiffies(1*HZ); -+ -+- if (ar->state != ATH10K_STATE_ON) -+- goto exit; -++ ath10k_debug_fw_stats_reset(ar); -+ -+- buf = kzalloc(buf_len, GFP_KERNEL); -+- if (!buf) -+- goto exit; -++ for (;;) { -++ if (time_after(jiffies, timeout)) -++ return -ETIMEDOUT; -+ -+- ret = ath10k_wmi_request_stats(ar, WMI_REQUEST_PEER_STAT); -+- if (ret) { -+- ath10k_warn("could not request stats (%d)\n", ret); -+- goto exit; -++ reinit_completion(&ar->debug.fw_stats_complete); -++ -++ ret = ath10k_wmi_request_stats(ar, -++ WMI_STAT_PDEV | -++ WMI_STAT_VDEV | -++ WMI_STAT_PEER); -++ if (ret) { -++ ath10k_warn(ar, "could not request stats (%d)\n", ret); -++ return ret; -++ } -++ -++ ret = wait_for_completion_timeout(&ar->debug.fw_stats_complete, -++ 1*HZ); -++ if (ret == 0) -++ return -ETIMEDOUT; -++ -++ spin_lock_bh(&ar->data_lock); -++ if (ar->debug.fw_stats_done) { -++ spin_unlock_bh(&ar->data_lock); -++ break; -++ } -++ spin_unlock_bh(&ar->data_lock); -+ } -+ -+- left = wait_for_completion_timeout(&ar->debug.event_stats_compl, 1*HZ); -+- if (left <= 0) -+- goto exit; -++ return 0; -++} -++ -++/* FIXME: How to calculate the buffer size sanely? */ -++#define ATH10K_FW_STATS_BUF_SIZE (1024*1024) -++ -++static void ath10k_fw_stats_fill(struct ath10k *ar, -++ struct ath10k_fw_stats *fw_stats, -++ char *buf) -++{ -++ unsigned int len = 0; -++ unsigned int buf_len = ATH10K_FW_STATS_BUF_SIZE; -++ const struct ath10k_fw_stats_pdev *pdev; -++ const struct ath10k_fw_stats_vdev *vdev; -++ const struct ath10k_fw_stats_peer *peer; -++ size_t num_peers; -++ size_t num_vdevs; -++ int i; -+ -+ spin_lock_bh(&ar->data_lock); -++ -++ pdev = list_first_entry_or_null(&fw_stats->pdevs, -++ struct ath10k_fw_stats_pdev, list); -++ if (!pdev) { -++ ath10k_warn(ar, "failed to get pdev stats\n"); -++ goto unlock; -++ } -++ -++ num_peers = ath10k_debug_fw_stats_num_peers(&fw_stats->peers); -++ num_vdevs = ath10k_debug_fw_stats_num_vdevs(&fw_stats->vdevs); -++ -+ len += scnprintf(buf + len, buf_len - len, "\n"); -+ len += scnprintf(buf + len, buf_len - len, "%30s\n", -+ "ath10k PDEV stats"); -+@@ -325,29 +455,29 @@ static ssize_t ath10k_read_fw_stats(stru -+ "================="); -+ -+ len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", -+- "Channel noise floor", fw_stats->ch_noise_floor); -++ "Channel noise floor", pdev->ch_noise_floor); -+ len += scnprintf(buf + len, buf_len - len, "%30s %10u\n", -+- "Channel TX power", fw_stats->chan_tx_power); -++ "Channel TX power", pdev->chan_tx_power); -+ len += scnprintf(buf + len, buf_len - len, "%30s %10u\n", -+- "TX frame count", fw_stats->tx_frame_count); -++ "TX frame count", pdev->tx_frame_count); -+ len += scnprintf(buf + len, buf_len - len, "%30s %10u\n", -+- "RX frame count", fw_stats->rx_frame_count); -++ "RX frame count", pdev->rx_frame_count); -+ len += scnprintf(buf + len, buf_len - len, "%30s %10u\n", -+- "RX clear count", fw_stats->rx_clear_count); -++ "RX clear count", pdev->rx_clear_count); -+ len += scnprintf(buf + len, buf_len - len, "%30s %10u\n", -+- "Cycle count", fw_stats->cycle_count); -++ "Cycle count", pdev->cycle_count); -+ len += scnprintf(buf + len, buf_len - len, "%30s %10u\n", -+- "PHY error count", fw_stats->phy_err_count); -++ "PHY error count", pdev->phy_err_count); -+ len += scnprintf(buf + len, buf_len - len, "%30s %10u\n", -+- "RTS bad count", fw_stats->rts_bad); -++ "RTS bad count", pdev->rts_bad); -+ len += scnprintf(buf + len, buf_len - len, "%30s %10u\n", -+- "RTS good count", fw_stats->rts_good); -++ "RTS good count", pdev->rts_good); -+ len += scnprintf(buf + len, buf_len - len, "%30s %10u\n", -+- "FCS bad count", fw_stats->fcs_bad); -++ "FCS bad count", pdev->fcs_bad); -+ len += scnprintf(buf + len, buf_len - len, "%30s %10u\n", -+- "No beacon count", fw_stats->no_beacons); -++ "No beacon count", pdev->no_beacons); -+ len += scnprintf(buf + len, buf_len - len, "%30s %10u\n", -+- "MIB int count", fw_stats->mib_int_count); -++ "MIB int count", pdev->mib_int_count); -+ -+ len += scnprintf(buf + len, buf_len - len, "\n"); -+ len += scnprintf(buf + len, buf_len - len, "%30s\n", -+@@ -356,51 +486,51 @@ static ssize_t ath10k_read_fw_stats(stru -+ "================="); -+ -+ len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", -+- "HTT cookies queued", fw_stats->comp_queued); -++ "HTT cookies queued", pdev->comp_queued); -+ len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", -+- "HTT cookies disp.", fw_stats->comp_delivered); -++ "HTT cookies disp.", pdev->comp_delivered); -+ len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", -+- "MSDU queued", fw_stats->msdu_enqued); -++ "MSDU queued", pdev->msdu_enqued); -+ len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", -+- "MPDU queued", fw_stats->mpdu_enqued); -++ "MPDU queued", pdev->mpdu_enqued); -+ len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", -+- "MSDUs dropped", fw_stats->wmm_drop); -++ "MSDUs dropped", pdev->wmm_drop); -+ len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", -+- "Local enqued", fw_stats->local_enqued); -++ "Local enqued", pdev->local_enqued); -+ len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", -+- "Local freed", fw_stats->local_freed); -++ "Local freed", pdev->local_freed); -+ len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", -+- "HW queued", fw_stats->hw_queued); -++ "HW queued", pdev->hw_queued); -+ len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", -+- "PPDUs reaped", fw_stats->hw_reaped); -++ "PPDUs reaped", pdev->hw_reaped); -+ len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", -+- "Num underruns", fw_stats->underrun); -++ "Num underruns", pdev->underrun); -+ len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", -+- "PPDUs cleaned", fw_stats->tx_abort); -++ "PPDUs cleaned", pdev->tx_abort); -+ len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", -+- "MPDUs requed", fw_stats->mpdus_requed); -++ "MPDUs requed", pdev->mpdus_requed); -+ len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", -+- "Excessive retries", fw_stats->tx_ko); -++ "Excessive retries", pdev->tx_ko); -+ len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", -+- "HW rate", fw_stats->data_rc); -++ "HW rate", pdev->data_rc); -+ len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", -+- "Sched self tiggers", fw_stats->self_triggers); -++ "Sched self tiggers", pdev->self_triggers); -+ len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", -+ "Dropped due to SW retries", -+- fw_stats->sw_retry_failure); -++ pdev->sw_retry_failure); -+ len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", -+ "Illegal rate phy errors", -+- fw_stats->illgl_rate_phy_err); -++ pdev->illgl_rate_phy_err); -+ len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", -+- "Pdev continous xretry", fw_stats->pdev_cont_xretry); -++ "Pdev continous xretry", pdev->pdev_cont_xretry); -+ len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", -+- "TX timeout", fw_stats->pdev_tx_timeout); -++ "TX timeout", pdev->pdev_tx_timeout); -+ len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", -+- "PDEV resets", fw_stats->pdev_resets); -++ "PDEV resets", pdev->pdev_resets); -+ len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", -+- "PHY underrun", fw_stats->phy_underrun); -++ "PHY underrun", pdev->phy_underrun); -+ len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", -+- "MPDU is more than txop limit", fw_stats->txop_ovf); -++ "MPDU is more than txop limit", pdev->txop_ovf); -+ -+ len += scnprintf(buf + len, buf_len - len, "\n"); -+ len += scnprintf(buf + len, buf_len - len, "%30s\n", -+@@ -410,84 +540,254 @@ static ssize_t ath10k_read_fw_stats(stru -+ -+ len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", -+ "Mid PPDU route change", -+- fw_stats->mid_ppdu_route_change); -++ pdev->mid_ppdu_route_change); -+ len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", -+- "Tot. number of statuses", fw_stats->status_rcvd); -++ "Tot. number of statuses", pdev->status_rcvd); -+ len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", -+- "Extra frags on rings 0", fw_stats->r0_frags); -++ "Extra frags on rings 0", pdev->r0_frags); -+ len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", -+- "Extra frags on rings 1", fw_stats->r1_frags); -++ "Extra frags on rings 1", pdev->r1_frags); -+ len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", -+- "Extra frags on rings 2", fw_stats->r2_frags); -++ "Extra frags on rings 2", pdev->r2_frags); -+ len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", -+- "Extra frags on rings 3", fw_stats->r3_frags); -++ "Extra frags on rings 3", pdev->r3_frags); -+ len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", -+- "MSDUs delivered to HTT", fw_stats->htt_msdus); -++ "MSDUs delivered to HTT", pdev->htt_msdus); -+ len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", -+- "MPDUs delivered to HTT", fw_stats->htt_mpdus); -++ "MPDUs delivered to HTT", pdev->htt_mpdus); -+ len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", -+- "MSDUs delivered to stack", fw_stats->loc_msdus); -++ "MSDUs delivered to stack", pdev->loc_msdus); -+ len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", -+- "MPDUs delivered to stack", fw_stats->loc_mpdus); -++ "MPDUs delivered to stack", pdev->loc_mpdus); -+ len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", -+- "Oversized AMSUs", fw_stats->oversize_amsdu); -++ "Oversized AMSUs", pdev->oversize_amsdu); -+ len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", -+- "PHY errors", fw_stats->phy_errs); -++ "PHY errors", pdev->phy_errs); -+ len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", -+- "PHY errors drops", fw_stats->phy_err_drop); -++ "PHY errors drops", pdev->phy_err_drop); -+ len += scnprintf(buf + len, buf_len - len, "%30s %10d\n", -+- "MPDU errors (FCS, MIC, ENC)", fw_stats->mpdu_errs); -++ "MPDU errors (FCS, MIC, ENC)", pdev->mpdu_errs); -++ -++ len += scnprintf(buf + len, buf_len - len, "\n"); -++ len += scnprintf(buf + len, buf_len - len, "%30s (%zu)\n", -++ "ath10k VDEV stats", num_vdevs); -++ len += scnprintf(buf + len, buf_len - len, "%30s\n\n", -++ "================="); -++ -++ list_for_each_entry(vdev, &fw_stats->vdevs, list) { -++ len += scnprintf(buf + len, buf_len - len, "%30s %u\n", -++ "vdev id", vdev->vdev_id); -++ len += scnprintf(buf + len, buf_len - len, "%30s %u\n", -++ "beacon snr", vdev->beacon_snr); -++ len += scnprintf(buf + len, buf_len - len, "%30s %u\n", -++ "data snr", vdev->data_snr); -++ len += scnprintf(buf + len, buf_len - len, "%30s %u\n", -++ "num rx frames", vdev->num_rx_frames); -++ len += scnprintf(buf + len, buf_len - len, "%30s %u\n", -++ "num rts fail", vdev->num_rts_fail); -++ len += scnprintf(buf + len, buf_len - len, "%30s %u\n", -++ "num rts success", vdev->num_rts_success); -++ len += scnprintf(buf + len, buf_len - len, "%30s %u\n", -++ "num rx err", vdev->num_rx_err); -++ len += scnprintf(buf + len, buf_len - len, "%30s %u\n", -++ "num rx discard", vdev->num_rx_discard); -++ len += scnprintf(buf + len, buf_len - len, "%30s %u\n", -++ "num tx not acked", vdev->num_tx_not_acked); -++ -++ for (i = 0 ; i < ARRAY_SIZE(vdev->num_tx_frames); i++) -++ len += scnprintf(buf + len, buf_len - len, -++ "%25s [%02d] %u\n", -++ "num tx frames", i, -++ vdev->num_tx_frames[i]); -++ -++ for (i = 0 ; i < ARRAY_SIZE(vdev->num_tx_frames_retries); i++) -++ len += scnprintf(buf + len, buf_len - len, -++ "%25s [%02d] %u\n", -++ "num tx frames retries", i, -++ vdev->num_tx_frames_retries[i]); -++ -++ for (i = 0 ; i < ARRAY_SIZE(vdev->num_tx_frames_failures); i++) -++ len += scnprintf(buf + len, buf_len - len, -++ "%25s [%02d] %u\n", -++ "num tx frames failures", i, -++ vdev->num_tx_frames_failures[i]); -++ -++ for (i = 0 ; i < ARRAY_SIZE(vdev->tx_rate_history); i++) -++ len += scnprintf(buf + len, buf_len - len, -++ "%25s [%02d] 0x%08x\n", -++ "tx rate history", i, -++ vdev->tx_rate_history[i]); -++ -++ for (i = 0 ; i < ARRAY_SIZE(vdev->beacon_rssi_history); i++) -++ len += scnprintf(buf + len, buf_len - len, -++ "%25s [%02d] %u\n", -++ "beacon rssi history", i, -++ vdev->beacon_rssi_history[i]); -++ -++ len += scnprintf(buf + len, buf_len - len, "\n"); -++ } -+ -+ len += scnprintf(buf + len, buf_len - len, "\n"); -+- len += scnprintf(buf + len, buf_len - len, "%30s (%d)\n", -+- "ath10k PEER stats", fw_stats->peers); -++ len += scnprintf(buf + len, buf_len - len, "%30s (%zu)\n", -++ "ath10k PEER stats", num_peers); -+ len += scnprintf(buf + len, buf_len - len, "%30s\n\n", -+ "================="); -+ -+- for (i = 0; i < fw_stats->peers; i++) { -++ list_for_each_entry(peer, &fw_stats->peers, list) { -+ len += scnprintf(buf + len, buf_len - len, "%30s %pM\n", -+- "Peer MAC address", -+- fw_stats->peer_stat[i].peer_macaddr); -++ "Peer MAC address", peer->peer_macaddr); -+ len += scnprintf(buf + len, buf_len - len, "%30s %u\n", -+- "Peer RSSI", fw_stats->peer_stat[i].peer_rssi); -++ "Peer RSSI", peer->peer_rssi); -+ len += scnprintf(buf + len, buf_len - len, "%30s %u\n", -+- "Peer TX rate", -+- fw_stats->peer_stat[i].peer_tx_rate); -++ "Peer TX rate", peer->peer_tx_rate); -+ len += scnprintf(buf + len, buf_len - len, "%30s %u\n", -+- "Peer RX rate", -+- fw_stats->peer_stat[i].peer_rx_rate); -++ "Peer RX rate", peer->peer_rx_rate); -+ len += scnprintf(buf + len, buf_len - len, "\n"); -+ } -++ -++unlock: -+ spin_unlock_bh(&ar->data_lock); -+ -+- if (len > buf_len) -+- len = buf_len; -++ if (len >= buf_len) -++ buf[len - 1] = 0; -++ else -++ buf[len] = 0; -++} -+ -+- ret_cnt = simple_read_from_buffer(user_buf, count, ppos, buf, len); -++static int ath10k_fw_stats_open(struct inode *inode, struct file *file) -++{ -++ struct ath10k *ar = inode->i_private; -++ void *buf = NULL; -++ int ret; -++ -++ mutex_lock(&ar->conf_mutex); -++ -++ if (ar->state != ATH10K_STATE_ON) { -++ ret = -ENETDOWN; -++ goto err_unlock; -++ } -++ -++ buf = vmalloc(ATH10K_FW_STATS_BUF_SIZE); -++ if (!buf) { -++ ret = -ENOMEM; -++ goto err_unlock; -++ } -++ -++ ret = ath10k_debug_fw_stats_request(ar); -++ if (ret) { -++ ath10k_warn(ar, "failed to request fw stats: %d\n", ret); -++ goto err_free; -++ } -++ -++ ath10k_fw_stats_fill(ar, &ar->debug.fw_stats, buf); -++ file->private_data = buf; -+ -+-exit: -+ mutex_unlock(&ar->conf_mutex); -+- kfree(buf); -+- return ret_cnt; -++ return 0; -++ -++err_free: -++ vfree(buf); -++ -++err_unlock: -++ mutex_unlock(&ar->conf_mutex); -++ return ret; -++} -++ -++static int ath10k_fw_stats_release(struct inode *inode, struct file *file) -++{ -++ vfree(file->private_data); -++ -++ return 0; -++} -++ -++static ssize_t ath10k_fw_stats_read(struct file *file, char __user *user_buf, -++ size_t count, loff_t *ppos) -++{ -++ const char *buf = file->private_data; -++ unsigned int len = strlen(buf); -++ -++ return simple_read_from_buffer(user_buf, count, ppos, buf, len); -+ } -+ -+ static const struct file_operations fops_fw_stats = { -+- .read = ath10k_read_fw_stats, -++ .open = ath10k_fw_stats_open, -++ .release = ath10k_fw_stats_release, -++ .read = ath10k_fw_stats_read, -++ .owner = THIS_MODULE, -++ .llseek = default_llseek, -++}; -++ -++static ssize_t ath10k_debug_fw_reset_stats_read(struct file *file, -++ char __user *user_buf, -++ size_t count, loff_t *ppos) -++{ -++ struct ath10k *ar = file->private_data; -++ int ret, len, buf_len; -++ char *buf; -++ -++ buf_len = 500; -++ buf = kmalloc(buf_len, GFP_KERNEL); -++ if (!buf) -++ return -ENOMEM; -++ -++ spin_lock_bh(&ar->data_lock); -++ -++ len = 0; -++ len += scnprintf(buf + len, buf_len - len, -++ "fw_crash_counter\t\t%d\n", ar->stats.fw_crash_counter); -++ len += scnprintf(buf + len, buf_len - len, -++ "fw_warm_reset_counter\t\t%d\n", -++ ar->stats.fw_warm_reset_counter); -++ len += scnprintf(buf + len, buf_len - len, -++ "fw_cold_reset_counter\t\t%d\n", -++ ar->stats.fw_cold_reset_counter); -++ -++ spin_unlock_bh(&ar->data_lock); -++ -++ ret = simple_read_from_buffer(user_buf, count, ppos, buf, len); -++ -++ kfree(buf); -++ -++ return ret; -++} -++ -++static const struct file_operations fops_fw_reset_stats = { -+ .open = simple_open, -++ .read = ath10k_debug_fw_reset_stats_read, -+ .owner = THIS_MODULE, -+ .llseek = default_llseek, -+ }; -+ -++/* This is a clean assert crash in firmware. */ -++static int ath10k_debug_fw_assert(struct ath10k *ar) -++{ -++ struct wmi_vdev_install_key_cmd *cmd; -++ struct sk_buff *skb; -++ -++ skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd) + 16); -++ if (!skb) -++ return -ENOMEM; -++ -++ cmd = (struct wmi_vdev_install_key_cmd *)skb->data; -++ memset(cmd, 0, sizeof(*cmd)); -++ -++ /* big enough number so that firmware asserts */ -++ cmd->vdev_id = __cpu_to_le32(0x7ffe); -++ -++ return ath10k_wmi_cmd_send(ar, skb, -++ ar->wmi.cmd->vdev_install_key_cmdid); -++} -++ -+ static ssize_t ath10k_read_simulate_fw_crash(struct file *file, -+ char __user *user_buf, -+ size_t count, loff_t *ppos) -+ { -+- const char buf[] = "To simulate firmware crash write one of the" -+- " keywords to this file:\n `soft` - this will send" -+- " WMI_FORCE_FW_HANG_ASSERT to firmware if FW" -+- " supports that command.\n `hard` - this will send" -+- " to firmware command with illegal parameters" -+- " causing firmware crash.\n"; -++ const char buf[] = -++ "To simulate firmware crash write one of the keywords to this file:\n" -++ "`soft` - this will send WMI_FORCE_FW_HANG_ASSERT to firmware if FW supports that command.\n" -++ "`hard` - this will send to firmware command with illegal parameters causing firmware crash.\n" -++ "`assert` - this will send special illegal parameter to firmware to cause assert failure and crash.\n" -++ "`hw-restart` - this will simply queue hw restart without fw/hw actually crashing.\n"; -+ -+ return simple_read_from_buffer(user_buf, count, ppos, buf, strlen(buf)); -+ } -+@@ -527,19 +827,30 @@ static ssize_t ath10k_write_simulate_fw_ -+ } -+ -+ if (!strcmp(buf, "soft")) { -+- ath10k_info("simulating soft firmware crash\n"); -++ ath10k_info(ar, "simulating soft firmware crash\n"); -+ ret = ath10k_wmi_force_fw_hang(ar, WMI_FORCE_FW_HANG_ASSERT, 0); -+ } else if (!strcmp(buf, "hard")) { -+- ath10k_info("simulating hard firmware crash\n"); -+- ret = ath10k_wmi_vdev_set_param(ar, TARGET_NUM_VDEVS + 1, -+- ar->wmi.vdev_param->rts_threshold, 0); -++ ath10k_info(ar, "simulating hard firmware crash\n"); -++ /* 0x7fff is vdev id, and it is always out of range for all -++ * firmware variants in order to force a firmware crash. -++ */ -++ ret = ath10k_wmi_vdev_set_param(ar, 0x7fff, -++ ar->wmi.vdev_param->rts_threshold, -++ 0); -++ } else if (!strcmp(buf, "assert")) { -++ ath10k_info(ar, "simulating firmware assert crash\n"); -++ ret = ath10k_debug_fw_assert(ar); -++ } else if (!strcmp(buf, "hw-restart")) { -++ ath10k_info(ar, "user requested hw restart\n"); -++ queue_work(ar->workqueue, &ar->restart_work); -++ ret = 0; -+ } else { -+ ret = -EINVAL; -+ goto exit; -+ } -+ -+ if (ret) { -+- ath10k_warn("failed to simulate firmware crash: %d\n", ret); -++ ath10k_warn(ar, "failed to simulate firmware crash: %d\n", ret); -+ goto exit; -+ } -+ -+@@ -565,13 +876,375 @@ static ssize_t ath10k_read_chip_id(struc -+ unsigned int len; -+ char buf[50]; -+ -+- len = scnprintf(buf, sizeof(buf), "0x%08x\n", ar->chip_id); -++ len = scnprintf(buf, sizeof(buf), "0x%08x\n", ar->chip_id); -++ -++ return simple_read_from_buffer(user_buf, count, ppos, buf, len); -++} -++ -++static const struct file_operations fops_chip_id = { -++ .read = ath10k_read_chip_id, -++ .open = simple_open, -++ .owner = THIS_MODULE, -++ .llseek = default_llseek, -++}; -++ -++struct ath10k_fw_crash_data * -++ath10k_debug_get_new_fw_crash_data(struct ath10k *ar) -++{ -++ struct ath10k_fw_crash_data *crash_data = ar->debug.fw_crash_data; -++ -++ lockdep_assert_held(&ar->data_lock); -++ -++ crash_data->crashed_since_read = true; -++ uuid_le_gen(&crash_data->uuid); -++ getnstimeofday(&crash_data->timestamp); -++ -++ return crash_data; -++} -++EXPORT_SYMBOL(ath10k_debug_get_new_fw_crash_data); -++ -++static struct ath10k_dump_file_data *ath10k_build_dump_file(struct ath10k *ar) -++{ -++ struct ath10k_fw_crash_data *crash_data = ar->debug.fw_crash_data; -++ struct ath10k_dump_file_data *dump_data; -++ struct ath10k_tlv_dump_data *dump_tlv; -++ int hdr_len = sizeof(*dump_data); -++ unsigned int len, sofar = 0; -++ unsigned char *buf; -++ -++ len = hdr_len; -++ len += sizeof(*dump_tlv) + sizeof(crash_data->registers); -++ -++ sofar += hdr_len; -++ -++ /* This is going to get big when we start dumping FW RAM and such, -++ * so go ahead and use vmalloc. -++ */ -++ buf = vzalloc(len); -++ if (!buf) -++ return NULL; -++ -++ spin_lock_bh(&ar->data_lock); -++ -++ if (!crash_data->crashed_since_read) { -++ spin_unlock_bh(&ar->data_lock); -++ vfree(buf); -++ return NULL; -++ } -++ -++ dump_data = (struct ath10k_dump_file_data *)(buf); -++ strlcpy(dump_data->df_magic, "ATH10K-FW-DUMP", -++ sizeof(dump_data->df_magic)); -++ dump_data->len = cpu_to_le32(len); -++ -++ dump_data->version = cpu_to_le32(ATH10K_FW_CRASH_DUMP_VERSION); -++ -++ memcpy(dump_data->uuid, &crash_data->uuid, sizeof(dump_data->uuid)); -++ dump_data->chip_id = cpu_to_le32(ar->chip_id); -++ dump_data->bus_type = cpu_to_le32(0); -++ dump_data->target_version = cpu_to_le32(ar->target_version); -++ dump_data->fw_version_major = cpu_to_le32(ar->fw_version_major); -++ dump_data->fw_version_minor = cpu_to_le32(ar->fw_version_minor); -++ dump_data->fw_version_release = cpu_to_le32(ar->fw_version_release); -++ dump_data->fw_version_build = cpu_to_le32(ar->fw_version_build); -++ dump_data->phy_capability = cpu_to_le32(ar->phy_capability); -++ dump_data->hw_min_tx_power = cpu_to_le32(ar->hw_min_tx_power); -++ dump_data->hw_max_tx_power = cpu_to_le32(ar->hw_max_tx_power); -++ dump_data->ht_cap_info = cpu_to_le32(ar->ht_cap_info); -++ dump_data->vht_cap_info = cpu_to_le32(ar->vht_cap_info); -++ dump_data->num_rf_chains = cpu_to_le32(ar->num_rf_chains); -++ -++ strlcpy(dump_data->fw_ver, ar->hw->wiphy->fw_version, -++ sizeof(dump_data->fw_ver)); -++ -++ dump_data->kernel_ver_code = 0; -++ strlcpy(dump_data->kernel_ver, init_utsname()->release, -++ sizeof(dump_data->kernel_ver)); -++ -++ dump_data->tv_sec = cpu_to_le64(crash_data->timestamp.tv_sec); -++ dump_data->tv_nsec = cpu_to_le64(crash_data->timestamp.tv_nsec); -++ -++ /* Gather crash-dump */ -++ dump_tlv = (struct ath10k_tlv_dump_data *)(buf + sofar); -++ dump_tlv->type = cpu_to_le32(ATH10K_FW_CRASH_DUMP_REGISTERS); -++ dump_tlv->tlv_len = cpu_to_le32(sizeof(crash_data->registers)); -++ memcpy(dump_tlv->tlv_data, &crash_data->registers, -++ sizeof(crash_data->registers)); -++ sofar += sizeof(*dump_tlv) + sizeof(crash_data->registers); -++ -++ ar->debug.fw_crash_data->crashed_since_read = false; -++ -++ spin_unlock_bh(&ar->data_lock); -++ -++ return dump_data; -++} -++ -++static int ath10k_fw_crash_dump_open(struct inode *inode, struct file *file) -++{ -++ struct ath10k *ar = inode->i_private; -++ struct ath10k_dump_file_data *dump; -++ -++ dump = ath10k_build_dump_file(ar); -++ if (!dump) -++ return -ENODATA; -++ -++ file->private_data = dump; -++ -++ return 0; -++} -++ -++static ssize_t ath10k_fw_crash_dump_read(struct file *file, -++ char __user *user_buf, -++ size_t count, loff_t *ppos) -++{ -++ struct ath10k_dump_file_data *dump_file = file->private_data; -++ -++ return simple_read_from_buffer(user_buf, count, ppos, -++ dump_file, -++ le32_to_cpu(dump_file->len)); -++} -++ -++static int ath10k_fw_crash_dump_release(struct inode *inode, -++ struct file *file) -++{ -++ vfree(file->private_data); -++ -++ return 0; -++} -++ -++static const struct file_operations fops_fw_crash_dump = { -++ .open = ath10k_fw_crash_dump_open, -++ .read = ath10k_fw_crash_dump_read, -++ .release = ath10k_fw_crash_dump_release, -++ .owner = THIS_MODULE, -++ .llseek = default_llseek, -++}; -++ -++static ssize_t ath10k_reg_addr_read(struct file *file, -++ char __user *user_buf, -++ size_t count, loff_t *ppos) -++{ -++ struct ath10k *ar = file->private_data; -++ u8 buf[32]; -++ unsigned int len = 0; -++ u32 reg_addr; -++ -++ mutex_lock(&ar->conf_mutex); -++ reg_addr = ar->debug.reg_addr; -++ mutex_unlock(&ar->conf_mutex); -++ -++ len += scnprintf(buf + len, sizeof(buf) - len, "0x%x\n", reg_addr); -++ -++ return simple_read_from_buffer(user_buf, count, ppos, buf, len); -++} -++ -++static ssize_t ath10k_reg_addr_write(struct file *file, -++ const char __user *user_buf, -++ size_t count, loff_t *ppos) -++{ -++ struct ath10k *ar = file->private_data; -++ u32 reg_addr; -++ int ret; -++ -++ ret = kstrtou32_from_user(user_buf, count, 0, ®_addr); -++ if (ret) -++ return ret; -++ -++ if (!IS_ALIGNED(reg_addr, 4)) -++ return -EFAULT; -++ -++ mutex_lock(&ar->conf_mutex); -++ ar->debug.reg_addr = reg_addr; -++ mutex_unlock(&ar->conf_mutex); -++ -++ return count; -++} -++ -++static const struct file_operations fops_reg_addr = { -++ .read = ath10k_reg_addr_read, -++ .write = ath10k_reg_addr_write, -++ .open = simple_open, -++ .owner = THIS_MODULE, -++ .llseek = default_llseek, -++}; -++ -++static ssize_t ath10k_reg_value_read(struct file *file, -++ char __user *user_buf, -++ size_t count, loff_t *ppos) -++{ -++ struct ath10k *ar = file->private_data; -++ u8 buf[48]; -++ unsigned int len; -++ u32 reg_addr, reg_val; -++ int ret; -++ -++ mutex_lock(&ar->conf_mutex); -++ -++ if (ar->state != ATH10K_STATE_ON && -++ ar->state != ATH10K_STATE_UTF) { -++ ret = -ENETDOWN; -++ goto exit; -++ } -++ -++ reg_addr = ar->debug.reg_addr; -++ -++ reg_val = ath10k_hif_read32(ar, reg_addr); -++ len = scnprintf(buf, sizeof(buf), "0x%08x:0x%08x\n", reg_addr, reg_val); -++ -++ ret = simple_read_from_buffer(user_buf, count, ppos, buf, len); -++ -++exit: -++ mutex_unlock(&ar->conf_mutex); -++ -++ return ret; -++} -++ -++static ssize_t ath10k_reg_value_write(struct file *file, -++ const char __user *user_buf, -++ size_t count, loff_t *ppos) -++{ -++ struct ath10k *ar = file->private_data; -++ u32 reg_addr, reg_val; -++ int ret; -++ -++ mutex_lock(&ar->conf_mutex); -++ -++ if (ar->state != ATH10K_STATE_ON && -++ ar->state != ATH10K_STATE_UTF) { -++ ret = -ENETDOWN; -++ goto exit; -++ } -++ -++ reg_addr = ar->debug.reg_addr; -++ -++ ret = kstrtou32_from_user(user_buf, count, 0, ®_val); -++ if (ret) -++ goto exit; -++ -++ ath10k_hif_write32(ar, reg_addr, reg_val); -++ -++ ret = count; -++ -++exit: -++ mutex_unlock(&ar->conf_mutex); -++ -++ return ret; -++} -++ -++static const struct file_operations fops_reg_value = { -++ .read = ath10k_reg_value_read, -++ .write = ath10k_reg_value_write, -++ .open = simple_open, -++ .owner = THIS_MODULE, -++ .llseek = default_llseek, -++}; -++ -++static ssize_t ath10k_mem_value_read(struct file *file, -++ char __user *user_buf, -++ size_t count, loff_t *ppos) -++{ -++ struct ath10k *ar = file->private_data; -++ u8 *buf; -++ int ret; -++ -++ if (*ppos < 0) -++ return -EINVAL; -++ -++ if (!count) -++ return 0; -++ -++ mutex_lock(&ar->conf_mutex); -++ -++ buf = vmalloc(count); -++ if (!buf) { -++ ret = -ENOMEM; -++ goto exit; -++ } -++ -++ if (ar->state != ATH10K_STATE_ON && -++ ar->state != ATH10K_STATE_UTF) { -++ ret = -ENETDOWN; -++ goto exit; -++ } -++ -++ ret = ath10k_hif_diag_read(ar, *ppos, buf, count); -++ if (ret) { -++ ath10k_warn(ar, "failed to read address 0x%08x via diagnose window fnrom debugfs: %d\n", -++ (u32)(*ppos), ret); -++ goto exit; -++ } -++ -++ ret = copy_to_user(user_buf, buf, count); -++ if (ret) { -++ ret = -EFAULT; -++ goto exit; -++ } -++ -++ count -= ret; -++ *ppos += count; -++ ret = count; -++ -++exit: -++ vfree(buf); -++ mutex_unlock(&ar->conf_mutex); -++ -++ return ret; -++} -++ -++static ssize_t ath10k_mem_value_write(struct file *file, -++ const char __user *user_buf, -++ size_t count, loff_t *ppos) -++{ -++ struct ath10k *ar = file->private_data; -++ u8 *buf; -++ int ret; -++ -++ if (*ppos < 0) -++ return -EINVAL; -++ -++ if (!count) -++ return 0; -++ -++ mutex_lock(&ar->conf_mutex); -++ -++ buf = vmalloc(count); -++ if (!buf) { -++ ret = -ENOMEM; -++ goto exit; -++ } -++ -++ if (ar->state != ATH10K_STATE_ON && -++ ar->state != ATH10K_STATE_UTF) { -++ ret = -ENETDOWN; -++ goto exit; -++ } -++ -++ ret = copy_from_user(buf, user_buf, count); -++ if (ret) { -++ ret = -EFAULT; -++ goto exit; -++ } -++ -++ ret = ath10k_hif_diag_write(ar, *ppos, buf, count); -++ if (ret) { -++ ath10k_warn(ar, "failed to write address 0x%08x via diagnose window from debugfs: %d\n", -++ (u32)(*ppos), ret); -++ goto exit; -++ } -++ -++ *ppos += count; -++ ret = count; -+ -+- return simple_read_from_buffer(user_buf, count, ppos, buf, len); -++exit: -++ vfree(buf); -++ mutex_unlock(&ar->conf_mutex); -++ -++ return ret; -+ } -+ -+-static const struct file_operations fops_chip_id = { -+- .read = ath10k_read_chip_id, -++static const struct file_operations fops_mem_value = { -++ .read = ath10k_mem_value_read, -++ .write = ath10k_mem_value_write, -+ .open = simple_open, -+ .owner = THIS_MODULE, -+ .llseek = default_llseek, -+@@ -596,7 +1269,7 @@ static int ath10k_debug_htt_stats_req(st -+ ret = ath10k_htt_h2t_stats_req(&ar->htt, ar->debug.htt_stats_mask, -+ cookie); -+ if (ret) { -+- ath10k_warn("failed to send htt stats request: %d\n", ret); -++ ath10k_warn(ar, "failed to send htt stats request: %d\n", ret); -+ return ret; -+ } -+ -+@@ -619,8 +1292,8 @@ static void ath10k_debug_htt_stats_dwork -+ } -+ -+ static ssize_t ath10k_read_htt_stats_mask(struct file *file, -+- char __user *user_buf, -+- size_t count, loff_t *ppos) -++ char __user *user_buf, -++ size_t count, loff_t *ppos) -+ { -+ struct ath10k *ar = file->private_data; -+ char buf[32]; -+@@ -632,8 +1305,8 @@ static ssize_t ath10k_read_htt_stats_mas -+ } -+ -+ static ssize_t ath10k_write_htt_stats_mask(struct file *file, -+- const char __user *user_buf, -+- size_t count, loff_t *ppos) -++ const char __user *user_buf, -++ size_t count, loff_t *ppos) -+ { -+ struct ath10k *ar = file->private_data; -+ unsigned long mask; -+@@ -671,16 +1344,82 @@ static const struct file_operations fops -+ .llseek = default_llseek, -+ }; -+ -++static ssize_t ath10k_read_htt_max_amsdu_ampdu(struct file *file, -++ char __user *user_buf, -++ size_t count, loff_t *ppos) -++{ -++ struct ath10k *ar = file->private_data; -++ char buf[64]; -++ u8 amsdu = 3, ampdu = 64; -++ unsigned int len; -++ -++ mutex_lock(&ar->conf_mutex); -++ -++ if (ar->debug.htt_max_amsdu) -++ amsdu = ar->debug.htt_max_amsdu; -++ -++ if (ar->debug.htt_max_ampdu) -++ ampdu = ar->debug.htt_max_ampdu; -++ -++ mutex_unlock(&ar->conf_mutex); -++ -++ len = scnprintf(buf, sizeof(buf), "%u %u\n", amsdu, ampdu); -++ -++ return simple_read_from_buffer(user_buf, count, ppos, buf, len); -++} -++ -++static ssize_t ath10k_write_htt_max_amsdu_ampdu(struct file *file, -++ const char __user *user_buf, -++ size_t count, loff_t *ppos) -++{ -++ struct ath10k *ar = file->private_data; -++ int res; -++ char buf[64]; -++ unsigned int amsdu, ampdu; -++ -++ simple_write_to_buffer(buf, sizeof(buf) - 1, ppos, user_buf, count); -++ -++ /* make sure that buf is null terminated */ -++ buf[sizeof(buf) - 1] = 0; -++ -++ res = sscanf(buf, "%u %u", &amsdu, &du); -++ -++ if (res != 2) -++ return -EINVAL; -++ -++ mutex_lock(&ar->conf_mutex); -++ -++ res = ath10k_htt_h2t_aggr_cfg_msg(&ar->htt, ampdu, amsdu); -++ if (res) -++ goto out; -++ -++ res = count; -++ ar->debug.htt_max_amsdu = amsdu; -++ ar->debug.htt_max_ampdu = ampdu; -++ -++out: -++ mutex_unlock(&ar->conf_mutex); -++ return res; -++} -++ -++static const struct file_operations fops_htt_max_amsdu_ampdu = { -++ .read = ath10k_read_htt_max_amsdu_ampdu, -++ .write = ath10k_write_htt_max_amsdu_ampdu, -++ .open = simple_open, -++ .owner = THIS_MODULE, -++ .llseek = default_llseek, -++}; -++ -+ static ssize_t ath10k_read_fw_dbglog(struct file *file, -+- char __user *user_buf, -+- size_t count, loff_t *ppos) -++ char __user *user_buf, -++ size_t count, loff_t *ppos) -+ { -+ struct ath10k *ar = file->private_data; -+ unsigned int len; -+- char buf[32]; -++ char buf[64]; -+ -+- len = scnprintf(buf, sizeof(buf), "0x%08x\n", -+- ar->debug.fw_dbglog_mask); -++ len = scnprintf(buf, sizeof(buf), "0x%08x %u\n", -++ ar->debug.fw_dbglog_mask, ar->debug.fw_dbglog_level); -+ -+ return simple_read_from_buffer(user_buf, count, ppos, buf, len); -+ } -+@@ -690,21 +1429,34 @@ static ssize_t ath10k_write_fw_dbglog(st -+ size_t count, loff_t *ppos) -+ { -+ struct ath10k *ar = file->private_data; -+- unsigned long mask; -+ int ret; -++ char buf[64]; -++ unsigned int log_level, mask; -+ -+- ret = kstrtoul_from_user(user_buf, count, 0, &mask); -+- if (ret) -+- return ret; -++ simple_write_to_buffer(buf, sizeof(buf) - 1, ppos, user_buf, count); -++ -++ /* make sure that buf is null terminated */ -++ buf[sizeof(buf) - 1] = 0; -++ -++ ret = sscanf(buf, "%x %u", &mask, &log_level); -++ -++ if (!ret) -++ return -EINVAL; -++ -++ if (ret == 1) -++ /* default if user did not specify */ -++ log_level = ATH10K_DBGLOG_LEVEL_WARN; -+ -+ mutex_lock(&ar->conf_mutex); -+ -+ ar->debug.fw_dbglog_mask = mask; -++ ar->debug.fw_dbglog_level = log_level; -+ -+ if (ar->state == ATH10K_STATE_ON) { -+- ret = ath10k_wmi_dbglog_cfg(ar, ar->debug.fw_dbglog_mask); -++ ret = ath10k_wmi_dbglog_cfg(ar, ar->debug.fw_dbglog_mask, -++ ar->debug.fw_dbglog_level); -+ if (ret) { -+- ath10k_warn("dbglog cfg failed from debugfs: %d\n", -++ ath10k_warn(ar, "dbglog cfg failed from debugfs: %d\n", -+ ret); -+ goto exit; -+ } -+@@ -718,6 +1470,166 @@ exit: -+ return ret; -+ } -+ -++/* TODO: Would be nice to always support ethtool stats, would need to -++ * move the stats storage out of ath10k_debug, or always have ath10k_debug -++ * struct available.. -++ */ -++ -++/* This generally cooresponds to the debugfs fw_stats file */ -++static const char ath10k_gstrings_stats[][ETH_GSTRING_LEN] = { -++ "tx_pkts_nic", -++ "tx_bytes_nic", -++ "rx_pkts_nic", -++ "rx_bytes_nic", -++ "d_noise_floor", -++ "d_cycle_count", -++ "d_phy_error", -++ "d_rts_bad", -++ "d_rts_good", -++ "d_tx_power", /* in .5 dbM I think */ -++ "d_rx_crc_err", /* fcs_bad */ -++ "d_no_beacon", -++ "d_tx_mpdus_queued", -++ "d_tx_msdu_queued", -++ "d_tx_msdu_dropped", -++ "d_local_enqued", -++ "d_local_freed", -++ "d_tx_ppdu_hw_queued", -++ "d_tx_ppdu_reaped", -++ "d_tx_fifo_underrun", -++ "d_tx_ppdu_abort", -++ "d_tx_mpdu_requed", -++ "d_tx_excessive_retries", -++ "d_tx_hw_rate", -++ "d_tx_dropped_sw_retries", -++ "d_tx_illegal_rate", -++ "d_tx_continuous_xretries", -++ "d_tx_timeout", -++ "d_tx_mpdu_txop_limit", -++ "d_pdev_resets", -++ "d_rx_mid_ppdu_route_change", -++ "d_rx_status", -++ "d_rx_extra_frags_ring0", -++ "d_rx_extra_frags_ring1", -++ "d_rx_extra_frags_ring2", -++ "d_rx_extra_frags_ring3", -++ "d_rx_msdu_htt", -++ "d_rx_mpdu_htt", -++ "d_rx_msdu_stack", -++ "d_rx_mpdu_stack", -++ "d_rx_phy_err", -++ "d_rx_phy_err_drops", -++ "d_rx_mpdu_errors", /* FCS, MIC, ENC */ -++ "d_fw_crash_count", -++ "d_fw_warm_reset_count", -++ "d_fw_cold_reset_count", -++}; -++ -++#define ATH10K_SSTATS_LEN ARRAY_SIZE(ath10k_gstrings_stats) -++ -++void ath10k_debug_get_et_strings(struct ieee80211_hw *hw, -++ struct ieee80211_vif *vif, -++ u32 sset, u8 *data) -++{ -++ if (sset == ETH_SS_STATS) -++ memcpy(data, *ath10k_gstrings_stats, -++ sizeof(ath10k_gstrings_stats)); -++} -++ -++int ath10k_debug_get_et_sset_count(struct ieee80211_hw *hw, -++ struct ieee80211_vif *vif, int sset) -++{ -++ if (sset == ETH_SS_STATS) -++ return ATH10K_SSTATS_LEN; -++ -++ return 0; -++} -++ -++void ath10k_debug_get_et_stats(struct ieee80211_hw *hw, -++ struct ieee80211_vif *vif, -++ struct ethtool_stats *stats, u64 *data) -++{ -++ struct ath10k *ar = hw->priv; -++ static const struct ath10k_fw_stats_pdev zero_stats = {}; -++ const struct ath10k_fw_stats_pdev *pdev_stats; -++ int i = 0, ret; -++ -++ mutex_lock(&ar->conf_mutex); -++ -++ if (ar->state == ATH10K_STATE_ON) { -++ ret = ath10k_debug_fw_stats_request(ar); -++ if (ret) { -++ /* just print a warning and try to use older results */ -++ ath10k_warn(ar, -++ "failed to get fw stats for ethtool: %d\n", -++ ret); -++ } -++ } -++ -++ pdev_stats = list_first_entry_or_null(&ar->debug.fw_stats.pdevs, -++ struct ath10k_fw_stats_pdev, -++ list); -++ if (!pdev_stats) { -++ /* no results available so just return zeroes */ -++ pdev_stats = &zero_stats; -++ } -++ -++ spin_lock_bh(&ar->data_lock); -++ -++ data[i++] = pdev_stats->hw_reaped; /* ppdu reaped */ -++ data[i++] = 0; /* tx bytes */ -++ data[i++] = pdev_stats->htt_mpdus; -++ data[i++] = 0; /* rx bytes */ -++ data[i++] = pdev_stats->ch_noise_floor; -++ data[i++] = pdev_stats->cycle_count; -++ data[i++] = pdev_stats->phy_err_count; -++ data[i++] = pdev_stats->rts_bad; -++ data[i++] = pdev_stats->rts_good; -++ data[i++] = pdev_stats->chan_tx_power; -++ data[i++] = pdev_stats->fcs_bad; -++ data[i++] = pdev_stats->no_beacons; -++ data[i++] = pdev_stats->mpdu_enqued; -++ data[i++] = pdev_stats->msdu_enqued; -++ data[i++] = pdev_stats->wmm_drop; -++ data[i++] = pdev_stats->local_enqued; -++ data[i++] = pdev_stats->local_freed; -++ data[i++] = pdev_stats->hw_queued; -++ data[i++] = pdev_stats->hw_reaped; -++ data[i++] = pdev_stats->underrun; -++ data[i++] = pdev_stats->tx_abort; -++ data[i++] = pdev_stats->mpdus_requed; -++ data[i++] = pdev_stats->tx_ko; -++ data[i++] = pdev_stats->data_rc; -++ data[i++] = pdev_stats->sw_retry_failure; -++ data[i++] = pdev_stats->illgl_rate_phy_err; -++ data[i++] = pdev_stats->pdev_cont_xretry; -++ data[i++] = pdev_stats->pdev_tx_timeout; -++ data[i++] = pdev_stats->txop_ovf; -++ data[i++] = pdev_stats->pdev_resets; -++ data[i++] = pdev_stats->mid_ppdu_route_change; -++ data[i++] = pdev_stats->status_rcvd; -++ data[i++] = pdev_stats->r0_frags; -++ data[i++] = pdev_stats->r1_frags; -++ data[i++] = pdev_stats->r2_frags; -++ data[i++] = pdev_stats->r3_frags; -++ data[i++] = pdev_stats->htt_msdus; -++ data[i++] = pdev_stats->htt_mpdus; -++ data[i++] = pdev_stats->loc_msdus; -++ data[i++] = pdev_stats->loc_mpdus; -++ data[i++] = pdev_stats->phy_errs; -++ data[i++] = pdev_stats->phy_err_drop; -++ data[i++] = pdev_stats->mpdu_errs; -++ data[i++] = ar->stats.fw_crash_counter; -++ data[i++] = ar->stats.fw_warm_reset_counter; -++ data[i++] = ar->stats.fw_cold_reset_counter; -++ -++ spin_unlock_bh(&ar->data_lock); -++ -++ mutex_unlock(&ar->conf_mutex); -++ -++ WARN_ON(i != ATH10K_SSTATS_LEN); -++} -++ -+ static const struct file_operations fops_fw_dbglog = { -+ .read = ath10k_read_fw_dbglog, -+ .write = ath10k_write_fw_dbglog, -+@@ -726,6 +1638,151 @@ static const struct file_operations fops -+ .llseek = default_llseek, -+ }; -+ -++static int ath10k_debug_cal_data_open(struct inode *inode, struct file *file) -++{ -++ struct ath10k *ar = inode->i_private; -++ void *buf; -++ u32 hi_addr; -++ __le32 addr; -++ int ret; -++ -++ mutex_lock(&ar->conf_mutex); -++ -++ if (ar->state != ATH10K_STATE_ON && -++ ar->state != ATH10K_STATE_UTF) { -++ ret = -ENETDOWN; -++ goto err; -++ } -++ -++ buf = vmalloc(QCA988X_CAL_DATA_LEN); -++ if (!buf) { -++ ret = -ENOMEM; -++ goto err; -++ } -++ -++ hi_addr = host_interest_item_address(HI_ITEM(hi_board_data)); -++ -++ ret = ath10k_hif_diag_read(ar, hi_addr, &addr, sizeof(addr)); -++ if (ret) { -++ ath10k_warn(ar, "failed to read hi_board_data address: %d\n", ret); -++ goto err_vfree; -++ } -++ -++ ret = ath10k_hif_diag_read(ar, le32_to_cpu(addr), buf, -++ QCA988X_CAL_DATA_LEN); -++ if (ret) { -++ ath10k_warn(ar, "failed to read calibration data: %d\n", ret); -++ goto err_vfree; -++ } -++ -++ file->private_data = buf; -++ -++ mutex_unlock(&ar->conf_mutex); -++ -++ return 0; -++ -++err_vfree: -++ vfree(buf); -++ -++err: -++ mutex_unlock(&ar->conf_mutex); -++ -++ return ret; -++} -++ -++static ssize_t ath10k_debug_cal_data_read(struct file *file, -++ char __user *user_buf, -++ size_t count, loff_t *ppos) -++{ -++ void *buf = file->private_data; -++ -++ return simple_read_from_buffer(user_buf, count, ppos, -++ buf, QCA988X_CAL_DATA_LEN); -++} -++ -++static int ath10k_debug_cal_data_release(struct inode *inode, -++ struct file *file) -++{ -++ vfree(file->private_data); -++ -++ return 0; -++} -++ -++static const struct file_operations fops_cal_data = { -++ .open = ath10k_debug_cal_data_open, -++ .read = ath10k_debug_cal_data_read, -++ .release = ath10k_debug_cal_data_release, -++ .owner = THIS_MODULE, -++ .llseek = default_llseek, -++}; -++ -++static ssize_t ath10k_read_nf_cal_period(struct file *file, -++ char __user *user_buf, -++ size_t count, loff_t *ppos) -++{ -++ struct ath10k *ar = file->private_data; -++ unsigned int len; -++ char buf[32]; -++ -++ len = scnprintf(buf, sizeof(buf), "%d\n", -++ ar->debug.nf_cal_period); -++ -++ return simple_read_from_buffer(user_buf, count, ppos, buf, len); -++} -++ -++static ssize_t ath10k_write_nf_cal_period(struct file *file, -++ const char __user *user_buf, -++ size_t count, loff_t *ppos) -++{ -++ struct ath10k *ar = file->private_data; -++ unsigned long period; -++ int ret; -++ -++ ret = kstrtoul_from_user(user_buf, count, 0, &period); -++ if (ret) -++ return ret; -++ -++ if (period > WMI_PDEV_PARAM_CAL_PERIOD_MAX) -++ return -EINVAL; -++ -++ /* there's no way to switch back to the firmware default */ -++ if (period == 0) -++ return -EINVAL; -++ -++ mutex_lock(&ar->conf_mutex); -++ -++ ar->debug.nf_cal_period = period; -++ -++ if (ar->state != ATH10K_STATE_ON) { -++ /* firmware is not running, nothing else to do */ -++ ret = count; -++ goto exit; -++ } -++ -++ ret = ath10k_wmi_pdev_set_param(ar, ar->wmi.pdev_param->cal_period, -++ ar->debug.nf_cal_period); -++ if (ret) { -++ ath10k_warn(ar, "cal period cfg failed from debugfs: %d\n", -++ ret); -++ goto exit; -++ } -++ -++ ret = count; -++ -++exit: -++ mutex_unlock(&ar->conf_mutex); -++ -++ return ret; -++} -++ -++static const struct file_operations fops_nf_cal_period = { -++ .read = ath10k_read_nf_cal_period, -++ .write = ath10k_write_nf_cal_period, -++ .open = simple_open, -++ .owner = THIS_MODULE, -++ .llseek = default_llseek, -++}; -++ -+ int ath10k_debug_start(struct ath10k *ar) -+ { -+ int ret; -+@@ -735,17 +1792,44 @@ int ath10k_debug_start(struct ath10k *ar -+ ret = ath10k_debug_htt_stats_req(ar); -+ if (ret) -+ /* continue normally anyway, this isn't serious */ -+- ath10k_warn("failed to start htt stats workqueue: %d\n", ret); -++ ath10k_warn(ar, "failed to start htt stats workqueue: %d\n", -++ ret); -+ -+ if (ar->debug.fw_dbglog_mask) { -+- ret = ath10k_wmi_dbglog_cfg(ar, ar->debug.fw_dbglog_mask); -++ ret = ath10k_wmi_dbglog_cfg(ar, ar->debug.fw_dbglog_mask, -++ ATH10K_DBGLOG_LEVEL_WARN); -+ if (ret) -+ /* not serious */ -+- ath10k_warn("failed to enable dbglog during start: %d", -++ ath10k_warn(ar, "failed to enable dbglog during start: %d", -+ ret); -+ } -+ -+- return 0; -++ if (ar->debug.pktlog_filter) { -++ ret = ath10k_wmi_pdev_pktlog_enable(ar, -++ ar->debug.pktlog_filter); -++ if (ret) -++ /* not serious */ -++ ath10k_warn(ar, -++ "failed to enable pktlog filter %x: %d\n", -++ ar->debug.pktlog_filter, ret); -++ } else { -++ ret = ath10k_wmi_pdev_pktlog_disable(ar); -++ if (ret) -++ /* not serious */ -++ ath10k_warn(ar, "failed to disable pktlog: %d\n", ret); -++ } -++ -++ if (ar->debug.nf_cal_period) { -++ ret = ath10k_wmi_pdev_set_param(ar, -++ ar->wmi.pdev_param->cal_period, -++ ar->debug.nf_cal_period); -++ if (ret) -++ /* not serious */ -++ ath10k_warn(ar, "cal period cfg failed from debug start: %d\n", -++ ret); -++ } -++ -++ return ret; -+ } -+ -+ void ath10k_debug_stop(struct ath10k *ar) -+@@ -757,6 +1841,11 @@ void ath10k_debug_stop(struct ath10k *ar -+ * warning from del_timer(). */ -+ if (ar->debug.htt_stats_mask != 0) -+ cancel_delayed_work(&ar->debug.htt_stats_dwork); -++ -++ ar->debug.htt_max_amsdu = 0; -++ ar->debug.htt_max_ampdu = 0; -++ -++ ath10k_wmi_pdev_pktlog_disable(ar); -+ } -+ -+ static ssize_t ath10k_write_simulate_radar(struct file *file, -+@@ -839,37 +1928,149 @@ static const struct file_operations fops -+ .llseek = default_llseek, -+ }; -+ -++static ssize_t ath10k_write_pktlog_filter(struct file *file, -++ const char __user *ubuf, -++ size_t count, loff_t *ppos) -++{ -++ struct ath10k *ar = file->private_data; -++ u32 filter; -++ int ret; -++ -++ if (kstrtouint_from_user(ubuf, count, 0, &filter)) -++ return -EINVAL; -++ -++ mutex_lock(&ar->conf_mutex); -++ -++ if (ar->state != ATH10K_STATE_ON) { -++ ar->debug.pktlog_filter = filter; -++ ret = count; -++ goto out; -++ } -++ -++ if (filter && (filter != ar->debug.pktlog_filter)) { -++ ret = ath10k_wmi_pdev_pktlog_enable(ar, filter); -++ if (ret) { -++ ath10k_warn(ar, "failed to enable pktlog filter %x: %d\n", -++ ar->debug.pktlog_filter, ret); -++ goto out; -++ } -++ } else { -++ ret = ath10k_wmi_pdev_pktlog_disable(ar); -++ if (ret) { -++ ath10k_warn(ar, "failed to disable pktlog: %d\n", ret); -++ goto out; -++ } -++ } -++ -++ ar->debug.pktlog_filter = filter; -++ ret = count; -++ -++out: -++ mutex_unlock(&ar->conf_mutex); -++ return ret; -++} -++ -++static ssize_t ath10k_read_pktlog_filter(struct file *file, char __user *ubuf, -++ size_t count, loff_t *ppos) -++{ -++ char buf[32]; -++ struct ath10k *ar = file->private_data; -++ int len = 0; -++ -++ mutex_lock(&ar->conf_mutex); -++ len = scnprintf(buf, sizeof(buf) - len, "%08x\n", -++ ar->debug.pktlog_filter); -++ mutex_unlock(&ar->conf_mutex); -++ -++ return simple_read_from_buffer(ubuf, count, ppos, buf, len); -++} -++ -++static const struct file_operations fops_pktlog_filter = { -++ .read = ath10k_read_pktlog_filter, -++ .write = ath10k_write_pktlog_filter, -++ .open = simple_open -++}; -++ -+ int ath10k_debug_create(struct ath10k *ar) -+ { -++ ar->debug.fw_crash_data = vzalloc(sizeof(*ar->debug.fw_crash_data)); -++ if (!ar->debug.fw_crash_data) -++ return -ENOMEM; -++ -++ INIT_LIST_HEAD(&ar->debug.fw_stats.pdevs); -++ INIT_LIST_HEAD(&ar->debug.fw_stats.vdevs); -++ INIT_LIST_HEAD(&ar->debug.fw_stats.peers); -++ -++ return 0; -++} -++ -++void ath10k_debug_destroy(struct ath10k *ar) -++{ -++ vfree(ar->debug.fw_crash_data); -++ ar->debug.fw_crash_data = NULL; -++ -++ ath10k_debug_fw_stats_reset(ar); -++} -++ -++int ath10k_debug_register(struct ath10k *ar) -++{ -+ ar->debug.debugfs_phy = debugfs_create_dir("ath10k", -+ ar->hw->wiphy->debugfsdir); -++ if (IS_ERR_OR_NULL(ar->debug.debugfs_phy)) { -++ if (IS_ERR(ar->debug.debugfs_phy)) -++ return PTR_ERR(ar->debug.debugfs_phy); -+ -+- if (!ar->debug.debugfs_phy) -+ return -ENOMEM; -++ } -+ -+ INIT_DELAYED_WORK(&ar->debug.htt_stats_dwork, -+ ath10k_debug_htt_stats_dwork); -+ -+- init_completion(&ar->debug.event_stats_compl); -++ init_completion(&ar->debug.fw_stats_complete); -+ -+ debugfs_create_file("fw_stats", S_IRUSR, ar->debug.debugfs_phy, ar, -+ &fops_fw_stats); -+ -++ debugfs_create_file("fw_reset_stats", S_IRUSR, ar->debug.debugfs_phy, -++ ar, &fops_fw_reset_stats); -++ -+ debugfs_create_file("wmi_services", S_IRUSR, ar->debug.debugfs_phy, ar, -+ &fops_wmi_services); -+ -+ debugfs_create_file("simulate_fw_crash", S_IRUSR, ar->debug.debugfs_phy, -+ ar, &fops_simulate_fw_crash); -+ -++ debugfs_create_file("fw_crash_dump", S_IRUSR, ar->debug.debugfs_phy, -++ ar, &fops_fw_crash_dump); -++ -++ debugfs_create_file("reg_addr", S_IRUSR | S_IWUSR, -++ ar->debug.debugfs_phy, ar, &fops_reg_addr); -++ -++ debugfs_create_file("reg_value", S_IRUSR | S_IWUSR, -++ ar->debug.debugfs_phy, ar, &fops_reg_value); -++ -++ debugfs_create_file("mem_value", S_IRUSR | S_IWUSR, -++ ar->debug.debugfs_phy, ar, &fops_mem_value); -++ -+ debugfs_create_file("chip_id", S_IRUSR, ar->debug.debugfs_phy, -+ ar, &fops_chip_id); -+ -+ debugfs_create_file("htt_stats_mask", S_IRUSR, ar->debug.debugfs_phy, -+ ar, &fops_htt_stats_mask); -+ -++ debugfs_create_file("htt_max_amsdu_ampdu", S_IRUSR | S_IWUSR, -++ ar->debug.debugfs_phy, ar, -++ &fops_htt_max_amsdu_ampdu); -++ -+ debugfs_create_file("fw_dbglog", S_IRUSR, ar->debug.debugfs_phy, -+ ar, &fops_fw_dbglog); -+ -++ debugfs_create_file("cal_data", S_IRUSR, ar->debug.debugfs_phy, -++ ar, &fops_cal_data); -++ -++ debugfs_create_file("nf_cal_period", S_IRUSR | S_IWUSR, -++ ar->debug.debugfs_phy, ar, &fops_nf_cal_period); -++ -+ if (config_enabled(CPTCFG_ATH10K_DFS_CERTIFIED)) { -+ debugfs_create_file("dfs_simulate_radar", S_IWUSR, -+ ar->debug.debugfs_phy, ar, -+@@ -884,10 +2085,13 @@ int ath10k_debug_create(struct ath10k *a -+ &fops_dfs_stats); -+ } -+ -++ debugfs_create_file("pktlog_filter", S_IRUGO | S_IWUSR, -++ ar->debug.debugfs_phy, ar, &fops_pktlog_filter); -++ -+ return 0; -+ } -+ -+-void ath10k_debug_destroy(struct ath10k *ar) -++void ath10k_debug_unregister(struct ath10k *ar) -+ { -+ cancel_delayed_work_sync(&ar->debug.htt_stats_dwork); -+ } -+@@ -895,7 +2099,8 @@ void ath10k_debug_destroy(struct ath10k -+ #endif /* CPTCFG_ATH10K_DEBUGFS */ -+ -+ #ifdef CPTCFG_ATH10K_DEBUG -+-void ath10k_dbg(enum ath10k_debug_mask mask, const char *fmt, ...) -++void ath10k_dbg(struct ath10k *ar, enum ath10k_debug_mask mask, -++ const char *fmt, ...) -+ { -+ struct va_format vaf; -+ va_list args; -+@@ -906,27 +2111,43 @@ void ath10k_dbg(enum ath10k_debug_mask m -+ vaf.va = &args; -+ -+ if (ath10k_debug_mask & mask) -+- ath10k_printk(KERN_DEBUG, "%pV", &vaf); -++ dev_printk(KERN_DEBUG, ar->dev, "%pV", &vaf); -+ -+- trace_ath10k_log_dbg(mask, &vaf); -++ trace_ath10k_log_dbg(ar, mask, &vaf); -+ -+ va_end(args); -+ } -+ EXPORT_SYMBOL(ath10k_dbg); -+ -+-void ath10k_dbg_dump(enum ath10k_debug_mask mask, -++void ath10k_dbg_dump(struct ath10k *ar, -++ enum ath10k_debug_mask mask, -+ const char *msg, const char *prefix, -+ const void *buf, size_t len) -+ { -++ char linebuf[256]; -++ unsigned int linebuflen; -++ const void *ptr; -++ -+ if (ath10k_debug_mask & mask) { -+ if (msg) -+- ath10k_dbg(mask, "%s\n", msg); -++ ath10k_dbg(ar, mask, "%s\n", msg); -+ -+- print_hex_dump_bytes(prefix, DUMP_PREFIX_OFFSET, buf, len); -++ for (ptr = buf; (ptr - buf) < len; ptr += 16) { -++ linebuflen = 0; -++ linebuflen += scnprintf(linebuf + linebuflen, -++ sizeof(linebuf) - linebuflen, -++ "%s%08x: ", -++ (prefix ? prefix : ""), -++ (unsigned int)(ptr - buf)); -++ hex_dump_to_buffer(ptr, len - (ptr - buf), 16, 1, -++ linebuf + linebuflen, -++ sizeof(linebuf) - linebuflen, true); -++ dev_printk(KERN_DEBUG, ar->dev, "%s\n", linebuf); -++ } -+ } -+ -+ /* tracing code doesn't like null strings :/ */ -+- trace_ath10k_log_dbg_dump(msg ? msg : "", prefix ? prefix : "", -++ trace_ath10k_log_dbg_dump(ar, msg ? msg : "", prefix ? prefix : "", -+ buf, len); -+ } -+ EXPORT_SYMBOL(ath10k_dbg_dump); -+--- a/drivers/net/wireless/ath/ath10k/debug.h -++++ b/drivers/net/wireless/ath/ath10k/debug.h -+@@ -34,28 +34,55 @@ enum ath10k_debug_mask { -+ ATH10K_DBG_DATA = 0x00000200, -+ ATH10K_DBG_BMI = 0x00000400, -+ ATH10K_DBG_REGULATORY = 0x00000800, -++ ATH10K_DBG_TESTMODE = 0x00001000, -++ ATH10K_DBG_WMI_PRINT = 0x00002000, -+ ATH10K_DBG_ANY = 0xffffffff, -+ }; -+ -++enum ath10k_pktlog_filter { -++ ATH10K_PKTLOG_RX = 0x000000001, -++ ATH10K_PKTLOG_TX = 0x000000002, -++ ATH10K_PKTLOG_RCFIND = 0x000000004, -++ ATH10K_PKTLOG_RCUPDATE = 0x000000008, -++ ATH10K_PKTLOG_DBG_PRINT = 0x000000010, -++ ATH10K_PKTLOG_ANY = 0x00000001f, -++}; -++ -++enum ath10k_dbg_aggr_mode { -++ ATH10K_DBG_AGGR_MODE_AUTO, -++ ATH10K_DBG_AGGR_MODE_MANUAL, -++ ATH10K_DBG_AGGR_MODE_MAX, -++}; -++ -+ extern unsigned int ath10k_debug_mask; -+ -+-__printf(1, 2) int ath10k_info(const char *fmt, ...); -+-__printf(1, 2) int ath10k_err(const char *fmt, ...); -+-__printf(1, 2) int ath10k_warn(const char *fmt, ...); -++__printf(2, 3) void ath10k_info(struct ath10k *ar, const char *fmt, ...); -++__printf(2, 3) void ath10k_err(struct ath10k *ar, const char *fmt, ...); -++__printf(2, 3) void ath10k_warn(struct ath10k *ar, const char *fmt, ...); -++void ath10k_print_driver_info(struct ath10k *ar); -+ -+ #ifdef CPTCFG_ATH10K_DEBUGFS -+ int ath10k_debug_start(struct ath10k *ar); -+ void ath10k_debug_stop(struct ath10k *ar); -+ int ath10k_debug_create(struct ath10k *ar); -+ void ath10k_debug_destroy(struct ath10k *ar); -+-void ath10k_debug_read_service_map(struct ath10k *ar, -+- void *service_map, -+- size_t map_size); -+-void ath10k_debug_read_target_stats(struct ath10k *ar, -+- struct wmi_stats_event *ev); -++int ath10k_debug_register(struct ath10k *ar); -++void ath10k_debug_unregister(struct ath10k *ar); -++void ath10k_debug_fw_stats_process(struct ath10k *ar, struct sk_buff *skb); -++struct ath10k_fw_crash_data * -++ath10k_debug_get_new_fw_crash_data(struct ath10k *ar); -+ -++void ath10k_debug_dbglog_add(struct ath10k *ar, u8 *buffer, int len); -+ #define ATH10K_DFS_STAT_INC(ar, c) (ar->debug.dfs_stats.c++) -+ -++void ath10k_debug_get_et_strings(struct ieee80211_hw *hw, -++ struct ieee80211_vif *vif, -++ u32 sset, u8 *data); -++int ath10k_debug_get_et_sset_count(struct ieee80211_hw *hw, -++ struct ieee80211_vif *vif, int sset); -++void ath10k_debug_get_et_stats(struct ieee80211_hw *hw, -++ struct ieee80211_vif *vif, -++ struct ethtool_stats *stats, u64 *data); -+ #else -+ static inline int ath10k_debug_start(struct ath10k *ar) -+ { -+@@ -75,36 +102,62 @@ static inline void ath10k_debug_destroy( -+ { -+ } -+ -+-static inline void ath10k_debug_read_service_map(struct ath10k *ar, -+- void *service_map, -+- size_t map_size) -++static inline int ath10k_debug_register(struct ath10k *ar) -++{ -++ return 0; -++} -++ -++static inline void ath10k_debug_unregister(struct ath10k *ar) -+ { -+ } -+ -+-static inline void ath10k_debug_read_target_stats(struct ath10k *ar, -+- struct wmi_stats_event *ev) -++static inline void ath10k_debug_fw_stats_process(struct ath10k *ar, -++ struct sk_buff *skb) -+ { -+ } -+ -++static inline void ath10k_debug_dbglog_add(struct ath10k *ar, u8 *buffer, -++ int len) -++{ -++} -++ -++static inline struct ath10k_fw_crash_data * -++ath10k_debug_get_new_fw_crash_data(struct ath10k *ar) -++{ -++ return NULL; -++} -++ -+ #define ATH10K_DFS_STAT_INC(ar, c) do { } while (0) -+ -++#define ath10k_debug_get_et_strings NULL -++#define ath10k_debug_get_et_sset_count NULL -++#define ath10k_debug_get_et_stats NULL -++ -+ #endif /* CPTCFG_ATH10K_DEBUGFS */ -++#ifdef CPTCFG_MAC80211_DEBUGFS -++void ath10k_sta_add_debugfs(struct ieee80211_hw *hw, struct ieee80211_vif *vif, -++ struct ieee80211_sta *sta, struct dentry *dir); -++#endif /* CPTCFG_MAC80211_DEBUGFS */ -+ -+ #ifdef CPTCFG_ATH10K_DEBUG -+-__printf(2, 3) void ath10k_dbg(enum ath10k_debug_mask mask, -++__printf(3, 4) void ath10k_dbg(struct ath10k *ar, -++ enum ath10k_debug_mask mask, -+ const char *fmt, ...); -+-void ath10k_dbg_dump(enum ath10k_debug_mask mask, -++void ath10k_dbg_dump(struct ath10k *ar, -++ enum ath10k_debug_mask mask, -+ const char *msg, const char *prefix, -+ const void *buf, size_t len); -+ #else /* CPTCFG_ATH10K_DEBUG */ -+ -+-static inline int ath10k_dbg(enum ath10k_debug_mask dbg_mask, -++static inline int ath10k_dbg(struct ath10k *ar, -++ enum ath10k_debug_mask dbg_mask, -+ const char *fmt, ...) -+ { -+ return 0; -+ } -+ -+-static inline void ath10k_dbg_dump(enum ath10k_debug_mask mask, -++static inline void ath10k_dbg_dump(struct ath10k *ar, -++ enum ath10k_debug_mask mask, -+ const char *msg, const char *prefix, -+ const void *buf, size_t len) -+ { -+--- a/drivers/net/wireless/ath/ath10k/hif.h -++++ b/drivers/net/wireless/ath/ath10k/hif.h -+@@ -20,6 +20,7 @@ -+ -+ #include -+ #include "core.h" -++#include "debug.h" -+ -+ struct ath10k_hif_sg_item { -+ u16 transfer_id; -+@@ -31,11 +32,9 @@ struct ath10k_hif_sg_item { -+ -+ struct ath10k_hif_cb { -+ int (*tx_completion)(struct ath10k *ar, -+- struct sk_buff *wbuf, -+- unsigned transfer_id); -++ struct sk_buff *wbuf); -+ int (*rx_completion)(struct ath10k *ar, -+- struct sk_buff *wbuf, -+- u8 pipe_id); -++ struct sk_buff *wbuf); -+ }; -+ -+ struct ath10k_hif_ops { -+@@ -43,6 +42,12 @@ struct ath10k_hif_ops { -+ int (*tx_sg)(struct ath10k *ar, u8 pipe_id, -+ struct ath10k_hif_sg_item *items, int n_items); -+ -++ /* read firmware memory through the diagnose interface */ -++ int (*diag_read)(struct ath10k *ar, u32 address, void *buf, -++ size_t buf_len); -++ -++ int (*diag_write)(struct ath10k *ar, u32 address, const void *data, -++ int nbytes); -+ /* -+ * API to handle HIF-specific BMI message exchanges, this API is -+ * synchronous and only allowed to be called from a context that -+@@ -80,6 +85,10 @@ struct ath10k_hif_ops { -+ -+ u16 (*get_free_queue_number)(struct ath10k *ar, u8 pipe_id); -+ -++ u32 (*read32)(struct ath10k *ar, u32 address); -++ -++ void (*write32)(struct ath10k *ar, u32 address, u32 value); -++ -+ /* Power up the device and enter BMI transfer mode for FW download */ -+ int (*power_up)(struct ath10k *ar); -+ -+@@ -91,7 +100,6 @@ struct ath10k_hif_ops { -+ int (*resume)(struct ath10k *ar); -+ }; -+ -+- -+ static inline int ath10k_hif_tx_sg(struct ath10k *ar, u8 pipe_id, -+ struct ath10k_hif_sg_item *items, -+ int n_items) -+@@ -99,6 +107,21 @@ static inline int ath10k_hif_tx_sg(struc -+ return ar->hif.ops->tx_sg(ar, pipe_id, items, n_items); -+ } -+ -++static inline int ath10k_hif_diag_read(struct ath10k *ar, u32 address, void *buf, -++ size_t buf_len) -++{ -++ return ar->hif.ops->diag_read(ar, address, buf, buf_len); -++} -++ -++static inline int ath10k_hif_diag_write(struct ath10k *ar, u32 address, -++ const void *data, int nbytes) -++{ -++ if (!ar->hif.ops->diag_write) -++ return -EOPNOTSUPP; -++ -++ return ar->hif.ops->diag_write(ar, address, data, nbytes); -++} -++ -+ static inline int ath10k_hif_exchange_bmi_msg(struct ath10k *ar, -+ void *request, u32 request_len, -+ void *response, u32 *response_len) -+@@ -178,4 +201,25 @@ static inline int ath10k_hif_resume(stru -+ return ar->hif.ops->resume(ar); -+ } -+ -++static inline u32 ath10k_hif_read32(struct ath10k *ar, u32 address) -++{ -++ if (!ar->hif.ops->read32) { -++ ath10k_warn(ar, "hif read32 not supported\n"); -++ return 0xdeaddead; -++ } -++ -++ return ar->hif.ops->read32(ar, address); -++} -++ -++static inline void ath10k_hif_write32(struct ath10k *ar, -++ u32 address, u32 data) -++{ -++ if (!ar->hif.ops->write32) { -++ ath10k_warn(ar, "hif write32 not supported\n"); -++ return; -++ } -++ -++ ar->hif.ops->write32(ar, address, data); -++} -++ -+ #endif /* _HIF_H_ */ -+--- a/drivers/net/wireless/ath/ath10k/htc.c -++++ b/drivers/net/wireless/ath/ath10k/htc.c -+@@ -45,10 +45,8 @@ static struct sk_buff *ath10k_htc_build_ -+ struct ath10k_skb_cb *skb_cb; -+ -+ skb = dev_alloc_skb(ATH10K_HTC_CONTROL_BUFFER_SIZE); -+- if (!skb) { -+- ath10k_warn("Unable to allocate ctrl skb\n"); -++ if (!skb) -+ return NULL; -+- } -+ -+ skb_reserve(skb, 20); /* FIXME: why 20 bytes? */ -+ WARN_ONCE((unsigned long)skb->data & 3, "unaligned skb"); -+@@ -56,7 +54,7 @@ static struct sk_buff *ath10k_htc_build_ -+ skb_cb = ATH10K_SKB_CB(skb); -+ memset(skb_cb, 0, sizeof(*skb_cb)); -+ -+- ath10k_dbg(ATH10K_DBG_HTC, "%s: skb %p\n", __func__, skb); -++ ath10k_dbg(ar, ATH10K_DBG_HTC, "%s: skb %p\n", __func__, skb); -+ return skb; -+ } -+ -+@@ -72,13 +70,15 @@ static inline void ath10k_htc_restore_tx -+ static void ath10k_htc_notify_tx_completion(struct ath10k_htc_ep *ep, -+ struct sk_buff *skb) -+ { -+- ath10k_dbg(ATH10K_DBG_HTC, "%s: ep %d skb %p\n", __func__, -++ struct ath10k *ar = ep->htc->ar; -++ -++ ath10k_dbg(ar, ATH10K_DBG_HTC, "%s: ep %d skb %p\n", __func__, -+ ep->eid, skb); -+ -+ ath10k_htc_restore_tx_skb(ep->htc, skb); -+ -+ if (!ep->ep_ops.ep_tx_complete) { -+- ath10k_warn("no tx handler for eid %d\n", ep->eid); -++ ath10k_warn(ar, "no tx handler for eid %d\n", ep->eid); -+ dev_kfree_skb_any(skb); -+ return; -+ } -+@@ -89,12 +89,14 @@ static void ath10k_htc_notify_tx_complet -+ /* assumes tx_lock is held */ -+ static bool ath10k_htc_ep_need_credit_update(struct ath10k_htc_ep *ep) -+ { -++ struct ath10k *ar = ep->htc->ar; -++ -+ if (!ep->tx_credit_flow_enabled) -+ return false; -+ if (ep->tx_credits >= ep->tx_credits_per_max_message) -+ return false; -+ -+- ath10k_dbg(ATH10K_DBG_HTC, "HTC: endpoint %d needs credit update\n", -++ ath10k_dbg(ar, ATH10K_DBG_HTC, "HTC: endpoint %d needs credit update\n", -+ ep->eid); -+ return true; -+ } -+@@ -123,6 +125,7 @@ int ath10k_htc_send(struct ath10k_htc *h -+ enum ath10k_htc_ep_id eid, -+ struct sk_buff *skb) -+ { -++ struct ath10k *ar = htc->ar; -+ struct ath10k_htc_ep *ep = &htc->endpoint[eid]; -+ struct ath10k_skb_cb *skb_cb = ATH10K_SKB_CB(skb); -+ struct ath10k_hif_sg_item sg_item; -+@@ -134,18 +137,10 @@ int ath10k_htc_send(struct ath10k_htc *h -+ return -ECOMM; -+ -+ if (eid >= ATH10K_HTC_EP_COUNT) { -+- ath10k_warn("Invalid endpoint id: %d\n", eid); -++ ath10k_warn(ar, "Invalid endpoint id: %d\n", eid); -+ return -ENOENT; -+ } -+ -+- /* FIXME: This looks ugly, can we fix it? */ -+- spin_lock_bh(&htc->tx_lock); -+- if (htc->stopped) { -+- spin_unlock_bh(&htc->tx_lock); -+- return -ESHUTDOWN; -+- } -+- spin_unlock_bh(&htc->tx_lock); -+- -+ skb_push(skb, sizeof(struct ath10k_htc_hdr)); -+ -+ if (ep->tx_credit_flow_enabled) { -+@@ -157,7 +152,7 @@ int ath10k_htc_send(struct ath10k_htc *h -+ goto err_pull; -+ } -+ ep->tx_credits -= credits; -+- ath10k_dbg(ATH10K_DBG_HTC, -++ ath10k_dbg(ar, ATH10K_DBG_HTC, -+ "htc ep %d consumed %d credits (total %d)\n", -+ eid, credits, ep->tx_credits); -+ spin_unlock_bh(&htc->tx_lock); -+@@ -165,6 +160,7 @@ int ath10k_htc_send(struct ath10k_htc *h -+ -+ ath10k_htc_prepare_tx_skb(ep, skb); -+ -++ skb_cb->eid = eid; -+ skb_cb->paddr = dma_map_single(dev, skb->data, skb->len, DMA_TO_DEVICE); -+ ret = dma_mapping_error(dev, skb_cb->paddr); -+ if (ret) -+@@ -188,7 +184,7 @@ err_credits: -+ if (ep->tx_credit_flow_enabled) { -+ spin_lock_bh(&htc->tx_lock); -+ ep->tx_credits += credits; -+- ath10k_dbg(ATH10K_DBG_HTC, -++ ath10k_dbg(ar, ATH10K_DBG_HTC, -+ "htc ep %d reverted %d credits back (total %d)\n", -+ eid, credits, ep->tx_credits); -+ spin_unlock_bh(&htc->tx_lock); -+@@ -202,15 +198,18 @@ err_pull: -+ } -+ -+ static int ath10k_htc_tx_completion_handler(struct ath10k *ar, -+- struct sk_buff *skb, -+- unsigned int eid) -++ struct sk_buff *skb) -+ { -+ struct ath10k_htc *htc = &ar->htc; -+- struct ath10k_htc_ep *ep = &htc->endpoint[eid]; -++ struct ath10k_skb_cb *skb_cb; -++ struct ath10k_htc_ep *ep; -+ -+ if (WARN_ON_ONCE(!skb)) -+ return 0; -+ -++ skb_cb = ATH10K_SKB_CB(skb); -++ ep = &htc->endpoint[skb_cb->eid]; -++ -+ ath10k_htc_notify_tx_completion(ep, skb); -+ /* the skb now belongs to the completion handler */ -+ -+@@ -227,11 +226,12 @@ ath10k_htc_process_credit_report(struct -+ int len, -+ enum ath10k_htc_ep_id eid) -+ { -++ struct ath10k *ar = htc->ar; -+ struct ath10k_htc_ep *ep; -+ int i, n_reports; -+ -+ if (len % sizeof(*report)) -+- ath10k_warn("Uneven credit report len %d", len); -++ ath10k_warn(ar, "Uneven credit report len %d", len); -+ -+ n_reports = len / sizeof(*report); -+ -+@@ -243,7 +243,7 @@ ath10k_htc_process_credit_report(struct -+ ep = &htc->endpoint[report->eid]; -+ ep->tx_credits += report->credits; -+ -+- ath10k_dbg(ATH10K_DBG_HTC, "htc ep %d got %d credits (total %d)\n", -++ ath10k_dbg(ar, ATH10K_DBG_HTC, "htc ep %d got %d credits (total %d)\n", -+ report->eid, report->credits, ep->tx_credits); -+ -+ if (ep->ep_ops.ep_tx_credits) { -+@@ -260,6 +260,7 @@ static int ath10k_htc_process_trailer(st -+ int length, -+ enum ath10k_htc_ep_id src_eid) -+ { -++ struct ath10k *ar = htc->ar; -+ int status = 0; -+ struct ath10k_htc_record *record; -+ u8 *orig_buffer; -+@@ -279,7 +280,7 @@ static int ath10k_htc_process_trailer(st -+ -+ if (record->hdr.len > length) { -+ /* no room left in buffer for record */ -+- ath10k_warn("Invalid record length: %d\n", -++ ath10k_warn(ar, "Invalid record length: %d\n", -+ record->hdr.len); -+ status = -EINVAL; -+ break; -+@@ -289,7 +290,7 @@ static int ath10k_htc_process_trailer(st -+ case ATH10K_HTC_RECORD_CREDITS: -+ len = sizeof(struct ath10k_htc_credit_report); -+ if (record->hdr.len < len) { -+- ath10k_warn("Credit report too long\n"); -++ ath10k_warn(ar, "Credit report too long\n"); -+ status = -EINVAL; -+ break; -+ } -+@@ -299,7 +300,7 @@ static int ath10k_htc_process_trailer(st -+ src_eid); -+ break; -+ default: -+- ath10k_warn("Unhandled record: id:%d length:%d\n", -++ ath10k_warn(ar, "Unhandled record: id:%d length:%d\n", -+ record->hdr.id, record->hdr.len); -+ break; -+ } -+@@ -313,15 +314,14 @@ static int ath10k_htc_process_trailer(st -+ } -+ -+ if (status) -+- ath10k_dbg_dump(ATH10K_DBG_HTC, "htc rx bad trailer", "", -++ ath10k_dbg_dump(ar, ATH10K_DBG_HTC, "htc rx bad trailer", "", -+ orig_buffer, orig_length); -+ -+ return status; -+ } -+ -+ static int ath10k_htc_rx_completion_handler(struct ath10k *ar, -+- struct sk_buff *skb, -+- u8 pipe_id) -++ struct sk_buff *skb) -+ { -+ int status = 0; -+ struct ath10k_htc *htc = &ar->htc; -+@@ -339,8 +339,8 @@ static int ath10k_htc_rx_completion_hand -+ eid = hdr->eid; -+ -+ if (eid >= ATH10K_HTC_EP_COUNT) { -+- ath10k_warn("HTC Rx: invalid eid %d\n", eid); -+- ath10k_dbg_dump(ATH10K_DBG_HTC, "htc bad header", "", -++ ath10k_warn(ar, "HTC Rx: invalid eid %d\n", eid); -++ ath10k_dbg_dump(ar, ATH10K_DBG_HTC, "htc bad header", "", -+ hdr, sizeof(*hdr)); -+ status = -EINVAL; -+ goto out; -+@@ -360,19 +360,19 @@ static int ath10k_htc_rx_completion_hand -+ payload_len = __le16_to_cpu(hdr->len); -+ -+ if (payload_len + sizeof(*hdr) > ATH10K_HTC_MAX_LEN) { -+- ath10k_warn("HTC rx frame too long, len: %zu\n", -++ ath10k_warn(ar, "HTC rx frame too long, len: %zu\n", -+ payload_len + sizeof(*hdr)); -+- ath10k_dbg_dump(ATH10K_DBG_HTC, "htc bad rx pkt len", "", -++ ath10k_dbg_dump(ar, ATH10K_DBG_HTC, "htc bad rx pkt len", "", -+ hdr, sizeof(*hdr)); -+ status = -EINVAL; -+ goto out; -+ } -+ -+ if (skb->len < payload_len) { -+- ath10k_dbg(ATH10K_DBG_HTC, -++ ath10k_dbg(ar, ATH10K_DBG_HTC, -+ "HTC Rx: insufficient length, got %d, expected %d\n", -+ skb->len, payload_len); -+- ath10k_dbg_dump(ATH10K_DBG_HTC, "htc bad rx pkt len", -++ ath10k_dbg_dump(ar, ATH10K_DBG_HTC, "htc bad rx pkt len", -+ "", hdr, sizeof(*hdr)); -+ status = -EINVAL; -+ goto out; -+@@ -388,7 +388,7 @@ static int ath10k_htc_rx_completion_hand -+ -+ if ((trailer_len < min_len) || -+ (trailer_len > payload_len)) { -+- ath10k_warn("Invalid trailer length: %d\n", -++ ath10k_warn(ar, "Invalid trailer length: %d\n", -+ trailer_len); -+ status = -EPROTO; -+ goto out; -+@@ -421,7 +421,7 @@ static int ath10k_htc_rx_completion_hand -+ * this is a fatal error, target should not be -+ * sending unsolicited messages on the ep 0 -+ */ -+- ath10k_warn("HTC rx ctrl still processing\n"); -++ ath10k_warn(ar, "HTC rx ctrl still processing\n"); -+ status = -EINVAL; -+ complete(&htc->ctl_resp); -+ goto out; -+@@ -442,7 +442,7 @@ static int ath10k_htc_rx_completion_hand -+ goto out; -+ } -+ -+- ath10k_dbg(ATH10K_DBG_HTC, "htc rx completion ep %d skb %p\n", -++ ath10k_dbg(ar, ATH10K_DBG_HTC, "htc rx completion ep %d skb %p\n", -+ eid, skb); -+ ep->ep_ops.ep_rx_complete(ar, skb); -+ -+@@ -459,7 +459,7 @@ static void ath10k_htc_control_rx_comple -+ { -+ /* This is unexpected. FW is not supposed to send regular rx on this -+ * endpoint. */ -+- ath10k_warn("unexpected htc rx\n"); -++ ath10k_warn(ar, "unexpected htc rx\n"); -+ kfree_skb(skb); -+ } -+ -+@@ -546,7 +546,8 @@ static u8 ath10k_htc_get_credit_allocati -+ -+ int ath10k_htc_wait_target(struct ath10k_htc *htc) -+ { -+- int status = 0; -++ struct ath10k *ar = htc->ar; -++ int i, status = 0; -+ struct ath10k_htc_svc_conn_req conn_req; -+ struct ath10k_htc_svc_conn_resp conn_resp; -+ struct ath10k_htc_msg *msg; -+@@ -556,16 +557,32 @@ int ath10k_htc_wait_target(struct ath10k -+ -+ status = wait_for_completion_timeout(&htc->ctl_resp, -+ ATH10K_HTC_WAIT_TIMEOUT_HZ); -+- if (status <= 0) { -++ if (status == 0) { -++ /* Workaround: In some cases the PCI HIF doesn't -++ * receive interrupt for the control response message -++ * even if the buffer was completed. It is suspected -++ * iomap writes unmasking PCI CE irqs aren't propagated -++ * properly in KVM PCI-passthrough sometimes. -++ */ -++ ath10k_warn(ar, "failed to receive control response completion, polling..\n"); -++ -++ for (i = 0; i < CE_COUNT; i++) -++ ath10k_hif_send_complete_check(htc->ar, i, 1); -++ -++ status = wait_for_completion_timeout(&htc->ctl_resp, -++ ATH10K_HTC_WAIT_TIMEOUT_HZ); -++ -+ if (status == 0) -+ status = -ETIMEDOUT; -++ } -+ -+- ath10k_err("ctl_resp never came in (%d)\n", status); -++ if (status < 0) { -++ ath10k_err(ar, "ctl_resp never came in (%d)\n", status); -+ return status; -+ } -+ -+ if (htc->control_resp_len < sizeof(msg->hdr) + sizeof(msg->ready)) { -+- ath10k_err("Invalid HTC ready msg len:%d\n", -++ ath10k_err(ar, "Invalid HTC ready msg len:%d\n", -+ htc->control_resp_len); -+ return -ECOMM; -+ } -+@@ -576,21 +593,21 @@ int ath10k_htc_wait_target(struct ath10k -+ credit_size = __le16_to_cpu(msg->ready.credit_size); -+ -+ if (message_id != ATH10K_HTC_MSG_READY_ID) { -+- ath10k_err("Invalid HTC ready msg: 0x%x\n", message_id); -++ ath10k_err(ar, "Invalid HTC ready msg: 0x%x\n", message_id); -+ return -ECOMM; -+ } -+ -+ htc->total_transmit_credits = credit_count; -+ htc->target_credit_size = credit_size; -+ -+- ath10k_dbg(ATH10K_DBG_HTC, -++ ath10k_dbg(ar, ATH10K_DBG_HTC, -+ "Target ready! transmit resources: %d size:%d\n", -+ htc->total_transmit_credits, -+ htc->target_credit_size); -+ -+ if ((htc->total_transmit_credits == 0) || -+ (htc->target_credit_size == 0)) { -+- ath10k_err("Invalid credit size received\n"); -++ ath10k_err(ar, "Invalid credit size received\n"); -+ return -ECOMM; -+ } -+ -+@@ -607,7 +624,8 @@ int ath10k_htc_wait_target(struct ath10k -+ /* connect fake service */ -+ status = ath10k_htc_connect_service(htc, &conn_req, &conn_resp); -+ if (status) { -+- ath10k_err("could not connect to htc service (%d)\n", status); -++ ath10k_err(ar, "could not connect to htc service (%d)\n", -++ status); -+ return status; -+ } -+ -+@@ -618,6 +636,7 @@ int ath10k_htc_connect_service(struct at -+ struct ath10k_htc_svc_conn_req *conn_req, -+ struct ath10k_htc_svc_conn_resp *conn_resp) -+ { -++ struct ath10k *ar = htc->ar; -+ struct ath10k_htc_msg *msg; -+ struct ath10k_htc_conn_svc *req_msg; -+ struct ath10k_htc_conn_svc_response resp_msg_dummy; -+@@ -643,13 +662,13 @@ int ath10k_htc_connect_service(struct at -+ tx_alloc = ath10k_htc_get_credit_allocation(htc, -+ conn_req->service_id); -+ if (!tx_alloc) -+- ath10k_dbg(ATH10K_DBG_BOOT, -++ ath10k_dbg(ar, ATH10K_DBG_BOOT, -+ "boot htc service %s does not allocate target credits\n", -+ htc_service_name(conn_req->service_id)); -+ -+ skb = ath10k_htc_build_tx_ctrl_skb(htc->ar); -+ if (!skb) { -+- ath10k_err("Failed to allocate HTC packet\n"); -++ ath10k_err(ar, "Failed to allocate HTC packet\n"); -+ return -ENOMEM; -+ } -+ -+@@ -684,11 +703,9 @@ int ath10k_htc_connect_service(struct at -+ /* wait for response */ -+ status = wait_for_completion_timeout(&htc->ctl_resp, -+ ATH10K_HTC_CONN_SVC_TIMEOUT_HZ); -+- if (status <= 0) { -+- if (status == 0) -+- status = -ETIMEDOUT; -+- ath10k_err("Service connect timeout: %d\n", status); -+- return status; -++ if (status == 0) { -++ ath10k_err(ar, "Service connect timeout: %d\n", status); -++ return -ETIMEDOUT; -+ } -+ -+ /* we controlled the buffer creation, it's aligned */ -+@@ -700,11 +717,11 @@ int ath10k_htc_connect_service(struct at -+ if ((message_id != ATH10K_HTC_MSG_CONNECT_SERVICE_RESP_ID) || -+ (htc->control_resp_len < sizeof(msg->hdr) + -+ sizeof(msg->connect_service_response))) { -+- ath10k_err("Invalid resp message ID 0x%x", message_id); -++ ath10k_err(ar, "Invalid resp message ID 0x%x", message_id); -+ return -EPROTO; -+ } -+ -+- ath10k_dbg(ATH10K_DBG_HTC, -++ ath10k_dbg(ar, ATH10K_DBG_HTC, -+ "HTC Service %s connect response: status: 0x%x, assigned ep: 0x%x\n", -+ htc_service_name(service_id), -+ resp_msg->status, resp_msg->eid); -+@@ -713,7 +730,7 @@ int ath10k_htc_connect_service(struct at -+ -+ /* check response status */ -+ if (resp_msg->status != ATH10K_HTC_CONN_SVC_STATUS_SUCCESS) { -+- ath10k_err("HTC Service %s connect request failed: 0x%x)\n", -++ ath10k_err(ar, "HTC Service %s connect request failed: 0x%x)\n", -+ htc_service_name(service_id), -+ resp_msg->status); -+ return -EPROTO; -+@@ -764,18 +781,18 @@ setup: -+ if (status) -+ return status; -+ -+- ath10k_dbg(ATH10K_DBG_BOOT, -++ ath10k_dbg(ar, ATH10K_DBG_BOOT, -+ "boot htc service '%s' ul pipe %d dl pipe %d eid %d ready\n", -+ htc_service_name(ep->service_id), ep->ul_pipe_id, -+ ep->dl_pipe_id, ep->eid); -+ -+- ath10k_dbg(ATH10K_DBG_BOOT, -++ ath10k_dbg(ar, ATH10K_DBG_BOOT, -+ "boot htc ep %d ul polled %d dl polled %d\n", -+ ep->eid, ep->ul_is_polled, ep->dl_is_polled); -+ -+ if (disable_credit_flow_ctrl && ep->tx_credit_flow_enabled) { -+ ep->tx_credit_flow_enabled = false; -+- ath10k_dbg(ATH10K_DBG_BOOT, -++ ath10k_dbg(ar, ATH10K_DBG_BOOT, -+ "boot htc service '%s' eid %d TX flow control disabled\n", -+ htc_service_name(ep->service_id), assigned_eid); -+ } -+@@ -783,27 +800,26 @@ setup: -+ return status; -+ } -+ -+-struct sk_buff *ath10k_htc_alloc_skb(int size) -++struct sk_buff *ath10k_htc_alloc_skb(struct ath10k *ar, int size) -+ { -+ struct sk_buff *skb; -+ -+ skb = dev_alloc_skb(size + sizeof(struct ath10k_htc_hdr)); -+- if (!skb) { -+- ath10k_warn("could not allocate HTC tx skb\n"); -++ if (!skb) -+ return NULL; -+- } -+ -+ skb_reserve(skb, sizeof(struct ath10k_htc_hdr)); -+ -+ /* FW/HTC requires 4-byte aligned streams */ -+ if (!IS_ALIGNED((unsigned long)skb->data, 4)) -+- ath10k_warn("Unaligned HTC tx skb\n"); -++ ath10k_warn(ar, "Unaligned HTC tx skb\n"); -+ -+ return skb; -+ } -+ -+ int ath10k_htc_start(struct ath10k_htc *htc) -+ { -++ struct ath10k *ar = htc->ar; -+ struct sk_buff *skb; -+ int status = 0; -+ struct ath10k_htc_msg *msg; -+@@ -819,7 +835,7 @@ int ath10k_htc_start(struct ath10k_htc * -+ msg->hdr.message_id = -+ __cpu_to_le16(ATH10K_HTC_MSG_SETUP_COMPLETE_EX_ID); -+ -+- ath10k_dbg(ATH10K_DBG_HTC, "HTC is using TX credit flow control\n"); -++ ath10k_dbg(ar, ATH10K_DBG_HTC, "HTC is using TX credit flow control\n"); -+ -+ status = ath10k_htc_send(htc, ATH10K_HTC_EP_0, skb); -+ if (status) { -+@@ -830,19 +846,6 @@ int ath10k_htc_start(struct ath10k_htc * -+ return 0; -+ } -+ -+-/* -+- * stop HTC communications, i.e. stop interrupt reception, and flush all -+- * queued buffers -+- */ -+-void ath10k_htc_stop(struct ath10k_htc *htc) -+-{ -+- spin_lock_bh(&htc->tx_lock); -+- htc->stopped = true; -+- spin_unlock_bh(&htc->tx_lock); -+- -+- ath10k_hif_stop(htc->ar); -+-} -+- -+ /* registered target arrival callback from the HIF layer */ -+ int ath10k_htc_init(struct ath10k *ar) -+ { -+@@ -852,7 +855,6 @@ int ath10k_htc_init(struct ath10k *ar) -+ -+ spin_lock_init(&htc->tx_lock); -+ -+- htc->stopped = false; -+ ath10k_htc_reset_endpoint_states(htc); -+ -+ /* setup HIF layer callbacks */ -+--- a/drivers/net/wireless/ath/ath10k/htc.h -++++ b/drivers/net/wireless/ath/ath10k/htc.h -+@@ -214,7 +214,6 @@ struct ath10k_htc_frame { -+ struct ath10k_htc_record trailer[0]; -+ } __packed __aligned(4); -+ -+- -+ /*******************/ -+ /* Host-side stuff */ -+ /*******************/ -+@@ -332,7 +331,7 @@ struct ath10k_htc { -+ struct ath10k *ar; -+ struct ath10k_htc_ep endpoint[ATH10K_HTC_EP_COUNT]; -+ -+- /* protects endpoint and stopped fields */ -++ /* protects endpoints */ -+ spinlock_t tx_lock; -+ -+ struct ath10k_htc_ops htc_ops; -+@@ -345,8 +344,6 @@ struct ath10k_htc { -+ int total_transmit_credits; -+ struct ath10k_htc_svc_tx_credits service_tx_alloc[ATH10K_HTC_EP_COUNT]; -+ int target_credit_size; -+- -+- bool stopped; -+ }; -+ -+ int ath10k_htc_init(struct ath10k *ar); -+@@ -357,7 +354,6 @@ int ath10k_htc_connect_service(struct at -+ struct ath10k_htc_svc_conn_resp *conn_resp); -+ int ath10k_htc_send(struct ath10k_htc *htc, enum ath10k_htc_ep_id eid, -+ struct sk_buff *packet); -+-void ath10k_htc_stop(struct ath10k_htc *htc); -+-struct sk_buff *ath10k_htc_alloc_skb(int size); -++struct sk_buff *ath10k_htc_alloc_skb(struct ath10k *ar, int size); -+ -+ #endif -+--- a/drivers/net/wireless/ath/ath10k/htt.c -++++ b/drivers/net/wireless/ath/ath10k/htt.c -+@@ -22,7 +22,7 @@ -+ #include "core.h" -+ #include "debug.h" -+ -+-static int ath10k_htt_htc_attach(struct ath10k_htt *htt) -++int ath10k_htt_connect(struct ath10k_htt *htt) -+ { -+ struct ath10k_htc_svc_conn_req conn_req; -+ struct ath10k_htc_svc_conn_resp conn_resp; -+@@ -48,37 +48,11 @@ static int ath10k_htt_htc_attach(struct -+ return 0; -+ } -+ -+-int ath10k_htt_attach(struct ath10k *ar) -++int ath10k_htt_init(struct ath10k *ar) -+ { -+ struct ath10k_htt *htt = &ar->htt; -+- int ret; -+ -+ htt->ar = ar; -+- htt->max_throughput_mbps = 800; -+- -+- /* -+- * Connect to HTC service. -+- * This has to be done before calling ath10k_htt_rx_attach, -+- * since ath10k_htt_rx_attach involves sending a rx ring configure -+- * message to the target. -+- */ -+- ret = ath10k_htt_htc_attach(htt); -+- if (ret) { -+- ath10k_err("could not attach htt htc (%d)\n", ret); -+- goto err_htc_attach; -+- } -+- -+- ret = ath10k_htt_tx_attach(htt); -+- if (ret) { -+- ath10k_err("could not attach htt tx (%d)\n", ret); -+- goto err_htc_attach; -+- } -+- -+- ret = ath10k_htt_rx_attach(htt); -+- if (ret) { -+- ath10k_err("could not attach htt rx (%d)\n", ret); -+- goto err_rx_attach; -+- } -+ -+ /* -+ * Prefetch enough data to satisfy target -+@@ -93,23 +67,20 @@ int ath10k_htt_attach(struct ath10k *ar) -+ 2; /* ip4 dscp or ip6 priority */ -+ -+ return 0; -+- -+-err_rx_attach: -+- ath10k_htt_tx_detach(htt); -+-err_htc_attach: -+- return ret; -+ } -+ -+ #define HTT_TARGET_VERSION_TIMEOUT_HZ (3*HZ) -+ -+ static int ath10k_htt_verify_version(struct ath10k_htt *htt) -+ { -+- ath10k_dbg(ATH10K_DBG_BOOT, "htt target version %d.%d\n", -++ struct ath10k *ar = htt->ar; -++ -++ ath10k_dbg(ar, ATH10K_DBG_BOOT, "htt target version %d.%d\n", -+ htt->target_version_major, htt->target_version_minor); -+ -+ if (htt->target_version_major != 2 && -+ htt->target_version_major != 3) { -+- ath10k_err("unsupported htt major version %d. supported versions are 2 and 3\n", -++ ath10k_err(ar, "unsupported htt major version %d. supported versions are 2 and 3\n", -+ htt->target_version_major); -+ return -ENOTSUPP; -+ } -+@@ -117,8 +88,9 @@ static int ath10k_htt_verify_version(str -+ return 0; -+ } -+ -+-int ath10k_htt_attach_target(struct ath10k_htt *htt) -++int ath10k_htt_setup(struct ath10k_htt *htt) -+ { -++ struct ath10k *ar = htt->ar; -+ int status; -+ -+ init_completion(&htt->target_version_received); -+@@ -128,9 +100,9 @@ int ath10k_htt_attach_target(struct ath1 -+ return status; -+ -+ status = wait_for_completion_timeout(&htt->target_version_received, -+- HTT_TARGET_VERSION_TIMEOUT_HZ); -+- if (status <= 0) { -+- ath10k_warn("htt version request timed out\n"); -++ HTT_TARGET_VERSION_TIMEOUT_HZ); -++ if (status == 0) { -++ ath10k_warn(ar, "htt version request timed out\n"); -+ return -ETIMEDOUT; -+ } -+ -+@@ -140,9 +112,3 @@ int ath10k_htt_attach_target(struct ath1 -+ -+ return ath10k_htt_send_rx_ring_cfg_ll(htt); -+ } -+- -+-void ath10k_htt_detach(struct ath10k_htt *htt) -+-{ -+- ath10k_htt_rx_detach(htt); -+- ath10k_htt_tx_detach(htt); -+-} -+--- a/drivers/net/wireless/ath/ath10k/htt.h -++++ b/drivers/net/wireless/ath/ath10k/htt.h -+@@ -21,6 +21,7 @@ -+ #include -+ #include -+ #include -++#include -+ #include -+ -+ #include "htc.h" -+@@ -126,6 +127,7 @@ enum htt_data_tx_ext_tid { -+ * (HL hosts manage queues on the host ) -+ * more_in_batch: only for HL hosts. indicates if more packets are -+ * pending. this allows target to wait and aggregate -++ * freq: 0 means home channel of given vdev. intended for offchannel -+ */ -+ struct htt_data_tx_desc { -+ u8 flags0; /* %HTT_DATA_TX_DESC_FLAGS0_ */ -+@@ -133,7 +135,8 @@ struct htt_data_tx_desc { -+ __le16 len; -+ __le16 id; -+ __le32 frags_paddr; -+- __le32 peerid; -++ __le16 peerid; -++ __le16 freq; -+ u8 prefetch[0]; /* start of frame, for FW classification engine */ -+ } __packed; -+ -+@@ -156,6 +159,9 @@ enum htt_rx_ring_flags { -+ HTT_RX_RING_FLAGS_PHY_DATA_RX = 1 << 15 -+ }; -+ -++#define HTT_RX_RING_SIZE_MIN 128 -++#define HTT_RX_RING_SIZE_MAX 2048 -++ -+ struct htt_rx_ring_setup_ring { -+ __le32 fw_idx_shadow_reg_paddr; -+ __le32 rx_ring_base_paddr; -+@@ -240,16 +246,10 @@ struct htt_oob_sync_req { -+ __le16 rsvd0; -+ } __packed; -+ -+-#define HTT_AGGR_CONF_MAX_NUM_AMSDU_SUBFRAMES_MASK 0x1F -+-#define HTT_AGGR_CONF_MAX_NUM_AMSDU_SUBFRAMES_LSB 0 -+- -+ struct htt_aggr_conf { -+ u8 max_num_ampdu_subframes; -+- union { -+- /* dont use bitfields; undefined behaviour */ -+- u8 flags; /* see %HTT_AGGR_CONF_MAX_NUM_AMSDU_SUBFRAMES_ */ -+- u8 max_num_amsdu_subframes:5; -+- } __packed; -++ /* amsdu_subframes is limited by 0x1F mask */ -++ u8 max_num_amsdu_subframes; -+ } __packed; -+ -+ #define HTT_MGMT_FRM_HDR_DOWNLOAD_LEN 32 -+@@ -271,7 +271,6 @@ enum htt_mgmt_tx_status { -+ -+ /*=== target -> host messages ===============================================*/ -+ -+- -+ enum htt_t2h_msg_type { -+ HTT_T2H_MSG_TYPE_VERSION_CONF = 0x0, -+ HTT_T2H_MSG_TYPE_RX_IND = 0x1, -+@@ -288,7 +287,19 @@ enum htt_t2h_msg_type { -+ HTT_T2H_MSG_TYPE_RC_UPDATE_IND = 0xc, -+ HTT_T2H_MSG_TYPE_TX_INSPECT_IND = 0xd, -+ HTT_T2H_MSG_TYPE_MGMT_TX_COMPLETION = 0xe, -++ HTT_T2H_MSG_TYPE_TX_CREDIT_UPDATE_IND = 0xf, -++ HTT_T2H_MSG_TYPE_RX_PN_IND = 0x10, -++ HTT_T2H_MSG_TYPE_RX_OFFLOAD_DELIVER_IND = 0x11, -++ HTT_T2H_MSG_TYPE_RX_IN_ORD_PADDR_IND = 0x12, -++ /* 0x13 reservd */ -++ HTT_T2H_MSG_TYPE_WDI_IPA_OP_RESPONSE = 0x14, -++ -++ /* FIXME: Do not depend on this event id. Numbering of this event id is -++ * broken across different firmware revisions and HTT version fails to -++ * indicate this. -++ */ -+ HTT_T2H_MSG_TYPE_TEST, -++ -+ /* keep this last */ -+ HTT_T2H_NUM_MSGS -+ }; -+@@ -657,6 +668,53 @@ struct htt_rx_fragment_indication { -+ #define HTT_RX_FRAG_IND_INFO1_FLUSH_SEQ_NUM_END_MASK 0x00000FC0 -+ #define HTT_RX_FRAG_IND_INFO1_FLUSH_SEQ_NUM_END_LSB 6 -+ -++struct htt_rx_pn_ind { -++ __le16 peer_id; -++ u8 tid; -++ u8 seqno_start; -++ u8 seqno_end; -++ u8 pn_ie_count; -++ u8 reserved; -++ u8 pn_ies[0]; -++} __packed; -++ -++struct htt_rx_offload_msdu { -++ __le16 msdu_len; -++ __le16 peer_id; -++ u8 vdev_id; -++ u8 tid; -++ u8 fw_desc; -++ u8 payload[0]; -++} __packed; -++ -++struct htt_rx_offload_ind { -++ u8 reserved; -++ __le16 msdu_count; -++} __packed; -++ -++struct htt_rx_in_ord_msdu_desc { -++ __le32 msdu_paddr; -++ __le16 msdu_len; -++ u8 fw_desc; -++ u8 reserved; -++} __packed; -++ -++struct htt_rx_in_ord_ind { -++ u8 info; -++ __le16 peer_id; -++ u8 vdev_id; -++ u8 reserved; -++ __le16 msdu_count; -++ struct htt_rx_in_ord_msdu_desc msdu_descs[0]; -++} __packed; -++ -++#define HTT_RX_IN_ORD_IND_INFO_TID_MASK 0x0000001f -++#define HTT_RX_IN_ORD_IND_INFO_TID_LSB 0 -++#define HTT_RX_IN_ORD_IND_INFO_OFFLOAD_MASK 0x00000020 -++#define HTT_RX_IN_ORD_IND_INFO_OFFLOAD_LSB 5 -++#define HTT_RX_IN_ORD_IND_INFO_FRAG_MASK 0x00000040 -++#define HTT_RX_IN_ORD_IND_INFO_FRAG_LSB 6 -++ -+ /* -+ * target -> host test message definition -+ * -+@@ -732,7 +790,7 @@ static inline u8 *htt_rx_test_get_chars( -+ */ -+ struct htt_pktlog_msg { -+ u8 pad[3]; -+- __le32 payload[1 /* or more */]; -++ u8 payload[0]; -+ } __packed; -+ -+ struct htt_dbg_stats_rx_reorder_stats { -+@@ -1038,6 +1096,7 @@ static inline struct htt_stats_conf_item -+ { -+ return (void *)item + sizeof(*item) + roundup(item->length, 4); -+ } -++ -+ /* -+ * host -> target FRAG DESCRIPTOR/MSDU_EXT DESC bank -+ * -+@@ -1151,10 +1210,12 @@ struct htt_resp { -+ struct htt_rx_test rx_test; -+ struct htt_pktlog_msg pktlog_msg; -+ struct htt_stats_conf stats_conf; -++ struct htt_rx_pn_ind rx_pn_ind; -++ struct htt_rx_offload_ind rx_offload_ind; -++ struct htt_rx_in_ord_ind rx_in_ord_ind; -+ }; -+ } __packed; -+ -+- -+ /*** host side structures follow ***/ -+ -+ struct htt_tx_done { -+@@ -1184,7 +1245,6 @@ struct ath10k_htt { -+ struct ath10k *ar; -+ enum ath10k_htc_ep_id eid; -+ -+- int max_throughput_mbps; -+ u8 target_version_major; -+ u8 target_version_minor; -+ struct completion target_version_received; -+@@ -1200,6 +1260,20 @@ struct ath10k_htt { -+ * filled. -+ */ -+ struct sk_buff **netbufs_ring; -++ -++ /* This is used only with firmware supporting IN_ORD_IND. -++ * -++ * With Full Rx Reorder the HTT Rx Ring is more of a temporary -++ * buffer ring from which buffer addresses are copied by the -++ * firmware to MAC Rx ring. Firmware then delivers IN_ORD_IND -++ * pointing to specific (re-ordered) buffers. -++ * -++ * FIXME: With kernel generic hashing functions there's a lot -++ * of hash collisions for sk_buffs. -++ */ -++ bool in_ord_rx; -++ DECLARE_HASHTABLE(skb_table, 4); -++ -+ /* -+ * Ring of buffer addresses - -+ * This ring holds the "physical" device address of the -+@@ -1254,12 +1328,11 @@ struct ath10k_htt { -+ -+ unsigned int prefetch_len; -+ -+- /* Protects access to %pending_tx, %used_msdu_ids */ -++ /* Protects access to pending_tx, num_pending_tx */ -+ spinlock_t tx_lock; -+ int max_num_pending_tx; -+ int num_pending_tx; -+- struct sk_buff **pending_tx; -+- unsigned long *used_msdu_ids; /* bitmap */ -++ struct idr pending_tx; -+ wait_queue_head_t empty_tx_wq; -+ struct dma_pool *tx_pool; -+ -+@@ -1273,6 +1346,7 @@ struct ath10k_htt { -+ struct tasklet_struct txrx_compl_task; -+ struct sk_buff_head tx_compl_q; -+ struct sk_buff_head rx_compl_q; -++ struct sk_buff_head rx_in_ord_compl_q; -+ -+ /* rx_status template */ -+ struct ieee80211_rx_status rx_status; -+@@ -1328,22 +1402,28 @@ struct htt_rx_desc { -+ #define HTT_LOG2_MAX_CACHE_LINE_SIZE 7 /* 2^7 = 128 */ -+ #define HTT_MAX_CACHE_LINE_SIZE_MASK ((1 << HTT_LOG2_MAX_CACHE_LINE_SIZE) - 1) -+ -+-int ath10k_htt_attach(struct ath10k *ar); -+-int ath10k_htt_attach_target(struct ath10k_htt *htt); -+-void ath10k_htt_detach(struct ath10k_htt *htt); -+- -+-int ath10k_htt_tx_attach(struct ath10k_htt *htt); -+-void ath10k_htt_tx_detach(struct ath10k_htt *htt); -+-int ath10k_htt_rx_attach(struct ath10k_htt *htt); -+-void ath10k_htt_rx_detach(struct ath10k_htt *htt); -++int ath10k_htt_connect(struct ath10k_htt *htt); -++int ath10k_htt_init(struct ath10k *ar); -++int ath10k_htt_setup(struct ath10k_htt *htt); -++ -++int ath10k_htt_tx_alloc(struct ath10k_htt *htt); -++void ath10k_htt_tx_free(struct ath10k_htt *htt); -++ -++int ath10k_htt_rx_alloc(struct ath10k_htt *htt); -++int ath10k_htt_rx_ring_refill(struct ath10k *ar); -++void ath10k_htt_rx_free(struct ath10k_htt *htt); -++ -+ void ath10k_htt_htc_tx_complete(struct ath10k *ar, struct sk_buff *skb); -+ void ath10k_htt_t2h_msg_handler(struct ath10k *ar, struct sk_buff *skb); -+ int ath10k_htt_h2t_ver_req_msg(struct ath10k_htt *htt); -+ int ath10k_htt_h2t_stats_req(struct ath10k_htt *htt, u8 mask, u64 cookie); -+ int ath10k_htt_send_rx_ring_cfg_ll(struct ath10k_htt *htt); -++int ath10k_htt_h2t_aggr_cfg_msg(struct ath10k_htt *htt, -++ u8 max_subfrms_ampdu, -++ u8 max_subfrms_amsdu); -+ -+ void __ath10k_htt_tx_dec_pending(struct ath10k_htt *htt); -+-int ath10k_htt_tx_alloc_msdu_id(struct ath10k_htt *htt); -++int ath10k_htt_tx_alloc_msdu_id(struct ath10k_htt *htt, struct sk_buff *skb); -+ void ath10k_htt_tx_free_msdu_id(struct ath10k_htt *htt, u16 msdu_id); -+ int ath10k_htt_mgmt_tx(struct ath10k_htt *htt, struct sk_buff *); -+ int ath10k_htt_tx(struct ath10k_htt *htt, struct sk_buff *); -+--- a/drivers/net/wireless/ath/ath10k/htt_rx.c -++++ b/drivers/net/wireless/ath/ath10k/htt_rx.c -+@@ -21,118 +21,84 @@ -+ #include "txrx.h" -+ #include "debug.h" -+ #include "trace.h" -++#include "mac.h" -+ -+ #include -+ -+-/* slightly larger than one large A-MPDU */ -+-#define HTT_RX_RING_SIZE_MIN 128 -+- -+-/* roughly 20 ms @ 1 Gbps of 1500B MSDUs */ -+-#define HTT_RX_RING_SIZE_MAX 2048 -+- -+-#define HTT_RX_AVG_FRM_BYTES 1000 -+- -+-/* ms, very conservative */ -+-#define HTT_RX_HOST_LATENCY_MAX_MS 20 -+- -+-/* ms, conservative */ -+-#define HTT_RX_HOST_LATENCY_WORST_LIKELY_MS 10 -++#define HTT_RX_RING_SIZE HTT_RX_RING_SIZE_MAX -++#define HTT_RX_RING_FILL_LEVEL (((HTT_RX_RING_SIZE) / 2) - 1) -+ -+ /* when under memory pressure rx ring refill may fail and needs a retry */ -+ #define HTT_RX_RING_REFILL_RETRY_MS 50 -+ -+- -+ static int ath10k_htt_rx_get_csum_state(struct sk_buff *skb); -+ static void ath10k_htt_txrx_compl_task(unsigned long ptr); -+ -+-static int ath10k_htt_rx_ring_size(struct ath10k_htt *htt) -+-{ -+- int size; -+- -+- /* -+- * It is expected that the host CPU will typically be able to -+- * service the rx indication from one A-MPDU before the rx -+- * indication from the subsequent A-MPDU happens, roughly 1-2 ms -+- * later. However, the rx ring should be sized very conservatively, -+- * to accomodate the worst reasonable delay before the host CPU -+- * services a rx indication interrupt. -+- * -+- * The rx ring need not be kept full of empty buffers. In theory, -+- * the htt host SW can dynamically track the low-water mark in the -+- * rx ring, and dynamically adjust the level to which the rx ring -+- * is filled with empty buffers, to dynamically meet the desired -+- * low-water mark. -+- * -+- * In contrast, it's difficult to resize the rx ring itself, once -+- * it's in use. Thus, the ring itself should be sized very -+- * conservatively, while the degree to which the ring is filled -+- * with empty buffers should be sized moderately conservatively. -+- */ -+- -+- /* 1e6 bps/mbps / 1e3 ms per sec = 1000 */ -+- size = -+- htt->max_throughput_mbps + -+- 1000 / -+- (8 * HTT_RX_AVG_FRM_BYTES) * HTT_RX_HOST_LATENCY_MAX_MS; -+- -+- if (size < HTT_RX_RING_SIZE_MIN) -+- size = HTT_RX_RING_SIZE_MIN; -+- -+- if (size > HTT_RX_RING_SIZE_MAX) -+- size = HTT_RX_RING_SIZE_MAX; -+- -+- size = roundup_pow_of_two(size); -+- -+- return size; -+-} -+- -+-static int ath10k_htt_rx_ring_fill_level(struct ath10k_htt *htt) -++static struct sk_buff * -++ath10k_htt_rx_find_skb_paddr(struct ath10k *ar, u32 paddr) -+ { -+- int size; -++ struct ath10k_skb_rxcb *rxcb; -+ -+- /* 1e6 bps/mbps / 1e3 ms per sec = 1000 */ -+- size = -+- htt->max_throughput_mbps * -+- 1000 / -+- (8 * HTT_RX_AVG_FRM_BYTES) * HTT_RX_HOST_LATENCY_WORST_LIKELY_MS; -+- -+- /* -+- * Make sure the fill level is at least 1 less than the ring size. -+- * Leaving 1 element empty allows the SW to easily distinguish -+- * between a full ring vs. an empty ring. -+- */ -+- if (size >= htt->rx_ring.size) -+- size = htt->rx_ring.size - 1; -++ hash_for_each_possible(ar->htt.rx_ring.skb_table, rxcb, hlist, paddr) -++ if (rxcb->paddr == paddr) -++ return ATH10K_RXCB_SKB(rxcb); -+ -+- return size; -++ WARN_ON_ONCE(1); -++ return NULL; -+ } -+ -+ static void ath10k_htt_rx_ring_free(struct ath10k_htt *htt) -+ { -+ struct sk_buff *skb; -+- struct ath10k_skb_cb *cb; -++ struct ath10k_skb_rxcb *rxcb; -++ struct hlist_node *n; -+ int i; -+ -+- for (i = 0; i < htt->rx_ring.fill_cnt; i++) { -+- skb = htt->rx_ring.netbufs_ring[i]; -+- cb = ATH10K_SKB_CB(skb); -+- dma_unmap_single(htt->ar->dev, cb->paddr, -+- skb->len + skb_tailroom(skb), -+- DMA_FROM_DEVICE); -+- dev_kfree_skb_any(skb); -++ if (htt->rx_ring.in_ord_rx) { -++ hash_for_each_safe(htt->rx_ring.skb_table, i, n, rxcb, hlist) { -++ skb = ATH10K_RXCB_SKB(rxcb); -++ dma_unmap_single(htt->ar->dev, rxcb->paddr, -++ skb->len + skb_tailroom(skb), -++ DMA_FROM_DEVICE); -++ hash_del(&rxcb->hlist); -++ dev_kfree_skb_any(skb); -++ } -++ } else { -++ for (i = 0; i < htt->rx_ring.size; i++) { -++ skb = htt->rx_ring.netbufs_ring[i]; -++ if (!skb) -++ continue; -++ -++ rxcb = ATH10K_SKB_RXCB(skb); -++ dma_unmap_single(htt->ar->dev, rxcb->paddr, -++ skb->len + skb_tailroom(skb), -++ DMA_FROM_DEVICE); -++ dev_kfree_skb_any(skb); -++ } -+ } -+ -+ htt->rx_ring.fill_cnt = 0; -++ hash_init(htt->rx_ring.skb_table); -++ memset(htt->rx_ring.netbufs_ring, 0, -++ htt->rx_ring.size * sizeof(htt->rx_ring.netbufs_ring[0])); -+ } -+ -+ static int __ath10k_htt_rx_ring_fill_n(struct ath10k_htt *htt, int num) -+ { -+ struct htt_rx_desc *rx_desc; -++ struct ath10k_skb_rxcb *rxcb; -+ struct sk_buff *skb; -+ dma_addr_t paddr; -+ int ret = 0, idx; -+ -+- idx = __le32_to_cpu(*(htt->rx_ring.alloc_idx.vaddr)); -++ /* The Full Rx Reorder firmware has no way of telling the host -++ * implicitly when it copied HTT Rx Ring buffers to MAC Rx Ring. -++ * To keep things simple make sure ring is always half empty. This -++ * guarantees there'll be no replenishment overruns possible. -++ */ -++ BUILD_BUG_ON(HTT_RX_RING_FILL_LEVEL >= HTT_RX_RING_SIZE / 2); -++ -++ idx = __le32_to_cpu(*htt->rx_ring.alloc_idx.vaddr); -+ while (num > 0) { -+ skb = dev_alloc_skb(HTT_RX_BUF_SIZE + HTT_RX_DESC_ALIGN); -+ if (!skb) { -+@@ -159,18 +125,30 @@ static int __ath10k_htt_rx_ring_fill_n(s -+ goto fail; -+ } -+ -+- ATH10K_SKB_CB(skb)->paddr = paddr; -++ rxcb = ATH10K_SKB_RXCB(skb); -++ rxcb->paddr = paddr; -+ htt->rx_ring.netbufs_ring[idx] = skb; -+ htt->rx_ring.paddrs_ring[idx] = __cpu_to_le32(paddr); -+ htt->rx_ring.fill_cnt++; -+ -++ if (htt->rx_ring.in_ord_rx) { -++ hash_add(htt->rx_ring.skb_table, -++ &ATH10K_SKB_RXCB(skb)->hlist, -++ (u32)paddr); -++ } -++ -+ num--; -+ idx++; -+ idx &= htt->rx_ring.size_mask; -+ } -+ -+ fail: -+- *(htt->rx_ring.alloc_idx.vaddr) = __cpu_to_le32(idx); -++ /* -++ * Make sure the rx buffer is updated before available buffer -++ * index to avoid any potential rx ring corruption. -++ */ -++ mb(); -++ *htt->rx_ring.alloc_idx.vaddr = __cpu_to_le32(idx); -+ return ret; -+ } -+ -+@@ -198,7 +176,7 @@ static void ath10k_htt_rx_msdu_buff_repl -+ * automatically balances load wrt to CPU power. -+ * -+ * This probably comes at a cost of lower maximum throughput but -+- * improves the avarage and stability. */ -++ * improves the average and stability. */ -+ spin_lock_bh(&htt->rx_ring.lock); -+ num_deficit = htt->rx_ring.fill_level - htt->rx_ring.fill_cnt; -+ num_to_fill = min(ATH10K_HTT_MAX_NUM_REFILL, num_deficit); -+@@ -222,32 +200,37 @@ static void ath10k_htt_rx_msdu_buff_repl -+ static void ath10k_htt_rx_ring_refill_retry(unsigned long arg) -+ { -+ struct ath10k_htt *htt = (struct ath10k_htt *)arg; -++ -+ ath10k_htt_rx_msdu_buff_replenish(htt); -+ } -+ -+-void ath10k_htt_rx_detach(struct ath10k_htt *htt) -++int ath10k_htt_rx_ring_refill(struct ath10k *ar) -+ { -+- int sw_rd_idx = htt->rx_ring.sw_rd_idx.msdu_payld; -++ struct ath10k_htt *htt = &ar->htt; -++ int ret; -++ -++ spin_lock_bh(&htt->rx_ring.lock); -++ ret = ath10k_htt_rx_ring_fill_n(htt, (htt->rx_ring.fill_level - -++ htt->rx_ring.fill_cnt)); -++ spin_unlock_bh(&htt->rx_ring.lock); -++ -++ if (ret) -++ ath10k_htt_rx_ring_free(htt); -++ -++ return ret; -++} -+ -++void ath10k_htt_rx_free(struct ath10k_htt *htt) -++{ -+ del_timer_sync(&htt->rx_ring.refill_retry_timer); -+ tasklet_kill(&htt->rx_replenish_task); -+ tasklet_kill(&htt->txrx_compl_task); -+ -+ skb_queue_purge(&htt->tx_compl_q); -+ skb_queue_purge(&htt->rx_compl_q); -++ skb_queue_purge(&htt->rx_in_ord_compl_q); -+ -+- while (sw_rd_idx != __le32_to_cpu(*(htt->rx_ring.alloc_idx.vaddr))) { -+- struct sk_buff *skb = -+- htt->rx_ring.netbufs_ring[sw_rd_idx]; -+- struct ath10k_skb_cb *cb = ATH10K_SKB_CB(skb); -+- -+- dma_unmap_single(htt->ar->dev, cb->paddr, -+- skb->len + skb_tailroom(skb), -+- DMA_FROM_DEVICE); -+- dev_kfree_skb_any(htt->rx_ring.netbufs_ring[sw_rd_idx]); -+- sw_rd_idx++; -+- sw_rd_idx &= htt->rx_ring.size_mask; -+- } -++ ath10k_htt_rx_ring_free(htt); -+ -+ dma_free_coherent(htt->ar->dev, -+ (htt->rx_ring.size * -+@@ -265,66 +248,59 @@ void ath10k_htt_rx_detach(struct ath10k_ -+ -+ static inline struct sk_buff *ath10k_htt_rx_netbuf_pop(struct ath10k_htt *htt) -+ { -++ struct ath10k *ar = htt->ar; -+ int idx; -+ struct sk_buff *msdu; -+ -+ lockdep_assert_held(&htt->rx_ring.lock); -+ -+ if (htt->rx_ring.fill_cnt == 0) { -+- ath10k_warn("tried to pop sk_buff from an empty rx ring\n"); -++ ath10k_warn(ar, "tried to pop sk_buff from an empty rx ring\n"); -+ return NULL; -+ } -+ -+ idx = htt->rx_ring.sw_rd_idx.msdu_payld; -+ msdu = htt->rx_ring.netbufs_ring[idx]; -++ htt->rx_ring.netbufs_ring[idx] = NULL; -++ htt->rx_ring.paddrs_ring[idx] = 0; -+ -+ idx++; -+ idx &= htt->rx_ring.size_mask; -+ htt->rx_ring.sw_rd_idx.msdu_payld = idx; -+ htt->rx_ring.fill_cnt--; -+ -+- return msdu; -+-} -+- -+-static void ath10k_htt_rx_free_msdu_chain(struct sk_buff *skb) -+-{ -+- struct sk_buff *next; -++ dma_unmap_single(htt->ar->dev, -++ ATH10K_SKB_RXCB(msdu)->paddr, -++ msdu->len + skb_tailroom(msdu), -++ DMA_FROM_DEVICE); -++ ath10k_dbg_dump(ar, ATH10K_DBG_HTT_DUMP, NULL, "htt rx netbuf pop: ", -++ msdu->data, msdu->len + skb_tailroom(msdu)); -+ -+- while (skb) { -+- next = skb->next; -+- dev_kfree_skb_any(skb); -+- skb = next; -+- } -++ return msdu; -+ } -+ -+ /* return: < 0 fatal error, 0 - non chained msdu, 1 chained msdu */ -+ static int ath10k_htt_rx_amsdu_pop(struct ath10k_htt *htt, -+ u8 **fw_desc, int *fw_desc_len, -+- struct sk_buff **head_msdu, -+- struct sk_buff **tail_msdu) -++ struct sk_buff_head *amsdu) -+ { -++ struct ath10k *ar = htt->ar; -+ int msdu_len, msdu_chaining = 0; -+ struct sk_buff *msdu; -+ struct htt_rx_desc *rx_desc; -+ -+ lockdep_assert_held(&htt->rx_ring.lock); -+ -+- if (htt->rx_confused) { -+- ath10k_warn("htt is confused. refusing rx\n"); -+- return -1; -+- } -+- -+- msdu = *head_msdu = ath10k_htt_rx_netbuf_pop(htt); -+- while (msdu) { -++ for (;;) { -+ int last_msdu, msdu_len_invalid, msdu_chained; -+ -+- dma_unmap_single(htt->ar->dev, -+- ATH10K_SKB_CB(msdu)->paddr, -+- msdu->len + skb_tailroom(msdu), -+- DMA_FROM_DEVICE); -++ msdu = ath10k_htt_rx_netbuf_pop(htt); -++ if (!msdu) { -++ __skb_queue_purge(amsdu); -++ return -ENOENT; -++ } -+ -+- ath10k_dbg_dump(ATH10K_DBG_HTT_DUMP, NULL, "htt rx pop: ", -+- msdu->data, msdu->len + skb_tailroom(msdu)); -++ __skb_queue_tail(amsdu, msdu); -+ -+ rx_desc = (struct htt_rx_desc *)msdu->data; -+ -+@@ -343,12 +319,8 @@ static int ath10k_htt_rx_amsdu_pop(struc -+ */ -+ if (!(__le32_to_cpu(rx_desc->attention.flags) -+ & RX_ATTENTION_FLAGS_MSDU_DONE)) { -+- ath10k_htt_rx_free_msdu_chain(*head_msdu); -+- *head_msdu = NULL; -+- msdu = NULL; -+- ath10k_err("htt rx stopped. cannot recover\n"); -+- htt->rx_confused = true; -+- break; -++ __skb_queue_purge(amsdu); -++ return -EIO; -+ } -+ -+ /* -+@@ -399,7 +371,6 @@ static int ath10k_htt_rx_amsdu_pop(struc -+ msdu_len = MS(__le32_to_cpu(rx_desc->msdu_start.info0), -+ RX_MSDU_START_INFO0_MSDU_LENGTH); -+ msdu_chained = rx_desc->frag_info.ring2_more_count; -+- msdu_chaining = msdu_chained; -+ -+ if (msdu_len_invalid) -+ msdu_len = 0; -+@@ -408,42 +379,32 @@ static int ath10k_htt_rx_amsdu_pop(struc -+ skb_put(msdu, min(msdu_len, HTT_RX_MSDU_SIZE)); -+ msdu_len -= msdu->len; -+ -+- /* FIXME: Do chained buffers include htt_rx_desc or not? */ -++ /* Note: Chained buffers do not contain rx descriptor */ -+ while (msdu_chained--) { -+- struct sk_buff *next = ath10k_htt_rx_netbuf_pop(htt); -+- -+- dma_unmap_single(htt->ar->dev, -+- ATH10K_SKB_CB(next)->paddr, -+- next->len + skb_tailroom(next), -+- DMA_FROM_DEVICE); -+- -+- ath10k_dbg_dump(ATH10K_DBG_HTT_DUMP, NULL, -+- "htt rx chained: ", next->data, -+- next->len + skb_tailroom(next)); -+- -+- skb_trim(next, 0); -+- skb_put(next, min(msdu_len, HTT_RX_BUF_SIZE)); -+- msdu_len -= next->len; -++ msdu = ath10k_htt_rx_netbuf_pop(htt); -++ if (!msdu) { -++ __skb_queue_purge(amsdu); -++ return -ENOENT; -++ } -+ -+- msdu->next = next; -+- msdu = next; -++ __skb_queue_tail(amsdu, msdu); -++ skb_trim(msdu, 0); -++ skb_put(msdu, min(msdu_len, HTT_RX_BUF_SIZE)); -++ msdu_len -= msdu->len; -++ msdu_chaining = 1; -+ } -+ -+ last_msdu = __le32_to_cpu(rx_desc->msdu_end.info0) & -+ RX_MSDU_END_INFO0_LAST_MSDU; -+ -+- if (last_msdu) { -+- msdu->next = NULL; -++ trace_ath10k_htt_rx_desc(ar, &rx_desc->attention, -++ sizeof(*rx_desc) - sizeof(u32)); -++ -++ if (last_msdu) -+ break; -+- } else { -+- struct sk_buff *next = ath10k_htt_rx_netbuf_pop(htt); -+- msdu->next = next; -+- msdu = next; -+- } -+ } -+- *tail_msdu = msdu; -+ -+- if (*head_msdu == NULL) -++ if (skb_queue_empty(amsdu)) -+ msdu_chaining = -1; -+ -+ /* -+@@ -465,43 +426,117 @@ static int ath10k_htt_rx_amsdu_pop(struc -+ static void ath10k_htt_rx_replenish_task(unsigned long ptr) -+ { -+ struct ath10k_htt *htt = (struct ath10k_htt *)ptr; -++ -+ ath10k_htt_rx_msdu_buff_replenish(htt); -+ } -+ -+-int ath10k_htt_rx_attach(struct ath10k_htt *htt) -++static struct sk_buff *ath10k_htt_rx_pop_paddr(struct ath10k_htt *htt, -++ u32 paddr) -++{ -++ struct ath10k *ar = htt->ar; -++ struct ath10k_skb_rxcb *rxcb; -++ struct sk_buff *msdu; -++ -++ lockdep_assert_held(&htt->rx_ring.lock); -++ -++ msdu = ath10k_htt_rx_find_skb_paddr(ar, paddr); -++ if (!msdu) -++ return NULL; -++ -++ rxcb = ATH10K_SKB_RXCB(msdu); -++ hash_del(&rxcb->hlist); -++ htt->rx_ring.fill_cnt--; -++ -++ dma_unmap_single(htt->ar->dev, rxcb->paddr, -++ msdu->len + skb_tailroom(msdu), -++ DMA_FROM_DEVICE); -++ ath10k_dbg_dump(ar, ATH10K_DBG_HTT_DUMP, NULL, "htt rx netbuf pop: ", -++ msdu->data, msdu->len + skb_tailroom(msdu)); -++ -++ return msdu; -++} -++ -++static int ath10k_htt_rx_pop_paddr_list(struct ath10k_htt *htt, -++ struct htt_rx_in_ord_ind *ev, -++ struct sk_buff_head *list) -+ { -++ struct ath10k *ar = htt->ar; -++ struct htt_rx_in_ord_msdu_desc *msdu_desc = ev->msdu_descs; -++ struct htt_rx_desc *rxd; -++ struct sk_buff *msdu; -++ int msdu_count; -++ bool is_offload; -++ u32 paddr; -++ -++ lockdep_assert_held(&htt->rx_ring.lock); -++ -++ msdu_count = __le16_to_cpu(ev->msdu_count); -++ is_offload = !!(ev->info & HTT_RX_IN_ORD_IND_INFO_OFFLOAD_MASK); -++ -++ while (msdu_count--) { -++ paddr = __le32_to_cpu(msdu_desc->msdu_paddr); -++ -++ msdu = ath10k_htt_rx_pop_paddr(htt, paddr); -++ if (!msdu) { -++ __skb_queue_purge(list); -++ return -ENOENT; -++ } -++ -++ __skb_queue_tail(list, msdu); -++ -++ if (!is_offload) { -++ rxd = (void *)msdu->data; -++ -++ trace_ath10k_htt_rx_desc(ar, rxd, sizeof(*rxd)); -++ -++ skb_put(msdu, sizeof(*rxd)); -++ skb_pull(msdu, sizeof(*rxd)); -++ skb_put(msdu, __le16_to_cpu(msdu_desc->msdu_len)); -++ -++ if (!(__le32_to_cpu(rxd->attention.flags) & -++ RX_ATTENTION_FLAGS_MSDU_DONE)) { -++ ath10k_warn(htt->ar, "tried to pop an incomplete frame, oops!\n"); -++ return -EIO; -++ } -++ } -++ -++ msdu_desc++; -++ } -++ -++ return 0; -++} -++ -++int ath10k_htt_rx_alloc(struct ath10k_htt *htt) -++{ -++ struct ath10k *ar = htt->ar; -+ dma_addr_t paddr; -+ void *vaddr; -++ size_t size; -+ struct timer_list *timer = &htt->rx_ring.refill_retry_timer; -+ -+- htt->rx_ring.size = ath10k_htt_rx_ring_size(htt); -+- if (!is_power_of_2(htt->rx_ring.size)) { -+- ath10k_warn("htt rx ring size is not power of 2\n"); -+- return -EINVAL; -+- } -++ htt->rx_confused = false; -+ -++ /* XXX: The fill level could be changed during runtime in response to -++ * the host processing latency. Is this really worth it? -++ */ -++ htt->rx_ring.size = HTT_RX_RING_SIZE; -+ htt->rx_ring.size_mask = htt->rx_ring.size - 1; -++ htt->rx_ring.fill_level = HTT_RX_RING_FILL_LEVEL; -+ -+- /* -+- * Set the initial value for the level to which the rx ring -+- * should be filled, based on the max throughput and the -+- * worst likely latency for the host to fill the rx ring -+- * with new buffers. In theory, this fill level can be -+- * dynamically adjusted from the initial value set here, to -+- * reflect the actual host latency rather than a -+- * conservative assumption about the host latency. -+- */ -+- htt->rx_ring.fill_level = ath10k_htt_rx_ring_fill_level(htt); -++ if (!is_power_of_2(htt->rx_ring.size)) { -++ ath10k_warn(ar, "htt rx ring size is not power of 2\n"); -++ return -EINVAL; -++ } -+ -+ htt->rx_ring.netbufs_ring = -+- kmalloc(htt->rx_ring.size * sizeof(struct sk_buff *), -++ kzalloc(htt->rx_ring.size * sizeof(struct sk_buff *), -+ GFP_KERNEL); -+ if (!htt->rx_ring.netbufs_ring) -+ goto err_netbuf; -+ -+- vaddr = dma_alloc_coherent(htt->ar->dev, -+- (htt->rx_ring.size * sizeof(htt->rx_ring.paddrs_ring)), -+- &paddr, GFP_DMA); -++ size = htt->rx_ring.size * sizeof(htt->rx_ring.paddrs_ring); -++ -++ vaddr = dma_alloc_coherent(htt->ar->dev, size, &paddr, GFP_DMA); -+ if (!vaddr) -+ goto err_dma_ring; -+ -+@@ -516,7 +551,7 @@ int ath10k_htt_rx_attach(struct ath10k_h -+ -+ htt->rx_ring.alloc_idx.vaddr = vaddr; -+ htt->rx_ring.alloc_idx.paddr = paddr; -+- htt->rx_ring.sw_rd_idx.msdu_payld = 0; -++ htt->rx_ring.sw_rd_idx.msdu_payld = htt->rx_ring.size_mask; -+ *htt->rx_ring.alloc_idx.vaddr = 0; -+ -+ /* Initialize the Rx refill retry timer */ -+@@ -525,28 +560,23 @@ int ath10k_htt_rx_attach(struct ath10k_h -+ spin_lock_init(&htt->rx_ring.lock); -+ -+ htt->rx_ring.fill_cnt = 0; -+- if (__ath10k_htt_rx_ring_fill_n(htt, htt->rx_ring.fill_level)) -+- goto err_fill_ring; -++ htt->rx_ring.sw_rd_idx.msdu_payld = 0; -++ hash_init(htt->rx_ring.skb_table); -+ -+ tasklet_init(&htt->rx_replenish_task, ath10k_htt_rx_replenish_task, -+ (unsigned long)htt); -+ -+ skb_queue_head_init(&htt->tx_compl_q); -+ skb_queue_head_init(&htt->rx_compl_q); -++ skb_queue_head_init(&htt->rx_in_ord_compl_q); -+ -+ tasklet_init(&htt->txrx_compl_task, ath10k_htt_txrx_compl_task, -+ (unsigned long)htt); -+ -+- ath10k_dbg(ATH10K_DBG_BOOT, "htt rx ring size %d fill_level %d\n", -++ ath10k_dbg(ar, ATH10K_DBG_BOOT, "htt rx ring size %d fill_level %d\n", -+ htt->rx_ring.size, htt->rx_ring.fill_level); -+ return 0; -+ -+-err_fill_ring: -+- ath10k_htt_rx_ring_free(htt); -+- dma_free_coherent(htt->ar->dev, -+- sizeof(*htt->rx_ring.alloc_idx.vaddr), -+- htt->rx_ring.alloc_idx.vaddr, -+- htt->rx_ring.alloc_idx.paddr); -+ err_dma_idx: -+ dma_free_coherent(htt->ar->dev, -+ (htt->rx_ring.size * -+@@ -559,73 +589,54 @@ err_netbuf: -+ return -ENOMEM; -+ } -+ -+-static int ath10k_htt_rx_crypto_param_len(enum htt_rx_mpdu_encrypt_type type) -++static int ath10k_htt_rx_crypto_param_len(struct ath10k *ar, -++ enum htt_rx_mpdu_encrypt_type type) -+ { -+ switch (type) { -++ case HTT_RX_MPDU_ENCRYPT_NONE: -++ return 0; -+ case HTT_RX_MPDU_ENCRYPT_WEP40: -+ case HTT_RX_MPDU_ENCRYPT_WEP104: -+- return 4; -++ return IEEE80211_WEP_IV_LEN; -+ case HTT_RX_MPDU_ENCRYPT_TKIP_WITHOUT_MIC: -+- case HTT_RX_MPDU_ENCRYPT_WEP128: /* not tested */ -+ case HTT_RX_MPDU_ENCRYPT_TKIP_WPA: -+- case HTT_RX_MPDU_ENCRYPT_WAPI: /* not tested */ -++ return IEEE80211_TKIP_IV_LEN; -+ case HTT_RX_MPDU_ENCRYPT_AES_CCM_WPA2: -+- return 8; -+- case HTT_RX_MPDU_ENCRYPT_NONE: -+- return 0; -++ return IEEE80211_CCMP_HDR_LEN; -++ case HTT_RX_MPDU_ENCRYPT_WEP128: -++ case HTT_RX_MPDU_ENCRYPT_WAPI: -++ break; -+ } -+ -+- ath10k_warn("unknown encryption type %d\n", type); -++ ath10k_warn(ar, "unsupported encryption type %d\n", type); -+ return 0; -+ } -+ -+-static int ath10k_htt_rx_crypto_tail_len(enum htt_rx_mpdu_encrypt_type type) -++#define MICHAEL_MIC_LEN 8 -++ -++static int ath10k_htt_rx_crypto_tail_len(struct ath10k *ar, -++ enum htt_rx_mpdu_encrypt_type type) -+ { -+ switch (type) { -+ case HTT_RX_MPDU_ENCRYPT_NONE: -++ return 0; -+ case HTT_RX_MPDU_ENCRYPT_WEP40: -+ case HTT_RX_MPDU_ENCRYPT_WEP104: -+- case HTT_RX_MPDU_ENCRYPT_WEP128: -+- case HTT_RX_MPDU_ENCRYPT_WAPI: -+- return 0; -++ return IEEE80211_WEP_ICV_LEN; -+ case HTT_RX_MPDU_ENCRYPT_TKIP_WITHOUT_MIC: -+ case HTT_RX_MPDU_ENCRYPT_TKIP_WPA: -+- return 4; -++ return IEEE80211_TKIP_ICV_LEN; -+ case HTT_RX_MPDU_ENCRYPT_AES_CCM_WPA2: -+- return 8; -++ return IEEE80211_CCMP_MIC_LEN; -++ case HTT_RX_MPDU_ENCRYPT_WEP128: -++ case HTT_RX_MPDU_ENCRYPT_WAPI: -++ break; -+ } -+ -+- ath10k_warn("unknown encryption type %d\n", type); -++ ath10k_warn(ar, "unsupported encryption type %d\n", type); -+ return 0; -+ } -+ -+-/* Applies for first msdu in chain, before altering it. */ -+-static struct ieee80211_hdr *ath10k_htt_rx_skb_get_hdr(struct sk_buff *skb) -+-{ -+- struct htt_rx_desc *rxd; -+- enum rx_msdu_decap_format fmt; -+- -+- rxd = (void *)skb->data - sizeof(*rxd); -+- fmt = MS(__le32_to_cpu(rxd->msdu_start.info1), -+- RX_MSDU_START_INFO1_DECAP_FORMAT); -+- -+- if (fmt == RX_MSDU_DECAP_RAW) -+- return (void *)skb->data; -+- else -+- return (void *)skb->data - RX_HTT_HDR_STATUS_LEN; -+-} -+- -+-/* This function only applies for first msdu in an msdu chain */ -+-static bool ath10k_htt_rx_hdr_is_amsdu(struct ieee80211_hdr *hdr) -+-{ -+- if (ieee80211_is_data_qos(hdr->frame_control)) { -+- u8 *qc = ieee80211_get_qos_ctl(hdr); -+- if (qc[0] & 0x80) -+- return true; -+- } -+- return false; -+-} -+- -+ struct rfc1042_hdr { -+ u8 llc_dsap; -+ u8 llc_ssap; -+@@ -660,23 +671,34 @@ static const u8 rx_legacy_rate_idx[] = { -+ }; -+ -+ static void ath10k_htt_rx_h_rates(struct ath10k *ar, -+- enum ieee80211_band band, -+- u8 info0, u32 info1, u32 info2, -+- struct ieee80211_rx_status *status) -++ struct ieee80211_rx_status *status, -++ struct htt_rx_desc *rxd) -+ { -++ enum ieee80211_band band; -+ u8 cck, rate, rate_idx, bw, sgi, mcs, nss; -+ u8 preamble = 0; -++ u32 info1, info2, info3; -+ -+- /* Check if valid fields */ -+- if (!(info0 & HTT_RX_INDICATION_INFO0_START_VALID)) -++ /* Band value can't be set as undefined but freq can be 0 - use that to -++ * determine whether band is provided. -++ * -++ * FIXME: Perhaps this can go away if CCK rate reporting is a little -++ * reworked? -++ */ -++ if (!status->freq) -+ return; -+ -+- preamble = MS(info1, HTT_RX_INDICATION_INFO1_PREAMBLE_TYPE); -++ band = status->band; -++ info1 = __le32_to_cpu(rxd->ppdu_start.info1); -++ info2 = __le32_to_cpu(rxd->ppdu_start.info2); -++ info3 = __le32_to_cpu(rxd->ppdu_start.info3); -++ -++ preamble = MS(info1, RX_PPDU_START_INFO1_PREAMBLE_TYPE); -+ -+ switch (preamble) { -+ case HTT_RX_LEGACY: -+- cck = info0 & HTT_RX_INDICATION_INFO0_LEGACY_RATE_CCK; -+- rate = MS(info0, HTT_RX_INDICATION_INFO0_LEGACY_RATE); -++ cck = info1 & RX_PPDU_START_INFO1_L_SIG_RATE_SELECT; -++ rate = MS(info1, RX_PPDU_START_INFO1_L_SIG_RATE); -+ rate_idx = 0; -+ -+ if (rate < 0x08 || rate > 0x0F) -+@@ -703,11 +725,11 @@ static void ath10k_htt_rx_h_rates(struct -+ break; -+ case HTT_RX_HT: -+ case HTT_RX_HT_WITH_TXBF: -+- /* HT-SIG - Table 20-11 in info1 and info2 */ -+- mcs = info1 & 0x1F; -++ /* HT-SIG - Table 20-11 in info2 and info3 */ -++ mcs = info2 & 0x1F; -+ nss = mcs >> 3; -+- bw = (info1 >> 7) & 1; -+- sgi = (info2 >> 7) & 1; -++ bw = (info2 >> 7) & 1; -++ sgi = (info3 >> 7) & 1; -+ -+ status->rate_idx = mcs; -+ status->flag |= RX_FLAG_HT; -+@@ -718,12 +740,12 @@ static void ath10k_htt_rx_h_rates(struct -+ break; -+ case HTT_RX_VHT: -+ case HTT_RX_VHT_WITH_TXBF: -+- /* VHT-SIG-A1 in info 1, VHT-SIG-A2 in info2 -++ /* VHT-SIG-A1 in info2, VHT-SIG-A2 in info3 -+ TODO check this */ -+- mcs = (info2 >> 4) & 0x0F; -+- nss = ((info1 >> 10) & 0x07) + 1; -+- bw = info1 & 3; -+- sgi = info2 & 1; -++ mcs = (info3 >> 4) & 0x0F; -++ nss = ((info2 >> 10) & 0x07) + 1; -++ bw = info2 & 3; -++ sgi = info3 & 1; -+ -+ status->rate_idx = mcs; -+ status->vht_nss = nss; -+@@ -751,28 +773,6 @@ static void ath10k_htt_rx_h_rates(struct -+ } -+ } -+ -+-static void ath10k_htt_rx_h_protected(struct ath10k_htt *htt, -+- struct ieee80211_rx_status *rx_status, -+- struct sk_buff *skb, -+- enum htt_rx_mpdu_encrypt_type enctype) -+-{ -+- struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; -+- -+- -+- if (enctype == HTT_RX_MPDU_ENCRYPT_NONE) { -+- rx_status->flag &= ~(RX_FLAG_DECRYPTED | -+- RX_FLAG_IV_STRIPPED | -+- RX_FLAG_MMIC_STRIPPED); -+- return; -+- } -+- -+- rx_status->flag |= RX_FLAG_DECRYPTED | -+- RX_FLAG_IV_STRIPPED | -+- RX_FLAG_MMIC_STRIPPED; -+- hdr->frame_control = __cpu_to_le16(__le16_to_cpu(hdr->frame_control) & -+- ~IEEE80211_FCTL_PROTECTED); -+-} -+- -+ static bool ath10k_htt_rx_h_channel(struct ath10k *ar, -+ struct ieee80211_rx_status *status) -+ { -+@@ -793,19 +793,121 @@ static bool ath10k_htt_rx_h_channel(stru -+ return true; -+ } -+ -++static void ath10k_htt_rx_h_signal(struct ath10k *ar, -++ struct ieee80211_rx_status *status, -++ struct htt_rx_desc *rxd) -++{ -++ /* FIXME: Get real NF */ -++ status->signal = ATH10K_DEFAULT_NOISE_FLOOR + -++ rxd->ppdu_start.rssi_comb; -++ status->flag &= ~RX_FLAG_NO_SIGNAL_VAL; -++} -++ -++static void ath10k_htt_rx_h_mactime(struct ath10k *ar, -++ struct ieee80211_rx_status *status, -++ struct htt_rx_desc *rxd) -++{ -++ /* FIXME: TSF is known only at the end of PPDU, in the last MPDU. This -++ * means all prior MSDUs in a PPDU are reported to mac80211 without the -++ * TSF. Is it worth holding frames until end of PPDU is known? -++ * -++ * FIXME: Can we get/compute 64bit TSF? -++ */ -++ status->mactime = __le32_to_cpu(rxd->ppdu_end.common.tsf_timestamp); -++ status->flag |= RX_FLAG_MACTIME_END; -++} -++ -++static void ath10k_htt_rx_h_ppdu(struct ath10k *ar, -++ struct sk_buff_head *amsdu, -++ struct ieee80211_rx_status *status) -++{ -++ struct sk_buff *first; -++ struct htt_rx_desc *rxd; -++ bool is_first_ppdu; -++ bool is_last_ppdu; -++ -++ if (skb_queue_empty(amsdu)) -++ return; -++ -++ first = skb_peek(amsdu); -++ rxd = (void *)first->data - sizeof(*rxd); -++ -++ is_first_ppdu = !!(rxd->attention.flags & -++ __cpu_to_le32(RX_ATTENTION_FLAGS_FIRST_MPDU)); -++ is_last_ppdu = !!(rxd->attention.flags & -++ __cpu_to_le32(RX_ATTENTION_FLAGS_LAST_MPDU)); -++ -++ if (is_first_ppdu) { -++ /* New PPDU starts so clear out the old per-PPDU status. */ -++ status->freq = 0; -++ status->rate_idx = 0; -++ status->vht_nss = 0; -++ status->vht_flag &= ~RX_VHT_FLAG_80MHZ; -++ status->flag &= ~(RX_FLAG_HT | -++ RX_FLAG_VHT | -++ RX_FLAG_SHORT_GI | -++ RX_FLAG_40MHZ | -++ RX_FLAG_MACTIME_END); -++ status->flag |= RX_FLAG_NO_SIGNAL_VAL; -++ -++ ath10k_htt_rx_h_signal(ar, status, rxd); -++ ath10k_htt_rx_h_channel(ar, status); -++ ath10k_htt_rx_h_rates(ar, status, rxd); -++ } -++ -++ if (is_last_ppdu) -++ ath10k_htt_rx_h_mactime(ar, status, rxd); -++} -++ -++static const char * const tid_to_ac[] = { -++ "BE", -++ "BK", -++ "BK", -++ "BE", -++ "VI", -++ "VI", -++ "VO", -++ "VO", -++}; -++ -++static char *ath10k_get_tid(struct ieee80211_hdr *hdr, char *out, size_t size) -++{ -++ u8 *qc; -++ int tid; -++ -++ if (!ieee80211_is_data_qos(hdr->frame_control)) -++ return ""; -++ -++ qc = ieee80211_get_qos_ctl(hdr); -++ tid = *qc & IEEE80211_QOS_CTL_TID_MASK; -++ if (tid < 8) -++ snprintf(out, size, "tid %d (%s)", tid, tid_to_ac[tid]); -++ else -++ snprintf(out, size, "tid %d", tid); -++ -++ return out; -++} -++ -+ static void ath10k_process_rx(struct ath10k *ar, -+ struct ieee80211_rx_status *rx_status, -+ struct sk_buff *skb) -+ { -+ struct ieee80211_rx_status *status; -++ struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; -++ char tid[32]; -+ -+ status = IEEE80211_SKB_RXCB(skb); -+ *status = *rx_status; -+ -+- ath10k_dbg(ATH10K_DBG_DATA, -+- "rx skb %p len %u %s%s%s%s%s %srate_idx %u vht_nss %u freq %u band %u flag 0x%x fcs-err %imic-err %i\n", -++ ath10k_dbg(ar, ATH10K_DBG_DATA, -++ "rx skb %p len %u peer %pM %s %s sn %u %s%s%s%s%s %srate_idx %u vht_nss %u freq %u band %u flag 0x%x fcs-err %i mic-err %i amsdu-more %i\n", -+ skb, -+ skb->len, -++ ieee80211_get_SA(hdr), -++ ath10k_get_tid(hdr, tid, sizeof(tid)), -++ is_multicast_ether_addr(ieee80211_get_DA(hdr)) ? -++ "mcast" : "ucast", -++ (__le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_SEQ) >> 4, -+ status->flag == 0 ? "legacy" : "", -+ status->flag & RX_FLAG_HT ? "ht" : "", -+ status->flag & RX_FLAG_VHT ? "vht" : "", -+@@ -817,9 +919,12 @@ static void ath10k_process_rx(struct ath -+ status->freq, -+ status->band, status->flag, -+ !!(status->flag & RX_FLAG_FAILED_FCS_CRC), -+- !!(status->flag & RX_FLAG_MMIC_ERROR)); -+- ath10k_dbg_dump(ATH10K_DBG_HTT_DUMP, NULL, "rx skb: ", -++ !!(status->flag & RX_FLAG_MMIC_ERROR), -++ !!(status->flag & RX_FLAG_AMSDU_MORE)); -++ ath10k_dbg_dump(ar, ATH10K_DBG_HTT_DUMP, NULL, "rx skb: ", -+ skb->data, skb->len); -++ trace_ath10k_rx_hdr(ar, skb->data, skb->len); -++ trace_ath10k_rx_payload(ar, skb->data, skb->len); -+ -+ ieee80211_rx(ar->hw, skb); -+ } -+@@ -830,179 +935,263 @@ static int ath10k_htt_rx_nwifi_hdrlen(st -+ return round_up(ieee80211_hdrlen(hdr->frame_control), 4); -+ } -+ -+-static void ath10k_htt_rx_amsdu(struct ath10k_htt *htt, -+- struct ieee80211_rx_status *rx_status, -+- struct sk_buff *skb_in) -++static void ath10k_htt_rx_h_undecap_raw(struct ath10k *ar, -++ struct sk_buff *msdu, -++ struct ieee80211_rx_status *status, -++ enum htt_rx_mpdu_encrypt_type enctype, -++ bool is_decrypted) -+ { -++ struct ieee80211_hdr *hdr; -+ struct htt_rx_desc *rxd; -+- struct sk_buff *skb = skb_in; -+- struct sk_buff *first; -+- enum rx_msdu_decap_format fmt; -+- enum htt_rx_mpdu_encrypt_type enctype; -++ size_t hdr_len; -++ size_t crypto_len; -++ bool is_first; -++ bool is_last; -++ -++ rxd = (void *)msdu->data - sizeof(*rxd); -++ is_first = !!(rxd->msdu_end.info0 & -++ __cpu_to_le32(RX_MSDU_END_INFO0_FIRST_MSDU)); -++ is_last = !!(rxd->msdu_end.info0 & -++ __cpu_to_le32(RX_MSDU_END_INFO0_LAST_MSDU)); -++ -++ /* Delivered decapped frame: -++ * [802.11 header] -++ * [crypto param] <-- can be trimmed if !fcs_err && -++ * !decrypt_err && !peer_idx_invalid -++ * [amsdu header] <-- only if A-MSDU -++ * [rfc1042/llc] -++ * [payload] -++ * [FCS] <-- at end, needs to be trimmed -++ */ -++ -++ /* This probably shouldn't happen but warn just in case */ -++ if (unlikely(WARN_ON_ONCE(!is_first))) -++ return; -++ -++ /* This probably shouldn't happen but warn just in case */ -++ if (unlikely(WARN_ON_ONCE(!(is_first && is_last)))) -++ return; -++ -++ skb_trim(msdu, msdu->len - FCS_LEN); -++ -++ /* In most cases this will be true for sniffed frames. It makes sense -++ * to deliver them as-is without stripping the crypto param. This would -++ * also make sense for software based decryption (which is not -++ * implemented in ath10k). -++ * -++ * If there's no error then the frame is decrypted. At least that is -++ * the case for frames that come in via fragmented rx indication. -++ */ -++ if (!is_decrypted) -++ return; -++ -++ /* The payload is decrypted so strip crypto params. Start from tail -++ * since hdr is used to compute some stuff. -++ */ -++ -++ hdr = (void *)msdu->data; -++ -++ /* Tail */ -++ skb_trim(msdu, msdu->len - ath10k_htt_rx_crypto_tail_len(ar, enctype)); -++ -++ /* MMIC */ -++ if (!ieee80211_has_morefrags(hdr->frame_control) && -++ enctype == HTT_RX_MPDU_ENCRYPT_TKIP_WPA) -++ skb_trim(msdu, msdu->len - 8); -++ -++ /* Head */ -++ hdr_len = ieee80211_hdrlen(hdr->frame_control); -++ crypto_len = ath10k_htt_rx_crypto_param_len(ar, enctype); -++ -++ memmove((void *)msdu->data + crypto_len, -++ (void *)msdu->data, hdr_len); -++ skb_pull(msdu, crypto_len); -++} -++ -++static void ath10k_htt_rx_h_undecap_nwifi(struct ath10k *ar, -++ struct sk_buff *msdu, -++ struct ieee80211_rx_status *status, -++ const u8 first_hdr[64]) -++{ -+ struct ieee80211_hdr *hdr; -+- u8 hdr_buf[64], addr[ETH_ALEN], *qos; -+- unsigned int hdr_len; -++ size_t hdr_len; -++ u8 da[ETH_ALEN]; -++ u8 sa[ETH_ALEN]; -++ -++ /* Delivered decapped frame: -++ * [nwifi 802.11 header] <-- replaced with 802.11 hdr -++ * [rfc1042/llc] -++ * -++ * Note: The nwifi header doesn't have QoS Control and is -++ * (always?) a 3addr frame. -++ * -++ * Note2: There's no A-MSDU subframe header. Even if it's part -++ * of an A-MSDU. -++ */ -+ -+- rxd = (void *)skb->data - sizeof(*rxd); -+- enctype = MS(__le32_to_cpu(rxd->mpdu_start.info0), -+- RX_MPDU_START_INFO0_ENCRYPT_TYPE); -++ /* pull decapped header and copy SA & DA */ -++ hdr = (struct ieee80211_hdr *)msdu->data; -++ hdr_len = ath10k_htt_rx_nwifi_hdrlen(hdr); -++ ether_addr_copy(da, ieee80211_get_DA(hdr)); -++ ether_addr_copy(sa, ieee80211_get_SA(hdr)); -++ skb_pull(msdu, hdr_len); -+ -+- hdr = (struct ieee80211_hdr *)rxd->rx_hdr_status; -++ /* push original 802.11 header */ -++ hdr = (struct ieee80211_hdr *)first_hdr; -+ hdr_len = ieee80211_hdrlen(hdr->frame_control); -+- memcpy(hdr_buf, hdr, hdr_len); -+- hdr = (struct ieee80211_hdr *)hdr_buf; -++ memcpy(skb_push(msdu, hdr_len), hdr, hdr_len); -+ -+- first = skb; -+- while (skb) { -+- void *decap_hdr; -+- int len; -+- -+- rxd = (void *)skb->data - sizeof(*rxd); -+- fmt = MS(__le32_to_cpu(rxd->msdu_start.info1), -+- RX_MSDU_START_INFO1_DECAP_FORMAT); -+- decap_hdr = (void *)rxd->rx_hdr_status; -+- -+- skb->ip_summed = ath10k_htt_rx_get_csum_state(skb); -+- -+- /* First frame in an A-MSDU chain has more decapped data. */ -+- if (skb == first) { -+- len = round_up(ieee80211_hdrlen(hdr->frame_control), 4); -+- len += round_up(ath10k_htt_rx_crypto_param_len(enctype), -+- 4); -+- decap_hdr += len; -+- } -++ /* original 802.11 header has a different DA and in -++ * case of 4addr it may also have different SA -++ */ -++ hdr = (struct ieee80211_hdr *)msdu->data; -++ ether_addr_copy(ieee80211_get_DA(hdr), da); -++ ether_addr_copy(ieee80211_get_SA(hdr), sa); -++} -+ -+- switch (fmt) { -+- case RX_MSDU_DECAP_RAW: -+- /* remove trailing FCS */ -+- skb_trim(skb, skb->len - FCS_LEN); -+- break; -+- case RX_MSDU_DECAP_NATIVE_WIFI: -+- /* pull decapped header and copy DA */ -+- hdr = (struct ieee80211_hdr *)skb->data; -+- hdr_len = ath10k_htt_rx_nwifi_hdrlen(hdr); -+- memcpy(addr, ieee80211_get_DA(hdr), ETH_ALEN); -+- skb_pull(skb, hdr_len); -+- -+- /* push original 802.11 header */ -+- hdr = (struct ieee80211_hdr *)hdr_buf; -+- hdr_len = ieee80211_hdrlen(hdr->frame_control); -+- memcpy(skb_push(skb, hdr_len), hdr, hdr_len); -+- -+- /* original A-MSDU header has the bit set but we're -+- * not including A-MSDU subframe header */ -+- hdr = (struct ieee80211_hdr *)skb->data; -+- qos = ieee80211_get_qos_ctl(hdr); -+- qos[0] &= ~IEEE80211_QOS_CTL_A_MSDU_PRESENT; -++static void *ath10k_htt_rx_h_find_rfc1042(struct ath10k *ar, -++ struct sk_buff *msdu, -++ enum htt_rx_mpdu_encrypt_type enctype) -++{ -++ struct ieee80211_hdr *hdr; -++ struct htt_rx_desc *rxd; -++ size_t hdr_len, crypto_len; -++ void *rfc1042; -++ bool is_first, is_last, is_amsdu; -+ -+- /* original 802.11 header has a different DA */ -+- memcpy(ieee80211_get_DA(hdr), addr, ETH_ALEN); -+- break; -+- case RX_MSDU_DECAP_ETHERNET2_DIX: -+- /* strip ethernet header and insert decapped 802.11 -+- * header, amsdu subframe header and rfc1042 header */ -+- -+- len = 0; -+- len += sizeof(struct rfc1042_hdr); -+- len += sizeof(struct amsdu_subframe_hdr); -+- -+- skb_pull(skb, sizeof(struct ethhdr)); -+- memcpy(skb_push(skb, len), decap_hdr, len); -+- memcpy(skb_push(skb, hdr_len), hdr, hdr_len); -+- break; -+- case RX_MSDU_DECAP_8023_SNAP_LLC: -+- /* insert decapped 802.11 header making a singly -+- * A-MSDU */ -+- memcpy(skb_push(skb, hdr_len), hdr, hdr_len); -+- break; -+- } -++ rxd = (void *)msdu->data - sizeof(*rxd); -++ hdr = (void *)rxd->rx_hdr_status; -+ -+- skb_in = skb; -+- ath10k_htt_rx_h_protected(htt, rx_status, skb_in, enctype); -+- skb = skb->next; -+- skb_in->next = NULL; -++ is_first = !!(rxd->msdu_end.info0 & -++ __cpu_to_le32(RX_MSDU_END_INFO0_FIRST_MSDU)); -++ is_last = !!(rxd->msdu_end.info0 & -++ __cpu_to_le32(RX_MSDU_END_INFO0_LAST_MSDU)); -++ is_amsdu = !(is_first && is_last); -+ -+- if (skb) -+- rx_status->flag |= RX_FLAG_AMSDU_MORE; -+- else -+- rx_status->flag &= ~RX_FLAG_AMSDU_MORE; -++ rfc1042 = hdr; -++ -++ if (is_first) { -++ hdr_len = ieee80211_hdrlen(hdr->frame_control); -++ crypto_len = ath10k_htt_rx_crypto_param_len(ar, enctype); -+ -+- ath10k_process_rx(htt->ar, rx_status, skb_in); -++ rfc1042 += round_up(hdr_len, 4) + -++ round_up(crypto_len, 4); -+ } -+ -+- /* FIXME: It might be nice to re-assemble the A-MSDU when there's a -+- * monitor interface active for sniffing purposes. */ -++ if (is_amsdu) -++ rfc1042 += sizeof(struct amsdu_subframe_hdr); -++ -++ return rfc1042; -+ } -+ -+-static void ath10k_htt_rx_msdu(struct ath10k_htt *htt, -+- struct ieee80211_rx_status *rx_status, -+- struct sk_buff *skb) -++static void ath10k_htt_rx_h_undecap_eth(struct ath10k *ar, -++ struct sk_buff *msdu, -++ struct ieee80211_rx_status *status, -++ const u8 first_hdr[64], -++ enum htt_rx_mpdu_encrypt_type enctype) -+ { -+- struct htt_rx_desc *rxd; -+ struct ieee80211_hdr *hdr; -+- enum rx_msdu_decap_format fmt; -+- enum htt_rx_mpdu_encrypt_type enctype; -+- int hdr_len; -++ struct ethhdr *eth; -++ size_t hdr_len; -+ void *rfc1042; -++ u8 da[ETH_ALEN]; -++ u8 sa[ETH_ALEN]; -+ -+- /* This shouldn't happen. If it does than it may be a FW bug. */ -+- if (skb->next) { -+- ath10k_warn("htt rx received chained non A-MSDU frame\n"); -+- ath10k_htt_rx_free_msdu_chain(skb->next); -+- skb->next = NULL; -+- } -++ /* Delivered decapped frame: -++ * [eth header] <-- replaced with 802.11 hdr & rfc1042/llc -++ * [payload] -++ */ -+ -+- rxd = (void *)skb->data - sizeof(*rxd); -+- fmt = MS(__le32_to_cpu(rxd->msdu_start.info1), -+- RX_MSDU_START_INFO1_DECAP_FORMAT); -+- enctype = MS(__le32_to_cpu(rxd->mpdu_start.info0), -+- RX_MPDU_START_INFO0_ENCRYPT_TYPE); -+- hdr = (struct ieee80211_hdr *)rxd->rx_hdr_status; -++ rfc1042 = ath10k_htt_rx_h_find_rfc1042(ar, msdu, enctype); -++ if (WARN_ON_ONCE(!rfc1042)) -++ return; -++ -++ /* pull decapped header and copy SA & DA */ -++ eth = (struct ethhdr *)msdu->data; -++ ether_addr_copy(da, eth->h_dest); -++ ether_addr_copy(sa, eth->h_source); -++ skb_pull(msdu, sizeof(struct ethhdr)); -++ -++ /* push rfc1042/llc/snap */ -++ memcpy(skb_push(msdu, sizeof(struct rfc1042_hdr)), rfc1042, -++ sizeof(struct rfc1042_hdr)); -++ -++ /* push original 802.11 header */ -++ hdr = (struct ieee80211_hdr *)first_hdr; -+ hdr_len = ieee80211_hdrlen(hdr->frame_control); -++ memcpy(skb_push(msdu, hdr_len), hdr, hdr_len); -++ -++ /* original 802.11 header has a different DA and in -++ * case of 4addr it may also have different SA -++ */ -++ hdr = (struct ieee80211_hdr *)msdu->data; -++ ether_addr_copy(ieee80211_get_DA(hdr), da); -++ ether_addr_copy(ieee80211_get_SA(hdr), sa); -++} -++ -++static void ath10k_htt_rx_h_undecap_snap(struct ath10k *ar, -++ struct sk_buff *msdu, -++ struct ieee80211_rx_status *status, -++ const u8 first_hdr[64]) -++{ -++ struct ieee80211_hdr *hdr; -++ size_t hdr_len; -++ -++ /* Delivered decapped frame: -++ * [amsdu header] <-- replaced with 802.11 hdr -++ * [rfc1042/llc] -++ * [payload] -++ */ -++ -++ skb_pull(msdu, sizeof(struct amsdu_subframe_hdr)); -++ -++ hdr = (struct ieee80211_hdr *)first_hdr; -++ hdr_len = ieee80211_hdrlen(hdr->frame_control); -++ memcpy(skb_push(msdu, hdr_len), hdr, hdr_len); -++} -++ -++static void ath10k_htt_rx_h_undecap(struct ath10k *ar, -++ struct sk_buff *msdu, -++ struct ieee80211_rx_status *status, -++ u8 first_hdr[64], -++ enum htt_rx_mpdu_encrypt_type enctype, -++ bool is_decrypted) -++{ -++ struct htt_rx_desc *rxd; -++ enum rx_msdu_decap_format decap; -++ struct ieee80211_hdr *hdr; -++ -++ /* First msdu's decapped header: -++ * [802.11 header] <-- padded to 4 bytes long -++ * [crypto param] <-- padded to 4 bytes long -++ * [amsdu header] <-- only if A-MSDU -++ * [rfc1042/llc] -++ * -++ * Other (2nd, 3rd, ..) msdu's decapped header: -++ * [amsdu header] <-- only if A-MSDU -++ * [rfc1042/llc] -++ */ -+ -+- skb->ip_summed = ath10k_htt_rx_get_csum_state(skb); -++ rxd = (void *)msdu->data - sizeof(*rxd); -++ hdr = (void *)rxd->rx_hdr_status; -++ decap = MS(__le32_to_cpu(rxd->msdu_start.info1), -++ RX_MSDU_START_INFO1_DECAP_FORMAT); -+ -+- switch (fmt) { -++ switch (decap) { -+ case RX_MSDU_DECAP_RAW: -+- /* remove trailing FCS */ -+- skb_trim(skb, skb->len - FCS_LEN); -++ ath10k_htt_rx_h_undecap_raw(ar, msdu, status, enctype, -++ is_decrypted); -+ break; -+ case RX_MSDU_DECAP_NATIVE_WIFI: -+- /* Pull decapped header */ -+- hdr = (struct ieee80211_hdr *)skb->data; -+- hdr_len = ath10k_htt_rx_nwifi_hdrlen(hdr); -+- skb_pull(skb, hdr_len); -+- -+- /* Push original header */ -+- hdr = (struct ieee80211_hdr *)rxd->rx_hdr_status; -+- hdr_len = ieee80211_hdrlen(hdr->frame_control); -+- memcpy(skb_push(skb, hdr_len), hdr, hdr_len); -++ ath10k_htt_rx_h_undecap_nwifi(ar, msdu, status, first_hdr); -+ break; -+ case RX_MSDU_DECAP_ETHERNET2_DIX: -+- /* strip ethernet header and insert decapped 802.11 header and -+- * rfc1042 header */ -+- -+- rfc1042 = hdr; -+- rfc1042 += roundup(hdr_len, 4); -+- rfc1042 += roundup(ath10k_htt_rx_crypto_param_len(enctype), 4); -+- -+- skb_pull(skb, sizeof(struct ethhdr)); -+- memcpy(skb_push(skb, sizeof(struct rfc1042_hdr)), -+- rfc1042, sizeof(struct rfc1042_hdr)); -+- memcpy(skb_push(skb, hdr_len), hdr, hdr_len); -++ ath10k_htt_rx_h_undecap_eth(ar, msdu, status, first_hdr, enctype); -+ break; -+ case RX_MSDU_DECAP_8023_SNAP_LLC: -+- /* remove A-MSDU subframe header and insert -+- * decapped 802.11 header. rfc1042 header is already there */ -+- -+- skb_pull(skb, sizeof(struct amsdu_subframe_hdr)); -+- memcpy(skb_push(skb, hdr_len), hdr, hdr_len); -++ ath10k_htt_rx_h_undecap_snap(ar, msdu, status, first_hdr); -+ break; -+ } -+- -+- ath10k_htt_rx_h_protected(htt, rx_status, skb, enctype); -+- -+- ath10k_process_rx(htt->ar, rx_status, skb); -+ } -+ -+ static int ath10k_htt_rx_get_csum_state(struct sk_buff *skb) -+@@ -1036,10 +1225,128 @@ static int ath10k_htt_rx_get_csum_state( -+ return CHECKSUM_UNNECESSARY; -+ } -+ -+-static int ath10k_unchain_msdu(struct sk_buff *msdu_head) -++static void ath10k_htt_rx_h_csum_offload(struct sk_buff *msdu) -++{ -++ msdu->ip_summed = ath10k_htt_rx_get_csum_state(msdu); -++} -++ -++static void ath10k_htt_rx_h_mpdu(struct ath10k *ar, -++ struct sk_buff_head *amsdu, -++ struct ieee80211_rx_status *status) -++{ -++ struct sk_buff *first; -++ struct sk_buff *last; -++ struct sk_buff *msdu; -++ struct htt_rx_desc *rxd; -++ struct ieee80211_hdr *hdr; -++ enum htt_rx_mpdu_encrypt_type enctype; -++ u8 first_hdr[64]; -++ u8 *qos; -++ size_t hdr_len; -++ bool has_fcs_err; -++ bool has_crypto_err; -++ bool has_tkip_err; -++ bool has_peer_idx_invalid; -++ bool is_decrypted; -++ u32 attention; -++ -++ if (skb_queue_empty(amsdu)) -++ return; -++ -++ first = skb_peek(amsdu); -++ rxd = (void *)first->data - sizeof(*rxd); -++ -++ enctype = MS(__le32_to_cpu(rxd->mpdu_start.info0), -++ RX_MPDU_START_INFO0_ENCRYPT_TYPE); -++ -++ /* First MSDU's Rx descriptor in an A-MSDU contains full 802.11 -++ * decapped header. It'll be used for undecapping of each MSDU. -++ */ -++ hdr = (void *)rxd->rx_hdr_status; -++ hdr_len = ieee80211_hdrlen(hdr->frame_control); -++ memcpy(first_hdr, hdr, hdr_len); -++ -++ /* Each A-MSDU subframe will use the original header as the base and be -++ * reported as a separate MSDU so strip the A-MSDU bit from QoS Ctl. -++ */ -++ hdr = (void *)first_hdr; -++ qos = ieee80211_get_qos_ctl(hdr); -++ qos[0] &= ~IEEE80211_QOS_CTL_A_MSDU_PRESENT; -++ -++ /* Some attention flags are valid only in the last MSDU. */ -++ last = skb_peek_tail(amsdu); -++ rxd = (void *)last->data - sizeof(*rxd); -++ attention = __le32_to_cpu(rxd->attention.flags); -++ -++ has_fcs_err = !!(attention & RX_ATTENTION_FLAGS_FCS_ERR); -++ has_crypto_err = !!(attention & RX_ATTENTION_FLAGS_DECRYPT_ERR); -++ has_tkip_err = !!(attention & RX_ATTENTION_FLAGS_TKIP_MIC_ERR); -++ has_peer_idx_invalid = !!(attention & RX_ATTENTION_FLAGS_PEER_IDX_INVALID); -++ -++ /* Note: If hardware captures an encrypted frame that it can't decrypt, -++ * e.g. due to fcs error, missing peer or invalid key data it will -++ * report the frame as raw. -++ */ -++ is_decrypted = (enctype != HTT_RX_MPDU_ENCRYPT_NONE && -++ !has_fcs_err && -++ !has_crypto_err && -++ !has_peer_idx_invalid); -++ -++ /* Clear per-MPDU flags while leaving per-PPDU flags intact. */ -++ status->flag &= ~(RX_FLAG_FAILED_FCS_CRC | -++ RX_FLAG_MMIC_ERROR | -++ RX_FLAG_DECRYPTED | -++ RX_FLAG_IV_STRIPPED | -++ RX_FLAG_MMIC_STRIPPED); -++ -++ if (has_fcs_err) -++ status->flag |= RX_FLAG_FAILED_FCS_CRC; -++ -++ if (has_tkip_err) -++ status->flag |= RX_FLAG_MMIC_ERROR; -++ -++ if (is_decrypted) -++ status->flag |= RX_FLAG_DECRYPTED | -++ RX_FLAG_IV_STRIPPED | -++ RX_FLAG_MMIC_STRIPPED; -++ -++ skb_queue_walk(amsdu, msdu) { -++ ath10k_htt_rx_h_csum_offload(msdu); -++ ath10k_htt_rx_h_undecap(ar, msdu, status, first_hdr, enctype, -++ is_decrypted); -++ -++ /* Undecapping involves copying the original 802.11 header back -++ * to sk_buff. If frame is protected and hardware has decrypted -++ * it then remove the protected bit. -++ */ -++ if (!is_decrypted) -++ continue; -++ -++ hdr = (void *)msdu->data; -++ hdr->frame_control &= ~__cpu_to_le16(IEEE80211_FCTL_PROTECTED); -++ } -++} -++ -++static void ath10k_htt_rx_h_deliver(struct ath10k *ar, -++ struct sk_buff_head *amsdu, -++ struct ieee80211_rx_status *status) -++{ -++ struct sk_buff *msdu; -++ -++ while ((msdu = __skb_dequeue(amsdu))) { -++ /* Setup per-MSDU flags */ -++ if (skb_queue_empty(amsdu)) -++ status->flag &= ~RX_FLAG_AMSDU_MORE; -++ else -++ status->flag |= RX_FLAG_AMSDU_MORE; -++ -++ ath10k_process_rx(ar, status, msdu); -++ } -++} -++ -++static int ath10k_unchain_msdu(struct sk_buff_head *amsdu) -+ { -+- struct sk_buff *next = msdu_head->next; -+- struct sk_buff *to_free = next; -++ struct sk_buff *skb, *first; -+ int space; -+ int total_len = 0; -+ -+@@ -1050,110 +1357,142 @@ static int ath10k_unchain_msdu(struct sk -+ * skb? -+ */ -+ -+- msdu_head->next = NULL; -++ first = __skb_dequeue(amsdu); -+ -+ /* Allocate total length all at once. */ -+- while (next) { -+- total_len += next->len; -+- next = next->next; -+- } -++ skb_queue_walk(amsdu, skb) -++ total_len += skb->len; -+ -+- space = total_len - skb_tailroom(msdu_head); -++ space = total_len - skb_tailroom(first); -+ if ((space > 0) && -+- (pskb_expand_head(msdu_head, 0, space, GFP_ATOMIC) < 0)) { -++ (pskb_expand_head(first, 0, space, GFP_ATOMIC) < 0)) { -+ /* TODO: bump some rx-oom error stat */ -+ /* put it back together so we can free the -+ * whole list at once. -+ */ -+- msdu_head->next = to_free; -++ __skb_queue_head(amsdu, first); -+ return -1; -+ } -+ -+ /* Walk list again, copying contents into -+ * msdu_head -+ */ -+- next = to_free; -+- while (next) { -+- skb_copy_from_linear_data(next, skb_put(msdu_head, next->len), -+- next->len); -+- next = next->next; -++ while ((skb = __skb_dequeue(amsdu))) { -++ skb_copy_from_linear_data(skb, skb_put(first, skb->len), -++ skb->len); -++ dev_kfree_skb_any(skb); -+ } -+ -+- /* If here, we have consolidated skb. Free the -+- * fragments and pass the main skb on up the -+- * stack. -+- */ -+- ath10k_htt_rx_free_msdu_chain(to_free); -++ __skb_queue_head(amsdu, first); -+ return 0; -+ } -+ -+-static bool ath10k_htt_rx_amsdu_allowed(struct ath10k_htt *htt, -+- struct sk_buff *head, -+- enum htt_rx_mpdu_status status, -+- bool channel_set, -+- u32 attention) -+-{ -+- if (head->len == 0) { -+- ath10k_dbg(ATH10K_DBG_HTT, -+- "htt rx dropping due to zero-len\n"); -+- return false; -+- } -++static void ath10k_htt_rx_h_unchain(struct ath10k *ar, -++ struct sk_buff_head *amsdu, -++ bool chained) -++{ -++ struct sk_buff *first; -++ struct htt_rx_desc *rxd; -++ enum rx_msdu_decap_format decap; -+ -+- if (attention & RX_ATTENTION_FLAGS_DECRYPT_ERR) { -+- ath10k_dbg(ATH10K_DBG_HTT, -+- "htt rx dropping due to decrypt-err\n"); -+- return false; -+- } -++ first = skb_peek(amsdu); -++ rxd = (void *)first->data - sizeof(*rxd); -++ decap = MS(__le32_to_cpu(rxd->msdu_start.info1), -++ RX_MSDU_START_INFO1_DECAP_FORMAT); -+ -+- if (!channel_set) { -+- ath10k_warn("no channel configured; ignoring frame!\n"); -+- return false; -++ if (!chained) -++ return; -++ -++ /* FIXME: Current unchaining logic can only handle simple case of raw -++ * msdu chaining. If decapping is other than raw the chaining may be -++ * more complex and this isn't handled by the current code. Don't even -++ * try re-constructing such frames - it'll be pretty much garbage. -++ */ -++ if (decap != RX_MSDU_DECAP_RAW || -++ skb_queue_len(amsdu) != 1 + rxd->frag_info.ring2_more_count) { -++ __skb_queue_purge(amsdu); -++ return; -+ } -+ -+- /* Skip mgmt frames while we handle this in WMI */ -+- if (status == HTT_RX_IND_MPDU_STATUS_MGMT_CTRL || -+- attention & RX_ATTENTION_FLAGS_MGMT_TYPE) { -+- ath10k_dbg(ATH10K_DBG_HTT, "htt rx mgmt ctrl\n"); -++ ath10k_unchain_msdu(amsdu); -++} -++ -++static bool ath10k_htt_rx_amsdu_allowed(struct ath10k *ar, -++ struct sk_buff_head *amsdu, -++ struct ieee80211_rx_status *rx_status) -++{ -++ struct sk_buff *msdu; -++ struct htt_rx_desc *rxd; -++ bool is_mgmt; -++ bool has_fcs_err; -++ -++ msdu = skb_peek(amsdu); -++ rxd = (void *)msdu->data - sizeof(*rxd); -++ -++ /* FIXME: It might be a good idea to do some fuzzy-testing to drop -++ * invalid/dangerous frames. -++ */ -++ -++ if (!rx_status->freq) { -++ ath10k_warn(ar, "no channel configured; ignoring frame(s)!\n"); -+ return false; -+ } -+ -+- if (status != HTT_RX_IND_MPDU_STATUS_OK && -+- status != HTT_RX_IND_MPDU_STATUS_TKIP_MIC_ERR && -+- status != HTT_RX_IND_MPDU_STATUS_ERR_INV_PEER && -+- !htt->ar->monitor_started) { -+- ath10k_dbg(ATH10K_DBG_HTT, -+- "htt rx ignoring frame w/ status %d\n", -+- status); -++ is_mgmt = !!(rxd->attention.flags & -++ __cpu_to_le32(RX_ATTENTION_FLAGS_MGMT_TYPE)); -++ has_fcs_err = !!(rxd->attention.flags & -++ __cpu_to_le32(RX_ATTENTION_FLAGS_FCS_ERR)); -++ -++ /* Management frames are handled via WMI events. The pros of such -++ * approach is that channel is explicitly provided in WMI events -++ * whereas HTT doesn't provide channel information for Rxed frames. -++ * -++ * However some firmware revisions don't report corrupted frames via -++ * WMI so don't drop them. -++ */ -++ if (is_mgmt && !has_fcs_err) { -++ ath10k_dbg(ar, ATH10K_DBG_HTT, "htt rx mgmt ctrl\n"); -+ return false; -+ } -+ -+- if (test_bit(ATH10K_CAC_RUNNING, &htt->ar->dev_flags)) { -+- ath10k_dbg(ATH10K_DBG_HTT, -+- "htt rx CAC running\n"); -++ if (test_bit(ATH10K_CAC_RUNNING, &ar->dev_flags)) { -++ ath10k_dbg(ar, ATH10K_DBG_HTT, "htt rx cac running\n"); -+ return false; -+ } -+ -+ return true; -+ } -+ -++static void ath10k_htt_rx_h_filter(struct ath10k *ar, -++ struct sk_buff_head *amsdu, -++ struct ieee80211_rx_status *rx_status) -++{ -++ if (skb_queue_empty(amsdu)) -++ return; -++ -++ if (ath10k_htt_rx_amsdu_allowed(ar, amsdu, rx_status)) -++ return; -++ -++ __skb_queue_purge(amsdu); -++} -++ -+ static void ath10k_htt_rx_handler(struct ath10k_htt *htt, -+ struct htt_rx_indication *rx) -+ { -++ struct ath10k *ar = htt->ar; -+ struct ieee80211_rx_status *rx_status = &htt->rx_status; -+ struct htt_rx_indication_mpdu_range *mpdu_ranges; -+- struct htt_rx_desc *rxd; -+- enum htt_rx_mpdu_status status; -+- struct ieee80211_hdr *hdr; -++ struct sk_buff_head amsdu; -+ int num_mpdu_ranges; -+- u32 attention; -+ int fw_desc_len; -+ u8 *fw_desc; -+- bool channel_set; -+- int i, j; -+- int ret; -++ int i, ret, mpdu_count = 0; -+ -+ lockdep_assert_held(&htt->rx_ring.lock); -+ -++ if (htt->rx_confused) -++ return; -++ -+ fw_desc_len = __le16_to_cpu(rx->prefix.fw_rx_desc_bytes); -+ fw_desc = (u8 *)&rx->fw_desc; -+ -+@@ -1161,201 +1500,82 @@ static void ath10k_htt_rx_handler(struct -+ HTT_RX_INDICATION_INFO1_NUM_MPDU_RANGES); -+ mpdu_ranges = htt_rx_ind_get_mpdu_ranges(rx); -+ -+- /* Fill this once, while this is per-ppdu */ -+- if (rx->ppdu.info0 & HTT_RX_INDICATION_INFO0_START_VALID) { -+- memset(rx_status, 0, sizeof(*rx_status)); -+- rx_status->signal = ATH10K_DEFAULT_NOISE_FLOOR + -+- rx->ppdu.combined_rssi; -+- } -+- -+- if (rx->ppdu.info0 & HTT_RX_INDICATION_INFO0_END_VALID) { -+- /* TSF available only in 32-bit */ -+- rx_status->mactime = __le32_to_cpu(rx->ppdu.tsf) & 0xffffffff; -+- rx_status->flag |= RX_FLAG_MACTIME_END; -+- } -+- -+- channel_set = ath10k_htt_rx_h_channel(htt->ar, rx_status); -+- -+- if (channel_set) { -+- ath10k_htt_rx_h_rates(htt->ar, rx_status->band, -+- rx->ppdu.info0, -+- __le32_to_cpu(rx->ppdu.info1), -+- __le32_to_cpu(rx->ppdu.info2), -+- rx_status); -+- } -+- -+- ath10k_dbg_dump(ATH10K_DBG_HTT_DUMP, NULL, "htt rx ind: ", -++ ath10k_dbg_dump(ar, ATH10K_DBG_HTT_DUMP, NULL, "htt rx ind: ", -+ rx, sizeof(*rx) + -+ (sizeof(struct htt_rx_indication_mpdu_range) * -+ num_mpdu_ranges)); -+ -+- for (i = 0; i < num_mpdu_ranges; i++) { -+- status = mpdu_ranges[i].mpdu_range_status; -+- -+- for (j = 0; j < mpdu_ranges[i].mpdu_count; j++) { -+- struct sk_buff *msdu_head, *msdu_tail; -++ for (i = 0; i < num_mpdu_ranges; i++) -++ mpdu_count += mpdu_ranges[i].mpdu_count; -+ -+- msdu_head = NULL; -+- msdu_tail = NULL; -+- ret = ath10k_htt_rx_amsdu_pop(htt, -+- &fw_desc, -+- &fw_desc_len, -+- &msdu_head, -+- &msdu_tail); -+- -+- if (ret < 0) { -+- ath10k_warn("failed to pop amsdu from htt rx ring %d\n", -+- ret); -+- ath10k_htt_rx_free_msdu_chain(msdu_head); -+- continue; -+- } -+- -+- rxd = container_of((void *)msdu_head->data, -+- struct htt_rx_desc, -+- msdu_payload); -+- attention = __le32_to_cpu(rxd->attention.flags); -+- -+- if (!ath10k_htt_rx_amsdu_allowed(htt, msdu_head, -+- status, -+- channel_set, -+- attention)) { -+- ath10k_htt_rx_free_msdu_chain(msdu_head); -+- continue; -+- } -+- -+- if (ret > 0 && -+- ath10k_unchain_msdu(msdu_head) < 0) { -+- ath10k_htt_rx_free_msdu_chain(msdu_head); -+- continue; -+- } -+- -+- if (attention & RX_ATTENTION_FLAGS_FCS_ERR) -+- rx_status->flag |= RX_FLAG_FAILED_FCS_CRC; -+- else -+- rx_status->flag &= ~RX_FLAG_FAILED_FCS_CRC; -+- -+- if (attention & RX_ATTENTION_FLAGS_TKIP_MIC_ERR) -+- rx_status->flag |= RX_FLAG_MMIC_ERROR; -+- else -+- rx_status->flag &= ~RX_FLAG_MMIC_ERROR; -+- -+- hdr = ath10k_htt_rx_skb_get_hdr(msdu_head); -+- -+- if (ath10k_htt_rx_hdr_is_amsdu(hdr)) -+- ath10k_htt_rx_amsdu(htt, rx_status, msdu_head); -+- else -+- ath10k_htt_rx_msdu(htt, rx_status, msdu_head); -++ while (mpdu_count--) { -++ __skb_queue_head_init(&amsdu); -++ ret = ath10k_htt_rx_amsdu_pop(htt, &fw_desc, -++ &fw_desc_len, &amsdu); -++ if (ret < 0) { -++ ath10k_warn(ar, "rx ring became corrupted: %d\n", ret); -++ __skb_queue_purge(&amsdu); -++ /* FIXME: It's probably a good idea to reboot the -++ * device instead of leaving it inoperable. -++ */ -++ htt->rx_confused = true; -++ break; -+ } -++ -++ ath10k_htt_rx_h_ppdu(ar, &amsdu, rx_status); -++ ath10k_htt_rx_h_unchain(ar, &amsdu, ret > 0); -++ ath10k_htt_rx_h_filter(ar, &amsdu, rx_status); -++ ath10k_htt_rx_h_mpdu(ar, &amsdu, rx_status); -++ ath10k_htt_rx_h_deliver(ar, &amsdu, rx_status); -+ } -+ -+ tasklet_schedule(&htt->rx_replenish_task); -+ } -+ -+ static void ath10k_htt_rx_frag_handler(struct ath10k_htt *htt, -+- struct htt_rx_fragment_indication *frag) -++ struct htt_rx_fragment_indication *frag) -+ { -+- struct sk_buff *msdu_head, *msdu_tail; -+- enum htt_rx_mpdu_encrypt_type enctype; -+- struct htt_rx_desc *rxd; -+- enum rx_msdu_decap_format fmt; -++ struct ath10k *ar = htt->ar; -+ struct ieee80211_rx_status *rx_status = &htt->rx_status; -+- struct ieee80211_hdr *hdr; -++ struct sk_buff_head amsdu; -+ int ret; -+- bool tkip_mic_err; -+- bool decrypt_err; -+ u8 *fw_desc; -+- int fw_desc_len, hdrlen, paramlen; -+- int trim; -++ int fw_desc_len; -+ -+ fw_desc_len = __le16_to_cpu(frag->fw_rx_desc_bytes); -+ fw_desc = (u8 *)frag->fw_msdu_rx_desc; -+ -+- msdu_head = NULL; -+- msdu_tail = NULL; -++ __skb_queue_head_init(&amsdu); -+ -+ spin_lock_bh(&htt->rx_ring.lock); -+ ret = ath10k_htt_rx_amsdu_pop(htt, &fw_desc, &fw_desc_len, -+- &msdu_head, &msdu_tail); -++ &amsdu); -+ spin_unlock_bh(&htt->rx_ring.lock); -+ -+- ath10k_dbg(ATH10K_DBG_HTT_DUMP, "htt rx frag ahead\n"); -++ tasklet_schedule(&htt->rx_replenish_task); -++ -++ ath10k_dbg(ar, ATH10K_DBG_HTT_DUMP, "htt rx frag ahead\n"); -+ -+ if (ret) { -+- ath10k_warn("failed to pop amsdu from httr rx ring for fragmented rx %d\n", -++ ath10k_warn(ar, "failed to pop amsdu from httr rx ring for fragmented rx %d\n", -+ ret); -+- ath10k_htt_rx_free_msdu_chain(msdu_head); -++ __skb_queue_purge(&amsdu); -+ return; -+ } -+ -+- /* FIXME: implement signal strength */ -+- -+- hdr = (struct ieee80211_hdr *)msdu_head->data; -+- rxd = (void *)msdu_head->data - sizeof(*rxd); -+- tkip_mic_err = !!(__le32_to_cpu(rxd->attention.flags) & -+- RX_ATTENTION_FLAGS_TKIP_MIC_ERR); -+- decrypt_err = !!(__le32_to_cpu(rxd->attention.flags) & -+- RX_ATTENTION_FLAGS_DECRYPT_ERR); -+- fmt = MS(__le32_to_cpu(rxd->msdu_start.info1), -+- RX_MSDU_START_INFO1_DECAP_FORMAT); -+- -+- if (fmt != RX_MSDU_DECAP_RAW) { -+- ath10k_warn("we dont support non-raw fragmented rx yet\n"); -+- dev_kfree_skb_any(msdu_head); -+- goto end; -+- } -+- -+- enctype = MS(__le32_to_cpu(rxd->mpdu_start.info0), -+- RX_MPDU_START_INFO0_ENCRYPT_TYPE); -+- ath10k_htt_rx_h_protected(htt, rx_status, msdu_head, enctype); -+- msdu_head->ip_summed = ath10k_htt_rx_get_csum_state(msdu_head); -+- -+- if (tkip_mic_err) -+- ath10k_warn("tkip mic error\n"); -+- -+- if (decrypt_err) { -+- ath10k_warn("decryption err in fragmented rx\n"); -+- dev_kfree_skb_any(msdu_head); -+- goto end; -+- } -+- -+- if (enctype != HTT_RX_MPDU_ENCRYPT_NONE) { -+- hdrlen = ieee80211_hdrlen(hdr->frame_control); -+- paramlen = ath10k_htt_rx_crypto_param_len(enctype); -+- -+- /* It is more efficient to move the header than the payload */ -+- memmove((void *)msdu_head->data + paramlen, -+- (void *)msdu_head->data, -+- hdrlen); -+- skb_pull(msdu_head, paramlen); -+- hdr = (struct ieee80211_hdr *)msdu_head->data; -+- } -+- -+- /* remove trailing FCS */ -+- trim = 4; -+- -+- /* remove crypto trailer */ -+- trim += ath10k_htt_rx_crypto_tail_len(enctype); -+- -+- /* last fragment of TKIP frags has MIC */ -+- if (!ieee80211_has_morefrags(hdr->frame_control) && -+- enctype == HTT_RX_MPDU_ENCRYPT_TKIP_WPA) -+- trim += 8; -+- -+- if (trim > msdu_head->len) { -+- ath10k_warn("htt rx fragment: trailer longer than the frame itself? drop\n"); -+- dev_kfree_skb_any(msdu_head); -+- goto end; -++ if (skb_queue_len(&amsdu) != 1) { -++ ath10k_warn(ar, "failed to pop frag amsdu: too many msdus\n"); -++ __skb_queue_purge(&amsdu); -++ return; -+ } -+ -+- skb_trim(msdu_head, msdu_head->len - trim); -+- -+- ath10k_dbg_dump(ATH10K_DBG_HTT_DUMP, NULL, "htt rx frag mpdu: ", -+- msdu_head->data, msdu_head->len); -+- ath10k_process_rx(htt->ar, rx_status, msdu_head); -++ ath10k_htt_rx_h_ppdu(ar, &amsdu, rx_status); -++ ath10k_htt_rx_h_filter(ar, &amsdu, rx_status); -++ ath10k_htt_rx_h_mpdu(ar, &amsdu, rx_status); -++ ath10k_htt_rx_h_deliver(ar, &amsdu, rx_status); -+ -+-end: -+ if (fw_desc_len > 0) { -+- ath10k_dbg(ATH10K_DBG_HTT, -++ ath10k_dbg(ar, ATH10K_DBG_HTT, -+ "expecting more fragmented rx in one indication %d\n", -+ fw_desc_len); -+ } -+@@ -1385,12 +1605,12 @@ static void ath10k_htt_rx_frm_tx_compl(s -+ tx_done.discard = true; -+ break; -+ default: -+- ath10k_warn("unhandled tx completion status %d\n", status); -++ ath10k_warn(ar, "unhandled tx completion status %d\n", status); -+ tx_done.discard = true; -+ break; -+ } -+ -+- ath10k_dbg(ATH10K_DBG_HTT, "htt tx completion num_msdus %d\n", -++ ath10k_dbg(ar, ATH10K_DBG_HTT, "htt tx completion num_msdus %d\n", -+ resp->data_tx_completion.num_msdus); -+ -+ for (i = 0; i < resp->data_tx_completion.num_msdus; i++) { -+@@ -1400,6 +1620,274 @@ static void ath10k_htt_rx_frm_tx_compl(s -+ } -+ } -+ -++static void ath10k_htt_rx_addba(struct ath10k *ar, struct htt_resp *resp) -++{ -++ struct htt_rx_addba *ev = &resp->rx_addba; -++ struct ath10k_peer *peer; -++ struct ath10k_vif *arvif; -++ u16 info0, tid, peer_id; -++ -++ info0 = __le16_to_cpu(ev->info0); -++ tid = MS(info0, HTT_RX_BA_INFO0_TID); -++ peer_id = MS(info0, HTT_RX_BA_INFO0_PEER_ID); -++ -++ ath10k_dbg(ar, ATH10K_DBG_HTT, -++ "htt rx addba tid %hu peer_id %hu size %hhu\n", -++ tid, peer_id, ev->window_size); -++ -++ spin_lock_bh(&ar->data_lock); -++ peer = ath10k_peer_find_by_id(ar, peer_id); -++ if (!peer) { -++ ath10k_warn(ar, "received addba event for invalid peer_id: %hu\n", -++ peer_id); -++ spin_unlock_bh(&ar->data_lock); -++ return; -++ } -++ -++ arvif = ath10k_get_arvif(ar, peer->vdev_id); -++ if (!arvif) { -++ ath10k_warn(ar, "received addba event for invalid vdev_id: %u\n", -++ peer->vdev_id); -++ spin_unlock_bh(&ar->data_lock); -++ return; -++ } -++ -++ ath10k_dbg(ar, ATH10K_DBG_HTT, -++ "htt rx start rx ba session sta %pM tid %hu size %hhu\n", -++ peer->addr, tid, ev->window_size); -++ -++ ieee80211_start_rx_ba_session_offl(arvif->vif, peer->addr, tid); -++ spin_unlock_bh(&ar->data_lock); -++} -++ -++static void ath10k_htt_rx_delba(struct ath10k *ar, struct htt_resp *resp) -++{ -++ struct htt_rx_delba *ev = &resp->rx_delba; -++ struct ath10k_peer *peer; -++ struct ath10k_vif *arvif; -++ u16 info0, tid, peer_id; -++ -++ info0 = __le16_to_cpu(ev->info0); -++ tid = MS(info0, HTT_RX_BA_INFO0_TID); -++ peer_id = MS(info0, HTT_RX_BA_INFO0_PEER_ID); -++ -++ ath10k_dbg(ar, ATH10K_DBG_HTT, -++ "htt rx delba tid %hu peer_id %hu\n", -++ tid, peer_id); -++ -++ spin_lock_bh(&ar->data_lock); -++ peer = ath10k_peer_find_by_id(ar, peer_id); -++ if (!peer) { -++ ath10k_warn(ar, "received addba event for invalid peer_id: %hu\n", -++ peer_id); -++ spin_unlock_bh(&ar->data_lock); -++ return; -++ } -++ -++ arvif = ath10k_get_arvif(ar, peer->vdev_id); -++ if (!arvif) { -++ ath10k_warn(ar, "received addba event for invalid vdev_id: %u\n", -++ peer->vdev_id); -++ spin_unlock_bh(&ar->data_lock); -++ return; -++ } -++ -++ ath10k_dbg(ar, ATH10K_DBG_HTT, -++ "htt rx stop rx ba session sta %pM tid %hu\n", -++ peer->addr, tid); -++ -++ ieee80211_stop_rx_ba_session_offl(arvif->vif, peer->addr, tid); -++ spin_unlock_bh(&ar->data_lock); -++} -++ -++static int ath10k_htt_rx_extract_amsdu(struct sk_buff_head *list, -++ struct sk_buff_head *amsdu) -++{ -++ struct sk_buff *msdu; -++ struct htt_rx_desc *rxd; -++ -++ if (skb_queue_empty(list)) -++ return -ENOBUFS; -++ -++ if (WARN_ON(!skb_queue_empty(amsdu))) -++ return -EINVAL; -++ -++ while ((msdu = __skb_dequeue(list))) { -++ __skb_queue_tail(amsdu, msdu); -++ -++ rxd = (void *)msdu->data - sizeof(*rxd); -++ if (rxd->msdu_end.info0 & -++ __cpu_to_le32(RX_MSDU_END_INFO0_LAST_MSDU)) -++ break; -++ } -++ -++ msdu = skb_peek_tail(amsdu); -++ rxd = (void *)msdu->data - sizeof(*rxd); -++ if (!(rxd->msdu_end.info0 & -++ __cpu_to_le32(RX_MSDU_END_INFO0_LAST_MSDU))) { -++ skb_queue_splice_init(amsdu, list); -++ return -EAGAIN; -++ } -++ -++ return 0; -++} -++ -++static void ath10k_htt_rx_h_rx_offload_prot(struct ieee80211_rx_status *status, -++ struct sk_buff *skb) -++{ -++ struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; -++ -++ if (!ieee80211_has_protected(hdr->frame_control)) -++ return; -++ -++ /* Offloaded frames are already decrypted but firmware insists they are -++ * protected in the 802.11 header. Strip the flag. Otherwise mac80211 -++ * will drop the frame. -++ */ -++ -++ hdr->frame_control &= ~__cpu_to_le16(IEEE80211_FCTL_PROTECTED); -++ status->flag |= RX_FLAG_DECRYPTED | -++ RX_FLAG_IV_STRIPPED | -++ RX_FLAG_MMIC_STRIPPED; -++} -++ -++static void ath10k_htt_rx_h_rx_offload(struct ath10k *ar, -++ struct sk_buff_head *list) -++{ -++ struct ath10k_htt *htt = &ar->htt; -++ struct ieee80211_rx_status *status = &htt->rx_status; -++ struct htt_rx_offload_msdu *rx; -++ struct sk_buff *msdu; -++ size_t offset; -++ -++ while ((msdu = __skb_dequeue(list))) { -++ /* Offloaded frames don't have Rx descriptor. Instead they have -++ * a short meta information header. -++ */ -++ -++ rx = (void *)msdu->data; -++ -++ skb_put(msdu, sizeof(*rx)); -++ skb_pull(msdu, sizeof(*rx)); -++ -++ if (skb_tailroom(msdu) < __le16_to_cpu(rx->msdu_len)) { -++ ath10k_warn(ar, "dropping frame: offloaded rx msdu is too long!\n"); -++ dev_kfree_skb_any(msdu); -++ continue; -++ } -++ -++ skb_put(msdu, __le16_to_cpu(rx->msdu_len)); -++ -++ /* Offloaded rx header length isn't multiple of 2 nor 4 so the -++ * actual payload is unaligned. Align the frame. Otherwise -++ * mac80211 complains. This shouldn't reduce performance much -++ * because these offloaded frames are rare. -++ */ -++ offset = 4 - ((unsigned long)msdu->data & 3); -++ skb_put(msdu, offset); -++ memmove(msdu->data + offset, msdu->data, msdu->len); -++ skb_pull(msdu, offset); -++ -++ /* FIXME: The frame is NWifi. Re-construct QoS Control -++ * if possible later. -++ */ -++ -++ memset(status, 0, sizeof(*status)); -++ status->flag |= RX_FLAG_NO_SIGNAL_VAL; -++ -++ ath10k_htt_rx_h_rx_offload_prot(status, msdu); -++ ath10k_htt_rx_h_channel(ar, status); -++ ath10k_process_rx(ar, status, msdu); -++ } -++} -++ -++static void ath10k_htt_rx_in_ord_ind(struct ath10k *ar, struct sk_buff *skb) -++{ -++ struct ath10k_htt *htt = &ar->htt; -++ struct htt_resp *resp = (void *)skb->data; -++ struct ieee80211_rx_status *status = &htt->rx_status; -++ struct sk_buff_head list; -++ struct sk_buff_head amsdu; -++ u16 peer_id; -++ u16 msdu_count; -++ u8 vdev_id; -++ u8 tid; -++ bool offload; -++ bool frag; -++ int ret; -++ -++ lockdep_assert_held(&htt->rx_ring.lock); -++ -++ if (htt->rx_confused) -++ return; -++ -++ skb_pull(skb, sizeof(resp->hdr)); -++ skb_pull(skb, sizeof(resp->rx_in_ord_ind)); -++ -++ peer_id = __le16_to_cpu(resp->rx_in_ord_ind.peer_id); -++ msdu_count = __le16_to_cpu(resp->rx_in_ord_ind.msdu_count); -++ vdev_id = resp->rx_in_ord_ind.vdev_id; -++ tid = SM(resp->rx_in_ord_ind.info, HTT_RX_IN_ORD_IND_INFO_TID); -++ offload = !!(resp->rx_in_ord_ind.info & -++ HTT_RX_IN_ORD_IND_INFO_OFFLOAD_MASK); -++ frag = !!(resp->rx_in_ord_ind.info & HTT_RX_IN_ORD_IND_INFO_FRAG_MASK); -++ -++ ath10k_dbg(ar, ATH10K_DBG_HTT, -++ "htt rx in ord vdev %i peer %i tid %i offload %i frag %i msdu count %i\n", -++ vdev_id, peer_id, tid, offload, frag, msdu_count); -++ -++ if (skb->len < msdu_count * sizeof(*resp->rx_in_ord_ind.msdu_descs)) { -++ ath10k_warn(ar, "dropping invalid in order rx indication\n"); -++ return; -++ } -++ -++ /* The event can deliver more than 1 A-MSDU. Each A-MSDU is later -++ * extracted and processed. -++ */ -++ __skb_queue_head_init(&list); -++ ret = ath10k_htt_rx_pop_paddr_list(htt, &resp->rx_in_ord_ind, &list); -++ if (ret < 0) { -++ ath10k_warn(ar, "failed to pop paddr list: %d\n", ret); -++ htt->rx_confused = true; -++ return; -++ } -++ -++ /* Offloaded frames are very different and need to be handled -++ * separately. -++ */ -++ if (offload) -++ ath10k_htt_rx_h_rx_offload(ar, &list); -++ -++ while (!skb_queue_empty(&list)) { -++ __skb_queue_head_init(&amsdu); -++ ret = ath10k_htt_rx_extract_amsdu(&list, &amsdu); -++ switch (ret) { -++ case 0: -++ /* Note: The in-order indication may report interleaved -++ * frames from different PPDUs meaning reported rx rate -++ * to mac80211 isn't accurate/reliable. It's still -++ * better to report something than nothing though. This -++ * should still give an idea about rx rate to the user. -++ */ -++ ath10k_htt_rx_h_ppdu(ar, &amsdu, status); -++ ath10k_htt_rx_h_filter(ar, &amsdu, status); -++ ath10k_htt_rx_h_mpdu(ar, &amsdu, status); -++ ath10k_htt_rx_h_deliver(ar, &amsdu, status); -++ break; -++ case -EAGAIN: -++ /* fall through */ -++ default: -++ /* Should not happen. */ -++ ath10k_warn(ar, "failed to extract amsdu: %d\n", ret); -++ htt->rx_confused = true; -++ __skb_queue_purge(&list); -++ return; -++ } -++ } -++ -++ tasklet_schedule(&htt->rx_replenish_task); -++} -++ -+ void ath10k_htt_t2h_msg_handler(struct ath10k *ar, struct sk_buff *skb) -+ { -+ struct ath10k_htt *htt = &ar->htt; -+@@ -1407,9 +1895,9 @@ void ath10k_htt_t2h_msg_handler(struct a -+ -+ /* confirm alignment */ -+ if (!IS_ALIGNED((unsigned long)skb->data, 4)) -+- ath10k_warn("unaligned htt message, expect trouble\n"); -++ ath10k_warn(ar, "unaligned htt message, expect trouble\n"); -+ -+- ath10k_dbg(ATH10K_DBG_HTT, "htt rx, msg_type: 0x%0X\n", -++ ath10k_dbg(ar, ATH10K_DBG_HTT, "htt rx, msg_type: 0x%0X\n", -+ resp->hdr.msg_type); -+ switch (resp->hdr.msg_type) { -+ case HTT_T2H_MSG_TYPE_VERSION_CONF: { -+@@ -1473,7 +1961,7 @@ void ath10k_htt_t2h_msg_handler(struct a -+ struct ath10k *ar = htt->ar; -+ struct htt_security_indication *ev = &resp->security_indication; -+ -+- ath10k_dbg(ATH10K_DBG_HTT, -++ ath10k_dbg(ar, ATH10K_DBG_HTT, -+ "sec ind peer_id %d unicast %d type %d\n", -+ __le16_to_cpu(ev->peer_id), -+ !!(ev->flags & HTT_SECURITY_IS_UNICAST), -+@@ -1482,7 +1970,7 @@ void ath10k_htt_t2h_msg_handler(struct a -+ break; -+ } -+ case HTT_T2H_MSG_TYPE_RX_FRAG_IND: { -+- ath10k_dbg_dump(ATH10K_DBG_HTT_DUMP, NULL, "htt event: ", -++ ath10k_dbg_dump(ar, ATH10K_DBG_HTT_DUMP, NULL, "htt event: ", -+ skb->data, skb->len); -+ ath10k_htt_rx_frag_handler(htt, &resp->rx_frag_ind); -+ break; -+@@ -1491,16 +1979,55 @@ void ath10k_htt_t2h_msg_handler(struct a -+ /* FIX THIS */ -+ break; -+ case HTT_T2H_MSG_TYPE_STATS_CONF: -+- trace_ath10k_htt_stats(skb->data, skb->len); -++ trace_ath10k_htt_stats(ar, skb->data, skb->len); -+ break; -+ case HTT_T2H_MSG_TYPE_TX_INSPECT_IND: -++ /* Firmware can return tx frames if it's unable to fully -++ * process them and suspects host may be able to fix it. ath10k -++ * sends all tx frames as already inspected so this shouldn't -++ * happen unless fw has a bug. -++ */ -++ ath10k_warn(ar, "received an unexpected htt tx inspect event\n"); -++ break; -+ case HTT_T2H_MSG_TYPE_RX_ADDBA: -++ ath10k_htt_rx_addba(ar, resp); -++ break; -+ case HTT_T2H_MSG_TYPE_RX_DELBA: -+- case HTT_T2H_MSG_TYPE_RX_FLUSH: -++ ath10k_htt_rx_delba(ar, resp); -++ break; -++ case HTT_T2H_MSG_TYPE_PKTLOG: { -++ struct ath10k_pktlog_hdr *hdr = -++ (struct ath10k_pktlog_hdr *)resp->pktlog_msg.payload; -++ -++ trace_ath10k_htt_pktlog(ar, resp->pktlog_msg.payload, -++ sizeof(*hdr) + -++ __le16_to_cpu(hdr->size)); -++ break; -++ } -++ case HTT_T2H_MSG_TYPE_RX_FLUSH: { -++ /* Ignore this event because mac80211 takes care of Rx -++ * aggregation reordering. -++ */ -++ break; -++ } -++ case HTT_T2H_MSG_TYPE_RX_IN_ORD_PADDR_IND: { -++ spin_lock_bh(&htt->rx_ring.lock); -++ __skb_queue_tail(&htt->rx_in_ord_compl_q, skb); -++ spin_unlock_bh(&htt->rx_ring.lock); -++ tasklet_schedule(&htt->txrx_compl_task); -++ return; -++ } -++ case HTT_T2H_MSG_TYPE_TX_CREDIT_UPDATE_IND: -++ /* FIXME: This WMI-TLV event is overlapping with 10.2 -++ * CHAN_CHANGE - both being 0xF. Neither is being used in -++ * practice so no immediate action is necessary. Nevertheless -++ * HTT may need an abstraction layer like WMI has one day. -++ */ -++ break; -+ default: -+- ath10k_dbg(ATH10K_DBG_HTT, "htt event (%d) not handled\n", -+- resp->hdr.msg_type); -+- ath10k_dbg_dump(ATH10K_DBG_HTT_DUMP, NULL, "htt event: ", -++ ath10k_warn(ar, "htt event (%d) not handled\n", -++ resp->hdr.msg_type); -++ ath10k_dbg_dump(ar, ATH10K_DBG_HTT_DUMP, NULL, "htt event: ", -+ skb->data, skb->len); -+ break; -+ }; -+@@ -1512,6 +2039,7 @@ void ath10k_htt_t2h_msg_handler(struct a -+ static void ath10k_htt_txrx_compl_task(unsigned long ptr) -+ { -+ struct ath10k_htt *htt = (struct ath10k_htt *)ptr; -++ struct ath10k *ar = htt->ar; -+ struct htt_resp *resp; -+ struct sk_buff *skb; -+ -+@@ -1528,5 +2056,10 @@ static void ath10k_htt_txrx_compl_task(u -+ ath10k_htt_rx_handler(htt, &resp->rx_ind); -+ dev_kfree_skb_any(skb); -+ } -++ -++ while ((skb = __skb_dequeue(&htt->rx_in_ord_compl_q))) { -++ ath10k_htt_rx_in_ord_ind(ar, skb); -++ dev_kfree_skb_any(skb); -++ } -+ spin_unlock_bh(&htt->rx_ring.lock); -+ } -+--- a/drivers/net/wireless/ath/ath10k/htt_tx.c -++++ b/drivers/net/wireless/ath/ath10k/htt_tx.c -+@@ -56,98 +56,74 @@ exit: -+ return ret; -+ } -+ -+-int ath10k_htt_tx_alloc_msdu_id(struct ath10k_htt *htt) -++int ath10k_htt_tx_alloc_msdu_id(struct ath10k_htt *htt, struct sk_buff *skb) -+ { -+- int msdu_id; -++ struct ath10k *ar = htt->ar; -++ int ret; -+ -+ lockdep_assert_held(&htt->tx_lock); -+ -+- msdu_id = find_first_zero_bit(htt->used_msdu_ids, -+- htt->max_num_pending_tx); -+- if (msdu_id == htt->max_num_pending_tx) -+- return -ENOBUFS; -+- -+- ath10k_dbg(ATH10K_DBG_HTT, "htt tx alloc msdu_id %d\n", msdu_id); -+- __set_bit(msdu_id, htt->used_msdu_ids); -+- return msdu_id; -++ ret = idr_alloc(&htt->pending_tx, skb, 0, 0x10000, GFP_ATOMIC); -++ -++ ath10k_dbg(ar, ATH10K_DBG_HTT, "htt tx alloc msdu_id %d\n", ret); -++ -++ return ret; -+ } -+ -+ void ath10k_htt_tx_free_msdu_id(struct ath10k_htt *htt, u16 msdu_id) -+ { -++ struct ath10k *ar = htt->ar; -++ -+ lockdep_assert_held(&htt->tx_lock); -+ -+- if (!test_bit(msdu_id, htt->used_msdu_ids)) -+- ath10k_warn("trying to free unallocated msdu_id %d\n", msdu_id); -++ ath10k_dbg(ar, ATH10K_DBG_HTT, "htt tx free msdu_id %hu\n", msdu_id); -+ -+- ath10k_dbg(ATH10K_DBG_HTT, "htt tx free msdu_id %hu\n", msdu_id); -+- __clear_bit(msdu_id, htt->used_msdu_ids); -++ idr_remove(&htt->pending_tx, msdu_id); -+ } -+ -+-int ath10k_htt_tx_attach(struct ath10k_htt *htt) -++int ath10k_htt_tx_alloc(struct ath10k_htt *htt) -+ { -+- spin_lock_init(&htt->tx_lock); -+- init_waitqueue_head(&htt->empty_tx_wq); -+- -+- if (test_bit(ATH10K_FW_FEATURE_WMI_10X, htt->ar->fw_features)) -+- htt->max_num_pending_tx = TARGET_10X_NUM_MSDU_DESC; -+- else -+- htt->max_num_pending_tx = TARGET_NUM_MSDU_DESC; -++ struct ath10k *ar = htt->ar; -+ -+- ath10k_dbg(ATH10K_DBG_BOOT, "htt tx max num pending tx %d\n", -++ ath10k_dbg(ar, ATH10K_DBG_BOOT, "htt tx max num pending tx %d\n", -+ htt->max_num_pending_tx); -+ -+- htt->pending_tx = kzalloc(sizeof(*htt->pending_tx) * -+- htt->max_num_pending_tx, GFP_KERNEL); -+- if (!htt->pending_tx) -+- return -ENOMEM; -+- -+- htt->used_msdu_ids = kzalloc(sizeof(unsigned long) * -+- BITS_TO_LONGS(htt->max_num_pending_tx), -+- GFP_KERNEL); -+- if (!htt->used_msdu_ids) { -+- kfree(htt->pending_tx); -+- return -ENOMEM; -+- } -++ spin_lock_init(&htt->tx_lock); -++ idr_init(&htt->pending_tx); -+ -+ htt->tx_pool = dma_pool_create("ath10k htt tx pool", htt->ar->dev, -+ sizeof(struct ath10k_htt_txbuf), 4, 0); -+ if (!htt->tx_pool) { -+- kfree(htt->used_msdu_ids); -+- kfree(htt->pending_tx); -++ idr_destroy(&htt->pending_tx); -+ return -ENOMEM; -+ } -+ -+ return 0; -+ } -+ -+-static void ath10k_htt_tx_cleanup_pending(struct ath10k_htt *htt) -++static int ath10k_htt_tx_clean_up_pending(int msdu_id, void *skb, void *ctx) -+ { -++ struct ath10k *ar = ctx; -++ struct ath10k_htt *htt = &ar->htt; -+ struct htt_tx_done tx_done = {0}; -+- int msdu_id; -+- -+- spin_lock_bh(&htt->tx_lock); -+- for (msdu_id = 0; msdu_id < htt->max_num_pending_tx; msdu_id++) { -+- if (!test_bit(msdu_id, htt->used_msdu_ids)) -+- continue; -+ -+- ath10k_dbg(ATH10K_DBG_HTT, "force cleanup msdu_id %hu\n", -+- msdu_id); -++ ath10k_dbg(ar, ATH10K_DBG_HTT, "force cleanup msdu_id %hu\n", msdu_id); -+ -+- tx_done.discard = 1; -+- tx_done.msdu_id = msdu_id; -++ tx_done.discard = 1; -++ tx_done.msdu_id = msdu_id; -+ -+- ath10k_txrx_tx_unref(htt, &tx_done); -+- } -++ spin_lock_bh(&htt->tx_lock); -++ ath10k_txrx_tx_unref(htt, &tx_done); -+ spin_unlock_bh(&htt->tx_lock); -++ -++ return 0; -+ } -+ -+-void ath10k_htt_tx_detach(struct ath10k_htt *htt) -++void ath10k_htt_tx_free(struct ath10k_htt *htt) -+ { -+- ath10k_htt_tx_cleanup_pending(htt); -+- kfree(htt->pending_tx); -+- kfree(htt->used_msdu_ids); -++ idr_for_each(&htt->pending_tx, ath10k_htt_tx_clean_up_pending, htt->ar); -++ idr_destroy(&htt->pending_tx); -+ dma_pool_destroy(htt->tx_pool); -+- return; -+ } -+ -+ void ath10k_htt_htc_tx_complete(struct ath10k *ar, struct sk_buff *skb) -+@@ -157,6 +133,7 @@ void ath10k_htt_htc_tx_complete(struct a -+ -+ int ath10k_htt_h2t_ver_req_msg(struct ath10k_htt *htt) -+ { -++ struct ath10k *ar = htt->ar; -+ struct sk_buff *skb; -+ struct htt_cmd *cmd; -+ int len = 0; -+@@ -165,7 +142,7 @@ int ath10k_htt_h2t_ver_req_msg(struct at -+ len += sizeof(cmd->hdr); -+ len += sizeof(cmd->ver_req); -+ -+- skb = ath10k_htc_alloc_skb(len); -++ skb = ath10k_htc_alloc_skb(ar, len); -+ if (!skb) -+ return -ENOMEM; -+ -+@@ -184,6 +161,7 @@ int ath10k_htt_h2t_ver_req_msg(struct at -+ -+ int ath10k_htt_h2t_stats_req(struct ath10k_htt *htt, u8 mask, u64 cookie) -+ { -++ struct ath10k *ar = htt->ar; -+ struct htt_stats_req *req; -+ struct sk_buff *skb; -+ struct htt_cmd *cmd; -+@@ -192,7 +170,7 @@ int ath10k_htt_h2t_stats_req(struct ath1 -+ len += sizeof(cmd->hdr); -+ len += sizeof(cmd->stats_req); -+ -+- skb = ath10k_htc_alloc_skb(len); -++ skb = ath10k_htc_alloc_skb(ar, len); -+ if (!skb) -+ return -ENOMEM; -+ -+@@ -214,7 +192,8 @@ int ath10k_htt_h2t_stats_req(struct ath1 -+ -+ ret = ath10k_htc_send(&htt->ar->htc, htt->eid, skb); -+ if (ret) { -+- ath10k_warn("failed to send htt type stats request: %d", ret); -++ ath10k_warn(ar, "failed to send htt type stats request: %d", -++ ret); -+ dev_kfree_skb_any(skb); -+ return ret; -+ } -+@@ -224,6 +203,7 @@ int ath10k_htt_h2t_stats_req(struct ath1 -+ -+ int ath10k_htt_send_rx_ring_cfg_ll(struct ath10k_htt *htt) -+ { -++ struct ath10k *ar = htt->ar; -+ struct sk_buff *skb; -+ struct htt_cmd *cmd; -+ struct htt_rx_ring_setup_ring *ring; -+@@ -242,7 +222,7 @@ int ath10k_htt_send_rx_ring_cfg_ll(struc -+ -+ len = sizeof(cmd->hdr) + sizeof(cmd->rx_setup.hdr) -+ + (sizeof(*ring) * num_rx_ring); -+- skb = ath10k_htc_alloc_skb(len); -++ skb = ath10k_htc_alloc_skb(ar, len); -+ if (!skb) -+ return -ENOMEM; -+ -+@@ -307,9 +287,57 @@ int ath10k_htt_send_rx_ring_cfg_ll(struc -+ return 0; -+ } -+ -++int ath10k_htt_h2t_aggr_cfg_msg(struct ath10k_htt *htt, -++ u8 max_subfrms_ampdu, -++ u8 max_subfrms_amsdu) -++{ -++ struct ath10k *ar = htt->ar; -++ struct htt_aggr_conf *aggr_conf; -++ struct sk_buff *skb; -++ struct htt_cmd *cmd; -++ int len; -++ int ret; -++ -++ /* Firmware defaults are: amsdu = 3 and ampdu = 64 */ -++ -++ if (max_subfrms_ampdu == 0 || max_subfrms_ampdu > 64) -++ return -EINVAL; -++ -++ if (max_subfrms_amsdu == 0 || max_subfrms_amsdu > 31) -++ return -EINVAL; -++ -++ len = sizeof(cmd->hdr); -++ len += sizeof(cmd->aggr_conf); -++ -++ skb = ath10k_htc_alloc_skb(ar, len); -++ if (!skb) -++ return -ENOMEM; -++ -++ skb_put(skb, len); -++ cmd = (struct htt_cmd *)skb->data; -++ cmd->hdr.msg_type = HTT_H2T_MSG_TYPE_AGGR_CFG; -++ -++ aggr_conf = &cmd->aggr_conf; -++ aggr_conf->max_num_ampdu_subframes = max_subfrms_ampdu; -++ aggr_conf->max_num_amsdu_subframes = max_subfrms_amsdu; -++ -++ ath10k_dbg(ar, ATH10K_DBG_HTT, "htt h2t aggr cfg msg amsdu %d ampdu %d", -++ aggr_conf->max_num_amsdu_subframes, -++ aggr_conf->max_num_ampdu_subframes); -++ -++ ret = ath10k_htc_send(&htt->ar->htc, htt->eid, skb); -++ if (ret) { -++ dev_kfree_skb_any(skb); -++ return ret; -++ } -++ -++ return 0; -++} -++ -+ int ath10k_htt_mgmt_tx(struct ath10k_htt *htt, struct sk_buff *msdu) -+ { -+- struct device *dev = htt->ar->dev; -++ struct ath10k *ar = htt->ar; -++ struct device *dev = ar->dev; -+ struct sk_buff *txdesc = NULL; -+ struct htt_cmd *cmd; -+ struct ath10k_skb_cb *skb_cb = ATH10K_SKB_CB(msdu); -+@@ -318,7 +346,6 @@ int ath10k_htt_mgmt_tx(struct ath10k_htt -+ int msdu_id = -1; -+ int res; -+ -+- -+ res = ath10k_htt_tx_inc_pending(htt); -+ if (res) -+ goto err; -+@@ -327,16 +354,15 @@ int ath10k_htt_mgmt_tx(struct ath10k_htt -+ len += sizeof(cmd->mgmt_tx); -+ -+ spin_lock_bh(&htt->tx_lock); -+- res = ath10k_htt_tx_alloc_msdu_id(htt); -++ res = ath10k_htt_tx_alloc_msdu_id(htt, msdu); -+ if (res < 0) { -+ spin_unlock_bh(&htt->tx_lock); -+ goto err_tx_dec; -+ } -+ msdu_id = res; -+- htt->pending_tx[msdu_id] = msdu; -+ spin_unlock_bh(&htt->tx_lock); -+ -+- txdesc = ath10k_htc_alloc_skb(len); -++ txdesc = ath10k_htc_alloc_skb(ar, len); -+ if (!txdesc) { -+ res = -ENOMEM; -+ goto err_free_msdu_id; -+@@ -372,7 +398,6 @@ err_free_txdesc: -+ dev_kfree_skb_any(txdesc); -+ err_free_msdu_id: -+ spin_lock_bh(&htt->tx_lock); -+- htt->pending_tx[msdu_id] = NULL; -+ ath10k_htt_tx_free_msdu_id(htt, msdu_id); -+ spin_unlock_bh(&htt->tx_lock); -+ err_tx_dec: -+@@ -383,7 +408,8 @@ err: -+ -+ int ath10k_htt_tx(struct ath10k_htt *htt, struct sk_buff *msdu) -+ { -+- struct device *dev = htt->ar->dev; -++ struct ath10k *ar = htt->ar; -++ struct device *dev = ar->dev; -+ struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)msdu->data; -+ struct ath10k_skb_cb *skb_cb = ATH10K_SKB_CB(msdu); -+ struct ath10k_hif_sg_item sg_items[2]; -+@@ -403,13 +429,12 @@ int ath10k_htt_tx(struct ath10k_htt *htt -+ goto err; -+ -+ spin_lock_bh(&htt->tx_lock); -+- res = ath10k_htt_tx_alloc_msdu_id(htt); -++ res = ath10k_htt_tx_alloc_msdu_id(htt, msdu); -+ if (res < 0) { -+ spin_unlock_bh(&htt->tx_lock); -+ goto err_tx_dec; -+ } -+ msdu_id = res; -+- htt->pending_tx[msdu_id] = msdu; -+ spin_unlock_bh(&htt->tx_lock); -+ -+ prefetch_len = min(htt->prefetch_len, msdu->len); -+@@ -423,10 +448,18 @@ int ath10k_htt_tx(struct ath10k_htt *htt -+ -+ skb_cb->htt.txbuf = dma_pool_alloc(htt->tx_pool, GFP_ATOMIC, -+ &paddr); -+- if (!skb_cb->htt.txbuf) -++ if (!skb_cb->htt.txbuf) { -++ res = -ENOMEM; -+ goto err_free_msdu_id; -++ } -+ skb_cb->htt.txbuf_paddr = paddr; -+ -++ if ((ieee80211_is_action(hdr->frame_control) || -++ ieee80211_is_deauth(hdr->frame_control) || -++ ieee80211_is_disassoc(hdr->frame_control)) && -++ ieee80211_has_protected(hdr->frame_control)) -++ skb_put(msdu, IEEE80211_CCMP_MIC_LEN); -++ -+ skb_cb->paddr = dma_map_single(dev, msdu->data, msdu->len, -+ DMA_TO_DEVICE); -+ res = dma_mapping_error(dev, skb_cb->paddr); -+@@ -482,8 +515,16 @@ int ath10k_htt_tx(struct ath10k_htt *htt -+ -+ flags1 |= SM((u16)vdev_id, HTT_DATA_TX_DESC_FLAGS1_VDEV_ID); -+ flags1 |= SM((u16)tid, HTT_DATA_TX_DESC_FLAGS1_EXT_TID); -+- flags1 |= HTT_DATA_TX_DESC_FLAGS1_CKSUM_L3_OFFLOAD; -+- flags1 |= HTT_DATA_TX_DESC_FLAGS1_CKSUM_L4_OFFLOAD; -++ if (msdu->ip_summed == CHECKSUM_PARTIAL) { -++ flags1 |= HTT_DATA_TX_DESC_FLAGS1_CKSUM_L3_OFFLOAD; -++ flags1 |= HTT_DATA_TX_DESC_FLAGS1_CKSUM_L4_OFFLOAD; -++ } -++ -++ /* Prevent firmware from sending up tx inspection requests. There's -++ * nothing ath10k can do with frames requested for inspection so force -++ * it to simply rely a regular tx completion with discard status. -++ */ -++ flags1 |= HTT_DATA_TX_DESC_FLAGS1_POSTPONED; -+ -+ skb_cb->htt.txbuf->cmd_hdr.msg_type = HTT_H2T_MSG_TYPE_TX_FRM; -+ skb_cb->htt.txbuf->cmd_tx.flags0 = flags0; -+@@ -491,14 +532,18 @@ int ath10k_htt_tx(struct ath10k_htt *htt -+ skb_cb->htt.txbuf->cmd_tx.len = __cpu_to_le16(msdu->len); -+ skb_cb->htt.txbuf->cmd_tx.id = __cpu_to_le16(msdu_id); -+ skb_cb->htt.txbuf->cmd_tx.frags_paddr = __cpu_to_le32(frags_paddr); -+- skb_cb->htt.txbuf->cmd_tx.peerid = __cpu_to_le32(HTT_INVALID_PEERID); -++ skb_cb->htt.txbuf->cmd_tx.peerid = __cpu_to_le16(HTT_INVALID_PEERID); -++ skb_cb->htt.txbuf->cmd_tx.freq = __cpu_to_le16(skb_cb->htt.freq); -+ -+- ath10k_dbg(ATH10K_DBG_HTT, -+- "htt tx flags0 %hhu flags1 %hu len %d id %hu frags_paddr %08x, msdu_paddr %08x vdev %hhu tid %hhu\n", -++ trace_ath10k_htt_tx(ar, msdu_id, msdu->len, vdev_id, tid); -++ ath10k_dbg(ar, ATH10K_DBG_HTT, -++ "htt tx flags0 %hhu flags1 %hu len %d id %hu frags_paddr %08x, msdu_paddr %08x vdev %hhu tid %hhu freq %hu\n", -+ flags0, flags1, msdu->len, msdu_id, frags_paddr, -+- (u32)skb_cb->paddr, vdev_id, tid); -+- ath10k_dbg_dump(ATH10K_DBG_HTT_DUMP, NULL, "htt tx msdu: ", -++ (u32)skb_cb->paddr, vdev_id, tid, skb_cb->htt.freq); -++ ath10k_dbg_dump(ar, ATH10K_DBG_HTT_DUMP, NULL, "htt tx msdu: ", -+ msdu->data, msdu->len); -++ trace_ath10k_tx_hdr(ar, msdu->data, msdu->len); -++ trace_ath10k_tx_payload(ar, msdu->data, msdu->len); -+ -+ sg_items[0].transfer_id = 0; -+ sg_items[0].transfer_context = NULL; -+@@ -531,7 +576,6 @@ err_free_txbuf: -+ skb_cb->htt.txbuf_paddr); -+ err_free_msdu_id: -+ spin_lock_bh(&htt->tx_lock); -+- htt->pending_tx[msdu_id] = NULL; -+ ath10k_htt_tx_free_msdu_id(htt, msdu_id); -+ spin_unlock_bh(&htt->tx_lock); -+ err_tx_dec: -+--- a/drivers/net/wireless/ath/ath10k/hw.h -++++ b/drivers/net/wireless/ath/ath10k/hw.h -+@@ -20,24 +20,73 @@ -+ -+ #include "targaddrs.h" -+ -++#define ATH10K_FW_DIR "ath10k" -++ -+ /* QCA988X 1.0 definitions (unsupported) */ -+ #define QCA988X_HW_1_0_CHIP_ID_REV 0x0 -+ -+ /* QCA988X 2.0 definitions */ -+ #define QCA988X_HW_2_0_VERSION 0x4100016c -+ #define QCA988X_HW_2_0_CHIP_ID_REV 0x2 -+-#define QCA988X_HW_2_0_FW_DIR "ath10k/QCA988X/hw2.0" -++#define QCA988X_HW_2_0_FW_DIR ATH10K_FW_DIR "/QCA988X/hw2.0" -+ #define QCA988X_HW_2_0_FW_FILE "firmware.bin" -+-#define QCA988X_HW_2_0_FW_2_FILE "firmware-2.bin" -+ #define QCA988X_HW_2_0_OTP_FILE "otp.bin" -+ #define QCA988X_HW_2_0_BOARD_DATA_FILE "board.bin" -+ #define QCA988X_HW_2_0_PATCH_LOAD_ADDR 0x1234 -+ -++/* QCA6174 target BMI version signatures */ -++#define QCA6174_HW_1_0_VERSION 0x05000000 -++#define QCA6174_HW_1_1_VERSION 0x05000001 -++#define QCA6174_HW_1_3_VERSION 0x05000003 -++#define QCA6174_HW_2_1_VERSION 0x05010000 -++#define QCA6174_HW_3_0_VERSION 0x05020000 -++#define QCA6174_HW_3_2_VERSION 0x05030000 -++ -++enum qca6174_pci_rev { -++ QCA6174_PCI_REV_1_1 = 0x11, -++ QCA6174_PCI_REV_1_3 = 0x13, -++ QCA6174_PCI_REV_2_0 = 0x20, -++ QCA6174_PCI_REV_3_0 = 0x30, -++}; -++ -++enum qca6174_chip_id_rev { -++ QCA6174_HW_1_0_CHIP_ID_REV = 0, -++ QCA6174_HW_1_1_CHIP_ID_REV = 1, -++ QCA6174_HW_1_3_CHIP_ID_REV = 2, -++ QCA6174_HW_2_1_CHIP_ID_REV = 4, -++ QCA6174_HW_2_2_CHIP_ID_REV = 5, -++ QCA6174_HW_3_0_CHIP_ID_REV = 8, -++ QCA6174_HW_3_1_CHIP_ID_REV = 9, -++ QCA6174_HW_3_2_CHIP_ID_REV = 10, -++}; -++ -++#define QCA6174_HW_2_1_FW_DIR "ath10k/QCA6174/hw2.1" -++#define QCA6174_HW_2_1_FW_FILE "firmware.bin" -++#define QCA6174_HW_2_1_OTP_FILE "otp.bin" -++#define QCA6174_HW_2_1_BOARD_DATA_FILE "board.bin" -++#define QCA6174_HW_2_1_PATCH_LOAD_ADDR 0x1234 -++ -++#define QCA6174_HW_3_0_FW_DIR "ath10k/QCA6174/hw3.0" -++#define QCA6174_HW_3_0_FW_FILE "firmware.bin" -++#define QCA6174_HW_3_0_OTP_FILE "otp.bin" -++#define QCA6174_HW_3_0_BOARD_DATA_FILE "board.bin" -++#define QCA6174_HW_3_0_PATCH_LOAD_ADDR 0x1234 -++ -+ #define ATH10K_FW_API2_FILE "firmware-2.bin" -++#define ATH10K_FW_API3_FILE "firmware-3.bin" -++ -++/* added support for ATH10K_FW_IE_WMI_OP_VERSION */ -++#define ATH10K_FW_API4_FILE "firmware-4.bin" -++ -++#define ATH10K_FW_UTF_FILE "utf.bin" -+ -+ /* includes also the null byte */ -+ #define ATH10K_FIRMWARE_MAGIC "QCA-ATH10K" -+ -++#define REG_DUMP_COUNT_QCA988X 60 -++ -++#define QCA988X_CAL_DATA_LEN 2116 -++ -+ struct ath10k_fw_ie { -+ __le32 id; -+ __le32 len; -+@@ -50,8 +99,57 @@ enum ath10k_fw_ie_type { -+ ATH10K_FW_IE_FEATURES = 2, -+ ATH10K_FW_IE_FW_IMAGE = 3, -+ ATH10K_FW_IE_OTP_IMAGE = 4, -++ -++ /* WMI "operations" interface version, 32 bit value. Supported from -++ * FW API 4 and above. -++ */ -++ ATH10K_FW_IE_WMI_OP_VERSION = 5, -++}; -++ -++enum ath10k_fw_wmi_op_version { -++ ATH10K_FW_WMI_OP_VERSION_UNSET = 0, -++ -++ ATH10K_FW_WMI_OP_VERSION_MAIN = 1, -++ ATH10K_FW_WMI_OP_VERSION_10_1 = 2, -++ ATH10K_FW_WMI_OP_VERSION_10_2 = 3, -++ ATH10K_FW_WMI_OP_VERSION_TLV = 4, -++ ATH10K_FW_WMI_OP_VERSION_10_2_4 = 5, -++ -++ /* keep last */ -++ ATH10K_FW_WMI_OP_VERSION_MAX, -++}; -++ -++enum ath10k_hw_rev { -++ ATH10K_HW_QCA988X, -++ ATH10K_HW_QCA6174, -++}; -++ -++struct ath10k_hw_regs { -++ u32 rtc_state_cold_reset_mask; -++ u32 rtc_soc_base_address; -++ u32 rtc_wmac_base_address; -++ u32 soc_core_base_address; -++ u32 ce_wrapper_base_address; -++ u32 ce0_base_address; -++ u32 ce1_base_address; -++ u32 ce2_base_address; -++ u32 ce3_base_address; -++ u32 ce4_base_address; -++ u32 ce5_base_address; -++ u32 ce6_base_address; -++ u32 ce7_base_address; -++ u32 soc_reset_control_si0_rst_mask; -++ u32 soc_reset_control_ce_rst_mask; -++ u32 soc_chip_id_address; -++ u32 scratch_3_address; -+ }; -+ -++extern const struct ath10k_hw_regs qca988x_regs; -++extern const struct ath10k_hw_regs qca6174_regs; -++ -++#define QCA_REV_988X(ar) ((ar)->hw_rev == ATH10K_HW_QCA988X) -++#define QCA_REV_6174(ar) ((ar)->hw_rev == ATH10K_HW_QCA6174) -++ -+ /* Known pecularities: -+ * - current FW doesn't support raw rx mode (last tested v599) -+ * - current FW dumps upon raw tx mode (last tested v599) -+@@ -73,6 +171,15 @@ enum ath10k_mcast2ucast_mode { -+ ATH10K_MCAST2UCAST_ENABLED = 1, -+ }; -+ -++struct ath10k_pktlog_hdr { -++ __le16 flags; -++ __le16 missed_cnt; -++ __le16 log_type; -++ __le16 size; -++ __le32 timestamp; -++ u8 payload[0]; -++} __packed; -++ -+ /* Target specific defines for MAIN firmware */ -+ #define TARGET_NUM_VDEVS 8 -+ #define TARGET_NUM_PEER_AST 2 -+@@ -80,11 +187,13 @@ enum ath10k_mcast2ucast_mode { -+ #define TARGET_DMA_BURST_SIZE 0 -+ #define TARGET_MAC_AGGR_DELIM 0 -+ #define TARGET_AST_SKID_LIMIT 16 -+-#define TARGET_NUM_PEERS 16 -++#define TARGET_NUM_STATIONS 16 -++#define TARGET_NUM_PEERS ((TARGET_NUM_STATIONS) + \ -++ (TARGET_NUM_VDEVS)) -+ #define TARGET_NUM_OFFLOAD_PEERS 0 -+ #define TARGET_NUM_OFFLOAD_REORDER_BUFS 0 -+ #define TARGET_NUM_PEER_KEYS 2 -+-#define TARGET_NUM_TIDS (2 * ((TARGET_NUM_PEERS) + (TARGET_NUM_VDEVS))) -++#define TARGET_NUM_TIDS ((TARGET_NUM_PEERS) * 2) -+ #define TARGET_TX_CHAIN_MASK (BIT(0) | BIT(1) | BIT(2)) -+ #define TARGET_RX_CHAIN_MASK (BIT(0) | BIT(1) | BIT(2)) -+ #define TARGET_RX_TIMEOUT_LO_PRI 100 -+@@ -115,12 +224,15 @@ enum ath10k_mcast2ucast_mode { -+ #define TARGET_10X_DMA_BURST_SIZE 0 -+ #define TARGET_10X_MAC_AGGR_DELIM 0 -+ #define TARGET_10X_AST_SKID_LIMIT 16 -+-#define TARGET_10X_NUM_PEERS (128 + (TARGET_10X_NUM_VDEVS)) -+-#define TARGET_10X_NUM_PEERS_MAX 128 -++#define TARGET_10X_NUM_STATIONS 128 -++#define TARGET_10X_NUM_PEERS ((TARGET_10X_NUM_STATIONS) + \ -++ (TARGET_10X_NUM_VDEVS)) -+ #define TARGET_10X_NUM_OFFLOAD_PEERS 0 -+ #define TARGET_10X_NUM_OFFLOAD_REORDER_BUFS 0 -+ #define TARGET_10X_NUM_PEER_KEYS 2 -+-#define TARGET_10X_NUM_TIDS 256 -++#define TARGET_10X_NUM_TIDS_MAX 256 -++#define TARGET_10X_NUM_TIDS min((TARGET_10X_NUM_TIDS_MAX), \ -++ (TARGET_10X_NUM_PEERS) * 2) -+ #define TARGET_10X_TX_CHAIN_MASK (BIT(0) | BIT(1) | BIT(2)) -+ #define TARGET_10X_RX_CHAIN_MASK (BIT(0) | BIT(1) | BIT(2)) -+ #define TARGET_10X_RX_TIMEOUT_LO_PRI 100 -+@@ -140,6 +252,18 @@ enum ath10k_mcast2ucast_mode { -+ #define TARGET_10X_NUM_MSDU_DESC (1024 + 400) -+ #define TARGET_10X_MAX_FRAG_ENTRIES 0 -+ -++/* 10.2 parameters */ -++#define TARGET_10_2_DMA_BURST_SIZE 1 -++ -++/* Target specific defines for WMI-TLV firmware */ -++#define TARGET_TLV_NUM_VDEVS 3 -++#define TARGET_TLV_NUM_STATIONS 32 -++#define TARGET_TLV_NUM_PEERS ((TARGET_TLV_NUM_STATIONS) + \ -++ (TARGET_TLV_NUM_VDEVS) + \ -++ 2) -++#define TARGET_TLV_NUM_TIDS ((TARGET_TLV_NUM_PEERS) * 2) -++#define TARGET_TLV_NUM_MSDU_DESC (1024 + 32) -++ -+ /* Number of Copy Engines supported */ -+ #define CE_COUNT 8 -+ -+@@ -170,7 +294,7 @@ enum ath10k_mcast2ucast_mode { -+ /* as of IP3.7.1 */ -+ #define RTC_STATE_V_ON 3 -+ -+-#define RTC_STATE_COLD_RESET_MASK 0x00000400 -++#define RTC_STATE_COLD_RESET_MASK ar->regs->rtc_state_cold_reset_mask -+ #define RTC_STATE_V_LSB 0 -+ #define RTC_STATE_V_MASK 0x00000007 -+ #define RTC_STATE_ADDRESS 0x0000 -+@@ -179,12 +303,12 @@ enum ath10k_mcast2ucast_mode { -+ #define PCIE_SOC_WAKE_RESET 0x00000000 -+ #define SOC_GLOBAL_RESET_ADDRESS 0x0008 -+ -+-#define RTC_SOC_BASE_ADDRESS 0x00004000 -+-#define RTC_WMAC_BASE_ADDRESS 0x00005000 -++#define RTC_SOC_BASE_ADDRESS ar->regs->rtc_soc_base_address -++#define RTC_WMAC_BASE_ADDRESS ar->regs->rtc_wmac_base_address -+ #define MAC_COEX_BASE_ADDRESS 0x00006000 -+ #define BT_COEX_BASE_ADDRESS 0x00007000 -+ #define SOC_PCIE_BASE_ADDRESS 0x00008000 -+-#define SOC_CORE_BASE_ADDRESS 0x00009000 -++#define SOC_CORE_BASE_ADDRESS ar->regs->soc_core_base_address -+ #define WLAN_UART_BASE_ADDRESS 0x0000c000 -+ #define WLAN_SI_BASE_ADDRESS 0x00010000 -+ #define WLAN_GPIO_BASE_ADDRESS 0x00014000 -+@@ -193,23 +317,23 @@ enum ath10k_mcast2ucast_mode { -+ #define EFUSE_BASE_ADDRESS 0x00030000 -+ #define FPGA_REG_BASE_ADDRESS 0x00039000 -+ #define WLAN_UART2_BASE_ADDRESS 0x00054c00 -+-#define CE_WRAPPER_BASE_ADDRESS 0x00057000 -+-#define CE0_BASE_ADDRESS 0x00057400 -+-#define CE1_BASE_ADDRESS 0x00057800 -+-#define CE2_BASE_ADDRESS 0x00057c00 -+-#define CE3_BASE_ADDRESS 0x00058000 -+-#define CE4_BASE_ADDRESS 0x00058400 -+-#define CE5_BASE_ADDRESS 0x00058800 -+-#define CE6_BASE_ADDRESS 0x00058c00 -+-#define CE7_BASE_ADDRESS 0x00059000 -++#define CE_WRAPPER_BASE_ADDRESS ar->regs->ce_wrapper_base_address -++#define CE0_BASE_ADDRESS ar->regs->ce0_base_address -++#define CE1_BASE_ADDRESS ar->regs->ce1_base_address -++#define CE2_BASE_ADDRESS ar->regs->ce2_base_address -++#define CE3_BASE_ADDRESS ar->regs->ce3_base_address -++#define CE4_BASE_ADDRESS ar->regs->ce4_base_address -++#define CE5_BASE_ADDRESS ar->regs->ce5_base_address -++#define CE6_BASE_ADDRESS ar->regs->ce6_base_address -++#define CE7_BASE_ADDRESS ar->regs->ce7_base_address -+ #define DBI_BASE_ADDRESS 0x00060000 -+ #define WLAN_ANALOG_INTF_PCIE_BASE_ADDRESS 0x0006c000 -+ #define PCIE_LOCAL_BASE_ADDRESS 0x00080000 -+ -+ #define SOC_RESET_CONTROL_ADDRESS 0x00000000 -+ #define SOC_RESET_CONTROL_OFFSET 0x00000000 -+-#define SOC_RESET_CONTROL_SI0_RST_MASK 0x00000001 -+-#define SOC_RESET_CONTROL_CE_RST_MASK 0x00040000 -++#define SOC_RESET_CONTROL_SI0_RST_MASK ar->regs->soc_reset_control_si0_rst_mask -++#define SOC_RESET_CONTROL_CE_RST_MASK ar->regs->soc_reset_control_ce_rst_mask -+ #define SOC_RESET_CONTROL_CPU_WARM_RST_MASK 0x00000040 -+ #define SOC_CPU_CLOCK_OFFSET 0x00000020 -+ #define SOC_CPU_CLOCK_STANDARD_LSB 0 -+@@ -223,7 +347,7 @@ enum ath10k_mcast2ucast_mode { -+ #define SOC_LF_TIMER_CONTROL0_ADDRESS 0x00000050 -+ #define SOC_LF_TIMER_CONTROL0_ENABLE_MASK 0x00000004 -+ -+-#define SOC_CHIP_ID_ADDRESS 0x000000ec -++#define SOC_CHIP_ID_ADDRESS ar->regs->soc_chip_id_address -+ #define SOC_CHIP_ID_REV_LSB 8 -+ #define SOC_CHIP_ID_REV_MASK 0x00000f00 -+ -+@@ -274,11 +398,12 @@ enum ath10k_mcast2ucast_mode { -+ #define SI_RX_DATA1_OFFSET 0x00000014 -+ -+ #define CORE_CTRL_CPU_INTR_MASK 0x00002000 -++#define CORE_CTRL_PCIE_REG_31_MASK 0x00000800 -+ #define CORE_CTRL_ADDRESS 0x0000 -+ #define PCIE_INTR_ENABLE_ADDRESS 0x0008 -+ #define PCIE_INTR_CAUSE_ADDRESS 0x000c -+ #define PCIE_INTR_CLR_ADDRESS 0x0014 -+-#define SCRATCH_3_ADDRESS 0x0030 -++#define SCRATCH_3_ADDRESS ar->regs->scratch_3_address -+ #define CPU_INTR_ADDRESS 0x0010 -+ -+ /* Firmware indications to the Host via SCRATCH_3 register. */ -+--- a/drivers/net/wireless/ath/ath10k/mac.c -++++ b/drivers/net/wireless/ath/ath10k/mac.c -+@@ -26,6 +26,9 @@ -+ #include "wmi.h" -+ #include "htt.h" -+ #include "txrx.h" -++#include "testmode.h" -++#include "wmi.h" -++#include "wmi-ops.h" -+ -+ /**********/ -+ /* Crypto */ -+@@ -34,8 +37,9 @@ -+ static int ath10k_send_key(struct ath10k_vif *arvif, -+ struct ieee80211_key_conf *key, -+ enum set_key_cmd cmd, -+- const u8 *macaddr) -++ const u8 *macaddr, bool def_idx) -+ { -++ struct ath10k *ar = arvif->ar; -+ struct wmi_vdev_install_key_arg arg = { -+ .vdev_id = arvif->vdev_id, -+ .key_idx = key->keyidx, -+@@ -54,7 +58,7 @@ static int ath10k_send_key(struct ath10k -+ switch (key->cipher) { -+ case WLAN_CIPHER_SUITE_CCMP: -+ arg.key_cipher = WMI_CIPHER_AES_CCM; -+- key->flags |= IEEE80211_KEY_FLAG_SW_MGMT_TX; -++ key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV_MGMT; -+ break; -+ case WLAN_CIPHER_SUITE_TKIP: -+ arg.key_cipher = WMI_CIPHER_TKIP; -+@@ -68,9 +72,12 @@ static int ath10k_send_key(struct ath10k -+ * Otherwise pairwise key must be set */ -+ if (memcmp(macaddr, arvif->vif->addr, ETH_ALEN)) -+ arg.key_flags = WMI_KEY_PAIRWISE; -++ -++ if (def_idx) -++ arg.key_flags |= WMI_KEY_TX_USAGE; -+ break; -+ default: -+- ath10k_warn("cipher %d is not supported\n", key->cipher); -++ ath10k_warn(ar, "cipher %d is not supported\n", key->cipher); -+ return -EOPNOTSUPP; -+ } -+ -+@@ -85,7 +92,7 @@ static int ath10k_send_key(struct ath10k -+ static int ath10k_install_key(struct ath10k_vif *arvif, -+ struct ieee80211_key_conf *key, -+ enum set_key_cmd cmd, -+- const u8 *macaddr) -++ const u8 *macaddr, bool def_idx) -+ { -+ struct ath10k *ar = arvif->ar; -+ int ret; -+@@ -94,7 +101,7 @@ static int ath10k_install_key(struct ath -+ -+ reinit_completion(&ar->install_key_done); -+ -+- ret = ath10k_send_key(arvif, key, cmd, macaddr); -++ ret = ath10k_send_key(arvif, key, cmd, macaddr, def_idx); -+ if (ret) -+ return ret; -+ -+@@ -112,6 +119,7 @@ static int ath10k_install_peer_wep_keys( -+ struct ath10k_peer *peer; -+ int ret; -+ int i; -++ bool def_idx; -+ -+ lockdep_assert_held(&ar->conf_mutex); -+ -+@@ -125,13 +133,20 @@ static int ath10k_install_peer_wep_keys( -+ for (i = 0; i < ARRAY_SIZE(arvif->wep_keys); i++) { -+ if (arvif->wep_keys[i] == NULL) -+ continue; -++ /* set TX_USAGE flag for default key id */ -++ if (arvif->def_wep_key_idx == i) -++ def_idx = true; -++ else -++ def_idx = false; -+ -+ ret = ath10k_install_key(arvif, arvif->wep_keys[i], SET_KEY, -+- addr); -++ addr, def_idx); -+ if (ret) -+ return ret; -+ -++ spin_lock_bh(&ar->data_lock); -+ peer->keys[i] = arvif->wep_keys[i]; -++ spin_unlock_bh(&ar->data_lock); -+ } -+ -+ return 0; -+@@ -159,21 +174,49 @@ static int ath10k_clear_peer_keys(struct -+ if (peer->keys[i] == NULL) -+ continue; -+ -++ /* key flags are not required to delete the key */ -+ ret = ath10k_install_key(arvif, peer->keys[i], -+- DISABLE_KEY, addr); -++ DISABLE_KEY, addr, false); -+ if (ret && first_errno == 0) -+ first_errno = ret; -+ -+ if (ret) -+- ath10k_warn("failed to remove peer wep key %d: %d\n", -++ ath10k_warn(ar, "failed to remove peer wep key %d: %d\n", -+ i, ret); -+ -++ spin_lock_bh(&ar->data_lock); -+ peer->keys[i] = NULL; -++ spin_unlock_bh(&ar->data_lock); -+ } -+ -+ return first_errno; -+ } -+ -++bool ath10k_mac_is_peer_wep_key_set(struct ath10k *ar, const u8 *addr, -++ u8 keyidx) -++{ -++ struct ath10k_peer *peer; -++ int i; -++ -++ lockdep_assert_held(&ar->data_lock); -++ -++ /* We don't know which vdev this peer belongs to, -++ * since WMI doesn't give us that information. -++ * -++ * FIXME: multi-bss needs to be handled. -++ */ -++ peer = ath10k_peer_find(ar, 0, addr); -++ if (!peer) -++ return false; -++ -++ for (i = 0; i < ARRAY_SIZE(peer->keys); i++) { -++ if (peer->keys[i] && peer->keys[i]->keyidx == keyidx) -++ return true; -++ } -++ -++ return false; -++} -++ -+ static int ath10k_clear_vdev_key(struct ath10k_vif *arvif, -+ struct ieee80211_key_conf *key) -+ { -+@@ -194,7 +237,7 @@ static int ath10k_clear_vdev_key(struct -+ list_for_each_entry(peer, &ar->peers, list) { -+ for (i = 0; i < ARRAY_SIZE(peer->keys); i++) { -+ if (peer->keys[i] == key) { -+- memcpy(addr, peer->addr, ETH_ALEN); -++ ether_addr_copy(addr, peer->addr); -+ peer->keys[i] = NULL; -+ break; -+ } -+@@ -207,20 +250,19 @@ static int ath10k_clear_vdev_key(struct -+ -+ if (i == ARRAY_SIZE(peer->keys)) -+ break; -+- -+- ret = ath10k_install_key(arvif, key, DISABLE_KEY, addr); -++ /* key flags are not required to delete the key */ -++ ret = ath10k_install_key(arvif, key, DISABLE_KEY, addr, false); -+ if (ret && first_errno == 0) -+ first_errno = ret; -+ -+ if (ret) -+- ath10k_warn("failed to remove key for %pM: %d\n", -++ ath10k_warn(ar, "failed to remove key for %pM: %d\n", -+ addr, ret); -+ } -+ -+ return first_errno; -+ } -+ -+- -+ /*********************/ -+ /* General utilities */ -+ /*********************/ -+@@ -234,7 +276,10 @@ chan_to_phymode(const struct cfg80211_ch -+ case IEEE80211_BAND_2GHZ: -+ switch (chandef->width) { -+ case NL80211_CHAN_WIDTH_20_NOHT: -+- phymode = MODE_11G; -++ if (chandef->chan->flags & IEEE80211_CHAN_NO_OFDM) -++ phymode = MODE_11B; -++ else -++ phymode = MODE_11G; -+ break; -+ case NL80211_CHAN_WIDTH_20: -+ phymode = MODE_11NG_HT20; -+@@ -322,22 +367,24 @@ static int ath10k_peer_create(struct ath -+ -+ lockdep_assert_held(&ar->conf_mutex); -+ -++ if (ar->num_peers >= ar->max_num_peers) -++ return -ENOBUFS; -++ -+ ret = ath10k_wmi_peer_create(ar, vdev_id, addr); -+ if (ret) { -+- ath10k_warn("failed to create wmi peer %pM on vdev %i: %i\n", -++ ath10k_warn(ar, "failed to create wmi peer %pM on vdev %i: %i\n", -+ addr, vdev_id, ret); -+ return ret; -+ } -+ -+ ret = ath10k_wait_for_peer_created(ar, vdev_id, addr); -+ if (ret) { -+- ath10k_warn("failed to wait for created wmi peer %pM on vdev %i: %i\n", -++ ath10k_warn(ar, "failed to wait for created wmi peer %pM on vdev %i: %i\n", -+ addr, vdev_id, ret); -+ return ret; -+ } -+- spin_lock_bh(&ar->data_lock); -++ -+ ar->num_peers++; -+- spin_unlock_bh(&ar->data_lock); -+ -+ return 0; -+ } -+@@ -352,7 +399,7 @@ static int ath10k_mac_set_kickout(struct -+ ret = ath10k_wmi_pdev_set_param(ar, param, -+ ATH10K_KICKOUT_THRESHOLD); -+ if (ret) { -+- ath10k_warn("failed to set kickout threshold on vdev %i: %d\n", -++ ath10k_warn(ar, "failed to set kickout threshold on vdev %i: %d\n", -+ arvif->vdev_id, ret); -+ return ret; -+ } -+@@ -361,7 +408,7 @@ static int ath10k_mac_set_kickout(struct -+ ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, param, -+ ATH10K_KEEPALIVE_MIN_IDLE); -+ if (ret) { -+- ath10k_warn("failed to set keepalive minimum idle time on vdev %i: %d\n", -++ ath10k_warn(ar, "failed to set keepalive minimum idle time on vdev %i: %d\n", -+ arvif->vdev_id, ret); -+ return ret; -+ } -+@@ -370,7 +417,7 @@ static int ath10k_mac_set_kickout(struct -+ ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, param, -+ ATH10K_KEEPALIVE_MAX_IDLE); -+ if (ret) { -+- ath10k_warn("failed to set keepalive maximum idle time on vdev %i: %d\n", -++ ath10k_warn(ar, "failed to set keepalive maximum idle time on vdev %i: %d\n", -+ arvif->vdev_id, ret); -+ return ret; -+ } -+@@ -379,7 +426,7 @@ static int ath10k_mac_set_kickout(struct -+ ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, param, -+ ATH10K_KEEPALIVE_MAX_UNRESPONSIVE); -+ if (ret) { -+- ath10k_warn("failed to set keepalive maximum unresponsive time on vdev %i: %d\n", -++ ath10k_warn(ar, "failed to set keepalive maximum unresponsive time on vdev %i: %d\n", -+ arvif->vdev_id, ret); -+ return ret; -+ } -+@@ -387,15 +434,11 @@ static int ath10k_mac_set_kickout(struct -+ return 0; -+ } -+ -+-static int ath10k_mac_set_rts(struct ath10k_vif *arvif, u32 value) -++static int ath10k_mac_set_rts(struct ath10k_vif *arvif, u32 value) -+ { -+ struct ath10k *ar = arvif->ar; -+ u32 vdev_param; -+ -+- if (value != 0xFFFFFFFF) -+- value = min_t(u32, arvif->ar->hw->wiphy->rts_threshold, -+- ATH10K_RTS_MAX); -+- -+ vdev_param = ar->wmi.vdev_param->rts_threshold; -+ return ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param, value); -+ } -+@@ -428,9 +471,7 @@ static int ath10k_peer_delete(struct ath -+ if (ret) -+ return ret; -+ -+- spin_lock_bh(&ar->data_lock); -+ ar->num_peers--; -+- spin_unlock_bh(&ar->data_lock); -+ -+ return 0; -+ } -+@@ -446,7 +487,7 @@ static void ath10k_peer_cleanup(struct a -+ if (peer->vdev_id != vdev_id) -+ continue; -+ -+- ath10k_warn("removing stale peer %pM from vdev_id %d\n", -++ ath10k_warn(ar, "removing stale peer %pM from vdev_id %d\n", -+ peer->addr, vdev_id); -+ -+ list_del(&peer->list); -+@@ -467,20 +508,63 @@ static void ath10k_peer_cleanup_all(stru -+ list_del(&peer->list); -+ kfree(peer); -+ } -+- ar->num_peers = 0; -+ spin_unlock_bh(&ar->data_lock); -++ -++ ar->num_peers = 0; -++ ar->num_stations = 0; -+ } -+ -+ /************************/ -+ /* Interface management */ -+ /************************/ -+ -++void ath10k_mac_vif_beacon_free(struct ath10k_vif *arvif) -++{ -++ struct ath10k *ar = arvif->ar; -++ -++ lockdep_assert_held(&ar->data_lock); -++ -++ if (!arvif->beacon) -++ return; -++ -++ if (!arvif->beacon_buf) -++ dma_unmap_single(ar->dev, ATH10K_SKB_CB(arvif->beacon)->paddr, -++ arvif->beacon->len, DMA_TO_DEVICE); -++ -++ if (WARN_ON(arvif->beacon_state != ATH10K_BEACON_SCHEDULED && -++ arvif->beacon_state != ATH10K_BEACON_SENT)) -++ return; -++ -++ dev_kfree_skb_any(arvif->beacon); -++ -++ arvif->beacon = NULL; -++ arvif->beacon_state = ATH10K_BEACON_SCHEDULED; -++} -++ -++static void ath10k_mac_vif_beacon_cleanup(struct ath10k_vif *arvif) -++{ -++ struct ath10k *ar = arvif->ar; -++ -++ lockdep_assert_held(&ar->data_lock); -++ -++ ath10k_mac_vif_beacon_free(arvif); -++ -++ if (arvif->beacon_buf) { -++ dma_free_coherent(ar->dev, IEEE80211_MAX_FRAME_LEN, -++ arvif->beacon_buf, arvif->beacon_paddr); -++ arvif->beacon_buf = NULL; -++ } -++} -++ -+ static inline int ath10k_vdev_setup_sync(struct ath10k *ar) -+ { -+ int ret; -+ -+ lockdep_assert_held(&ar->conf_mutex); -+ -++ if (test_bit(ATH10K_FLAG_CRASH_FLUSH, &ar->dev_flags)) -++ return -ESHUTDOWN; -++ -+ ret = wait_for_completion_timeout(&ar->vdev_setup_done, -+ ATH10K_VDEV_SETUP_TIMEOUT_HZ); -+ if (ret == 0) -+@@ -489,19 +573,6 @@ static inline int ath10k_vdev_setup_sync -+ return 0; -+ } -+ -+-static bool ath10k_monitor_is_enabled(struct ath10k *ar) -+-{ -+- lockdep_assert_held(&ar->conf_mutex); -+- -+- ath10k_dbg(ATH10K_DBG_MAC, -+- "mac monitor refs: promisc %d monitor %d cac %d\n", -+- ar->promisc, ar->monitor, -+- test_bit(ATH10K_CAC_RUNNING, &ar->dev_flags)); -+- -+- return ar->promisc || ar->monitor || -+- test_bit(ATH10K_CAC_RUNNING, &ar->dev_flags); -+-} -+- -+ static int ath10k_monitor_vdev_start(struct ath10k *ar, int vdev_id) -+ { -+ struct cfg80211_chan_def *chandef = &ar->chandef; -+@@ -526,37 +597,39 @@ static int ath10k_monitor_vdev_start(str -+ arg.channel.max_reg_power = channel->max_reg_power * 2; -+ arg.channel.max_antenna_gain = channel->max_antenna_gain * 2; -+ -++ reinit_completion(&ar->vdev_setup_done); -++ -+ ret = ath10k_wmi_vdev_start(ar, &arg); -+ if (ret) { -+- ath10k_warn("failed to request monitor vdev %i start: %d\n", -++ ath10k_warn(ar, "failed to request monitor vdev %i start: %d\n", -+ vdev_id, ret); -+ return ret; -+ } -+ -+ ret = ath10k_vdev_setup_sync(ar); -+ if (ret) { -+- ath10k_warn("failed to synchronize setup for monitor vdev %i: %d\n", -++ ath10k_warn(ar, "failed to synchronize setup for monitor vdev %i start: %d\n", -+ vdev_id, ret); -+ return ret; -+ } -+ -+ ret = ath10k_wmi_vdev_up(ar, vdev_id, 0, ar->mac_addr); -+ if (ret) { -+- ath10k_warn("failed to put up monitor vdev %i: %d\n", -++ ath10k_warn(ar, "failed to put up monitor vdev %i: %d\n", -+ vdev_id, ret); -+ goto vdev_stop; -+ } -+ -+ ar->monitor_vdev_id = vdev_id; -+ -+- ath10k_dbg(ATH10K_DBG_MAC, "mac monitor vdev %i started\n", -++ ath10k_dbg(ar, ATH10K_DBG_MAC, "mac monitor vdev %i started\n", -+ ar->monitor_vdev_id); -+ return 0; -+ -+ vdev_stop: -+ ret = ath10k_wmi_vdev_stop(ar, ar->monitor_vdev_id); -+ if (ret) -+- ath10k_warn("failed to stop monitor vdev %i after start failure: %d\n", -++ ath10k_warn(ar, "failed to stop monitor vdev %i after start failure: %d\n", -+ ar->monitor_vdev_id, ret); -+ -+ return ret; -+@@ -570,20 +643,22 @@ static int ath10k_monitor_vdev_stop(stru -+ -+ ret = ath10k_wmi_vdev_down(ar, ar->monitor_vdev_id); -+ if (ret) -+- ath10k_warn("failed to put down monitor vdev %i: %d\n", -++ ath10k_warn(ar, "failed to put down monitor vdev %i: %d\n", -+ ar->monitor_vdev_id, ret); -+ -++ reinit_completion(&ar->vdev_setup_done); -++ -+ ret = ath10k_wmi_vdev_stop(ar, ar->monitor_vdev_id); -+ if (ret) -+- ath10k_warn("failed to to request monitor vdev %i stop: %d\n", -++ ath10k_warn(ar, "failed to to request monitor vdev %i stop: %d\n", -+ ar->monitor_vdev_id, ret); -+ -+ ret = ath10k_vdev_setup_sync(ar); -+ if (ret) -+- ath10k_warn("failed to synchronise monitor vdev %i: %d\n", -++ ath10k_warn(ar, "failed to synchronize monitor vdev %i stop: %d\n", -+ ar->monitor_vdev_id, ret); -+ -+- ath10k_dbg(ATH10K_DBG_MAC, "mac monitor vdev %i stopped\n", -++ ath10k_dbg(ar, ATH10K_DBG_MAC, "mac monitor vdev %i stopped\n", -+ ar->monitor_vdev_id); -+ return ret; -+ } -+@@ -594,35 +669,29 @@ static int ath10k_monitor_vdev_create(st -+ -+ lockdep_assert_held(&ar->conf_mutex); -+ -+- bit = ffs(ar->free_vdev_map); -+- if (bit == 0) { -+- ath10k_warn("failed to find free vdev id for monitor vdev\n"); -++ if (ar->free_vdev_map == 0) { -++ ath10k_warn(ar, "failed to find free vdev id for monitor vdev\n"); -+ return -ENOMEM; -+ } -+ -+- ar->monitor_vdev_id = bit - 1; -+- ar->free_vdev_map &= ~(1 << ar->monitor_vdev_id); -++ bit = __ffs64(ar->free_vdev_map); -++ -++ ar->monitor_vdev_id = bit; -+ -+ ret = ath10k_wmi_vdev_create(ar, ar->monitor_vdev_id, -+ WMI_VDEV_TYPE_MONITOR, -+ 0, ar->mac_addr); -+ if (ret) { -+- ath10k_warn("failed to request monitor vdev %i creation: %d\n", -++ ath10k_warn(ar, "failed to request monitor vdev %i creation: %d\n", -+ ar->monitor_vdev_id, ret); -+- goto vdev_fail; -++ return ret; -+ } -+ -+- ath10k_dbg(ATH10K_DBG_MAC, "mac monitor vdev %d created\n", -++ ar->free_vdev_map &= ~(1LL << ar->monitor_vdev_id); -++ ath10k_dbg(ar, ATH10K_DBG_MAC, "mac monitor vdev %d created\n", -+ ar->monitor_vdev_id); -+ -+ return 0; -+- -+-vdev_fail: -+- /* -+- * Restore the ID to the global map. -+- */ -+- ar->free_vdev_map |= 1 << (ar->monitor_vdev_id); -+- return ret; -+ } -+ -+ static int ath10k_monitor_vdev_delete(struct ath10k *ar) -+@@ -633,14 +702,14 @@ static int ath10k_monitor_vdev_delete(st -+ -+ ret = ath10k_wmi_vdev_delete(ar, ar->monitor_vdev_id); -+ if (ret) { -+- ath10k_warn("failed to request wmi monitor vdev %i removal: %d\n", -++ ath10k_warn(ar, "failed to request wmi monitor vdev %i removal: %d\n", -+ ar->monitor_vdev_id, ret); -+ return ret; -+ } -+ -+- ar->free_vdev_map |= 1 << (ar->monitor_vdev_id); -++ ar->free_vdev_map |= 1LL << ar->monitor_vdev_id; -+ -+- ath10k_dbg(ATH10K_DBG_MAC, "mac monitor vdev %d deleted\n", -++ ath10k_dbg(ar, ATH10K_DBG_MAC, "mac monitor vdev %d deleted\n", -+ ar->monitor_vdev_id); -+ return ret; -+ } -+@@ -651,63 +720,70 @@ static int ath10k_monitor_start(struct a -+ -+ lockdep_assert_held(&ar->conf_mutex); -+ -+- if (!ath10k_monitor_is_enabled(ar)) { -+- ath10k_warn("trying to start monitor with no references\n"); -+- return 0; -+- } -+- -+- if (ar->monitor_started) { -+- ath10k_dbg(ATH10K_DBG_MAC, "mac monitor already started\n"); -+- return 0; -+- } -+- -+ ret = ath10k_monitor_vdev_create(ar); -+ if (ret) { -+- ath10k_warn("failed to create monitor vdev: %d\n", ret); -++ ath10k_warn(ar, "failed to create monitor vdev: %d\n", ret); -+ return ret; -+ } -+ -+ ret = ath10k_monitor_vdev_start(ar, ar->monitor_vdev_id); -+ if (ret) { -+- ath10k_warn("failed to start monitor vdev: %d\n", ret); -++ ath10k_warn(ar, "failed to start monitor vdev: %d\n", ret); -+ ath10k_monitor_vdev_delete(ar); -+ return ret; -+ } -+ -+ ar->monitor_started = true; -+- ath10k_dbg(ATH10K_DBG_MAC, "mac monitor started\n"); -++ ath10k_dbg(ar, ATH10K_DBG_MAC, "mac monitor started\n"); -+ -+ return 0; -+ } -+ -+-static void ath10k_monitor_stop(struct ath10k *ar) -++static int ath10k_monitor_stop(struct ath10k *ar) -+ { -+ int ret; -+ -+ lockdep_assert_held(&ar->conf_mutex); -+ -+- if (ath10k_monitor_is_enabled(ar)) { -+- ath10k_dbg(ATH10K_DBG_MAC, -+- "mac monitor will be stopped later\n"); -+- return; -++ ret = ath10k_monitor_vdev_stop(ar); -++ if (ret) { -++ ath10k_warn(ar, "failed to stop monitor vdev: %d\n", ret); -++ return ret; -+ } -+ -+- if (!ar->monitor_started) { -+- ath10k_dbg(ATH10K_DBG_MAC, -+- "mac monitor probably failed to start earlier\n"); -+- return; -++ ret = ath10k_monitor_vdev_delete(ar); -++ if (ret) { -++ ath10k_warn(ar, "failed to delete monitor vdev: %d\n", ret); -++ return ret; -+ } -+ -+- ret = ath10k_monitor_vdev_stop(ar); -+- if (ret) -+- ath10k_warn("failed to stop monitor vdev: %d\n", ret); -++ ar->monitor_started = false; -++ ath10k_dbg(ar, ATH10K_DBG_MAC, "mac monitor stopped\n"); -+ -+- ret = ath10k_monitor_vdev_delete(ar); -+- if (ret) -+- ath10k_warn("failed to delete monitor vdev: %d\n", ret); -++ return 0; -++} -+ -+- ar->monitor_started = false; -+- ath10k_dbg(ATH10K_DBG_MAC, "mac monitor stopped\n"); -++static int ath10k_monitor_recalc(struct ath10k *ar) -++{ -++ bool should_start; -++ -++ lockdep_assert_held(&ar->conf_mutex); -++ -++ should_start = ar->monitor || -++ ar->filter_flags & FIF_PROMISC_IN_BSS || -++ test_bit(ATH10K_CAC_RUNNING, &ar->dev_flags); -++ -++ ath10k_dbg(ar, ATH10K_DBG_MAC, -++ "mac monitor recalc started? %d should? %d\n", -++ ar->monitor_started, should_start); -++ -++ if (should_start == ar->monitor_started) -++ return 0; -++ -++ if (should_start) -++ return ath10k_monitor_start(ar); -++ -++ return ath10k_monitor_stop(ar); -+ } -+ -+ static int ath10k_recalc_rtscts_prot(struct ath10k_vif *arvif) -+@@ -738,14 +814,14 @@ static int ath10k_start_cac(struct ath10 -+ -+ set_bit(ATH10K_CAC_RUNNING, &ar->dev_flags); -+ -+- ret = ath10k_monitor_start(ar); -++ ret = ath10k_monitor_recalc(ar); -+ if (ret) { -+- ath10k_warn("failed to start monitor (cac): %d\n", ret); -++ ath10k_warn(ar, "failed to start monitor (cac): %d\n", ret); -+ clear_bit(ATH10K_CAC_RUNNING, &ar->dev_flags); -+ return ret; -+ } -+ -+- ath10k_dbg(ATH10K_DBG_MAC, "mac cac start monitor vdev %d\n", -++ ath10k_dbg(ar, ATH10K_DBG_MAC, "mac cac start monitor vdev %d\n", -+ ar->monitor_vdev_id); -+ -+ return 0; -+@@ -762,7 +838,7 @@ static int ath10k_stop_cac(struct ath10k -+ clear_bit(ATH10K_CAC_RUNNING, &ar->dev_flags); -+ ath10k_monitor_stop(ar); -+ -+- ath10k_dbg(ATH10K_DBG_MAC, "mac cac finished\n"); -++ ath10k_dbg(ar, ATH10K_DBG_MAC, "mac cac finished\n"); -+ -+ return 0; -+ } -+@@ -788,12 +864,12 @@ static void ath10k_recalc_radar_detectio -+ * radiation is not allowed, make this channel DFS_UNAVAILABLE -+ * by indicating that radar was detected. -+ */ -+- ath10k_warn("failed to start CAC: %d\n", ret); -++ ath10k_warn(ar, "failed to start CAC: %d\n", ret); -+ ieee80211_radar_detected(ar->hw); -+ } -+ } -+ -+-static int ath10k_vdev_start(struct ath10k_vif *arvif) -++static int ath10k_vdev_start_restart(struct ath10k_vif *arvif, bool restart) -+ { -+ struct ath10k *ar = arvif->ar; -+ struct cfg80211_chan_def *chandef = &ar->chandef; -+@@ -830,22 +906,27 @@ static int ath10k_vdev_start(struct ath1 -+ arg.ssid_len = arvif->vif->bss_conf.ssid_len; -+ } -+ -+- ath10k_dbg(ATH10K_DBG_MAC, -++ ath10k_dbg(ar, ATH10K_DBG_MAC, -+ "mac vdev %d start center_freq %d phymode %s\n", -+ arg.vdev_id, arg.channel.freq, -+ ath10k_wmi_phymode_str(arg.channel.mode)); -+ -+- ret = ath10k_wmi_vdev_start(ar, &arg); -++ if (restart) -++ ret = ath10k_wmi_vdev_restart(ar, &arg); -++ else -++ ret = ath10k_wmi_vdev_start(ar, &arg); -++ -+ if (ret) { -+- ath10k_warn("failed to start WMI vdev %i: %d\n", -++ ath10k_warn(ar, "failed to start WMI vdev %i: %d\n", -+ arg.vdev_id, ret); -+ return ret; -+ } -+ -+ ret = ath10k_vdev_setup_sync(ar); -+ if (ret) { -+- ath10k_warn("failed to synchronise setup for vdev %i: %d\n", -+- arg.vdev_id, ret); -++ ath10k_warn(ar, -++ "failed to synchronize setup for vdev %i restart %d: %d\n", -++ arg.vdev_id, restart, ret); -+ return ret; -+ } -+ -+@@ -855,6 +936,16 @@ static int ath10k_vdev_start(struct ath1 -+ return ret; -+ } -+ -++static int ath10k_vdev_start(struct ath10k_vif *arvif) -++{ -++ return ath10k_vdev_start_restart(arvif, false); -++} -++ -++static int ath10k_vdev_restart(struct ath10k_vif *arvif) -++{ -++ return ath10k_vdev_start_restart(arvif, true); -++} -++ -+ static int ath10k_vdev_stop(struct ath10k_vif *arvif) -+ { -+ struct ath10k *ar = arvif->ar; -+@@ -866,14 +957,14 @@ static int ath10k_vdev_stop(struct ath10 -+ -+ ret = ath10k_wmi_vdev_stop(ar, arvif->vdev_id); -+ if (ret) { -+- ath10k_warn("failed to stop WMI vdev %i: %d\n", -++ ath10k_warn(ar, "failed to stop WMI vdev %i: %d\n", -+ arvif->vdev_id, ret); -+ return ret; -+ } -+ -+ ret = ath10k_vdev_setup_sync(ar); -+ if (ret) { -+- ath10k_warn("failed to syncronise setup for vdev %i: %d\n", -++ ath10k_warn(ar, "failed to synchronize setup for vdev %i stop: %d\n", -+ arvif->vdev_id, ret); -+ return ret; -+ } -+@@ -888,9 +979,147 @@ static int ath10k_vdev_stop(struct ath10 -+ return ret; -+ } -+ -++static int ath10k_mac_setup_bcn_p2p_ie(struct ath10k_vif *arvif, -++ struct sk_buff *bcn) -++{ -++ struct ath10k *ar = arvif->ar; -++ struct ieee80211_mgmt *mgmt; -++ const u8 *p2p_ie; -++ int ret; -++ -++ if (arvif->vdev_type != WMI_VDEV_TYPE_AP) -++ return 0; -++ -++ if (arvif->vdev_subtype != WMI_VDEV_SUBTYPE_P2P_GO) -++ return 0; -++ -++ mgmt = (void *)bcn->data; -++ p2p_ie = cfg80211_find_vendor_ie(WLAN_OUI_WFA, WLAN_OUI_TYPE_WFA_P2P, -++ mgmt->u.beacon.variable, -++ bcn->len - (mgmt->u.beacon.variable - -++ bcn->data)); -++ if (!p2p_ie) -++ return -ENOENT; -++ -++ ret = ath10k_wmi_p2p_go_bcn_ie(ar, arvif->vdev_id, p2p_ie); -++ if (ret) { -++ ath10k_warn(ar, "failed to submit p2p go bcn ie for vdev %i: %d\n", -++ arvif->vdev_id, ret); -++ return ret; -++ } -++ -++ return 0; -++} -++ -++static int ath10k_mac_remove_vendor_ie(struct sk_buff *skb, unsigned int oui, -++ u8 oui_type, size_t ie_offset) -++{ -++ size_t len; -++ const u8 *next; -++ const u8 *end; -++ u8 *ie; -++ -++ if (WARN_ON(skb->len < ie_offset)) -++ return -EINVAL; -++ -++ ie = (u8 *)cfg80211_find_vendor_ie(oui, oui_type, -++ skb->data + ie_offset, -++ skb->len - ie_offset); -++ if (!ie) -++ return -ENOENT; -++ -++ len = ie[1] + 2; -++ end = skb->data + skb->len; -++ next = ie + len; -++ -++ if (WARN_ON(next > end)) -++ return -EINVAL; -++ -++ memmove(ie, next, end - next); -++ skb_trim(skb, skb->len - len); -++ -++ return 0; -++} -++ -++static int ath10k_mac_setup_bcn_tmpl(struct ath10k_vif *arvif) -++{ -++ struct ath10k *ar = arvif->ar; -++ struct ieee80211_hw *hw = ar->hw; -++ struct ieee80211_vif *vif = arvif->vif; -++ struct ieee80211_mutable_offsets offs = {}; -++ struct sk_buff *bcn; -++ int ret; -++ -++ if (!test_bit(WMI_SERVICE_BEACON_OFFLOAD, ar->wmi.svc_map)) -++ return 0; -++ -++ bcn = ieee80211_beacon_get_template(hw, vif, &offs); -++ if (!bcn) { -++ ath10k_warn(ar, "failed to get beacon template from mac80211\n"); -++ return -EPERM; -++ } -++ -++ ret = ath10k_mac_setup_bcn_p2p_ie(arvif, bcn); -++ if (ret) { -++ ath10k_warn(ar, "failed to setup p2p go bcn ie: %d\n", ret); -++ kfree_skb(bcn); -++ return ret; -++ } -++ -++ /* P2P IE is inserted by firmware automatically (as configured above) -++ * so remove it from the base beacon template to avoid duplicate P2P -++ * IEs in beacon frames. -++ */ -++ ath10k_mac_remove_vendor_ie(bcn, WLAN_OUI_WFA, WLAN_OUI_TYPE_WFA_P2P, -++ offsetof(struct ieee80211_mgmt, -++ u.beacon.variable)); -++ -++ ret = ath10k_wmi_bcn_tmpl(ar, arvif->vdev_id, offs.tim_offset, bcn, 0, -++ 0, NULL, 0); -++ kfree_skb(bcn); -++ -++ if (ret) { -++ ath10k_warn(ar, "failed to submit beacon template command: %d\n", -++ ret); -++ return ret; -++ } -++ -++ return 0; -++} -++ -++static int ath10k_mac_setup_prb_tmpl(struct ath10k_vif *arvif) -++{ -++ struct ath10k *ar = arvif->ar; -++ struct ieee80211_hw *hw = ar->hw; -++ struct ieee80211_vif *vif = arvif->vif; -++ struct sk_buff *prb; -++ int ret; -++ -++ if (!test_bit(WMI_SERVICE_BEACON_OFFLOAD, ar->wmi.svc_map)) -++ return 0; -++ -++ prb = ieee80211_proberesp_get(hw, vif); -++ if (!prb) { -++ ath10k_warn(ar, "failed to get probe resp template from mac80211\n"); -++ return -EPERM; -++ } -++ -++ ret = ath10k_wmi_prb_tmpl(ar, arvif->vdev_id, prb); -++ kfree_skb(prb); -++ -++ if (ret) { -++ ath10k_warn(ar, "failed to submit probe resp template command: %d\n", -++ ret); -++ return ret; -++ } -++ -++ return 0; -++} -++ -+ static void ath10k_control_beaconing(struct ath10k_vif *arvif, -+- struct ieee80211_bss_conf *info) -++ struct ieee80211_bss_conf *info) -+ { -++ struct ath10k *ar = arvif->ar; -+ int ret = 0; -+ -+ lockdep_assert_held(&arvif->ar->conf_mutex); -+@@ -902,15 +1131,7 @@ static void ath10k_control_beaconing(str -+ arvif->is_up = false; -+ -+ spin_lock_bh(&arvif->ar->data_lock); -+- if (arvif->beacon) { -+- dma_unmap_single(arvif->ar->dev, -+- ATH10K_SKB_CB(arvif->beacon)->paddr, -+- arvif->beacon->len, DMA_TO_DEVICE); -+- dev_kfree_skb_any(arvif->beacon); -+- -+- arvif->beacon = NULL; -+- arvif->beacon_sent = false; -+- } -++ ath10k_mac_vif_beacon_free(arvif); -+ spin_unlock_bh(&arvif->ar->data_lock); -+ -+ return; -+@@ -923,12 +1144,12 @@ static void ath10k_control_beaconing(str -+ return; -+ -+ arvif->aid = 0; -+- memcpy(arvif->bssid, info->bssid, ETH_ALEN); -++ ether_addr_copy(arvif->bssid, info->bssid); -+ -+ ret = ath10k_wmi_vdev_up(arvif->ar, arvif->vdev_id, arvif->aid, -+ arvif->bssid); -+ if (ret) { -+- ath10k_warn("failed to bring up vdev %d: %i\n", -++ ath10k_warn(ar, "failed to bring up vdev %d: %i\n", -+ arvif->vdev_id, ret); -+ ath10k_vdev_stop(arvif); -+ return; -+@@ -937,13 +1158,14 @@ static void ath10k_control_beaconing(str -+ arvif->is_started = true; -+ arvif->is_up = true; -+ -+- ath10k_dbg(ATH10K_DBG_MAC, "mac vdev %d up\n", arvif->vdev_id); -++ ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %d up\n", arvif->vdev_id); -+ } -+ -+ static void ath10k_control_ibss(struct ath10k_vif *arvif, -+ struct ieee80211_bss_conf *info, -+ const u8 self_peer[ETH_ALEN]) -+ { -++ struct ath10k *ar = arvif->ar; -+ u32 vdev_param; -+ int ret = 0; -+ -+@@ -952,20 +1174,12 @@ static void ath10k_control_ibss(struct a -+ if (!info->ibss_joined) { -+ ret = ath10k_peer_delete(arvif->ar, arvif->vdev_id, self_peer); -+ if (ret) -+- ath10k_warn("failed to delete IBSS self peer %pM for vdev %d: %d\n", -++ ath10k_warn(ar, "failed to delete IBSS self peer %pM for vdev %d: %d\n", -+ self_peer, arvif->vdev_id, ret); -+ -+ if (is_zero_ether_addr(arvif->bssid)) -+ return; -+ -+- ret = ath10k_peer_delete(arvif->ar, arvif->vdev_id, -+- arvif->bssid); -+- if (ret) { -+- ath10k_warn("failed to delete IBSS BSSID peer %pM for vdev %d: %d\n", -+- arvif->bssid, arvif->vdev_id, ret); -+- return; -+- } -+- -+ memset(arvif->bssid, 0, ETH_ALEN); -+ -+ return; -+@@ -973,7 +1187,7 @@ static void ath10k_control_ibss(struct a -+ -+ ret = ath10k_peer_create(arvif->ar, arvif->vdev_id, self_peer); -+ if (ret) { -+- ath10k_warn("failed to create IBSS self peer %pM for vdev %d: %d\n", -++ ath10k_warn(ar, "failed to create IBSS self peer %pM for vdev %d: %d\n", -+ self_peer, arvif->vdev_id, ret); -+ return; -+ } -+@@ -982,103 +1196,211 @@ static void ath10k_control_ibss(struct a -+ ret = ath10k_wmi_vdev_set_param(arvif->ar, arvif->vdev_id, vdev_param, -+ ATH10K_DEFAULT_ATIM); -+ if (ret) -+- ath10k_warn("failed to set IBSS ATIM for vdev %d: %d\n", -++ ath10k_warn(ar, "failed to set IBSS ATIM for vdev %d: %d\n", -+ arvif->vdev_id, ret); -+ } -+ -+-/* -+- * Review this when mac80211 gains per-interface powersave support. -+- */ -+-static int ath10k_mac_vif_setup_ps(struct ath10k_vif *arvif) -++static int ath10k_mac_vif_recalc_ps_wake_threshold(struct ath10k_vif *arvif) -+ { -+ struct ath10k *ar = arvif->ar; -+- struct ieee80211_conf *conf = &ar->hw->conf; -+- enum wmi_sta_powersave_param param; -+- enum wmi_sta_ps_mode psmode; -++ u32 param; -++ u32 value; -+ int ret; -+ -+ lockdep_assert_held(&arvif->ar->conf_mutex); -+ -+- if (arvif->vif->type != NL80211_IFTYPE_STATION) -+- return 0; -+- -+- if (conf->flags & IEEE80211_CONF_PS) { -+- psmode = WMI_STA_PS_MODE_ENABLED; -+- param = WMI_STA_PS_PARAM_INACTIVITY_TIME; -++ if (arvif->u.sta.uapsd) -++ value = WMI_STA_PS_TX_WAKE_THRESHOLD_NEVER; -++ else -++ value = WMI_STA_PS_TX_WAKE_THRESHOLD_ALWAYS; -+ -+- ret = ath10k_wmi_set_sta_ps_param(ar, arvif->vdev_id, param, -+- conf->dynamic_ps_timeout); -+- if (ret) { -+- ath10k_warn("failed to set inactivity time for vdev %d: %i\n", -+- arvif->vdev_id, ret); -+- return ret; -+- } -+- } else { -+- psmode = WMI_STA_PS_MODE_DISABLED; -++ param = WMI_STA_PS_PARAM_TX_WAKE_THRESHOLD; -++ ret = ath10k_wmi_set_sta_ps_param(ar, arvif->vdev_id, param, value); -++ if (ret) { -++ ath10k_warn(ar, "failed to submit ps wake threshold %u on vdev %i: %d\n", -++ value, arvif->vdev_id, ret); -++ return ret; -+ } -+ -+- ath10k_dbg(ATH10K_DBG_MAC, "mac vdev %d psmode %s\n", -+- arvif->vdev_id, psmode ? "enable" : "disable"); -++ return 0; -++} -+ -+- ret = ath10k_wmi_set_psmode(ar, arvif->vdev_id, psmode); -++static int ath10k_mac_vif_recalc_ps_poll_count(struct ath10k_vif *arvif) -++{ -++ struct ath10k *ar = arvif->ar; -++ u32 param; -++ u32 value; -++ int ret; -++ -++ lockdep_assert_held(&arvif->ar->conf_mutex); -++ -++ if (arvif->u.sta.uapsd) -++ value = WMI_STA_PS_PSPOLL_COUNT_UAPSD; -++ else -++ value = WMI_STA_PS_PSPOLL_COUNT_NO_MAX; -++ -++ param = WMI_STA_PS_PARAM_PSPOLL_COUNT; -++ ret = ath10k_wmi_set_sta_ps_param(ar, arvif->vdev_id, -++ param, value); -+ if (ret) { -+- ath10k_warn("failed to set PS Mode %d for vdev %d: %d\n", -+- psmode, arvif->vdev_id, ret); -++ ath10k_warn(ar, "failed to submit ps poll count %u on vdev %i: %d\n", -++ value, arvif->vdev_id, ret); -+ return ret; -+ } -+ -+ return 0; -+ } -+ -+-/**********************/ -+-/* Station management */ -+-/**********************/ -+- -+-static void ath10k_peer_assoc_h_basic(struct ath10k *ar, -+- struct ath10k_vif *arvif, -+- struct ieee80211_sta *sta, -+- struct ieee80211_bss_conf *bss_conf, -+- struct wmi_peer_assoc_complete_arg *arg) -++static int ath10k_mac_ps_vif_count(struct ath10k *ar) -+ { -++ struct ath10k_vif *arvif; -++ int num = 0; -++ -+ lockdep_assert_held(&ar->conf_mutex); -+ -+- memcpy(arg->addr, sta->addr, ETH_ALEN); -+- arg->vdev_id = arvif->vdev_id; -+- arg->peer_aid = sta->aid; -+- arg->peer_flags |= WMI_PEER_AUTH; -++ list_for_each_entry(arvif, &ar->arvifs, list) -++ if (arvif->ps) -++ num++; -+ -+- if (arvif->vdev_type == WMI_VDEV_TYPE_STA) -+- /* -+- * Seems FW have problems with Power Save in STA -+- * mode when we setup this parameter to high (eg. 5). -+- * Often we see that FW don't send NULL (with clean P flags) -+- * frame even there is info about buffered frames in beacons. -+- * Sometimes we have to wait more than 10 seconds before FW -+- * will wakeup. Often sending one ping from AP to our device -+- * just fail (more than 50%). -+- * -+- * Seems setting this FW parameter to 1 couse FW -+- * will check every beacon and will wakup immediately -+- * after detection buffered data. -+- */ -+- arg->peer_listen_intval = 1; -+- else -+- arg->peer_listen_intval = ar->hw->conf.listen_interval; -++ return num; -++} -+ -+- arg->peer_num_spatial_streams = 1; -++static int ath10k_mac_vif_setup_ps(struct ath10k_vif *arvif) -++{ -++ struct ath10k *ar = arvif->ar; -++ struct ieee80211_vif *vif = arvif->vif; -++ struct ieee80211_conf *conf = &ar->hw->conf; -++ enum wmi_sta_powersave_param param; -++ enum wmi_sta_ps_mode psmode; -++ int ret; -++ int ps_timeout; -++ bool enable_ps; -+ -+- /* -+- * The assoc capabilities are available only in managed mode. -++ lockdep_assert_held(&arvif->ar->conf_mutex); -++ -++ if (arvif->vif->type != NL80211_IFTYPE_STATION) -++ return 0; -++ -++ enable_ps = arvif->ps; -++ -++ if (enable_ps && ath10k_mac_ps_vif_count(ar) > 1 && -++ !test_bit(ATH10K_FW_FEATURE_MULTI_VIF_PS_SUPPORT, -++ ar->fw_features)) { -++ ath10k_warn(ar, "refusing to enable ps on vdev %i: not supported by fw\n", -++ arvif->vdev_id); -++ enable_ps = false; -++ } -++ -++ if (enable_ps) { -++ psmode = WMI_STA_PS_MODE_ENABLED; -++ param = WMI_STA_PS_PARAM_INACTIVITY_TIME; -++ -++ ps_timeout = conf->dynamic_ps_timeout; -++ if (ps_timeout == 0) { -++ /* Firmware doesn't like 0 */ -++ ps_timeout = ieee80211_tu_to_usec( -++ vif->bss_conf.beacon_int) / 1000; -++ } -++ -++ ret = ath10k_wmi_set_sta_ps_param(ar, arvif->vdev_id, param, -++ ps_timeout); -++ if (ret) { -++ ath10k_warn(ar, "failed to set inactivity time for vdev %d: %i\n", -++ arvif->vdev_id, ret); -++ return ret; -++ } -++ } else { -++ psmode = WMI_STA_PS_MODE_DISABLED; -++ } -++ -++ ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %d psmode %s\n", -++ arvif->vdev_id, psmode ? "enable" : "disable"); -++ -++ ret = ath10k_wmi_set_psmode(ar, arvif->vdev_id, psmode); -++ if (ret) { -++ ath10k_warn(ar, "failed to set PS Mode %d for vdev %d: %d\n", -++ psmode, arvif->vdev_id, ret); -++ return ret; -++ } -++ -++ return 0; -++} -++ -++static int ath10k_mac_vif_disable_keepalive(struct ath10k_vif *arvif) -++{ -++ struct ath10k *ar = arvif->ar; -++ struct wmi_sta_keepalive_arg arg = {}; -++ int ret; -++ -++ lockdep_assert_held(&arvif->ar->conf_mutex); -++ -++ if (arvif->vdev_type != WMI_VDEV_TYPE_STA) -++ return 0; -++ -++ if (!test_bit(WMI_SERVICE_STA_KEEP_ALIVE, ar->wmi.svc_map)) -++ return 0; -++ -++ /* Some firmware revisions have a bug and ignore the `enabled` field. -++ * Instead use the interval to disable the keepalive. -++ */ -++ arg.vdev_id = arvif->vdev_id; -++ arg.enabled = 1; -++ arg.method = WMI_STA_KEEPALIVE_METHOD_NULL_FRAME; -++ arg.interval = WMI_STA_KEEPALIVE_INTERVAL_DISABLE; -++ -++ ret = ath10k_wmi_sta_keepalive(ar, &arg); -++ if (ret) { -++ ath10k_warn(ar, "failed to submit keepalive on vdev %i: %d\n", -++ arvif->vdev_id, ret); -++ return ret; -++ } -++ -++ return 0; -++} -++ -++/**********************/ -++/* Station management */ -++/**********************/ -++ -++static u32 ath10k_peer_assoc_h_listen_intval(struct ath10k *ar, -++ struct ieee80211_vif *vif) -++{ -++ /* Some firmware revisions have unstable STA powersave when listen -++ * interval is set too high (e.g. 5). The symptoms are firmware doesn't -++ * generate NullFunc frames properly even if buffered frames have been -++ * indicated in Beacon TIM. Firmware would seldom wake up to pull -++ * buffered frames. Often pinging the device from AP would simply fail. -++ * -++ * As a workaround set it to 1. -+ */ -+- if (arvif->vdev_type == WMI_VDEV_TYPE_STA && bss_conf) -+- arg->peer_caps = bss_conf->assoc_capability; -++ if (vif->type == NL80211_IFTYPE_STATION) -++ return 1; -++ -++ return ar->hw->conf.listen_interval; -++} -++ -++static void ath10k_peer_assoc_h_basic(struct ath10k *ar, -++ struct ieee80211_vif *vif, -++ struct ieee80211_sta *sta, -++ struct wmi_peer_assoc_complete_arg *arg) -++{ -++ struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif); -++ -++ lockdep_assert_held(&ar->conf_mutex); -++ -++ ether_addr_copy(arg->addr, sta->addr); -++ arg->vdev_id = arvif->vdev_id; -++ arg->peer_aid = sta->aid; -++ arg->peer_flags |= WMI_PEER_AUTH; -++ arg->peer_listen_intval = ath10k_peer_assoc_h_listen_intval(ar, vif); -++ arg->peer_num_spatial_streams = 1; -++ arg->peer_caps = vif->bss_conf.assoc_capability; -+ } -+ -+ static void ath10k_peer_assoc_h_crypto(struct ath10k *ar, -+- struct ath10k_vif *arvif, -++ struct ieee80211_vif *vif, -+ struct wmi_peer_assoc_complete_arg *arg) -+ { -+- struct ieee80211_vif *vif = arvif->vif; -+ struct ieee80211_bss_conf *info = &vif->bss_conf; -+ struct cfg80211_bss *bss; -+ const u8 *rsnie = NULL; -+@@ -1097,21 +1419,21 @@ static void ath10k_peer_assoc_h_crypto(s -+ ies = rcu_dereference(bss->ies); -+ -+ wpaie = cfg80211_find_vendor_ie(WLAN_OUI_MICROSOFT, -+- WLAN_OUI_TYPE_MICROSOFT_WPA, -+- ies->data, -+- ies->len); -++ WLAN_OUI_TYPE_MICROSOFT_WPA, -++ ies->data, -++ ies->len); -+ rcu_read_unlock(); -+ cfg80211_put_bss(ar->hw->wiphy, bss); -+ } -+ -+ /* FIXME: base on RSN IE/WPA IE is a correct idea? */ -+ if (rsnie || wpaie) { -+- ath10k_dbg(ATH10K_DBG_WMI, "%s: rsn ie found\n", __func__); -++ ath10k_dbg(ar, ATH10K_DBG_WMI, "%s: rsn ie found\n", __func__); -+ arg->peer_flags |= WMI_PEER_NEED_PTK_4_WAY; -+ } -+ -+ if (wpaie) { -+- ath10k_dbg(ATH10K_DBG_WMI, "%s: wpa ie found\n", __func__); -++ ath10k_dbg(ar, ATH10K_DBG_WMI, "%s: wpa ie found\n", __func__); -+ arg->peer_flags |= WMI_PEER_NEED_GTK_2_WAY; -+ } -+ } -+@@ -1149,6 +1471,7 @@ static void ath10k_peer_assoc_h_ht(struc -+ { -+ const struct ieee80211_sta_ht_cap *ht_cap = &sta->ht_cap; -+ int i, n; -++ u32 stbc; -+ -+ lockdep_assert_held(&ar->conf_mutex); -+ -+@@ -1185,7 +1508,6 @@ static void ath10k_peer_assoc_h_ht(struc -+ } -+ -+ if (ht_cap->cap & IEEE80211_HT_CAP_RX_STBC) { -+- u32 stbc; -+ stbc = ht_cap->cap & IEEE80211_HT_CAP_RX_STBC; -+ stbc = stbc >> IEEE80211_HT_CAP_RX_STBC_SHIFT; -+ stbc = stbc << WMI_RC_RX_STBC_FLAG_S; -+@@ -1220,7 +1542,7 @@ static void ath10k_peer_assoc_h_ht(struc -+ arg->peer_num_spatial_streams = sta->rx_nss; -+ } -+ -+- ath10k_dbg(ATH10K_DBG_MAC, "mac ht peer %pM mcs cnt %d nss %d\n", -++ ath10k_dbg(ar, ATH10K_DBG_MAC, "mac ht peer %pM mcs cnt %d nss %d\n", -+ arg->addr, -+ arg->peer_ht_rates.num_rates, -+ arg->peer_num_spatial_streams); -+@@ -1237,7 +1559,7 @@ static int ath10k_peer_assoc_qos_ap(stru -+ lockdep_assert_held(&ar->conf_mutex); -+ -+ if (sta->wme && sta->uapsd_queues) { -+- ath10k_dbg(ATH10K_DBG_MAC, "mac uapsd_queues 0x%x max_sp %d\n", -++ ath10k_dbg(ar, ATH10K_DBG_MAC, "mac uapsd_queues 0x%x max_sp %d\n", -+ sta->uapsd_queues, sta->max_sp); -+ -+ if (sta->uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_VO) -+@@ -1253,7 +1575,6 @@ static int ath10k_peer_assoc_qos_ap(stru -+ uapsd |= WMI_AP_PS_UAPSD_AC0_DELIVERY_EN | -+ WMI_AP_PS_UAPSD_AC0_TRIGGER_EN; -+ -+- -+ if (sta->max_sp < MAX_WMI_AP_PS_PEER_PARAM_MAX_SP) -+ max_sp = sta->max_sp; -+ -+@@ -1262,7 +1583,7 @@ static int ath10k_peer_assoc_qos_ap(stru -+ WMI_AP_PS_PEER_PARAM_UAPSD, -+ uapsd); -+ if (ret) { -+- ath10k_warn("failed to set ap ps peer param uapsd for vdev %i: %d\n", -++ ath10k_warn(ar, "failed to set ap ps peer param uapsd for vdev %i: %d\n", -+ arvif->vdev_id, ret); -+ return ret; -+ } -+@@ -1272,7 +1593,7 @@ static int ath10k_peer_assoc_qos_ap(stru -+ WMI_AP_PS_PEER_PARAM_MAX_SP, -+ max_sp); -+ if (ret) { -+- ath10k_warn("failed to set ap ps peer param max sp for vdev %i: %d\n", -++ ath10k_warn(ar, "failed to set ap ps peer param max sp for vdev %i: %d\n", -+ arvif->vdev_id, ret); -+ return ret; -+ } -+@@ -1282,9 +1603,10 @@ static int ath10k_peer_assoc_qos_ap(stru -+ sta->listen_interval - mac80211 patch required. -+ Currently use 10 seconds */ -+ ret = ath10k_wmi_set_ap_ps_param(ar, arvif->vdev_id, sta->addr, -+- WMI_AP_PS_PEER_PARAM_AGEOUT_TIME, 10); -++ WMI_AP_PS_PEER_PARAM_AGEOUT_TIME, -++ 10); -+ if (ret) { -+- ath10k_warn("failed to set ap ps peer param ageout time for vdev %i: %d\n", -++ ath10k_warn(ar, "failed to set ap ps peer param ageout time for vdev %i: %d\n", -+ arvif->vdev_id, ret); -+ return ret; -+ } -+@@ -1304,8 +1626,11 @@ static void ath10k_peer_assoc_h_vht(stru -+ return; -+ -+ arg->peer_flags |= WMI_PEER_VHT; -+- arg->peer_vht_caps = vht_cap->cap; -+ -++ if (ar->hw->conf.chandef.chan->band == IEEE80211_BAND_2GHZ) -++ arg->peer_flags |= WMI_PEER_VHT_2G; -++ -++ arg->peer_vht_caps = vht_cap->cap; -+ -+ ampdu_factor = (vht_cap->cap & -+ IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MASK) >> -+@@ -1331,16 +1656,17 @@ static void ath10k_peer_assoc_h_vht(stru -+ arg->peer_vht_rates.tx_mcs_set = -+ __le16_to_cpu(vht_cap->vht_mcs.tx_mcs_map); -+ -+- ath10k_dbg(ATH10K_DBG_MAC, "mac vht peer %pM max_mpdu %d flags 0x%x\n", -++ ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vht peer %pM max_mpdu %d flags 0x%x\n", -+ sta->addr, arg->peer_max_mpdu, arg->peer_flags); -+ } -+ -+ static void ath10k_peer_assoc_h_qos(struct ath10k *ar, -+- struct ath10k_vif *arvif, -++ struct ieee80211_vif *vif, -+ struct ieee80211_sta *sta, -+- struct ieee80211_bss_conf *bss_conf, -+ struct wmi_peer_assoc_complete_arg *arg) -+ { -++ struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif); -++ -+ switch (arvif->vdev_type) { -+ case WMI_VDEV_TYPE_AP: -+ if (sta->wme) -+@@ -1352,16 +1678,29 @@ static void ath10k_peer_assoc_h_qos(stru -+ } -+ break; -+ case WMI_VDEV_TYPE_STA: -+- if (bss_conf->qos) -++ if (vif->bss_conf.qos) -++ arg->peer_flags |= WMI_PEER_QOS; -++ break; -++ case WMI_VDEV_TYPE_IBSS: -++ if (sta->wme) -+ arg->peer_flags |= WMI_PEER_QOS; -+ break; -+ default: -+ break; -+ } -++ -++ ath10k_dbg(ar, ATH10K_DBG_MAC, "mac peer %pM qos %d\n", -++ sta->addr, !!(arg->peer_flags & WMI_PEER_QOS)); -++} -++ -++static bool ath10k_mac_sta_has_11g_rates(struct ieee80211_sta *sta) -++{ -++ /* First 4 rates in ath10k_rates are CCK (11b) rates. */ -++ return sta->supp_rates[IEEE80211_BAND_2GHZ] >> 4; -+ } -+ -+ static void ath10k_peer_assoc_h_phymode(struct ath10k *ar, -+- struct ath10k_vif *arvif, -++ struct ieee80211_vif *vif, -+ struct ieee80211_sta *sta, -+ struct wmi_peer_assoc_complete_arg *arg) -+ { -+@@ -1369,13 +1708,20 @@ static void ath10k_peer_assoc_h_phymode( -+ -+ switch (ar->hw->conf.chandef.chan->band) { -+ case IEEE80211_BAND_2GHZ: -+- if (sta->ht_cap.ht_supported) { -++ if (sta->vht_cap.vht_supported) { -++ if (sta->bandwidth == IEEE80211_STA_RX_BW_40) -++ phymode = MODE_11AC_VHT40; -++ else -++ phymode = MODE_11AC_VHT20; -++ } else if (sta->ht_cap.ht_supported) { -+ if (sta->bandwidth == IEEE80211_STA_RX_BW_40) -+ phymode = MODE_11NG_HT40; -+ else -+ phymode = MODE_11NG_HT20; -+- } else { -++ } else if (ath10k_mac_sta_has_11g_rates(sta)) { -+ phymode = MODE_11G; -++ } else { -++ phymode = MODE_11B; -+ } -+ -+ break; -+@@ -1404,7 +1750,7 @@ static void ath10k_peer_assoc_h_phymode( -+ break; -+ } -+ -+- ath10k_dbg(ATH10K_DBG_MAC, "mac peer %pM phymode %s\n", -++ ath10k_dbg(ar, ATH10K_DBG_MAC, "mac peer %pM phymode %s\n", -+ sta->addr, ath10k_wmi_phymode_str(phymode)); -+ -+ arg->peer_phymode = phymode; -+@@ -1412,22 +1758,21 @@ static void ath10k_peer_assoc_h_phymode( -+ } -+ -+ static int ath10k_peer_assoc_prepare(struct ath10k *ar, -+- struct ath10k_vif *arvif, -++ struct ieee80211_vif *vif, -+ struct ieee80211_sta *sta, -+- struct ieee80211_bss_conf *bss_conf, -+ struct wmi_peer_assoc_complete_arg *arg) -+ { -+ lockdep_assert_held(&ar->conf_mutex); -+ -+ memset(arg, 0, sizeof(*arg)); -+ -+- ath10k_peer_assoc_h_basic(ar, arvif, sta, bss_conf, arg); -+- ath10k_peer_assoc_h_crypto(ar, arvif, arg); -++ ath10k_peer_assoc_h_basic(ar, vif, sta, arg); -++ ath10k_peer_assoc_h_crypto(ar, vif, arg); -+ ath10k_peer_assoc_h_rates(ar, sta, arg); -+ ath10k_peer_assoc_h_ht(ar, sta, arg); -+ ath10k_peer_assoc_h_vht(ar, sta, arg); -+- ath10k_peer_assoc_h_qos(ar, arvif, sta, bss_conf, arg); -+- ath10k_peer_assoc_h_phymode(ar, arvif, sta, arg); -++ ath10k_peer_assoc_h_qos(ar, vif, sta, arg); -++ ath10k_peer_assoc_h_phymode(ar, vif, sta, arg); -+ -+ return 0; -+ } -+@@ -1459,6 +1804,68 @@ static int ath10k_setup_peer_smps(struct -+ ath10k_smps_map[smps]); -+ } -+ -++static int ath10k_mac_vif_recalc_txbf(struct ath10k *ar, -++ struct ieee80211_vif *vif, -++ struct ieee80211_sta_vht_cap vht_cap) -++{ -++ struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif); -++ int ret; -++ u32 param; -++ u32 value; -++ -++ if (!(ar->vht_cap_info & -++ (IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE | -++ IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE | -++ IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE | -++ IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE))) -++ return 0; -++ -++ param = ar->wmi.vdev_param->txbf; -++ value = 0; -++ -++ if (WARN_ON(param == WMI_VDEV_PARAM_UNSUPPORTED)) -++ return 0; -++ -++ /* The following logic is correct. If a remote STA advertises support -++ * for being a beamformer then we should enable us being a beamformee. -++ */ -++ -++ if (ar->vht_cap_info & -++ (IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE | -++ IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE)) { -++ if (vht_cap.cap & IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE) -++ value |= WMI_VDEV_PARAM_TXBF_SU_TX_BFEE; -++ -++ if (vht_cap.cap & IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE) -++ value |= WMI_VDEV_PARAM_TXBF_MU_TX_BFEE; -++ } -++ -++ if (ar->vht_cap_info & -++ (IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE | -++ IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE)) { -++ if (vht_cap.cap & IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE) -++ value |= WMI_VDEV_PARAM_TXBF_SU_TX_BFER; -++ -++ if (vht_cap.cap & IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE) -++ value |= WMI_VDEV_PARAM_TXBF_MU_TX_BFER; -++ } -++ -++ if (value & WMI_VDEV_PARAM_TXBF_MU_TX_BFEE) -++ value |= WMI_VDEV_PARAM_TXBF_SU_TX_BFEE; -++ -++ if (value & WMI_VDEV_PARAM_TXBF_MU_TX_BFER) -++ value |= WMI_VDEV_PARAM_TXBF_SU_TX_BFER; -++ -++ ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, param, value); -++ if (ret) { -++ ath10k_warn(ar, "failed to submit vdev param txbf 0x%x: %d\n", -++ value, ret); -++ return ret; -++ } -++ -++ return 0; -++} -++ -+ /* can be called only in mac80211 callbacks due to `key_count` usage */ -+ static void ath10k_bss_assoc(struct ieee80211_hw *hw, -+ struct ieee80211_vif *vif, -+@@ -1467,17 +1874,21 @@ static void ath10k_bss_assoc(struct ieee -+ struct ath10k *ar = hw->priv; -+ struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif); -+ struct ieee80211_sta_ht_cap ht_cap; -++ struct ieee80211_sta_vht_cap vht_cap; -+ struct wmi_peer_assoc_complete_arg peer_arg; -+ struct ieee80211_sta *ap_sta; -+ int ret; -+ -+ lockdep_assert_held(&ar->conf_mutex); -+ -++ ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %i assoc bssid %pM aid %d\n", -++ arvif->vdev_id, arvif->bssid, arvif->aid); -++ -+ rcu_read_lock(); -+ -+ ap_sta = ieee80211_find_sta(vif, bss_conf->bssid); -+ if (!ap_sta) { -+- ath10k_warn("failed to find station entry for bss %pM vdev %i\n", -++ ath10k_warn(ar, "failed to find station entry for bss %pM vdev %i\n", -+ bss_conf->bssid, arvif->vdev_id); -+ rcu_read_unlock(); -+ return; -+@@ -1486,11 +1897,11 @@ static void ath10k_bss_assoc(struct ieee -+ /* ap_sta must be accessed only within rcu section which must be left -+ * before calling ath10k_setup_peer_smps() which might sleep. */ -+ ht_cap = ap_sta->ht_cap; -++ vht_cap = ap_sta->vht_cap; -+ -+- ret = ath10k_peer_assoc_prepare(ar, arvif, ap_sta, -+- bss_conf, &peer_arg); -++ ret = ath10k_peer_assoc_prepare(ar, vif, ap_sta, &peer_arg); -+ if (ret) { -+- ath10k_warn("failed to prepare peer assoc for %pM vdev %i: %d\n", -++ ath10k_warn(ar, "failed to prepare peer assoc for %pM vdev %i: %d\n", -+ bss_conf->bssid, arvif->vdev_id, ret); -+ rcu_read_unlock(); -+ return; -+@@ -1500,88 +1911,100 @@ static void ath10k_bss_assoc(struct ieee -+ -+ ret = ath10k_wmi_peer_assoc(ar, &peer_arg); -+ if (ret) { -+- ath10k_warn("failed to run peer assoc for %pM vdev %i: %d\n", -++ ath10k_warn(ar, "failed to run peer assoc for %pM vdev %i: %d\n", -+ bss_conf->bssid, arvif->vdev_id, ret); -+ return; -+ } -+ -+ ret = ath10k_setup_peer_smps(ar, arvif, bss_conf->bssid, &ht_cap); -+ if (ret) { -+- ath10k_warn("failed to setup peer SMPS for vdev %i: %d\n", -++ ath10k_warn(ar, "failed to setup peer SMPS for vdev %i: %d\n", -+ arvif->vdev_id, ret); -+ return; -+ } -+ -+- ath10k_dbg(ATH10K_DBG_MAC, -++ ret = ath10k_mac_vif_recalc_txbf(ar, vif, vht_cap); -++ if (ret) { -++ ath10k_warn(ar, "failed to recalc txbf for vdev %i on bss %pM: %d\n", -++ arvif->vdev_id, bss_conf->bssid, ret); -++ return; -++ } -++ -++ ath10k_dbg(ar, ATH10K_DBG_MAC, -+ "mac vdev %d up (associated) bssid %pM aid %d\n", -+ arvif->vdev_id, bss_conf->bssid, bss_conf->aid); -+ -++ WARN_ON(arvif->is_up); -++ -+ arvif->aid = bss_conf->aid; -+- memcpy(arvif->bssid, bss_conf->bssid, ETH_ALEN); -++ ether_addr_copy(arvif->bssid, bss_conf->bssid); -+ -+ ret = ath10k_wmi_vdev_up(ar, arvif->vdev_id, arvif->aid, arvif->bssid); -+ if (ret) { -+- ath10k_warn("failed to set vdev %d up: %d\n", -++ ath10k_warn(ar, "failed to set vdev %d up: %d\n", -+ arvif->vdev_id, ret); -+ return; -+ } -+ -+ arvif->is_up = true; -++ -++ /* Workaround: Some firmware revisions (tested with qca6174 -++ * WLAN.RM.2.0-00073) have buggy powersave state machine and must be -++ * poked with peer param command. -++ */ -++ ret = ath10k_wmi_peer_set_param(ar, arvif->vdev_id, arvif->bssid, -++ WMI_PEER_DUMMY_VAR, 1); -++ if (ret) { -++ ath10k_warn(ar, "failed to poke peer %pM param for ps workaround on vdev %i: %d\n", -++ arvif->bssid, arvif->vdev_id, ret); -++ return; -++ } -+ } -+ -+-/* -+- * FIXME: flush TIDs -+- */ -+ static void ath10k_bss_disassoc(struct ieee80211_hw *hw, -+ struct ieee80211_vif *vif) -+ { -+ struct ath10k *ar = hw->priv; -+ struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif); -++ struct ieee80211_sta_vht_cap vht_cap = {}; -+ int ret; -+ -+ lockdep_assert_held(&ar->conf_mutex); -+ -+- /* -+- * For some reason, calling VDEV-DOWN before VDEV-STOP -+- * makes the FW to send frames via HTT after disassociation. -+- * No idea why this happens, even though VDEV-DOWN is supposed -+- * to be analogous to link down, so just stop the VDEV. -+- */ -+- ath10k_dbg(ATH10K_DBG_MAC, "mac vdev %d stop (disassociated\n", -+- arvif->vdev_id); -+- -+- /* FIXME: check return value */ -+- ret = ath10k_vdev_stop(arvif); -+- -+- /* -+- * If we don't call VDEV-DOWN after VDEV-STOP FW will remain active and -+- * report beacons from previously associated network through HTT. -+- * This in turn would spam mac80211 WARN_ON if we bring down all -+- * interfaces as it expects there is no rx when no interface is -+- * running. -+- */ -+- ath10k_dbg(ATH10K_DBG_MAC, "mac vdev %d down\n", arvif->vdev_id); -++ ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %i disassoc bssid %pM\n", -++ arvif->vdev_id, arvif->bssid); -+ -+- /* FIXME: why don't we print error if wmi call fails? */ -+ ret = ath10k_wmi_vdev_down(ar, arvif->vdev_id); -++ if (ret) -++ ath10k_warn(ar, "faield to down vdev %i: %d\n", -++ arvif->vdev_id, ret); -+ -+- arvif->def_wep_key_idx = 0; -++ arvif->def_wep_key_idx = -1; -++ -++ ret = ath10k_mac_vif_recalc_txbf(ar, vif, vht_cap); -++ if (ret) { -++ ath10k_warn(ar, "failed to recalc txbf for vdev %i: %d\n", -++ arvif->vdev_id, ret); -++ return; -++ } -+ -+- arvif->is_started = false; -+ arvif->is_up = false; -+ } -+ -+-static int ath10k_station_assoc(struct ath10k *ar, struct ath10k_vif *arvif, -+- struct ieee80211_sta *sta, bool reassoc) -++static int ath10k_station_assoc(struct ath10k *ar, -++ struct ieee80211_vif *vif, -++ struct ieee80211_sta *sta, -++ bool reassoc) -+ { -++ struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif); -+ struct wmi_peer_assoc_complete_arg peer_arg; -+ int ret = 0; -+ -+ lockdep_assert_held(&ar->conf_mutex); -+ -+- ret = ath10k_peer_assoc_prepare(ar, arvif, sta, NULL, &peer_arg); -++ ret = ath10k_peer_assoc_prepare(ar, vif, sta, &peer_arg); -+ if (ret) { -+- ath10k_warn("failed to prepare WMI peer assoc for %pM vdev %i: %i\n", -++ ath10k_warn(ar, "failed to prepare WMI peer assoc for %pM vdev %i: %i\n", -+ sta->addr, arvif->vdev_id, ret); -+ return ret; -+ } -+@@ -1589,48 +2012,59 @@ static int ath10k_station_assoc(struct a -+ peer_arg.peer_reassoc = reassoc; -+ ret = ath10k_wmi_peer_assoc(ar, &peer_arg); -+ if (ret) { -+- ath10k_warn("failed to run peer assoc for STA %pM vdev %i: %d\n", -++ ath10k_warn(ar, "failed to run peer assoc for STA %pM vdev %i: %d\n", -+ sta->addr, arvif->vdev_id, ret); -+ return ret; -+ } -+ -+- ret = ath10k_setup_peer_smps(ar, arvif, sta->addr, &sta->ht_cap); -+- if (ret) { -+- ath10k_warn("failed to setup peer SMPS for vdev %d: %d\n", -+- arvif->vdev_id, ret); -+- return ret; -+- } -+- -+- if (!sta->wme) { -+- arvif->num_legacy_stations++; -+- ret = ath10k_recalc_rtscts_prot(arvif); -++ /* Re-assoc is run only to update supported rates for given station. It -++ * doesn't make much sense to reconfigure the peer completely. -++ */ -++ if (!reassoc) { -++ ret = ath10k_setup_peer_smps(ar, arvif, sta->addr, -++ &sta->ht_cap); -+ if (ret) { -+- ath10k_warn("failed to recalculate rts/cts prot for vdev %d: %d\n", -++ ath10k_warn(ar, "failed to setup peer SMPS for vdev %d: %d\n", -+ arvif->vdev_id, ret); -+ return ret; -+ } -+- } -+ -+- ret = ath10k_install_peer_wep_keys(arvif, sta->addr); -+- if (ret) { -+- ath10k_warn("failed to install peer wep keys for vdev %i: %d\n", -+- arvif->vdev_id, ret); -+- return ret; -+- } -++ ret = ath10k_peer_assoc_qos_ap(ar, arvif, sta); -++ if (ret) { -++ ath10k_warn(ar, "failed to set qos params for STA %pM for vdev %i: %d\n", -++ sta->addr, arvif->vdev_id, ret); -++ return ret; -++ } -+ -+- ret = ath10k_peer_assoc_qos_ap(ar, arvif, sta); -+- if (ret) { -+- ath10k_warn("failed to set qos params for STA %pM for vdev %i: %d\n", -+- sta->addr, arvif->vdev_id, ret); -+- return ret; -++ if (!sta->wme) { -++ arvif->num_legacy_stations++; -++ ret = ath10k_recalc_rtscts_prot(arvif); -++ if (ret) { -++ ath10k_warn(ar, "failed to recalculate rts/cts prot for vdev %d: %d\n", -++ arvif->vdev_id, ret); -++ return ret; -++ } -++ } -++ -++ /* Plumb cached keys only for static WEP */ -++ if (arvif->def_wep_key_idx != -1) { -++ ret = ath10k_install_peer_wep_keys(arvif, sta->addr); -++ if (ret) { -++ ath10k_warn(ar, "failed to install peer wep keys for vdev %i: %d\n", -++ arvif->vdev_id, ret); -++ return ret; -++ } -++ } -+ } -+ -+ return ret; -+ } -+ -+-static int ath10k_station_disassoc(struct ath10k *ar, struct ath10k_vif *arvif, -++static int ath10k_station_disassoc(struct ath10k *ar, -++ struct ieee80211_vif *vif, -+ struct ieee80211_sta *sta) -+ { -++ struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif); -+ int ret = 0; -+ -+ lockdep_assert_held(&ar->conf_mutex); -+@@ -1639,7 +2073,7 @@ static int ath10k_station_disassoc(struc -+ arvif->num_legacy_stations--; -+ ret = ath10k_recalc_rtscts_prot(arvif); -+ if (ret) { -+- ath10k_warn("failed to recalculate rts/cts prot for vdev %d: %d\n", -++ ath10k_warn(ar, "failed to recalculate rts/cts prot for vdev %d: %d\n", -+ arvif->vdev_id, ret); -+ return ret; -+ } -+@@ -1647,7 +2081,7 @@ static int ath10k_station_disassoc(struc -+ -+ ret = ath10k_clear_peer_keys(arvif, sta->addr); -+ if (ret) { -+- ath10k_warn("failed to clear all peer wep keys for vdev %i: %d\n", -++ ath10k_warn(ar, "failed to clear all peer wep keys for vdev %i: %d\n", -+ arvif->vdev_id, ret); -+ return ret; -+ } -+@@ -1722,6 +2156,7 @@ static int ath10k_update_channel_list(st -+ ch->passive = passive; -+ -+ ch->freq = channel->center_freq; -++ ch->band_center_freq1 = channel->center_freq; -+ ch->min_power = 0; -+ ch->max_power = channel->max_power * 2; -+ ch->max_reg_power = channel->max_reg_power * 2; -+@@ -1739,7 +2174,7 @@ static int ath10k_update_channel_list(st -+ if (WARN_ON_ONCE(ch->mode == MODE_UNKNOWN)) -+ continue; -+ -+- ath10k_dbg(ATH10K_DBG_WMI, -++ ath10k_dbg(ar, ATH10K_DBG_WMI, -+ "mac channel [%zd/%d] freq %d maxpower %d regpower %d antenna %d mode %d\n", -+ ch - arg.channels, arg.n_channels, -+ ch->freq, ch->max_power, ch->max_reg_power, -+@@ -1782,7 +2217,7 @@ static void ath10k_regd_update(struct at -+ -+ ret = ath10k_update_channel_list(ar); -+ if (ret) -+- ath10k_warn("failed to update channel list: %d\n", ret); -++ ath10k_warn(ar, "failed to update channel list: %d\n", ret); -+ -+ regpair = ar->ath_common.regulatory.regpair; -+ -+@@ -1803,7 +2238,7 @@ static void ath10k_regd_update(struct at -+ regpair->reg_5ghz_ctl, -+ wmi_dfs_reg); -+ if (ret) -+- ath10k_warn("failed to set pdev regdomain: %d\n", ret); -++ ath10k_warn(ar, "failed to set pdev regdomain: %d\n", ret); -+ } -+ -+ static void ath10k_reg_notifier(struct wiphy *wiphy, -+@@ -1816,12 +2251,12 @@ static void ath10k_reg_notifier(struct w -+ ath_reg_notifier_apply(wiphy, request, &ar->ath_common.regulatory); -+ -+ if (config_enabled(CPTCFG_ATH10K_DFS_CERTIFIED) && ar->dfs_detector) { -+- ath10k_dbg(ATH10K_DBG_REGULATORY, "dfs region 0x%x\n", -++ ath10k_dbg(ar, ATH10K_DBG_REGULATORY, "dfs region 0x%x\n", -+ request->dfs_region); -+ result = ar->dfs_detector->set_dfs_domain(ar->dfs_detector, -+ request->dfs_region); -+ if (!result) -+- ath10k_warn("DFS region 0x%X not supported, will trigger radar for every pulse\n", -++ ath10k_warn(ar, "DFS region 0x%X not supported, will trigger radar for every pulse\n", -+ request->dfs_region); -+ } -+ -+@@ -1849,28 +2284,25 @@ static u8 ath10k_tx_h_get_tid(struct iee -+ return ieee80211_get_qos_ctl(hdr)[0] & IEEE80211_QOS_CTL_TID_MASK; -+ } -+ -+-static u8 ath10k_tx_h_get_vdev_id(struct ath10k *ar, -+- struct ieee80211_tx_info *info) -++static u8 ath10k_tx_h_get_vdev_id(struct ath10k *ar, struct ieee80211_vif *vif) -+ { -+- if (info->control.vif) -+- return ath10k_vif_to_arvif(info->control.vif)->vdev_id; -++ if (vif) -++ return ath10k_vif_to_arvif(vif)->vdev_id; -+ -+ if (ar->monitor_started) -+ return ar->monitor_vdev_id; -+ -+- ath10k_warn("failed to resolve vdev id\n"); -++ ath10k_warn(ar, "failed to resolve vdev id\n"); -+ return 0; -+ } -+ -+-/* -+- * Frames sent to the FW have to be in "Native Wifi" format. -+- * Strip the QoS field from the 802.11 header. -++/* HTT Tx uses Native Wifi tx mode which expects 802.11 frames without QoS -++ * Control in the header. -+ */ -+-static void ath10k_tx_h_qos_workaround(struct ieee80211_hw *hw, -+- struct ieee80211_tx_control *control, -+- struct sk_buff *skb) -++static void ath10k_tx_h_nwifi(struct ieee80211_hw *hw, struct sk_buff *skb) -+ { -+ struct ieee80211_hdr *hdr = (void *)skb->data; -++ struct ath10k_skb_cb *cb = ATH10K_SKB_CB(skb); -+ u8 *qos_ctl; -+ -+ if (!ieee80211_is_data_qos(hdr->frame_control)) -+@@ -1880,68 +2312,24 @@ static void ath10k_tx_h_qos_workaround(s -+ memmove(skb->data + IEEE80211_QOS_CTL_LEN, -+ skb->data, (void *)qos_ctl - (void *)skb->data); -+ skb_pull(skb, IEEE80211_QOS_CTL_LEN); -+-} -+- -+-static void ath10k_tx_wep_key_work(struct work_struct *work) -+-{ -+- struct ath10k_vif *arvif = container_of(work, struct ath10k_vif, -+- wep_key_work); -+- int ret, keyidx = arvif->def_wep_key_newidx; -+- -+- if (arvif->def_wep_key_idx == keyidx) -+- return; -+- -+- ath10k_dbg(ATH10K_DBG_MAC, "mac vdev %d set keyidx %d\n", -+- arvif->vdev_id, keyidx); -+ -+- ret = ath10k_wmi_vdev_set_param(arvif->ar, -+- arvif->vdev_id, -+- arvif->ar->wmi.vdev_param->def_keyid, -+- keyidx); -+- if (ret) { -+- ath10k_warn("failed to update wep key index for vdev %d: %d\n", -+- arvif->vdev_id, -+- ret); -+- return; -++ /* Fw/Hw generates a corrupted QoS Control Field for QoS NullFunc -++ * frames. Powersave is handled by the fw/hw so QoS NyllFunc frames are -++ * used only for CQM purposes (e.g. hostapd station keepalive ping) so -++ * it is safe to downgrade to NullFunc. -++ */ -++ hdr = (void *)skb->data; -++ if (ieee80211_is_qos_nullfunc(hdr->frame_control)) { -++ hdr->frame_control &= ~__cpu_to_le16(IEEE80211_STYPE_QOS_DATA); -++ cb->htt.tid = HTT_DATA_TX_EXT_TID_NON_QOS_MCAST_BCAST; -+ } -+- -+- arvif->def_wep_key_idx = keyidx; -+ } -+ -+-static void ath10k_tx_h_update_wep_key(struct sk_buff *skb) -+-{ -+- struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); -+- struct ieee80211_vif *vif = info->control.vif; -+- struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif); -+- struct ath10k *ar = arvif->ar; -+- struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; -+- struct ieee80211_key_conf *key = info->control.hw_key; -+- -+- if (!ieee80211_has_protected(hdr->frame_control)) -+- return; -+- -+- if (!key) -+- return; -+- -+- if (key->cipher != WLAN_CIPHER_SUITE_WEP40 && -+- key->cipher != WLAN_CIPHER_SUITE_WEP104) -+- return; -+- -+- if (key->keyidx == arvif->def_wep_key_idx) -+- return; -+- -+- /* FIXME: Most likely a few frames will be TXed with an old key. Simply -+- * queueing frames until key index is updated is not an option because -+- * sk_buff may need more processing to be done, e.g. offchannel */ -+- arvif->def_wep_key_newidx = key->keyidx; -+- ieee80211_queue_work(ar->hw, &arvif->wep_key_work); -+-} -+- -+-static void ath10k_tx_h_add_p2p_noa_ie(struct ath10k *ar, struct sk_buff *skb) -++static void ath10k_tx_h_add_p2p_noa_ie(struct ath10k *ar, -++ struct ieee80211_vif *vif, -++ struct sk_buff *skb) -+ { -+ struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; -+- struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); -+- struct ieee80211_vif *vif = info->control.vif; -+ struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif); -+ -+ /* This is case only for P2P_GO */ -+@@ -1961,6 +2349,18 @@ static void ath10k_tx_h_add_p2p_noa_ie(s -+ } -+ } -+ -++static bool ath10k_mac_need_offchan_tx_work(struct ath10k *ar) -++{ -++ /* FIXME: Not really sure since when the behaviour changed. At some -++ * point new firmware stopped requiring creation of peer entries for -++ * offchannel tx (and actually creating them causes issues with wmi-htc -++ * tx credit replenishment and reliability). Assuming it's at least 3.4 -++ * because that's when the `freq` was introduced to TX_FRM HTT command. -++ */ -++ return !(ar->htt.target_version_major >= 3 && -++ ar->htt.target_version_minor >= 4); -++} -++ -+ static void ath10k_tx_htt(struct ath10k *ar, struct sk_buff *skb) -+ { -+ struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; -+@@ -1977,7 +2377,7 @@ static void ath10k_tx_htt(struct ath10k -+ ar->fw_features)) { -+ if (skb_queue_len(&ar->wmi_mgmt_tx_queue) >= -+ ATH10K_MAX_NUM_MGMT_PENDING) { -+- ath10k_warn("reached WMI management tranmist queue limit\n"); -++ ath10k_warn(ar, "reached WMI management transmit queue limit\n"); -+ ret = -EBUSY; -+ goto exit; -+ } -+@@ -2001,7 +2401,8 @@ static void ath10k_tx_htt(struct ath10k -+ -+ exit: -+ if (ret) { -+- ath10k_warn("failed to transmit packet, dropping: %d\n", ret); -++ ath10k_warn(ar, "failed to transmit packet, dropping: %d\n", -++ ret); -+ ieee80211_free_txskb(ar->hw, skb); -+ } -+ } -+@@ -2043,7 +2444,7 @@ void ath10k_offchan_tx_work(struct work_ -+ -+ mutex_lock(&ar->conf_mutex); -+ -+- ath10k_dbg(ATH10K_DBG_MAC, "mac offchannel skb %p\n", -++ ath10k_dbg(ar, ATH10K_DBG_MAC, "mac offchannel skb %p\n", -+ skb); -+ -+ hdr = (struct ieee80211_hdr *)skb->data; -+@@ -2056,13 +2457,13 @@ void ath10k_offchan_tx_work(struct work_ -+ -+ if (peer) -+ /* FIXME: should this use ath10k_warn()? */ -+- ath10k_dbg(ATH10K_DBG_MAC, "peer %pM on vdev %d already present\n", -++ ath10k_dbg(ar, ATH10K_DBG_MAC, "peer %pM on vdev %d already present\n", -+ peer_addr, vdev_id); -+ -+ if (!peer) { -+ ret = ath10k_peer_create(ar, vdev_id, peer_addr); -+ if (ret) -+- ath10k_warn("failed to create peer %pM on vdev %d: %d\n", -++ ath10k_warn(ar, "failed to create peer %pM on vdev %d: %d\n", -+ peer_addr, vdev_id, ret); -+ } -+ -+@@ -2075,14 +2476,14 @@ void ath10k_offchan_tx_work(struct work_ -+ -+ ret = wait_for_completion_timeout(&ar->offchan_tx_completed, -+ 3 * HZ); -+- if (ret <= 0) -+- ath10k_warn("timed out waiting for offchannel skb %p\n", -++ if (ret == 0) -++ ath10k_warn(ar, "timed out waiting for offchannel skb %p\n", -+ skb); -+ -+ if (!peer) { -+ ret = ath10k_peer_delete(ar, vdev_id, peer_addr); -+ if (ret) -+- ath10k_warn("failed to delete peer %pM on vdev %d: %d\n", -++ ath10k_warn(ar, "failed to delete peer %pM on vdev %d: %d\n", -+ peer_addr, vdev_id, ret); -+ } -+ -+@@ -2116,7 +2517,7 @@ void ath10k_mgmt_over_wmi_tx_work(struct -+ -+ ret = ath10k_wmi_mgmt_tx(ar, skb); -+ if (ret) { -+- ath10k_warn("failed to transmit management frame via WMI: %d\n", -++ ath10k_warn(ar, "failed to transmit management frame via WMI: %d\n", -+ ret); -+ ieee80211_free_txskb(ar->hw, skb); -+ } -+@@ -2127,34 +2528,41 @@ void ath10k_mgmt_over_wmi_tx_work(struct -+ /* Scanning */ -+ /************/ -+ -+-/* -+- * This gets called if we dont get a heart-beat during scan. -+- * This may indicate the FW has hung and we need to abort the -+- * scan manually to prevent cancel_hw_scan() from deadlocking -+- */ -+-void ath10k_reset_scan(unsigned long ptr) -++void __ath10k_scan_finish(struct ath10k *ar) -+ { -+- struct ath10k *ar = (struct ath10k *)ptr; -+- -+- spin_lock_bh(&ar->data_lock); -+- if (!ar->scan.in_progress) { -+- spin_unlock_bh(&ar->data_lock); -+- return; -+- } -++ lockdep_assert_held(&ar->data_lock); -+ -+- ath10k_warn("scan timed out, firmware problem?\n"); -+- -+- if (ar->scan.is_roc) -+- ieee80211_remain_on_channel_expired(ar->hw); -+- else -+- ieee80211_scan_completed(ar->hw, 1 /* aborted */); -++ switch (ar->scan.state) { -++ case ATH10K_SCAN_IDLE: -++ break; -++ case ATH10K_SCAN_RUNNING: -++ if (ar->scan.is_roc) -++ ieee80211_remain_on_channel_expired(ar->hw); -++ /* fall through */ -++ case ATH10K_SCAN_ABORTING: -++ if (!ar->scan.is_roc) -++ ieee80211_scan_completed(ar->hw, -++ (ar->scan.state == -++ ATH10K_SCAN_ABORTING)); -++ /* fall through */ -++ case ATH10K_SCAN_STARTING: -++ ar->scan.state = ATH10K_SCAN_IDLE; -++ ar->scan_channel = NULL; -++ ath10k_offchan_tx_purge(ar); -++ cancel_delayed_work(&ar->scan.timeout); -++ complete_all(&ar->scan.completed); -++ break; -++ } -++} -+ -+- ar->scan.in_progress = false; -+- complete_all(&ar->scan.completed); -++void ath10k_scan_finish(struct ath10k *ar) -++{ -++ spin_lock_bh(&ar->data_lock); -++ __ath10k_scan_finish(ar); -+ spin_unlock_bh(&ar->data_lock); -+ } -+ -+-static int ath10k_abort_scan(struct ath10k *ar) -++static int ath10k_scan_stop(struct ath10k *ar) -+ { -+ struct wmi_stop_scan_arg arg = { -+ .req_id = 1, /* FIXME */ -+@@ -2165,47 +2573,79 @@ static int ath10k_abort_scan(struct ath1 -+ -+ lockdep_assert_held(&ar->conf_mutex); -+ -+- del_timer_sync(&ar->scan.timeout); -++ ret = ath10k_wmi_stop_scan(ar, &arg); -++ if (ret) { -++ ath10k_warn(ar, "failed to stop wmi scan: %d\n", ret); -++ goto out; -++ } -+ -+- spin_lock_bh(&ar->data_lock); -+- if (!ar->scan.in_progress) { -+- spin_unlock_bh(&ar->data_lock); -+- return 0; -++ ret = wait_for_completion_timeout(&ar->scan.completed, 3*HZ); -++ if (ret == 0) { -++ ath10k_warn(ar, "failed to receive scan abortion completion: timed out\n"); -++ ret = -ETIMEDOUT; -++ } else if (ret > 0) { -++ ret = 0; -+ } -+ -+- ar->scan.aborting = true; -++out: -++ /* Scan state should be updated upon scan completion but in case -++ * firmware fails to deliver the event (for whatever reason) it is -++ * desired to clean up scan state anyway. Firmware may have just -++ * dropped the scan completion event delivery due to transport pipe -++ * being overflown with data and/or it can recover on its own before -++ * next scan request is submitted. -++ */ -++ spin_lock_bh(&ar->data_lock); -++ if (ar->scan.state != ATH10K_SCAN_IDLE) -++ __ath10k_scan_finish(ar); -+ spin_unlock_bh(&ar->data_lock); -+ -+- ret = ath10k_wmi_stop_scan(ar, &arg); -+- if (ret) { -+- ath10k_warn("failed to stop wmi scan: %d\n", ret); -+- spin_lock_bh(&ar->data_lock); -+- ar->scan.in_progress = false; -+- ath10k_offchan_tx_purge(ar); -+- spin_unlock_bh(&ar->data_lock); -+- return -EIO; -+- } -++ return ret; -++} -+ -+- ret = wait_for_completion_timeout(&ar->scan.completed, 3*HZ); -+- if (ret == 0) -+- ath10k_warn("timed out while waiting for scan to stop\n"); -++static void ath10k_scan_abort(struct ath10k *ar) -++{ -++ int ret; -+ -+- /* scan completion may be done right after we timeout here, so let's -+- * check the in_progress and tell mac80211 scan is completed. if we -+- * don't do that and FW fails to send us scan completion indication -+- * then userspace won't be able to scan anymore */ -+- ret = 0; -++ lockdep_assert_held(&ar->conf_mutex); -+ -+ spin_lock_bh(&ar->data_lock); -+- if (ar->scan.in_progress) { -+- ath10k_warn("failed to stop scan, it's still in progress\n"); -+- ar->scan.in_progress = false; -+- ath10k_offchan_tx_purge(ar); -+- ret = -ETIMEDOUT; -++ -++ switch (ar->scan.state) { -++ case ATH10K_SCAN_IDLE: -++ /* This can happen if timeout worker kicked in and called -++ * abortion while scan completion was being processed. -++ */ -++ break; -++ case ATH10K_SCAN_STARTING: -++ case ATH10K_SCAN_ABORTING: -++ ath10k_warn(ar, "refusing scan abortion due to invalid scan state: %s (%d)\n", -++ ath10k_scan_state_str(ar->scan.state), -++ ar->scan.state); -++ break; -++ case ATH10K_SCAN_RUNNING: -++ ar->scan.state = ATH10K_SCAN_ABORTING; -++ spin_unlock_bh(&ar->data_lock); -++ -++ ret = ath10k_scan_stop(ar); -++ if (ret) -++ ath10k_warn(ar, "failed to abort scan: %d\n", ret); -++ -++ spin_lock_bh(&ar->data_lock); -++ break; -+ } -++ -+ spin_unlock_bh(&ar->data_lock); -++} -+ -+- return ret; -++void ath10k_scan_timeout_work(struct work_struct *work) -++{ -++ struct ath10k *ar = container_of(work, struct ath10k, -++ scan.timeout.work); -++ -++ mutex_lock(&ar->conf_mutex); -++ ath10k_scan_abort(ar); -++ mutex_unlock(&ar->conf_mutex); -+ } -+ -+ static int ath10k_start_scan(struct ath10k *ar, -+@@ -2221,17 +2661,27 @@ static int ath10k_start_scan(struct ath1 -+ -+ ret = wait_for_completion_timeout(&ar->scan.started, 1*HZ); -+ if (ret == 0) { -+- ath10k_abort_scan(ar); -+- return ret; -++ ret = ath10k_scan_stop(ar); -++ if (ret) -++ ath10k_warn(ar, "failed to stop scan: %d\n", ret); -++ -++ return -ETIMEDOUT; -++ } -++ -++ /* If we failed to start the scan, return error code at -++ * this point. This is probably due to some issue in the -++ * firmware, but no need to wedge the driver due to that... -++ */ -++ spin_lock_bh(&ar->data_lock); -++ if (ar->scan.state == ATH10K_SCAN_IDLE) { -++ spin_unlock_bh(&ar->data_lock); -++ return -EINVAL; -+ } -++ spin_unlock_bh(&ar->data_lock); -+ -+- /* the scan can complete earlier, before we even -+- * start the timer. in that case the timer handler -+- * checks ar->scan.in_progress and bails out if its -+- * false. Add a 200ms margin to account event/command -+- * processing. */ -+- mod_timer(&ar->scan.timeout, jiffies + -+- msecs_to_jiffies(arg->max_scan_time+200)); -++ /* Add a 200ms margin to account for event/command processing */ -++ ieee80211_queue_delayed_work(ar->hw, &ar->scan.timeout, -++ msecs_to_jiffies(arg->max_scan_time+200)); -+ return 0; -+ } -+ -+@@ -2243,90 +2693,163 @@ static void ath10k_tx(struct ieee80211_h -+ struct ieee80211_tx_control *control, -+ struct sk_buff *skb) -+ { -++ struct ath10k *ar = hw->priv; -+ struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); -++ struct ieee80211_vif *vif = info->control.vif; -+ struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; -+- struct ath10k *ar = hw->priv; -+- u8 tid, vdev_id; -+ -+ /* We should disable CCK RATE due to P2P */ -+ if (info->flags & IEEE80211_TX_CTL_NO_CCK_RATE) -+- ath10k_dbg(ATH10K_DBG_MAC, "IEEE80211_TX_CTL_NO_CCK_RATE\n"); -++ ath10k_dbg(ar, ATH10K_DBG_MAC, "IEEE80211_TX_CTL_NO_CCK_RATE\n"); -+ -+- /* we must calculate tid before we apply qos workaround -+- * as we'd lose the qos control field */ -+- tid = ath10k_tx_h_get_tid(hdr); -+- vdev_id = ath10k_tx_h_get_vdev_id(ar, info); -++ ATH10K_SKB_CB(skb)->htt.is_offchan = false; -++ ATH10K_SKB_CB(skb)->htt.tid = ath10k_tx_h_get_tid(hdr); -++ ATH10K_SKB_CB(skb)->vdev_id = ath10k_tx_h_get_vdev_id(ar, vif); -+ -+ /* it makes no sense to process injected frames like that */ -+- if (info->control.vif && -+- info->control.vif->type != NL80211_IFTYPE_MONITOR) { -+- ath10k_tx_h_qos_workaround(hw, control, skb); -+- ath10k_tx_h_update_wep_key(skb); -+- ath10k_tx_h_add_p2p_noa_ie(ar, skb); -+- ath10k_tx_h_seq_no(skb); -++ if (vif && vif->type != NL80211_IFTYPE_MONITOR) { -++ ath10k_tx_h_nwifi(hw, skb); -++ ath10k_tx_h_add_p2p_noa_ie(ar, vif, skb); -++ ath10k_tx_h_seq_no(vif, skb); -+ } -+ -+- ATH10K_SKB_CB(skb)->vdev_id = vdev_id; -+- ATH10K_SKB_CB(skb)->htt.is_offchan = false; -+- ATH10K_SKB_CB(skb)->htt.tid = tid; -+- -+ if (info->flags & IEEE80211_TX_CTL_TX_OFFCHAN) { -+ spin_lock_bh(&ar->data_lock); -+- ATH10K_SKB_CB(skb)->htt.is_offchan = true; -++ ATH10K_SKB_CB(skb)->htt.freq = ar->scan.roc_freq; -+ ATH10K_SKB_CB(skb)->vdev_id = ar->scan.vdev_id; -+ spin_unlock_bh(&ar->data_lock); -+ -+- ath10k_dbg(ATH10K_DBG_MAC, "queued offchannel skb %p\n", skb); -++ if (ath10k_mac_need_offchan_tx_work(ar)) { -++ ATH10K_SKB_CB(skb)->htt.freq = 0; -++ ATH10K_SKB_CB(skb)->htt.is_offchan = true; -+ -+- skb_queue_tail(&ar->offchan_tx_queue, skb); -+- ieee80211_queue_work(hw, &ar->offchan_tx_work); -+- return; -++ ath10k_dbg(ar, ATH10K_DBG_MAC, "queued offchannel skb %p\n", -++ skb); -++ -++ skb_queue_tail(&ar->offchan_tx_queue, skb); -++ ieee80211_queue_work(hw, &ar->offchan_tx_work); -++ return; -++ } -+ } -+ -+ ath10k_tx_htt(ar, skb); -+ } -+ -+-/* -+- * Initialize various parameters with default vaules. -+- */ -++/* Must not be called with conf_mutex held as workers can use that also. */ -++void ath10k_drain_tx(struct ath10k *ar) -++{ -++ /* make sure rcu-protected mac80211 tx path itself is drained */ -++ synchronize_net(); -++ -++ ath10k_offchan_tx_purge(ar); -++ ath10k_mgmt_over_wmi_tx_purge(ar); -++ -++ cancel_work_sync(&ar->offchan_tx_work); -++ cancel_work_sync(&ar->wmi_mgmt_tx_work); -++} -++ -+ void ath10k_halt(struct ath10k *ar) -+ { -+ struct ath10k_vif *arvif; -+ -+ lockdep_assert_held(&ar->conf_mutex); -+ -+- if (ath10k_monitor_is_enabled(ar)) { -+- clear_bit(ATH10K_CAC_RUNNING, &ar->dev_flags); -+- ar->promisc = false; -+- ar->monitor = false; -++ clear_bit(ATH10K_CAC_RUNNING, &ar->dev_flags); -++ ar->filter_flags = 0; -++ ar->monitor = false; -++ -++ if (ar->monitor_started) -+ ath10k_monitor_stop(ar); -+- } -+ -+- del_timer_sync(&ar->scan.timeout); -+- ath10k_offchan_tx_purge(ar); -+- ath10k_mgmt_over_wmi_tx_purge(ar); -++ ar->monitor_started = false; -++ -++ ath10k_scan_finish(ar); -+ ath10k_peer_cleanup_all(ar); -+ ath10k_core_stop(ar); -+ ath10k_hif_power_down(ar); -+ -+ spin_lock_bh(&ar->data_lock); -+- if (ar->scan.in_progress) { -+- del_timer(&ar->scan.timeout); -+- ar->scan.in_progress = false; -+- ieee80211_scan_completed(ar->hw, true); -++ list_for_each_entry(arvif, &ar->arvifs, list) -++ ath10k_mac_vif_beacon_cleanup(arvif); -++ spin_unlock_bh(&ar->data_lock); -++} -++ -++static int ath10k_get_antenna(struct ieee80211_hw *hw, u32 *tx_ant, u32 *rx_ant) -++{ -++ struct ath10k *ar = hw->priv; -++ -++ mutex_lock(&ar->conf_mutex); -++ -++ if (ar->cfg_tx_chainmask) { -++ *tx_ant = ar->cfg_tx_chainmask; -++ *rx_ant = ar->cfg_rx_chainmask; -++ } else { -++ *tx_ant = ar->supp_tx_chainmask; -++ *rx_ant = ar->supp_rx_chainmask; -+ } -+ -+- list_for_each_entry(arvif, &ar->arvifs, list) { -+- if (!arvif->beacon) -+- continue; -++ mutex_unlock(&ar->conf_mutex); -+ -+- dma_unmap_single(arvif->ar->dev, -+- ATH10K_SKB_CB(arvif->beacon)->paddr, -+- arvif->beacon->len, DMA_TO_DEVICE); -+- dev_kfree_skb_any(arvif->beacon); -+- arvif->beacon = NULL; -++ return 0; -++} -++ -++static void ath10k_check_chain_mask(struct ath10k *ar, u32 cm, const char *dbg) -++{ -++ /* It is not clear that allowing gaps in chainmask -++ * is helpful. Probably it will not do what user -++ * is hoping for, so warn in that case. -++ */ -++ if (cm == 15 || cm == 7 || cm == 3 || cm == 1 || cm == 0) -++ return; -++ -++ ath10k_warn(ar, "mac %s antenna chainmask may be invalid: 0x%x. Suggested values: 15, 7, 3, 1 or 0.\n", -++ dbg, cm); -++} -++ -++static int __ath10k_set_antenna(struct ath10k *ar, u32 tx_ant, u32 rx_ant) -++{ -++ int ret; -++ -++ lockdep_assert_held(&ar->conf_mutex); -++ -++ ath10k_check_chain_mask(ar, tx_ant, "tx"); -++ ath10k_check_chain_mask(ar, rx_ant, "rx"); -++ -++ ar->cfg_tx_chainmask = tx_ant; -++ ar->cfg_rx_chainmask = rx_ant; -++ -++ if ((ar->state != ATH10K_STATE_ON) && -++ (ar->state != ATH10K_STATE_RESTARTED)) -++ return 0; -++ -++ ret = ath10k_wmi_pdev_set_param(ar, ar->wmi.pdev_param->tx_chain_mask, -++ tx_ant); -++ if (ret) { -++ ath10k_warn(ar, "failed to set tx-chainmask: %d, req 0x%x\n", -++ ret, tx_ant); -++ return ret; -+ } -+- spin_unlock_bh(&ar->data_lock); -++ -++ ret = ath10k_wmi_pdev_set_param(ar, ar->wmi.pdev_param->rx_chain_mask, -++ rx_ant); -++ if (ret) { -++ ath10k_warn(ar, "failed to set rx-chainmask: %d, req 0x%x\n", -++ ret, rx_ant); -++ return ret; -++ } -++ -++ return 0; -++} -++ -++static int ath10k_set_antenna(struct ieee80211_hw *hw, u32 tx_ant, u32 rx_ant) -++{ -++ struct ath10k *ar = hw->priv; -++ int ret; -++ -++ mutex_lock(&ar->conf_mutex); -++ ret = __ath10k_set_antenna(ar, tx_ant, rx_ant); -++ mutex_unlock(&ar->conf_mutex); -++ return ret; -+ } -+ -+ static int ath10k_start(struct ieee80211_hw *hw) -+@@ -2334,41 +2857,61 @@ static int ath10k_start(struct ieee80211 -+ struct ath10k *ar = hw->priv; -+ int ret = 0; -+ -++ /* -++ * This makes sense only when restarting hw. It is harmless to call -++ * uncoditionally. This is necessary to make sure no HTT/WMI tx -++ * commands will be submitted while restarting. -++ */ -++ ath10k_drain_tx(ar); -++ -+ mutex_lock(&ar->conf_mutex); -+ -+- if (ar->state != ATH10K_STATE_OFF && -+- ar->state != ATH10K_STATE_RESTARTING) { -++ switch (ar->state) { -++ case ATH10K_STATE_OFF: -++ ar->state = ATH10K_STATE_ON; -++ break; -++ case ATH10K_STATE_RESTARTING: -++ ath10k_halt(ar); -++ ar->state = ATH10K_STATE_RESTARTED; -++ break; -++ case ATH10K_STATE_ON: -++ case ATH10K_STATE_RESTARTED: -++ case ATH10K_STATE_WEDGED: -++ WARN_ON(1); -+ ret = -EINVAL; -+- goto exit; -++ goto err; -++ case ATH10K_STATE_UTF: -++ ret = -EBUSY; -++ goto err; -+ } -+ -+ ret = ath10k_hif_power_up(ar); -+ if (ret) { -+- ath10k_err("Could not init hif: %d\n", ret); -+- ar->state = ATH10K_STATE_OFF; -+- goto exit; -++ ath10k_err(ar, "Could not init hif: %d\n", ret); -++ goto err_off; -+ } -+ -+- ret = ath10k_core_start(ar); -++ ret = ath10k_core_start(ar, ATH10K_FIRMWARE_MODE_NORMAL); -+ if (ret) { -+- ath10k_err("Could not init core: %d\n", ret); -+- ath10k_hif_power_down(ar); -+- ar->state = ATH10K_STATE_OFF; -+- goto exit; -++ ath10k_err(ar, "Could not init core: %d\n", ret); -++ goto err_power_down; -+ } -+ -+- if (ar->state == ATH10K_STATE_OFF) -+- ar->state = ATH10K_STATE_ON; -+- else if (ar->state == ATH10K_STATE_RESTARTING) -+- ar->state = ATH10K_STATE_RESTARTED; -+- -+ ret = ath10k_wmi_pdev_set_param(ar, ar->wmi.pdev_param->pmf_qos, 1); -+- if (ret) -+- ath10k_warn("failed to enable PMF QOS: %d\n", ret); -++ if (ret) { -++ ath10k_warn(ar, "failed to enable PMF QOS: %d\n", ret); -++ goto err_core_stop; -++ } -+ -+ ret = ath10k_wmi_pdev_set_param(ar, ar->wmi.pdev_param->dynamic_bw, 1); -+- if (ret) -+- ath10k_warn("failed to enable dynamic BW: %d\n", ret); -++ if (ret) { -++ ath10k_warn(ar, "failed to enable dynamic BW: %d\n", ret); -++ goto err_core_stop; -++ } -++ -++ if (ar->cfg_tx_chainmask) -++ __ath10k_set_antenna(ar, ar->cfg_tx_chainmask, -++ ar->cfg_rx_chainmask); -+ -+ /* -+ * By default FW set ARP frames ac to voice (6). In that case ARP -+@@ -2382,16 +2925,29 @@ static int ath10k_start(struct ieee80211 -+ ret = ath10k_wmi_pdev_set_param(ar, -+ ar->wmi.pdev_param->arp_ac_override, 0); -+ if (ret) { -+- ath10k_warn("failed to set arp ac override parameter: %d\n", -++ ath10k_warn(ar, "failed to set arp ac override parameter: %d\n", -+ ret); -+- goto exit; -++ goto err_core_stop; -+ } -+ -+ ar->num_started_vdevs = 0; -+ ath10k_regd_update(ar); -+- ret = 0; -+ -+-exit: -++ ath10k_spectral_start(ar); -++ -++ mutex_unlock(&ar->conf_mutex); -++ return 0; -++ -++err_core_stop: -++ ath10k_core_stop(ar); -++ -++err_power_down: -++ ath10k_hif_power_down(ar); -++ -++err_off: -++ ar->state = ATH10K_STATE_OFF; -++ -++err: -+ mutex_unlock(&ar->conf_mutex); -+ return ret; -+ } -+@@ -2400,19 +2956,16 @@ static void ath10k_stop(struct ieee80211 -+ { -+ struct ath10k *ar = hw->priv; -+ -++ ath10k_drain_tx(ar); -++ -+ mutex_lock(&ar->conf_mutex); -+- if (ar->state == ATH10K_STATE_ON || -+- ar->state == ATH10K_STATE_RESTARTED || -+- ar->state == ATH10K_STATE_WEDGED) -++ if (ar->state != ATH10K_STATE_OFF) { -+ ath10k_halt(ar); -+- -+- ar->state = ATH10K_STATE_OFF; -++ ar->state = ATH10K_STATE_OFF; -++ } -+ mutex_unlock(&ar->conf_mutex); -+ -+- ath10k_mgmt_over_wmi_tx_purge(ar); -+- -+- cancel_work_sync(&ar->offchan_tx_work); -+- cancel_work_sync(&ar->wmi_mgmt_tx_work); -++ cancel_delayed_work_sync(&ar->scan.timeout); -+ cancel_work_sync(&ar->restart_work); -+ } -+ -+@@ -2426,7 +2979,7 @@ static int ath10k_config_ps(struct ath10 -+ list_for_each_entry(arvif, &ar->arvifs, list) { -+ ret = ath10k_mac_vif_setup_ps(arvif); -+ if (ret) { -+- ath10k_warn("failed to setup powersave: %d\n", ret); -++ ath10k_warn(ar, "failed to setup powersave: %d\n", ret); -+ break; -+ } -+ } -+@@ -2464,7 +3017,7 @@ static void ath10k_config_chan(struct at -+ -+ lockdep_assert_held(&ar->conf_mutex); -+ -+- ath10k_dbg(ATH10K_DBG_MAC, -++ ath10k_dbg(ar, ATH10K_DBG_MAC, -+ "mac config channel to %dMHz (cf1 %dMHz cf2 %dMHz width %s)\n", -+ ar->chandef.chan->center_freq, -+ ar->chandef.center_freq1, -+@@ -2474,24 +3027,27 @@ static void ath10k_config_chan(struct at -+ /* First stop monitor interface. Some FW versions crash if there's a -+ * lone monitor interface. */ -+ if (ar->monitor_started) -+- ath10k_monitor_vdev_stop(ar); -++ ath10k_monitor_stop(ar); -+ -+ list_for_each_entry(arvif, &ar->arvifs, list) { -+ if (!arvif->is_started) -+ continue; -+ -++ if (!arvif->is_up) -++ continue; -++ -+ if (arvif->vdev_type == WMI_VDEV_TYPE_MONITOR) -+ continue; -+ -+- ret = ath10k_vdev_stop(arvif); -++ ret = ath10k_wmi_vdev_down(ar, arvif->vdev_id); -+ if (ret) { -+- ath10k_warn("failed to stop vdev %d: %d\n", -++ ath10k_warn(ar, "failed to down vdev %d: %d\n", -+ arvif->vdev_id, ret); -+ continue; -+ } -+ } -+ -+- /* all vdevs are now stopped - now attempt to restart them */ -++ /* all vdevs are downed now - attempt to restart and re-up them */ -+ -+ list_for_each_entry(arvif, &ar->arvifs, list) { -+ if (!arvif->is_started) -+@@ -2500,9 +3056,9 @@ static void ath10k_config_chan(struct at -+ if (arvif->vdev_type == WMI_VDEV_TYPE_MONITOR) -+ continue; -+ -+- ret = ath10k_vdev_start(arvif); -++ ret = ath10k_vdev_restart(arvif); -+ if (ret) { -+- ath10k_warn("failed to start vdev %d: %d\n", -++ ath10k_warn(ar, "failed to restart vdev %d: %d\n", -+ arvif->vdev_id, ret); -+ continue; -+ } -+@@ -2513,14 +3069,70 @@ static void ath10k_config_chan(struct at -+ ret = ath10k_wmi_vdev_up(arvif->ar, arvif->vdev_id, arvif->aid, -+ arvif->bssid); -+ if (ret) { -+- ath10k_warn("failed to bring vdev up %d: %d\n", -++ ath10k_warn(ar, "failed to bring vdev up %d: %d\n", -+ arvif->vdev_id, ret); -+ continue; -+ } -+ } -+ -+- if (ath10k_monitor_is_enabled(ar)) -+- ath10k_monitor_vdev_start(ar, ar->monitor_vdev_id); -++ ath10k_monitor_recalc(ar); -++} -++ -++static int ath10k_mac_txpower_setup(struct ath10k *ar, int txpower) -++{ -++ int ret; -++ u32 param; -++ -++ lockdep_assert_held(&ar->conf_mutex); -++ -++ ath10k_dbg(ar, ATH10K_DBG_MAC, "mac txpower %d\n", txpower); -++ -++ param = ar->wmi.pdev_param->txpower_limit2g; -++ ret = ath10k_wmi_pdev_set_param(ar, param, txpower * 2); -++ if (ret) { -++ ath10k_warn(ar, "failed to set 2g txpower %d: %d\n", -++ txpower, ret); -++ return ret; -++ } -++ -++ param = ar->wmi.pdev_param->txpower_limit5g; -++ ret = ath10k_wmi_pdev_set_param(ar, param, txpower * 2); -++ if (ret) { -++ ath10k_warn(ar, "failed to set 5g txpower %d: %d\n", -++ txpower, ret); -++ return ret; -++ } -++ -++ return 0; -++} -++ -++static int ath10k_mac_txpower_recalc(struct ath10k *ar) -++{ -++ struct ath10k_vif *arvif; -++ int ret, txpower = -1; -++ -++ lockdep_assert_held(&ar->conf_mutex); -++ -++ list_for_each_entry(arvif, &ar->arvifs, list) { -++ WARN_ON(arvif->txpower < 0); -++ -++ if (txpower == -1) -++ txpower = arvif->txpower; -++ else -++ txpower = min(txpower, arvif->txpower); -++ } -++ -++ if (WARN_ON(txpower == -1)) -++ return -EINVAL; -++ -++ ret = ath10k_mac_txpower_setup(ar, txpower); -++ if (ret) { -++ ath10k_warn(ar, "failed to setup tx power %d: %d\n", -++ txpower, ret); -++ return ret; -++ } -++ -++ return 0; -+ } -+ -+ static int ath10k_config(struct ieee80211_hw *hw, u32 changed) -+@@ -2528,12 +3140,11 @@ static int ath10k_config(struct ieee8021 -+ struct ath10k *ar = hw->priv; -+ struct ieee80211_conf *conf = &hw->conf; -+ int ret = 0; -+- u32 param; -+ -+ mutex_lock(&ar->conf_mutex); -+ -+ if (changed & IEEE80211_CONF_CHANGE_CHANNEL) { -+- ath10k_dbg(ATH10K_DBG_MAC, -++ ath10k_dbg(ar, ATH10K_DBG_MAC, -+ "mac config channel %dMHz flags 0x%x radar %d\n", -+ conf->chandef.chan->center_freq, -+ conf->chandef.chan->flags, -+@@ -2552,48 +3163,31 @@ static int ath10k_config(struct ieee8021 -+ } -+ } -+ -+- if (changed & IEEE80211_CONF_CHANGE_POWER) { -+- ath10k_dbg(ATH10K_DBG_MAC, "mac config power %d\n", -+- hw->conf.power_level); -+- -+- param = ar->wmi.pdev_param->txpower_limit2g; -+- ret = ath10k_wmi_pdev_set_param(ar, param, -+- hw->conf.power_level * 2); -+- if (ret) -+- ath10k_warn("failed to set 2g txpower %d: %d\n", -+- hw->conf.power_level, ret); -+- -+- param = ar->wmi.pdev_param->txpower_limit5g; -+- ret = ath10k_wmi_pdev_set_param(ar, param, -+- hw->conf.power_level * 2); -+- if (ret) -+- ath10k_warn("failed to set 5g txpower %d: %d\n", -+- hw->conf.power_level, ret); -+- } -+- -+ if (changed & IEEE80211_CONF_CHANGE_PS) -+ ath10k_config_ps(ar); -+ -+ if (changed & IEEE80211_CONF_CHANGE_MONITOR) { -+- if (conf->flags & IEEE80211_CONF_MONITOR && !ar->monitor) { -+- ar->monitor = true; -+- ret = ath10k_monitor_start(ar); -+- if (ret) { -+- ath10k_warn("failed to start monitor (config): %d\n", -+- ret); -+- ar->monitor = false; -+- } -+- } else if (!(conf->flags & IEEE80211_CONF_MONITOR) && -+- ar->monitor) { -+- ar->monitor = false; -+- ath10k_monitor_stop(ar); -+- } -++ ar->monitor = conf->flags & IEEE80211_CONF_MONITOR; -++ ret = ath10k_monitor_recalc(ar); -++ if (ret) -++ ath10k_warn(ar, "failed to recalc monitor: %d\n", ret); -+ } -+ -+ mutex_unlock(&ar->conf_mutex); -+ return ret; -+ } -+ -++static u32 get_nss_from_chainmask(u16 chain_mask) -++{ -++ if ((chain_mask & 0x15) == 0x15) -++ return 4; -++ else if ((chain_mask & 0x7) == 0x7) -++ return 3; -++ else if ((chain_mask & 0x3) == 0x3) -++ return 2; -++ return 1; -++} -++ -+ /* -+ * TODO: -+ * Figure out how to handle WMI_VDEV_SUBTYPE_P2P_DEVICE, -+@@ -2619,22 +3213,26 @@ static int ath10k_add_interface(struct i -+ arvif->ar = ar; -+ arvif->vif = vif; -+ -+- INIT_WORK(&arvif->wep_key_work, ath10k_tx_wep_key_work); -+ INIT_LIST_HEAD(&arvif->list); -+ -+- bit = ffs(ar->free_vdev_map); -+- if (bit == 0) { -++ if (ar->free_vdev_map == 0) { -++ ath10k_warn(ar, "Free vdev map is empty, no more interfaces allowed.\n"); -+ ret = -EBUSY; -+ goto err; -+ } -++ bit = __ffs64(ar->free_vdev_map); -+ -+- arvif->vdev_id = bit - 1; -+- arvif->vdev_subtype = WMI_VDEV_SUBTYPE_NONE; -++ ath10k_dbg(ar, ATH10K_DBG_MAC, "mac create vdev %i map %llx\n", -++ bit, ar->free_vdev_map); -+ -+- if (ar->p2p) -+- arvif->vdev_subtype = WMI_VDEV_SUBTYPE_P2P_DEVICE; -++ arvif->vdev_id = bit; -++ arvif->vdev_subtype = WMI_VDEV_SUBTYPE_NONE; -+ -+ switch (vif->type) { -++ case NL80211_IFTYPE_P2P_DEVICE: -++ arvif->vdev_type = WMI_VDEV_TYPE_STA; -++ arvif->vdev_subtype = WMI_VDEV_SUBTYPE_P2P_DEVICE; -++ break; -+ case NL80211_IFTYPE_UNSPECIFIED: -+ case NL80211_IFTYPE_STATION: -+ arvif->vdev_type = WMI_VDEV_TYPE_STA; -+@@ -2658,50 +3256,98 @@ static int ath10k_add_interface(struct i -+ break; -+ } -+ -+- ath10k_dbg(ATH10K_DBG_MAC, "mac vdev create %d (add interface) type %d subtype %d\n", -+- arvif->vdev_id, arvif->vdev_type, arvif->vdev_subtype); -++ /* Some firmware revisions don't wait for beacon tx completion before -++ * sending another SWBA event. This could lead to hardware using old -++ * (freed) beacon data in some cases, e.g. tx credit starvation -++ * combined with missed TBTT. This is very very rare. -++ * -++ * On non-IOMMU-enabled hosts this could be a possible security issue -++ * because hw could beacon some random data on the air. On -++ * IOMMU-enabled hosts DMAR faults would occur in most cases and target -++ * device would crash. -++ * -++ * Since there are no beacon tx completions (implicit nor explicit) -++ * propagated to host the only workaround for this is to allocate a -++ * DMA-coherent buffer for a lifetime of a vif and use it for all -++ * beacon tx commands. Worst case for this approach is some beacons may -++ * become corrupted, e.g. have garbled IEs or out-of-date TIM bitmap. -++ */ -++ if (vif->type == NL80211_IFTYPE_ADHOC || -++ vif->type == NL80211_IFTYPE_AP) { -++ arvif->beacon_buf = dma_zalloc_coherent(ar->dev, -++ IEEE80211_MAX_FRAME_LEN, -++ &arvif->beacon_paddr, -++ GFP_ATOMIC); -++ if (!arvif->beacon_buf) { -++ ret = -ENOMEM; -++ ath10k_warn(ar, "failed to allocate beacon buffer: %d\n", -++ ret); -++ goto err; -++ } -++ } -++ -++ ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev create %d (add interface) type %d subtype %d bcnmode %s\n", -++ arvif->vdev_id, arvif->vdev_type, arvif->vdev_subtype, -++ arvif->beacon_buf ? "single-buf" : "per-skb"); -+ -+ ret = ath10k_wmi_vdev_create(ar, arvif->vdev_id, arvif->vdev_type, -+ arvif->vdev_subtype, vif->addr); -+ if (ret) { -+- ath10k_warn("failed to create WMI vdev %i: %d\n", -++ ath10k_warn(ar, "failed to create WMI vdev %i: %d\n", -+ arvif->vdev_id, ret); -+ goto err; -+ } -+ -+- ar->free_vdev_map &= ~BIT(arvif->vdev_id); -++ ar->free_vdev_map &= ~(1LL << arvif->vdev_id); -+ list_add(&arvif->list, &ar->arvifs); -+ -+- vdev_param = ar->wmi.vdev_param->def_keyid; -+- ret = ath10k_wmi_vdev_set_param(ar, 0, vdev_param, -+- arvif->def_wep_key_idx); -++ /* It makes no sense to have firmware do keepalives. mac80211 already -++ * takes care of this with idle connection polling. -++ */ -++ ret = ath10k_mac_vif_disable_keepalive(arvif); -+ if (ret) { -+- ath10k_warn("failed to set vdev %i default key id: %d\n", -++ ath10k_warn(ar, "failed to disable keepalive on vdev %i: %d\n", -+ arvif->vdev_id, ret); -+ goto err_vdev_delete; -+ } -+ -++ arvif->def_wep_key_idx = -1; -++ -+ vdev_param = ar->wmi.vdev_param->tx_encap_type; -+ ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param, -+ ATH10K_HW_TXRX_NATIVE_WIFI); -+ /* 10.X firmware does not support this VDEV parameter. Do not warn */ -+ if (ret && ret != -EOPNOTSUPP) { -+- ath10k_warn("failed to set vdev %i TX encapsulation: %d\n", -++ ath10k_warn(ar, "failed to set vdev %i TX encapsulation: %d\n", -+ arvif->vdev_id, ret); -+ goto err_vdev_delete; -+ } -+ -++ if (ar->cfg_tx_chainmask) { -++ u16 nss = get_nss_from_chainmask(ar->cfg_tx_chainmask); -++ -++ vdev_param = ar->wmi.vdev_param->nss; -++ ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param, -++ nss); -++ if (ret) { -++ ath10k_warn(ar, "failed to set vdev %i chainmask 0x%x, nss %i: %d\n", -++ arvif->vdev_id, ar->cfg_tx_chainmask, nss, -++ ret); -++ goto err_vdev_delete; -++ } -++ } -++ -+ if (arvif->vdev_type == WMI_VDEV_TYPE_AP) { -+ ret = ath10k_peer_create(ar, arvif->vdev_id, vif->addr); -+ if (ret) { -+- ath10k_warn("failed to create vdev %i peer for AP: %d\n", -++ ath10k_warn(ar, "failed to create vdev %i peer for AP: %d\n", -+ arvif->vdev_id, ret); -+ goto err_vdev_delete; -+ } -+ -+ ret = ath10k_mac_set_kickout(arvif); -+ if (ret) { -+- ath10k_warn("failed to set vdev %i kickout parameters: %d\n", -++ ath10k_warn(ar, "failed to set vdev %i kickout parameters: %d\n", -+ arvif->vdev_id, ret); -+ goto err_peer_delete; -+ } -+@@ -2713,27 +3359,21 @@ static int ath10k_add_interface(struct i -+ ret = ath10k_wmi_set_sta_ps_param(ar, arvif->vdev_id, -+ param, value); -+ if (ret) { -+- ath10k_warn("failed to set vdev %i RX wake policy: %d\n", -++ ath10k_warn(ar, "failed to set vdev %i RX wake policy: %d\n", -+ arvif->vdev_id, ret); -+ goto err_peer_delete; -+ } -+ -+- param = WMI_STA_PS_PARAM_TX_WAKE_THRESHOLD; -+- value = WMI_STA_PS_TX_WAKE_THRESHOLD_ALWAYS; -+- ret = ath10k_wmi_set_sta_ps_param(ar, arvif->vdev_id, -+- param, value); -++ ret = ath10k_mac_vif_recalc_ps_wake_threshold(arvif); -+ if (ret) { -+- ath10k_warn("failed to set vdev %i TX wake thresh: %d\n", -++ ath10k_warn(ar, "failed to recalc ps wake threshold on vdev %i: %d\n", -+ arvif->vdev_id, ret); -+ goto err_peer_delete; -+ } -+ -+- param = WMI_STA_PS_PARAM_PSPOLL_COUNT; -+- value = WMI_STA_PS_PSPOLL_COUNT_NO_MAX; -+- ret = ath10k_wmi_set_sta_ps_param(ar, arvif->vdev_id, -+- param, value); -++ ret = ath10k_mac_vif_recalc_ps_poll_count(arvif); -+ if (ret) { -+- ath10k_warn("failed to set vdev %i PSPOLL count: %d\n", -++ ath10k_warn(ar, "failed to recalc ps poll count on vdev %i: %d\n", -+ arvif->vdev_id, ret); -+ goto err_peer_delete; -+ } -+@@ -2741,15 +3381,22 @@ static int ath10k_add_interface(struct i -+ -+ ret = ath10k_mac_set_rts(arvif, ar->hw->wiphy->rts_threshold); -+ if (ret) { -+- ath10k_warn("failed to set rts threshold for vdev %d: %d\n", -++ ath10k_warn(ar, "failed to set rts threshold for vdev %d: %d\n", -++ arvif->vdev_id, ret); -++ goto err_peer_delete; -++ } -++ -++ ret = ath10k_mac_set_frag(arvif, ar->hw->wiphy->frag_threshold); -++ if (ret) { -++ ath10k_warn(ar, "failed to set frag threshold for vdev %d: %d\n", -+ arvif->vdev_id, ret); -+ goto err_peer_delete; -+ } -+ -+- ret = ath10k_mac_set_frag(arvif, ar->hw->wiphy->frag_threshold); -++ arvif->txpower = vif->bss_conf.txpower; -++ ret = ath10k_mac_txpower_recalc(ar); -+ if (ret) { -+- ath10k_warn("failed to set frag threshold for vdev %d: %d\n", -+- arvif->vdev_id, ret); -++ ath10k_warn(ar, "failed to recalc tx power: %d\n", ret); -+ goto err_peer_delete; -+ } -+ -+@@ -2762,10 +3409,16 @@ err_peer_delete: -+ -+ err_vdev_delete: -+ ath10k_wmi_vdev_delete(ar, arvif->vdev_id); -+- ar->free_vdev_map &= ~BIT(arvif->vdev_id); -++ ar->free_vdev_map |= 1LL << arvif->vdev_id; -+ list_del(&arvif->list); -+ -+ err: -++ if (arvif->beacon_buf) { -++ dma_free_coherent(ar->dev, IEEE80211_MAX_FRAME_LEN, -++ arvif->beacon_buf, arvif->beacon_paddr); -++ arvif->beacon_buf = NULL; -++ } -++ -+ mutex_unlock(&ar->conf_mutex); -+ -+ return ret; -+@@ -2780,38 +3433,51 @@ static void ath10k_remove_interface(stru -+ -+ mutex_lock(&ar->conf_mutex); -+ -+- cancel_work_sync(&arvif->wep_key_work); -+- -+ spin_lock_bh(&ar->data_lock); -+- if (arvif->beacon) { -+- dma_unmap_single(arvif->ar->dev, -+- ATH10K_SKB_CB(arvif->beacon)->paddr, -+- arvif->beacon->len, DMA_TO_DEVICE); -+- dev_kfree_skb_any(arvif->beacon); -+- arvif->beacon = NULL; -+- } -++ ath10k_mac_vif_beacon_cleanup(arvif); -+ spin_unlock_bh(&ar->data_lock); -+ -+- ar->free_vdev_map |= 1 << (arvif->vdev_id); -++ ret = ath10k_spectral_vif_stop(arvif); -++ if (ret) -++ ath10k_warn(ar, "failed to stop spectral for vdev %i: %d\n", -++ arvif->vdev_id, ret); -++ -++ ar->free_vdev_map |= 1LL << arvif->vdev_id; -+ list_del(&arvif->list); -+ -+ if (arvif->vdev_type == WMI_VDEV_TYPE_AP) { -+- ret = ath10k_peer_delete(arvif->ar, arvif->vdev_id, vif->addr); -++ ret = ath10k_wmi_peer_delete(arvif->ar, arvif->vdev_id, -++ vif->addr); -+ if (ret) -+- ath10k_warn("failed to remove peer for AP vdev %i: %d\n", -++ ath10k_warn(ar, "failed to submit AP self-peer removal on vdev %i: %d\n", -+ arvif->vdev_id, ret); -+ -+ kfree(arvif->u.ap.noa_data); -+ } -+ -+- ath10k_dbg(ATH10K_DBG_MAC, "mac vdev %i delete (remove interface)\n", -++ ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %i delete (remove interface)\n", -+ arvif->vdev_id); -+ -+ ret = ath10k_wmi_vdev_delete(ar, arvif->vdev_id); -+ if (ret) -+- ath10k_warn("failed to delete WMI vdev %i: %d\n", -++ ath10k_warn(ar, "failed to delete WMI vdev %i: %d\n", -+ arvif->vdev_id, ret); -+ -++ /* Some firmware revisions don't notify host about self-peer removal -++ * until after associated vdev is deleted. -++ */ -++ if (arvif->vdev_type == WMI_VDEV_TYPE_AP) { -++ ret = ath10k_wait_for_peer_deleted(ar, arvif->vdev_id, -++ vif->addr); -++ if (ret) -++ ath10k_warn(ar, "failed to remove AP self-peer on vdev %i: %d\n", -++ arvif->vdev_id, ret); -++ -++ spin_lock_bh(&ar->data_lock); -++ ar->num_peers--; -++ spin_unlock_bh(&ar->data_lock); -++ } -++ -+ ath10k_peer_cleanup(ar, arvif->vdev_id); -+ -+ mutex_unlock(&ar->conf_mutex); -+@@ -2844,18 +3510,9 @@ static void ath10k_configure_filter(stru -+ *total_flags &= SUPPORTED_FILTERS; -+ ar->filter_flags = *total_flags; -+ -+- if (ar->filter_flags & FIF_PROMISC_IN_BSS && !ar->promisc) { -+- ar->promisc = true; -+- ret = ath10k_monitor_start(ar); -+- if (ret) { -+- ath10k_warn("failed to start monitor (promisc): %d\n", -+- ret); -+- ar->promisc = false; -+- } -+- } else if (!(ar->filter_flags & FIF_PROMISC_IN_BSS) && ar->promisc) { -+- ar->promisc = false; -+- ath10k_monitor_stop(ar); -+- } -++ ret = ath10k_monitor_recalc(ar); -++ if (ret) -++ ath10k_warn(ar, "failed to recalc montior: %d\n", ret); -+ -+ mutex_unlock(&ar->conf_mutex); -+ } -+@@ -2868,7 +3525,7 @@ static void ath10k_bss_info_changed(stru -+ struct ath10k *ar = hw->priv; -+ struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif); -+ int ret = 0; -+- u32 vdev_param, pdev_param; -++ u32 vdev_param, pdev_param, slottime, preamble; -+ -+ mutex_lock(&ar->conf_mutex); -+ -+@@ -2880,17 +3537,17 @@ static void ath10k_bss_info_changed(stru -+ vdev_param = ar->wmi.vdev_param->beacon_interval; -+ ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param, -+ arvif->beacon_interval); -+- ath10k_dbg(ATH10K_DBG_MAC, -++ ath10k_dbg(ar, ATH10K_DBG_MAC, -+ "mac vdev %d beacon_interval %d\n", -+ arvif->vdev_id, arvif->beacon_interval); -+ -+ if (ret) -+- ath10k_warn("failed to set beacon interval for vdev %d: %i\n", -++ ath10k_warn(ar, "failed to set beacon interval for vdev %d: %i\n", -+ arvif->vdev_id, ret); -+ } -+ -+ if (changed & BSS_CHANGED_BEACON) { -+- ath10k_dbg(ATH10K_DBG_MAC, -++ ath10k_dbg(ar, ATH10K_DBG_MAC, -+ "vdev %d set beacon tx mode to staggered\n", -+ arvif->vdev_id); -+ -+@@ -2898,14 +3555,26 @@ static void ath10k_bss_info_changed(stru -+ ret = ath10k_wmi_pdev_set_param(ar, pdev_param, -+ WMI_BEACON_STAGGERED_MODE); -+ if (ret) -+- ath10k_warn("failed to set beacon mode for vdev %d: %i\n", -++ ath10k_warn(ar, "failed to set beacon mode for vdev %d: %i\n", -++ arvif->vdev_id, ret); -++ -++ ret = ath10k_mac_setup_bcn_tmpl(arvif); -++ if (ret) -++ ath10k_warn(ar, "failed to update beacon template: %d\n", -++ ret); -++ } -++ -++ if (changed & BSS_CHANGED_AP_PROBE_RESP) { -++ ret = ath10k_mac_setup_prb_tmpl(arvif); -++ if (ret) -++ ath10k_warn(ar, "failed to setup probe resp template on vdev %i: %d\n", -+ arvif->vdev_id, ret); -+ } -+ -+- if (changed & BSS_CHANGED_BEACON_INFO) { -++ if (changed & (BSS_CHANGED_BEACON_INFO | BSS_CHANGED_BEACON)) { -+ arvif->dtim_period = info->dtim_period; -+ -+- ath10k_dbg(ATH10K_DBG_MAC, -++ ath10k_dbg(ar, ATH10K_DBG_MAC, -+ "mac vdev %d dtim_period %d\n", -+ arvif->vdev_id, arvif->dtim_period); -+ -+@@ -2913,7 +3582,7 @@ static void ath10k_bss_info_changed(stru -+ ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param, -+ arvif->dtim_period); -+ if (ret) -+- ath10k_warn("failed to set dtim period for vdev %d: %i\n", -++ ath10k_warn(ar, "failed to set dtim period for vdev %d: %i\n", -+ arvif->vdev_id, ret); -+ } -+ -+@@ -2925,91 +3594,48 @@ static void ath10k_bss_info_changed(stru -+ arvif->u.ap.hidden_ssid = info->hidden_ssid; -+ } -+ -+- if (changed & BSS_CHANGED_BSSID) { -+- if (!is_zero_ether_addr(info->bssid)) { -+- ath10k_dbg(ATH10K_DBG_MAC, -+- "mac vdev %d create peer %pM\n", -+- arvif->vdev_id, info->bssid); -+- -+- ret = ath10k_peer_create(ar, arvif->vdev_id, -+- info->bssid); -+- if (ret) -+- ath10k_warn("failed to add peer %pM for vdev %d when changing bssid: %i\n", -+- info->bssid, arvif->vdev_id, ret); -+- -+- if (vif->type == NL80211_IFTYPE_STATION) { -+- /* -+- * this is never erased as we it for crypto key -+- * clearing; this is FW requirement -+- */ -+- memcpy(arvif->bssid, info->bssid, ETH_ALEN); -+- -+- ath10k_dbg(ATH10K_DBG_MAC, -+- "mac vdev %d start %pM\n", -+- arvif->vdev_id, info->bssid); -+- -+- ret = ath10k_vdev_start(arvif); -+- if (ret) { -+- ath10k_warn("failed to start vdev %i: %d\n", -+- arvif->vdev_id, ret); -+- goto exit; -+- } -+- -+- arvif->is_started = true; -+- } -+- -+- /* -+- * Mac80211 does not keep IBSS bssid when leaving IBSS, -+- * so driver need to store it. It is needed when leaving -+- * IBSS in order to remove BSSID peer. -+- */ -+- if (vif->type == NL80211_IFTYPE_ADHOC) -+- memcpy(arvif->bssid, info->bssid, -+- ETH_ALEN); -+- } -+- } -++ if (changed & BSS_CHANGED_BSSID && !is_zero_ether_addr(info->bssid)) -++ ether_addr_copy(arvif->bssid, info->bssid); -+ -+ if (changed & BSS_CHANGED_BEACON_ENABLED) -+ ath10k_control_beaconing(arvif, info); -+ -+ if (changed & BSS_CHANGED_ERP_CTS_PROT) { -+ arvif->use_cts_prot = info->use_cts_prot; -+- ath10k_dbg(ATH10K_DBG_MAC, "mac vdev %d cts_prot %d\n", -++ ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %d cts_prot %d\n", -+ arvif->vdev_id, info->use_cts_prot); -+ -+ ret = ath10k_recalc_rtscts_prot(arvif); -+ if (ret) -+- ath10k_warn("failed to recalculate rts/cts prot for vdev %d: %d\n", -++ ath10k_warn(ar, "failed to recalculate rts/cts prot for vdev %d: %d\n", -+ arvif->vdev_id, ret); -+ } -+ -+ if (changed & BSS_CHANGED_ERP_SLOT) { -+- u32 slottime; -+ if (info->use_short_slot) -+ slottime = WMI_VDEV_SLOT_TIME_SHORT; /* 9us */ -+ -+ else -+ slottime = WMI_VDEV_SLOT_TIME_LONG; /* 20us */ -+ -+- ath10k_dbg(ATH10K_DBG_MAC, "mac vdev %d slot_time %d\n", -++ ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %d slot_time %d\n", -+ arvif->vdev_id, slottime); -+ -+ vdev_param = ar->wmi.vdev_param->slot_time; -+ ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param, -+ slottime); -+ if (ret) -+- ath10k_warn("failed to set erp slot for vdev %d: %i\n", -++ ath10k_warn(ar, "failed to set erp slot for vdev %d: %i\n", -+ arvif->vdev_id, ret); -+ } -+ -+ if (changed & BSS_CHANGED_ERP_PREAMBLE) { -+- u32 preamble; -+ if (info->use_short_preamble) -+ preamble = WMI_VDEV_PREAMBLE_SHORT; -+ else -+ preamble = WMI_VDEV_PREAMBLE_LONG; -+ -+- ath10k_dbg(ATH10K_DBG_MAC, -++ ath10k_dbg(ar, ATH10K_DBG_MAC, -+ "mac vdev %d preamble %dn", -+ arvif->vdev_id, preamble); -+ -+@@ -3017,16 +3643,44 @@ static void ath10k_bss_info_changed(stru -+ ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param, -+ preamble); -+ if (ret) -+- ath10k_warn("failed to set preamble for vdev %d: %i\n", -++ ath10k_warn(ar, "failed to set preamble for vdev %d: %i\n", -+ arvif->vdev_id, ret); -+ } -+ -+ if (changed & BSS_CHANGED_ASSOC) { -+- if (info->assoc) -++ if (info->assoc) { -++ /* Workaround: Make sure monitor vdev is not running -++ * when associating to prevent some firmware revisions -++ * (e.g. 10.1 and 10.2) from crashing. -++ */ -++ if (ar->monitor_started) -++ ath10k_monitor_stop(ar); -+ ath10k_bss_assoc(hw, vif, info); -++ ath10k_monitor_recalc(ar); -++ } else { -++ ath10k_bss_disassoc(hw, vif); -++ } -++ } -++ -++ if (changed & BSS_CHANGED_TXPOWER) { -++ ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev_id %i txpower %d\n", -++ arvif->vdev_id, info->txpower); -++ -++ arvif->txpower = info->txpower; -++ ret = ath10k_mac_txpower_recalc(ar); -++ if (ret) -++ ath10k_warn(ar, "failed to recalc tx power: %d\n", ret); -++ } -++ -++ if (changed & BSS_CHANGED_PS) { -++ arvif->ps = vif->bss_conf.ps; -++ -++ ret = ath10k_config_ps(ar); -++ if (ret) -++ ath10k_warn(ar, "failed to setup ps on vdev %i: %d\n", -++ arvif->vdev_id, ret); -+ } -+ -+-exit: -+ mutex_unlock(&ar->conf_mutex); -+ } -+ -+@@ -3043,20 +3697,26 @@ static int ath10k_hw_scan(struct ieee802 -+ mutex_lock(&ar->conf_mutex); -+ -+ spin_lock_bh(&ar->data_lock); -+- if (ar->scan.in_progress) { -+- spin_unlock_bh(&ar->data_lock); -++ switch (ar->scan.state) { -++ case ATH10K_SCAN_IDLE: -++ reinit_completion(&ar->scan.started); -++ reinit_completion(&ar->scan.completed); -++ ar->scan.state = ATH10K_SCAN_STARTING; -++ ar->scan.is_roc = false; -++ ar->scan.vdev_id = arvif->vdev_id; -++ ret = 0; -++ break; -++ case ATH10K_SCAN_STARTING: -++ case ATH10K_SCAN_RUNNING: -++ case ATH10K_SCAN_ABORTING: -+ ret = -EBUSY; -+- goto exit; -++ break; -+ } -+- -+- reinit_completion(&ar->scan.started); -+- reinit_completion(&ar->scan.completed); -+- ar->scan.in_progress = true; -+- ar->scan.aborting = false; -+- ar->scan.is_roc = false; -+- ar->scan.vdev_id = arvif->vdev_id; -+ spin_unlock_bh(&ar->data_lock); -+ -++ if (ret) -++ goto exit; -++ -+ memset(&arg, 0, sizeof(arg)); -+ ath10k_wmi_start_scan_init(ar, &arg); -+ arg.vdev_id = arvif->vdev_id; -+@@ -3088,9 +3748,9 @@ static int ath10k_hw_scan(struct ieee802 -+ -+ ret = ath10k_start_scan(ar, &arg); -+ if (ret) { -+- ath10k_warn("failed to start hw scan: %d\n", ret); -++ ath10k_warn(ar, "failed to start hw scan: %d\n", ret); -+ spin_lock_bh(&ar->data_lock); -+- ar->scan.in_progress = false; -++ ar->scan.state = ATH10K_SCAN_IDLE; -+ spin_unlock_bh(&ar->data_lock); -+ } -+ -+@@ -3103,15 +3763,12 @@ static void ath10k_cancel_hw_scan(struct -+ struct ieee80211_vif *vif) -+ { -+ struct ath10k *ar = hw->priv; -+- int ret; -+ -+ mutex_lock(&ar->conf_mutex); -+- ret = ath10k_abort_scan(ar); -+- if (ret) { -+- ath10k_warn("failed to abort scan: %d\n", ret); -+- ieee80211_scan_completed(hw, 1 /* aborted */); -+- } -++ ath10k_scan_abort(ar); -+ mutex_unlock(&ar->conf_mutex); -++ -++ cancel_delayed_work_sync(&ar->scan.timeout); -+ } -+ -+ static void ath10k_set_key_h_def_keyidx(struct ath10k *ar, -+@@ -3148,7 +3805,7 @@ static void ath10k_set_key_h_def_keyidx( -+ ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param, -+ key->keyidx); -+ if (ret) -+- ath10k_warn("failed to set vdev %i group key as default key: %d\n", -++ ath10k_warn(ar, "failed to set vdev %i group key as default key: %d\n", -+ arvif->vdev_id, ret); -+ } -+ -+@@ -3162,6 +3819,7 @@ static int ath10k_set_key(struct ieee802 -+ const u8 *peer_addr; -+ bool is_wep = key->cipher == WLAN_CIPHER_SUITE_WEP40 || -+ key->cipher == WLAN_CIPHER_SUITE_WEP104; -++ bool def_idx = false; -+ int ret = 0; -+ -+ if (key->keyidx > WMI_MAX_KEY_INDEX) -+@@ -3186,7 +3844,7 @@ static int ath10k_set_key(struct ieee802 -+ -+ if (!peer) { -+ if (cmd == SET_KEY) { -+- ath10k_warn("failed to install key for non-existent peer %pM\n", -++ ath10k_warn(ar, "failed to install key for non-existent peer %pM\n", -+ peer_addr); -+ ret = -EOPNOTSUPP; -+ goto exit; -+@@ -3207,9 +3865,16 @@ static int ath10k_set_key(struct ieee802 -+ ath10k_clear_vdev_key(arvif, key); -+ } -+ -+- ret = ath10k_install_key(arvif, key, cmd, peer_addr); -++ /* set TX_USAGE flag for all the keys incase of dot1x-WEP. For -++ * static WEP, do not set this flag for the keys whose key id -++ * is greater than default key id. -++ */ -++ if (arvif->def_wep_key_idx == -1) -++ def_idx = true; -++ -++ ret = ath10k_install_key(arvif, key, cmd, peer_addr, def_idx); -+ if (ret) { -+- ath10k_warn("failed to install key for vdev %i peer %pM: %d\n", -++ ath10k_warn(ar, "failed to install key for vdev %i peer %pM: %d\n", -+ arvif->vdev_id, peer_addr, ret); -+ goto exit; -+ } -+@@ -3224,7 +3889,7 @@ static int ath10k_set_key(struct ieee802 -+ peer->keys[key->keyidx] = NULL; -+ else if (peer == NULL) -+ /* impossible unless FW goes crazy */ -+- ath10k_warn("Peer %pM disappeared!\n", peer_addr); -++ ath10k_warn(ar, "Peer %pM disappeared!\n", peer_addr); -+ spin_unlock_bh(&ar->data_lock); -+ -+ exit: -+@@ -3232,6 +3897,39 @@ exit: -+ return ret; -+ } -+ -++static void ath10k_set_default_unicast_key(struct ieee80211_hw *hw, -++ struct ieee80211_vif *vif, -++ int keyidx) -++{ -++ struct ath10k *ar = hw->priv; -++ struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif); -++ int ret; -++ -++ mutex_lock(&arvif->ar->conf_mutex); -++ -++ if (arvif->ar->state != ATH10K_STATE_ON) -++ goto unlock; -++ -++ ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %d set keyidx %d\n", -++ arvif->vdev_id, keyidx); -++ -++ ret = ath10k_wmi_vdev_set_param(arvif->ar, -++ arvif->vdev_id, -++ arvif->ar->wmi.vdev_param->def_keyid, -++ keyidx); -++ -++ if (ret) { -++ ath10k_warn(ar, "failed to update wep key index for vdev %d: %d\n", -++ arvif->vdev_id, -++ ret); -++ goto unlock; -++ } -++ -++ arvif->def_wep_key_idx = keyidx; -++unlock: -++ mutex_unlock(&arvif->ar->conf_mutex); -++} -++ -+ static void ath10k_sta_rc_update_wk(struct work_struct *wk) -+ { -+ struct ath10k *ar; -+@@ -3260,51 +3958,83 @@ static void ath10k_sta_rc_update_wk(stru -+ mutex_lock(&ar->conf_mutex); -+ -+ if (changed & IEEE80211_RC_BW_CHANGED) { -+- ath10k_dbg(ATH10K_DBG_MAC, "mac update sta %pM peer bw %d\n", -++ ath10k_dbg(ar, ATH10K_DBG_MAC, "mac update sta %pM peer bw %d\n", -+ sta->addr, bw); -+ -+ err = ath10k_wmi_peer_set_param(ar, arvif->vdev_id, sta->addr, -+ WMI_PEER_CHAN_WIDTH, bw); -+ if (err) -+- ath10k_warn("failed to update STA %pM peer bw %d: %d\n", -++ ath10k_warn(ar, "failed to update STA %pM peer bw %d: %d\n", -+ sta->addr, bw, err); -+ } -+ -+ if (changed & IEEE80211_RC_NSS_CHANGED) { -+- ath10k_dbg(ATH10K_DBG_MAC, "mac update sta %pM nss %d\n", -++ ath10k_dbg(ar, ATH10K_DBG_MAC, "mac update sta %pM nss %d\n", -+ sta->addr, nss); -+ -+ err = ath10k_wmi_peer_set_param(ar, arvif->vdev_id, sta->addr, -+ WMI_PEER_NSS, nss); -+ if (err) -+- ath10k_warn("failed to update STA %pM nss %d: %d\n", -++ ath10k_warn(ar, "failed to update STA %pM nss %d: %d\n", -+ sta->addr, nss, err); -+ } -+ -+ if (changed & IEEE80211_RC_SMPS_CHANGED) { -+- ath10k_dbg(ATH10K_DBG_MAC, "mac update sta %pM smps %d\n", -++ ath10k_dbg(ar, ATH10K_DBG_MAC, "mac update sta %pM smps %d\n", -+ sta->addr, smps); -+ -+ err = ath10k_wmi_peer_set_param(ar, arvif->vdev_id, sta->addr, -+ WMI_PEER_SMPS_STATE, smps); -+ if (err) -+- ath10k_warn("failed to update STA %pM smps %d: %d\n", -++ ath10k_warn(ar, "failed to update STA %pM smps %d: %d\n", -+ sta->addr, smps, err); -+ } -+ -+- if (changed & IEEE80211_RC_SUPP_RATES_CHANGED) { -+- ath10k_dbg(ATH10K_DBG_MAC, "mac update sta %pM supp rates\n", -++ if (changed & IEEE80211_RC_SUPP_RATES_CHANGED || -++ changed & IEEE80211_RC_NSS_CHANGED) { -++ ath10k_dbg(ar, ATH10K_DBG_MAC, "mac update sta %pM supp rates/nss\n", -+ sta->addr); -+ -+- err = ath10k_station_assoc(ar, arvif, sta, true); -++ err = ath10k_station_assoc(ar, arvif->vif, sta, true); -+ if (err) -+- ath10k_warn("failed to reassociate station: %pM\n", -++ ath10k_warn(ar, "failed to reassociate station: %pM\n", -+ sta->addr); -+ } -+ -+ mutex_unlock(&ar->conf_mutex); -+ } -+ -++static int ath10k_mac_inc_num_stations(struct ath10k_vif *arvif) -++{ -++ struct ath10k *ar = arvif->ar; -++ -++ lockdep_assert_held(&ar->conf_mutex); -++ -++ if (arvif->vdev_type != WMI_VDEV_TYPE_AP && -++ arvif->vdev_type != WMI_VDEV_TYPE_IBSS) -++ return 0; -++ -++ if (ar->num_stations >= ar->max_num_stations) -++ return -ENOBUFS; -++ -++ ar->num_stations++; -++ -++ return 0; -++} -++ -++static void ath10k_mac_dec_num_stations(struct ath10k_vif *arvif) -++{ -++ struct ath10k *ar = arvif->ar; -++ -++ lockdep_assert_held(&ar->conf_mutex); -++ -++ if (arvif->vdev_type != WMI_VDEV_TYPE_AP && -++ arvif->vdev_type != WMI_VDEV_TYPE_IBSS) -++ return; -++ -++ ar->num_stations--; -++} -++ -+ static int ath10k_sta_state(struct ieee80211_hw *hw, -+ struct ieee80211_vif *vif, -+ struct ieee80211_sta *sta, -+@@ -3314,7 +4044,6 @@ static int ath10k_sta_state(struct ieee8 -+ struct ath10k *ar = hw->priv; -+ struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif); -+ struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv; -+- int max_num_peers; -+ int ret = 0; -+ -+ if (old_state == IEEE80211_STA_NOTEXIST && -+@@ -3332,46 +4061,72 @@ static int ath10k_sta_state(struct ieee8 -+ mutex_lock(&ar->conf_mutex); -+ -+ if (old_state == IEEE80211_STA_NOTEXIST && -+- new_state == IEEE80211_STA_NONE && -+- vif->type != NL80211_IFTYPE_STATION) { -++ new_state == IEEE80211_STA_NONE) { -+ /* -+ * New station addition. -+ */ -+- if (test_bit(ATH10K_FW_FEATURE_WMI_10X, ar->fw_features)) -+- max_num_peers = TARGET_10X_NUM_PEERS_MAX - 1; -+- else -+- max_num_peers = TARGET_NUM_PEERS; -++ ath10k_dbg(ar, ATH10K_DBG_MAC, -++ "mac vdev %d peer create %pM (new sta) sta %d / %d peer %d / %d\n", -++ arvif->vdev_id, sta->addr, -++ ar->num_stations + 1, ar->max_num_stations, -++ ar->num_peers + 1, ar->max_num_peers); -+ -+- if (ar->num_peers >= max_num_peers) { -+- ath10k_warn("number of peers exceeded: peers number %d (max peers %d)\n", -+- ar->num_peers, max_num_peers); -+- ret = -ENOBUFS; -++ ret = ath10k_mac_inc_num_stations(arvif); -++ if (ret) { -++ ath10k_warn(ar, "refusing to associate station: too many connected already (%d)\n", -++ ar->max_num_stations); -+ goto exit; -+ } -+ -+- ath10k_dbg(ATH10K_DBG_MAC, -+- "mac vdev %d peer create %pM (new sta) num_peers %d\n", -+- arvif->vdev_id, sta->addr, ar->num_peers); -+- -+ ret = ath10k_peer_create(ar, arvif->vdev_id, sta->addr); -+- if (ret) -+- ath10k_warn("failed to add peer %pM for vdev %d when adding a new sta: %i\n", -++ if (ret) { -++ ath10k_warn(ar, "failed to add peer %pM for vdev %d when adding a new sta: %i\n", -+ sta->addr, arvif->vdev_id, ret); -++ ath10k_mac_dec_num_stations(arvif); -++ goto exit; -++ } -++ -++ if (vif->type == NL80211_IFTYPE_STATION) { -++ WARN_ON(arvif->is_started); -++ -++ ret = ath10k_vdev_start(arvif); -++ if (ret) { -++ ath10k_warn(ar, "failed to start vdev %i: %d\n", -++ arvif->vdev_id, ret); -++ WARN_ON(ath10k_peer_delete(ar, arvif->vdev_id, -++ sta->addr)); -++ ath10k_mac_dec_num_stations(arvif); -++ goto exit; -++ } -++ -++ arvif->is_started = true; -++ } -+ } else if ((old_state == IEEE80211_STA_NONE && -+ new_state == IEEE80211_STA_NOTEXIST)) { -+ /* -+ * Existing station deletion. -+ */ -+- ath10k_dbg(ATH10K_DBG_MAC, -++ ath10k_dbg(ar, ATH10K_DBG_MAC, -+ "mac vdev %d peer delete %pM (sta gone)\n", -+ arvif->vdev_id, sta->addr); -++ -++ if (vif->type == NL80211_IFTYPE_STATION) { -++ WARN_ON(!arvif->is_started); -++ -++ ret = ath10k_vdev_stop(arvif); -++ if (ret) -++ ath10k_warn(ar, "failed to stop vdev %i: %d\n", -++ arvif->vdev_id, ret); -++ -++ arvif->is_started = false; -++ } -++ -+ ret = ath10k_peer_delete(ar, arvif->vdev_id, sta->addr); -+ if (ret) -+- ath10k_warn("failed to delete peer %pM for vdev %d: %i\n", -++ ath10k_warn(ar, "failed to delete peer %pM for vdev %d: %i\n", -+ sta->addr, arvif->vdev_id, ret); -+ -+- if (vif->type == NL80211_IFTYPE_STATION) -+- ath10k_bss_disassoc(hw, vif); -++ ath10k_mac_dec_num_stations(arvif); -+ } else if (old_state == IEEE80211_STA_AUTH && -+ new_state == IEEE80211_STA_ASSOC && -+ (vif->type == NL80211_IFTYPE_AP || -+@@ -3379,12 +4134,12 @@ static int ath10k_sta_state(struct ieee8 -+ /* -+ * New association. -+ */ -+- ath10k_dbg(ATH10K_DBG_MAC, "mac sta %pM associated\n", -++ ath10k_dbg(ar, ATH10K_DBG_MAC, "mac sta %pM associated\n", -+ sta->addr); -+ -+- ret = ath10k_station_assoc(ar, arvif, sta, false); -++ ret = ath10k_station_assoc(ar, vif, sta, false); -+ if (ret) -+- ath10k_warn("failed to associate station %pM for vdev %i: %i\n", -++ ath10k_warn(ar, "failed to associate station %pM for vdev %i: %i\n", -+ sta->addr, arvif->vdev_id, ret); -+ } else if (old_state == IEEE80211_STA_ASSOC && -+ new_state == IEEE80211_STA_AUTH && -+@@ -3393,12 +4148,12 @@ static int ath10k_sta_state(struct ieee8 -+ /* -+ * Disassociation. -+ */ -+- ath10k_dbg(ATH10K_DBG_MAC, "mac sta %pM disassociated\n", -++ ath10k_dbg(ar, ATH10K_DBG_MAC, "mac sta %pM disassociated\n", -+ sta->addr); -+ -+- ret = ath10k_station_disassoc(ar, arvif, sta); -++ ret = ath10k_station_disassoc(ar, vif, sta); -+ if (ret) -+- ath10k_warn("failed to disassociate station: %pM vdev %i: %i\n", -++ ath10k_warn(ar, "failed to disassociate station: %pM vdev %i: %i\n", -+ sta->addr, arvif->vdev_id, ret); -+ } -+ exit: -+@@ -3407,9 +4162,11 @@ exit: -+ } -+ -+ static int ath10k_conf_tx_uapsd(struct ath10k *ar, struct ieee80211_vif *vif, -+- u16 ac, bool enable) -++ u16 ac, bool enable) -+ { -+ struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif); -++ struct wmi_sta_uapsd_auto_trig_arg arg = {}; -++ u32 prio = 0, acc = 0; -+ u32 value = 0; -+ int ret = 0; -+ -+@@ -3422,18 +4179,26 @@ static int ath10k_conf_tx_uapsd(struct a -+ case IEEE80211_AC_VO: -+ value = WMI_STA_PS_UAPSD_AC3_DELIVERY_EN | -+ WMI_STA_PS_UAPSD_AC3_TRIGGER_EN; -++ prio = 7; -++ acc = 3; -+ break; -+ case IEEE80211_AC_VI: -+ value = WMI_STA_PS_UAPSD_AC2_DELIVERY_EN | -+ WMI_STA_PS_UAPSD_AC2_TRIGGER_EN; -++ prio = 5; -++ acc = 2; -+ break; -+ case IEEE80211_AC_BE: -+ value = WMI_STA_PS_UAPSD_AC1_DELIVERY_EN | -+ WMI_STA_PS_UAPSD_AC1_TRIGGER_EN; -++ prio = 2; -++ acc = 1; -+ break; -+ case IEEE80211_AC_BK: -+ value = WMI_STA_PS_UAPSD_AC0_DELIVERY_EN | -+ WMI_STA_PS_UAPSD_AC0_TRIGGER_EN; -++ prio = 0; -++ acc = 0; -+ break; -+ } -+ -+@@ -3446,7 +4211,7 @@ static int ath10k_conf_tx_uapsd(struct a -+ WMI_STA_PS_PARAM_UAPSD, -+ arvif->u.sta.uapsd); -+ if (ret) { -+- ath10k_warn("failed to set uapsd params: %d\n", ret); -++ ath10k_warn(ar, "failed to set uapsd params: %d\n", ret); -+ goto exit; -+ } -+ -+@@ -3459,7 +4224,44 @@ static int ath10k_conf_tx_uapsd(struct a -+ WMI_STA_PS_PARAM_RX_WAKE_POLICY, -+ value); -+ if (ret) -+- ath10k_warn("failed to set rx wake param: %d\n", ret); -++ ath10k_warn(ar, "failed to set rx wake param: %d\n", ret); -++ -++ ret = ath10k_mac_vif_recalc_ps_wake_threshold(arvif); -++ if (ret) { -++ ath10k_warn(ar, "failed to recalc ps wake threshold on vdev %i: %d\n", -++ arvif->vdev_id, ret); -++ return ret; -++ } -++ -++ ret = ath10k_mac_vif_recalc_ps_poll_count(arvif); -++ if (ret) { -++ ath10k_warn(ar, "failed to recalc ps poll count on vdev %i: %d\n", -++ arvif->vdev_id, ret); -++ return ret; -++ } -++ -++ if (test_bit(WMI_SERVICE_STA_UAPSD_BASIC_AUTO_TRIG, ar->wmi.svc_map) || -++ test_bit(WMI_SERVICE_STA_UAPSD_VAR_AUTO_TRIG, ar->wmi.svc_map)) { -++ /* Only userspace can make an educated decision when to send -++ * trigger frame. The following effectively disables u-UAPSD -++ * autotrigger in firmware (which is enabled by default -++ * provided the autotrigger service is available). -++ */ -++ -++ arg.wmm_ac = acc; -++ arg.user_priority = prio; -++ arg.service_interval = 0; -++ arg.suspend_interval = WMI_STA_UAPSD_MAX_INTERVAL_MSEC; -++ arg.delay_interval = WMI_STA_UAPSD_MAX_INTERVAL_MSEC; -++ -++ ret = ath10k_wmi_vdev_sta_uapsd(ar, arvif->vdev_id, -++ arvif->bssid, &arg, 1); -++ if (ret) { -++ ath10k_warn(ar, "failed to set uapsd auto trigger %d\n", -++ ret); -++ return ret; -++ } -++ } -+ -+ exit: -+ return ret; -+@@ -3470,6 +4272,7 @@ static int ath10k_conf_tx(struct ieee802 -+ const struct ieee80211_tx_queue_params *params) -+ { -+ struct ath10k *ar = hw->priv; -++ struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif); -+ struct wmi_wmm_params_arg *p = NULL; -+ int ret; -+ -+@@ -3477,16 +4280,16 @@ static int ath10k_conf_tx(struct ieee802 -+ -+ switch (ac) { -+ case IEEE80211_AC_VO: -+- p = &ar->wmm_params.ac_vo; -++ p = &arvif->wmm_params.ac_vo; -+ break; -+ case IEEE80211_AC_VI: -+- p = &ar->wmm_params.ac_vi; -++ p = &arvif->wmm_params.ac_vi; -+ break; -+ case IEEE80211_AC_BE: -+- p = &ar->wmm_params.ac_be; -++ p = &arvif->wmm_params.ac_be; -+ break; -+ case IEEE80211_AC_BK: -+- p = &ar->wmm_params.ac_bk; -++ p = &arvif->wmm_params.ac_bk; -+ break; -+ } -+ -+@@ -3506,16 +4309,28 @@ static int ath10k_conf_tx(struct ieee802 -+ */ -+ p->txop = params->txop * 32; -+ -+- /* FIXME: FW accepts wmm params per hw, not per vif */ -+- ret = ath10k_wmi_pdev_set_wmm_params(ar, &ar->wmm_params); -+- if (ret) { -+- ath10k_warn("failed to set wmm params: %d\n", ret); -+- goto exit; -++ if (ar->wmi.ops->gen_vdev_wmm_conf) { -++ ret = ath10k_wmi_vdev_wmm_conf(ar, arvif->vdev_id, -++ &arvif->wmm_params); -++ if (ret) { -++ ath10k_warn(ar, "failed to set vdev wmm params on vdev %i: %d\n", -++ arvif->vdev_id, ret); -++ goto exit; -++ } -++ } else { -++ /* This won't work well with multi-interface cases but it's -++ * better than nothing. -++ */ -++ ret = ath10k_wmi_pdev_set_wmm_params(ar, &arvif->wmm_params); -++ if (ret) { -++ ath10k_warn(ar, "failed to set wmm params: %d\n", ret); -++ goto exit; -++ } -+ } -+ -+ ret = ath10k_conf_tx_uapsd(ar, vif, ac, params->uapsd); -+ if (ret) -+- ath10k_warn("failed to set sta uapsd: %d\n", ret); -++ ath10k_warn(ar, "failed to set sta uapsd: %d\n", ret); -+ -+ exit: -+ mutex_unlock(&ar->conf_mutex); -+@@ -3533,27 +4348,35 @@ static int ath10k_remain_on_channel(stru -+ struct ath10k *ar = hw->priv; -+ struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif); -+ struct wmi_start_scan_arg arg; -+- int ret; -++ int ret = 0; -+ -+ mutex_lock(&ar->conf_mutex); -+ -+ spin_lock_bh(&ar->data_lock); -+- if (ar->scan.in_progress) { -+- spin_unlock_bh(&ar->data_lock); -++ switch (ar->scan.state) { -++ case ATH10K_SCAN_IDLE: -++ reinit_completion(&ar->scan.started); -++ reinit_completion(&ar->scan.completed); -++ reinit_completion(&ar->scan.on_channel); -++ ar->scan.state = ATH10K_SCAN_STARTING; -++ ar->scan.is_roc = true; -++ ar->scan.vdev_id = arvif->vdev_id; -++ ar->scan.roc_freq = chan->center_freq; -++ ret = 0; -++ break; -++ case ATH10K_SCAN_STARTING: -++ case ATH10K_SCAN_RUNNING: -++ case ATH10K_SCAN_ABORTING: -+ ret = -EBUSY; -+- goto exit; -++ break; -+ } -+- -+- reinit_completion(&ar->scan.started); -+- reinit_completion(&ar->scan.completed); -+- reinit_completion(&ar->scan.on_channel); -+- ar->scan.in_progress = true; -+- ar->scan.aborting = false; -+- ar->scan.is_roc = true; -+- ar->scan.vdev_id = arvif->vdev_id; -+- ar->scan.roc_freq = chan->center_freq; -+ spin_unlock_bh(&ar->data_lock); -+ -++ if (ret) -++ goto exit; -++ -++ duration = max(duration, WMI_SCAN_CHAN_MIN_TIME_MSEC); -++ -+ memset(&arg, 0, sizeof(arg)); -+ ath10k_wmi_start_scan_init(ar, &arg); -+ arg.vdev_id = arvif->vdev_id; -+@@ -3568,17 +4391,21 @@ static int ath10k_remain_on_channel(stru -+ -+ ret = ath10k_start_scan(ar, &arg); -+ if (ret) { -+- ath10k_warn("failed to start roc scan: %d\n", ret); -++ ath10k_warn(ar, "failed to start roc scan: %d\n", ret); -+ spin_lock_bh(&ar->data_lock); -+- ar->scan.in_progress = false; -++ ar->scan.state = ATH10K_SCAN_IDLE; -+ spin_unlock_bh(&ar->data_lock); -+ goto exit; -+ } -+ -+ ret = wait_for_completion_timeout(&ar->scan.on_channel, 3*HZ); -+ if (ret == 0) { -+- ath10k_warn("failed to switch to channel for roc scan\n"); -+- ath10k_abort_scan(ar); -++ ath10k_warn(ar, "failed to switch to channel for roc scan\n"); -++ -++ ret = ath10k_scan_stop(ar); -++ if (ret) -++ ath10k_warn(ar, "failed to stop scan: %d\n", ret); -++ -+ ret = -ETIMEDOUT; -+ goto exit; -+ } -+@@ -3594,9 +4421,11 @@ static int ath10k_cancel_remain_on_chann -+ struct ath10k *ar = hw->priv; -+ -+ mutex_lock(&ar->conf_mutex); -+- ath10k_abort_scan(ar); -++ ath10k_scan_abort(ar); -+ mutex_unlock(&ar->conf_mutex); -+ -++ cancel_delayed_work_sync(&ar->scan.timeout); -++ -+ return 0; -+ } -+ -+@@ -3613,35 +4442,12 @@ static int ath10k_set_rts_threshold(stru -+ -+ mutex_lock(&ar->conf_mutex); -+ list_for_each_entry(arvif, &ar->arvifs, list) { -+- ath10k_dbg(ATH10K_DBG_MAC, "mac vdev %d rts threshold %d\n", -+- arvif->vdev_id, value); -+- -+- ret = ath10k_mac_set_rts(arvif, value); -+- if (ret) { -+- ath10k_warn("failed to set rts threshold for vdev %d: %d\n", -+- arvif->vdev_id, ret); -+- break; -+- } -+- } -+- mutex_unlock(&ar->conf_mutex); -+- -+- return ret; -+-} -+- -+-static int ath10k_set_frag_threshold(struct ieee80211_hw *hw, u32 value) -+-{ -+- struct ath10k *ar = hw->priv; -+- struct ath10k_vif *arvif; -+- int ret = 0; -+- -+- mutex_lock(&ar->conf_mutex); -+- list_for_each_entry(arvif, &ar->arvifs, list) { -+- ath10k_dbg(ATH10K_DBG_MAC, "mac vdev %d fragmentation threshold %d\n", -++ ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %d rts threshold %d\n", -+ arvif->vdev_id, value); -+ -+ ret = ath10k_mac_set_rts(arvif, value); -+ if (ret) { -+- ath10k_warn("failed to set fragmentation threshold for vdev %d: %d\n", -++ ath10k_warn(ar, "failed to set rts threshold for vdev %d: %d\n", -+ arvif->vdev_id, ret); -+ break; -+ } -+@@ -3675,13 +4481,15 @@ static void ath10k_flush(struct ieee8021 -+ empty = (ar->htt.num_pending_tx == 0); -+ spin_unlock_bh(&ar->htt.tx_lock); -+ -+- skip = (ar->state == ATH10K_STATE_WEDGED); -++ skip = (ar->state == ATH10K_STATE_WEDGED) || -++ test_bit(ATH10K_FLAG_CRASH_FLUSH, -++ &ar->dev_flags); -+ -+ (empty || skip); -+ }), ATH10K_FLUSH_TIMEOUT_HZ); -+ -+ if (ret <= 0 || skip) -+- ath10k_warn("failed to flush transmit queue (skip %i ar-state %i): %i\n", -++ ath10k_warn(ar, "failed to flush transmit queue (skip %i ar-state %i): %i\n", -+ skip, ar->state, ret); -+ -+ skip: -+@@ -3716,7 +4524,7 @@ static int ath10k_suspend(struct ieee802 -+ -+ ret = ath10k_hif_suspend(ar); -+ if (ret) { -+- ath10k_warn("failed to suspend hif: %d\n", ret); -++ ath10k_warn(ar, "failed to suspend hif: %d\n", ret); -+ goto resume; -+ } -+ -+@@ -3725,7 +4533,7 @@ static int ath10k_suspend(struct ieee802 -+ resume: -+ ret = ath10k_wmi_pdev_resume_target(ar); -+ if (ret) -+- ath10k_warn("failed to resume target: %d\n", ret); -++ ath10k_warn(ar, "failed to resume target: %d\n", ret); -+ -+ ret = 1; -+ exit: -+@@ -3742,14 +4550,14 @@ static int ath10k_resume(struct ieee8021 -+ -+ ret = ath10k_hif_resume(ar); -+ if (ret) { -+- ath10k_warn("failed to resume hif: %d\n", ret); -++ ath10k_warn(ar, "failed to resume hif: %d\n", ret); -+ ret = 1; -+ goto exit; -+ } -+ -+ ret = ath10k_wmi_pdev_resume_target(ar); -+ if (ret) { -+- ath10k_warn("failed to resume target: %d\n", ret); -++ ath10k_warn(ar, "failed to resume target: %d\n", ret); -+ ret = 1; -+ goto exit; -+ } -+@@ -3770,8 +4578,9 @@ static void ath10k_restart_complete(stru -+ /* If device failed to restart it will be in a different state, e.g. -+ * ATH10K_STATE_WEDGED */ -+ if (ar->state == ATH10K_STATE_RESTARTED) { -+- ath10k_info("device successfully recovered\n"); -++ ath10k_info(ar, "device successfully recovered\n"); -+ ar->state = ATH10K_STATE_ON; -++ ieee80211_wake_queues(ar->hw); -+ } -+ -+ mutex_unlock(&ar->conf_mutex); -+@@ -3807,6 +4616,9 @@ static int ath10k_get_survey(struct ieee -+ -+ survey->channel = &sband->channels[idx]; -+ -++ if (ar->rx_channel == survey->channel) -++ survey->filled |= SURVEY_INFO_IN_USE; -++ -+ exit: -+ mutex_unlock(&ar->conf_mutex); -+ return ret; -+@@ -3854,6 +4666,10 @@ ath10k_default_bitrate_mask(struct ath10 -+ u32 legacy = 0x00ff; -+ u8 ht = 0xff, i; -+ u16 vht = 0x3ff; -++ u16 nrf = ar->num_rf_chains; -++ -++ if (ar->cfg_tx_chainmask) -++ nrf = get_nss_from_chainmask(ar->cfg_tx_chainmask); -+ -+ switch (band) { -+ case IEEE80211_BAND_2GHZ: -+@@ -3869,11 +4685,11 @@ ath10k_default_bitrate_mask(struct ath10 -+ if (mask->control[band].legacy != legacy) -+ return false; -+ -+- for (i = 0; i < ar->num_rf_chains; i++) -++ for (i = 0; i < nrf; i++) -+ if (mask->control[band].ht_mcs[i] != ht) -+ return false; -+ -+- for (i = 0; i < ar->num_rf_chains; i++) -++ for (i = 0; i < nrf; i++) -+ if (mask->control[band].vht_mcs[i] != vht) -+ return false; -+ -+@@ -3897,8 +4713,8 @@ ath10k_bitrate_mask_nss(const struct cfg -+ continue; -+ else if (mask->control[band].ht_mcs[i] == 0x00) -+ break; -+- else -+- return false; -++ -++ return false; -+ } -+ -+ ht_nss = i; -+@@ -3909,8 +4725,8 @@ ath10k_bitrate_mask_nss(const struct cfg -+ continue; -+ else if (mask->control[band].vht_mcs[i] == 0x0000) -+ break; -+- else -+- return false; -++ -++ return false; -+ } -+ -+ vht_nss = i; -+@@ -3967,7 +4783,8 @@ ath10k_bitrate_mask_correct(const struct -+ } -+ -+ static bool -+-ath10k_bitrate_mask_rate(const struct cfg80211_bitrate_mask *mask, -++ath10k_bitrate_mask_rate(struct ath10k *ar, -++ const struct cfg80211_bitrate_mask *mask, -+ enum ieee80211_band band, -+ u8 *fixed_rate, -+ u8 *fixed_nss) -+@@ -4025,7 +4842,7 @@ ath10k_bitrate_mask_rate(const struct cf -+ nss <<= 4; -+ pream <<= 6; -+ -+- ath10k_dbg(ATH10K_DBG_MAC, "mac fixed rate pream 0x%02x nss 0x%02x rate 0x%02x\n", -++ ath10k_dbg(ar, ATH10K_DBG_MAC, "mac fixed rate pream 0x%02x nss 0x%02x rate 0x%02x\n", -+ pream, nss, rate); -+ -+ *fixed_rate = pream | nss | rate; -+@@ -4033,7 +4850,8 @@ ath10k_bitrate_mask_rate(const struct cf -+ return true; -+ } -+ -+-static bool ath10k_get_fixed_rate_nss(const struct cfg80211_bitrate_mask *mask, -++static bool ath10k_get_fixed_rate_nss(struct ath10k *ar, -++ const struct cfg80211_bitrate_mask *mask, -+ enum ieee80211_band band, -+ u8 *fixed_rate, -+ u8 *fixed_nss) -+@@ -4043,7 +4861,7 @@ static bool ath10k_get_fixed_rate_nss(co -+ return true; -+ -+ /* Next Check single rate is set */ -+- return ath10k_bitrate_mask_rate(mask, band, fixed_rate, fixed_nss); -++ return ath10k_bitrate_mask_rate(ar, mask, band, fixed_rate, fixed_nss); -+ } -+ -+ static int ath10k_set_fixed_rate_param(struct ath10k_vif *arvif, -+@@ -4063,16 +4881,16 @@ static int ath10k_set_fixed_rate_param(s -+ goto exit; -+ -+ if (fixed_rate == WMI_FIXED_RATE_NONE) -+- ath10k_dbg(ATH10K_DBG_MAC, "mac disable fixed bitrate mask\n"); -++ ath10k_dbg(ar, ATH10K_DBG_MAC, "mac disable fixed bitrate mask\n"); -+ -+ if (force_sgi) -+- ath10k_dbg(ATH10K_DBG_MAC, "mac force sgi\n"); -++ ath10k_dbg(ar, ATH10K_DBG_MAC, "mac force sgi\n"); -+ -+ vdev_param = ar->wmi.vdev_param->fixed_rate; -+ ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, -+ vdev_param, fixed_rate); -+ if (ret) { -+- ath10k_warn("failed to set fixed rate param 0x%02x: %d\n", -++ ath10k_warn(ar, "failed to set fixed rate param 0x%02x: %d\n", -+ fixed_rate, ret); -+ ret = -EINVAL; -+ goto exit; -+@@ -4085,7 +4903,7 @@ static int ath10k_set_fixed_rate_param(s -+ vdev_param, fixed_nss); -+ -+ if (ret) { -+- ath10k_warn("failed to set fixed nss param %d: %d\n", -++ ath10k_warn(ar, "failed to set fixed nss param %d: %d\n", -+ fixed_nss, ret); -+ ret = -EINVAL; -+ goto exit; -+@@ -4098,7 +4916,7 @@ static int ath10k_set_fixed_rate_param(s -+ force_sgi); -+ -+ if (ret) { -+- ath10k_warn("failed to set sgi param %d: %d\n", -++ ath10k_warn(ar, "failed to set sgi param %d: %d\n", -+ force_sgi, ret); -+ ret = -EINVAL; -+ goto exit; -+@@ -4122,19 +4940,22 @@ static int ath10k_set_bitrate_mask(struc -+ u8 fixed_nss = ar->num_rf_chains; -+ u8 force_sgi; -+ -++ if (ar->cfg_tx_chainmask) -++ fixed_nss = get_nss_from_chainmask(ar->cfg_tx_chainmask); -++ -+ force_sgi = mask->control[band].gi; -+ if (force_sgi == NL80211_TXRATE_FORCE_LGI) -+ return -EINVAL; -+ -+ if (!ath10k_default_bitrate_mask(ar, band, mask)) { -+- if (!ath10k_get_fixed_rate_nss(mask, band, -++ if (!ath10k_get_fixed_rate_nss(ar, mask, band, -+ &fixed_rate, -+ &fixed_nss)) -+ return -EINVAL; -+ } -+ -+ if (fixed_rate == WMI_FIXED_RATE_NONE && force_sgi) { -+- ath10k_warn("failed to force SGI usage for default rate settings\n"); -++ ath10k_warn(ar, "failed to force SGI usage for default rate settings\n"); -+ return -EINVAL; -+ } -+ -+@@ -4153,7 +4974,7 @@ static void ath10k_sta_rc_update(struct -+ -+ spin_lock_bh(&ar->data_lock); -+ -+- ath10k_dbg(ATH10K_DBG_MAC, -++ ath10k_dbg(ar, ATH10K_DBG_MAC, -+ "mac sta rc update for %pM changed %08x bw %d nss %d smps %d\n", -+ sta->addr, changed, sta->bandwidth, sta->rx_nss, -+ sta->smps_mode); -+@@ -4172,7 +4993,7 @@ static void ath10k_sta_rc_update(struct -+ bw = WMI_PEER_CHWIDTH_80MHZ; -+ break; -+ case IEEE80211_STA_RX_BW_160: -+- ath10k_warn("Invalid bandwith %d in rc update for %pM\n", -++ ath10k_warn(ar, "Invalid bandwith %d in rc update for %pM\n", -+ sta->bandwidth, sta->addr); -+ bw = WMI_PEER_CHWIDTH_20MHZ; -+ break; -+@@ -4199,7 +5020,7 @@ static void ath10k_sta_rc_update(struct -+ smps = WMI_PEER_SMPS_DYNAMIC; -+ break; -+ case IEEE80211_SMPS_NUM_MODES: -+- ath10k_warn("Invalid smps %d in sta rc update for %pM\n", -++ ath10k_warn(ar, "Invalid smps %d in sta rc update for %pM\n", -+ sta->smps_mode, sta->addr); -+ smps = WMI_PEER_SMPS_PS_NONE; -+ break; -+@@ -4225,6 +5046,39 @@ static u64 ath10k_get_tsf(struct ieee802 -+ return 0; -+ } -+ -++static int ath10k_ampdu_action(struct ieee80211_hw *hw, -++ struct ieee80211_vif *vif, -++ enum ieee80211_ampdu_mlme_action action, -++ struct ieee80211_sta *sta, u16 tid, u16 *ssn, -++ u8 buf_size) -++{ -++ struct ath10k *ar = hw->priv; -++ struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif); -++ -++ ath10k_dbg(ar, ATH10K_DBG_MAC, "mac ampdu vdev_id %i sta %pM tid %hu action %d\n", -++ arvif->vdev_id, sta->addr, tid, action); -++ -++ switch (action) { -++ case IEEE80211_AMPDU_RX_START: -++ case IEEE80211_AMPDU_RX_STOP: -++ /* HTT AddBa/DelBa events trigger mac80211 Rx BA session -++ * creation/removal. Do we need to verify this? -++ */ -++ return 0; -++ case IEEE80211_AMPDU_TX_START: -++ case IEEE80211_AMPDU_TX_STOP_CONT: -++ case IEEE80211_AMPDU_TX_STOP_FLUSH: -++ case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT: -++ case IEEE80211_AMPDU_TX_OPERATIONAL: -++ /* Firmware offloads Tx aggregation entirely so deny mac80211 -++ * Tx aggregation requests. -++ */ -++ return -EOPNOTSUPP; -++ } -++ -++ return -EINVAL; -++} -++ -+ static const struct ieee80211_ops ath10k_ops = { -+ .tx = ath10k_tx, -+ .start = ath10k_start, -+@@ -4237,23 +5091,35 @@ static const struct ieee80211_ops ath10k -+ .hw_scan = ath10k_hw_scan, -+ .cancel_hw_scan = ath10k_cancel_hw_scan, -+ .set_key = ath10k_set_key, -++ .set_default_unicast_key = ath10k_set_default_unicast_key, -+ .sta_state = ath10k_sta_state, -+ .conf_tx = ath10k_conf_tx, -+ .remain_on_channel = ath10k_remain_on_channel, -+ .cancel_remain_on_channel = ath10k_cancel_remain_on_channel, -+ .set_rts_threshold = ath10k_set_rts_threshold, -+- .set_frag_threshold = ath10k_set_frag_threshold, -+ .flush = ath10k_flush, -+ .tx_last_beacon = ath10k_tx_last_beacon, -++ .set_antenna = ath10k_set_antenna, -++ .get_antenna = ath10k_get_antenna, -+ .restart_complete = ath10k_restart_complete, -+ .get_survey = ath10k_get_survey, -+ .set_bitrate_mask = ath10k_set_bitrate_mask, -+ .sta_rc_update = ath10k_sta_rc_update, -+ .get_tsf = ath10k_get_tsf, -++ .ampdu_action = ath10k_ampdu_action, -++ .get_et_sset_count = ath10k_debug_get_et_sset_count, -++ .get_et_stats = ath10k_debug_get_et_stats, -++ .get_et_strings = ath10k_debug_get_et_strings, -++ -++ CFG80211_TESTMODE_CMD(ath10k_tm_cmd) -++ -+ #ifdef CONFIG_PM -+ .suspend = ath10k_suspend, -+ .resume = ath10k_resume, -+ #endif -++#ifdef CPTCFG_MAC80211_DEBUGFS -++ .sta_add_debugfs = ath10k_sta_add_debugfs, -++#endif -+ }; -+ -+ #define RATETAB_ENT(_rate, _rateid, _flags) { \ -+@@ -4324,6 +5190,9 @@ static const struct ieee80211_channel at -+ CHAN5G(165, 5825, 0), -+ }; -+ -++/* Note: Be careful if you re-order these. There is code which depends on this -++ * ordering. -++ */ -+ static struct ieee80211_rate ath10k_rates[] = { -+ /* CCK */ -+ RATETAB_ENT(10, 0x82, 0), -+@@ -4346,12 +5215,12 @@ static struct ieee80211_rate ath10k_rate -+ #define ath10k_g_rates (ath10k_rates + 0) -+ #define ath10k_g_rates_size (ARRAY_SIZE(ath10k_rates)) -+ -+-struct ath10k *ath10k_mac_create(void) -++struct ath10k *ath10k_mac_create(size_t priv_size) -+ { -+ struct ieee80211_hw *hw; -+ struct ath10k *ar; -+ -+- hw = ieee80211_alloc_hw(sizeof(struct ath10k), &ath10k_ops); -++ hw = ieee80211_alloc_hw(sizeof(struct ath10k) + priv_size, &ath10k_ops); -+ if (!hw) -+ return NULL; -+ -+@@ -4377,6 +5246,10 @@ static const struct ieee80211_iface_limi -+ .types = BIT(NL80211_IFTYPE_P2P_GO) -+ }, -+ { -++ .max = 1, -++ .types = BIT(NL80211_IFTYPE_P2P_DEVICE) -++ }, -++ { -+ .max = 7, -+ .types = BIT(NL80211_IFTYPE_AP) -+ }, -+@@ -4501,7 +5374,6 @@ static struct ieee80211_sta_ht_cap ath10 -+ return ht_cap; -+ } -+ -+- -+ static void ath10k_get_arvif_iter(void *data, u8 *mac, -+ struct ieee80211_vif *vif) -+ { -+@@ -4526,7 +5398,7 @@ struct ath10k_vif *ath10k_get_arvif(stru -+ ath10k_get_arvif_iter, -+ &arvif_iter); -+ if (!arvif_iter.arvif) { -+- ath10k_warn("No VIF found for vdev %d\n", vdev_id); -++ ath10k_warn(ar, "No VIF found for vdev %d\n", vdev_id); -+ return NULL; -+ } -+ -+@@ -4564,7 +5436,8 @@ int ath10k_mac_register(struct ath10k *a -+ band->bitrates = ath10k_g_rates; -+ band->ht_cap = ht_cap; -+ -+- /* vht is not supported in 2.4 GHz */ -++ /* Enable the VHT support at 2.4 GHz */ -++ band->vht_cap = vht_cap; -+ -+ ar->hw->wiphy->bands[IEEE80211_BAND_2GHZ] = band; -+ } -+@@ -4590,18 +5463,20 @@ int ath10k_mac_register(struct ath10k *a -+ -+ ar->hw->wiphy->interface_modes = -+ BIT(NL80211_IFTYPE_STATION) | -+- BIT(NL80211_IFTYPE_ADHOC) | -+ BIT(NL80211_IFTYPE_AP); -+ -++ ar->hw->wiphy->available_antennas_rx = ar->supp_rx_chainmask; -++ ar->hw->wiphy->available_antennas_tx = ar->supp_tx_chainmask; -++ -+ if (!test_bit(ATH10K_FW_FEATURE_NO_P2P, ar->fw_features)) -+ ar->hw->wiphy->interface_modes |= -++ BIT(NL80211_IFTYPE_P2P_DEVICE) | -+ BIT(NL80211_IFTYPE_P2P_CLIENT) | -+ BIT(NL80211_IFTYPE_P2P_GO); -+ -+ ar->hw->flags = IEEE80211_HW_SIGNAL_DBM | -+ IEEE80211_HW_SUPPORTS_PS | -+ IEEE80211_HW_SUPPORTS_DYNAMIC_PS | -+- IEEE80211_HW_SUPPORTS_UAPSD | -+ IEEE80211_HW_MFP_CAPABLE | -+ IEEE80211_HW_REPORTS_TX_ACK_STATUS | -+ IEEE80211_HW_HAS_RATE_CONTROL | -+@@ -4609,10 +5484,6 @@ int ath10k_mac_register(struct ath10k *a -+ IEEE80211_HW_AP_LINK_PS | -+ IEEE80211_HW_SPECTRUM_MGMT; -+ -+- /* MSDU can have HTT TX fragment pushed in front. The additional 4 -+- * bytes is used for padding/alignment if necessary. */ -+- ar->hw->extra_tx_headroom += sizeof(struct htt_data_tx_desc_frag)*2 + 4; -+- -+ if (ar->ht_cap_info & WMI_HT_CAP_DYNAMIC_SMPS) -+ ar->hw->flags |= IEEE80211_HW_SUPPORTS_DYNAMIC_SMPS; -+ -+@@ -4629,25 +5500,52 @@ int ath10k_mac_register(struct ath10k *a -+ -+ ar->hw->max_listen_interval = ATH10K_MAX_HW_LISTEN_INTERVAL; -+ -++ if (test_bit(WMI_SERVICE_BEACON_OFFLOAD, ar->wmi.svc_map)) { -++ ar->hw->wiphy->flags |= WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD; -++ -++ /* Firmware delivers WPS/P2P Probe Requests frames to driver so -++ * that userspace (e.g. wpa_supplicant/hostapd) can generate -++ * correct Probe Responses. This is more of a hack advert.. -++ */ -++ ar->hw->wiphy->probe_resp_offload |= -++ NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS | -++ NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS2 | -++ NL80211_PROBE_RESP_OFFLOAD_SUPPORT_P2P; -++ } -++ -+ ar->hw->wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL; -+ ar->hw->wiphy->flags |= WIPHY_FLAG_HAS_CHANNEL_SWITCH; -+ ar->hw->wiphy->max_remain_on_channel_duration = 5000; -+ -+ ar->hw->wiphy->flags |= WIPHY_FLAG_AP_UAPSD; -++ ar->hw->wiphy->features |= NL80211_FEATURE_AP_MODE_CHAN_WIDTH_CHANGE; -++ -+ /* -+ * on LL hardware queues are managed entirely by the FW -+ * so we only advertise to mac we can do the queues thing -+ */ -+ ar->hw->queues = 4; -+ -+- if (test_bit(ATH10K_FW_FEATURE_WMI_10X, ar->fw_features)) { -+- ar->hw->wiphy->iface_combinations = ath10k_10x_if_comb; -+- ar->hw->wiphy->n_iface_combinations = -+- ARRAY_SIZE(ath10k_10x_if_comb); -+- } else { -++ switch (ar->wmi.op_version) { -++ case ATH10K_FW_WMI_OP_VERSION_MAIN: -++ case ATH10K_FW_WMI_OP_VERSION_TLV: -+ ar->hw->wiphy->iface_combinations = ath10k_if_comb; -+ ar->hw->wiphy->n_iface_combinations = -+ ARRAY_SIZE(ath10k_if_comb); -++ ar->hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_ADHOC); -++ break; -++ case ATH10K_FW_WMI_OP_VERSION_10_1: -++ case ATH10K_FW_WMI_OP_VERSION_10_2: -++ case ATH10K_FW_WMI_OP_VERSION_10_2_4: -++ ar->hw->wiphy->iface_combinations = ath10k_10x_if_comb; -++ ar->hw->wiphy->n_iface_combinations = -++ ARRAY_SIZE(ath10k_10x_if_comb); -++ break; -++ case ATH10K_FW_WMI_OP_VERSION_UNSET: -++ case ATH10K_FW_WMI_OP_VERSION_MAX: -++ WARN_ON(1); -++ ret = -EINVAL; -++ goto err_free; -+ } -+ -+ ar->hw->netdev_features = NETIF_F_HW_CSUM; -+@@ -4659,19 +5557,19 @@ int ath10k_mac_register(struct ath10k *a -+ NL80211_DFS_UNSET); -+ -+ if (!ar->dfs_detector) -+- ath10k_warn("failed to initialise DFS pattern detector\n"); -++ ath10k_warn(ar, "failed to initialise DFS pattern detector\n"); -+ } -+ -+ ret = ath_regd_init(&ar->ath_common.regulatory, ar->hw->wiphy, -+ ath10k_reg_notifier); -+ if (ret) { -+- ath10k_err("failed to initialise regulatory: %i\n", ret); -++ ath10k_err(ar, "failed to initialise regulatory: %i\n", ret); -+ goto err_free; -+ } -+ -+ ret = ieee80211_register_hw(ar->hw); -+ if (ret) { -+- ath10k_err("failed to register ieee80211: %d\n", ret); -++ ath10k_err(ar, "failed to register ieee80211: %d\n", ret); -+ goto err_free; -+ } -+ -+--- a/drivers/net/wireless/ath/ath10k/mac.h -++++ b/drivers/net/wireless/ath/ath10k/mac.h -+@@ -21,33 +21,41 @@ -+ #include -+ #include "core.h" -+ -++#define WEP_KEYID_SHIFT 6 -++ -+ struct ath10k_generic_iter { -+ struct ath10k *ar; -+ int ret; -+ }; -+ -+-struct ath10k *ath10k_mac_create(void); -++struct ath10k *ath10k_mac_create(size_t priv_size); -+ void ath10k_mac_destroy(struct ath10k *ar); -+ int ath10k_mac_register(struct ath10k *ar); -+ void ath10k_mac_unregister(struct ath10k *ar); -+ struct ath10k_vif *ath10k_get_arvif(struct ath10k *ar, u32 vdev_id); -+-void ath10k_reset_scan(unsigned long ptr); -++void __ath10k_scan_finish(struct ath10k *ar); -++void ath10k_scan_finish(struct ath10k *ar); -++void ath10k_scan_timeout_work(struct work_struct *work); -+ void ath10k_offchan_tx_purge(struct ath10k *ar); -+ void ath10k_offchan_tx_work(struct work_struct *work); -+ void ath10k_mgmt_over_wmi_tx_purge(struct ath10k *ar); -+ void ath10k_mgmt_over_wmi_tx_work(struct work_struct *work); -+ void ath10k_halt(struct ath10k *ar); -++void ath10k_mac_vif_beacon_free(struct ath10k_vif *arvif); -++void ath10k_drain_tx(struct ath10k *ar); -++bool ath10k_mac_is_peer_wep_key_set(struct ath10k *ar, const u8 *addr, -++ u8 keyidx); -+ -+ static inline struct ath10k_vif *ath10k_vif_to_arvif(struct ieee80211_vif *vif) -+ { -+ return (struct ath10k_vif *)vif->drv_priv; -+ } -+ -+-static inline void ath10k_tx_h_seq_no(struct sk_buff *skb) -++static inline void ath10k_tx_h_seq_no(struct ieee80211_vif *vif, -++ struct sk_buff *skb) -+ { -+ struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); -+ struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; -+- struct ieee80211_vif *vif = info->control.vif; -+ struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif); -+ -+ if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) { -+--- a/drivers/net/wireless/ath/ath10k/pci.c -++++ b/drivers/net/wireless/ath/ath10k/pci.c -+@@ -44,13 +44,9 @@ enum ath10k_pci_reset_mode { -+ ATH10K_PCI_RESET_WARM_ONLY = 1, -+ }; -+ -+-static unsigned int ath10k_pci_target_ps; -+ static unsigned int ath10k_pci_irq_mode = ATH10K_PCI_IRQ_AUTO; -+ static unsigned int ath10k_pci_reset_mode = ATH10K_PCI_RESET_AUTO; -+ -+-module_param_named(target_ps, ath10k_pci_target_ps, uint, 0644); -+-MODULE_PARM_DESC(target_ps, "Enable ath10k Target (SoC) PS option"); -+- -+ module_param_named(irq_mode, ath10k_pci_irq_mode, uint, 0644); -+ MODULE_PARM_DESC(irq_mode, "0: auto, 1: legacy, 2: msi (default: 0)"); -+ -+@@ -59,21 +55,31 @@ MODULE_PARM_DESC(reset_mode, "0: auto, 1 -+ -+ /* how long wait to wait for target to initialise, in ms */ -+ #define ATH10K_PCI_TARGET_WAIT 3000 -++#define ATH10K_PCI_NUM_WARM_RESET_ATTEMPTS 3 -+ -+ #define QCA988X_2_0_DEVICE_ID (0x003c) -++#define QCA6174_2_1_DEVICE_ID (0x003e) -+ -+-static DEFINE_PCI_DEVICE_TABLE(ath10k_pci_id_table) = { -++static const struct pci_device_id ath10k_pci_id_table[] = { -+ { PCI_VDEVICE(ATHEROS, QCA988X_2_0_DEVICE_ID) }, /* PCI-E QCA988X V2 */ -++ { PCI_VDEVICE(ATHEROS, QCA6174_2_1_DEVICE_ID) }, /* PCI-E QCA6174 V2.1 */ -+ {0} -+ }; -+ -+-static int ath10k_pci_diag_read_access(struct ath10k *ar, u32 address, -+- u32 *data); -++static const struct ath10k_pci_supp_chip ath10k_pci_supp_chips[] = { -++ /* QCA988X pre 2.0 chips are not supported because they need some nasty -++ * hacks. ath10k doesn't have them and these devices crash horribly -++ * because of that. -++ */ -++ { QCA988X_2_0_DEVICE_ID, QCA988X_HW_2_0_CHIP_ID_REV }, -++ { QCA6174_2_1_DEVICE_ID, QCA6174_HW_2_1_CHIP_ID_REV }, -++ { QCA6174_2_1_DEVICE_ID, QCA6174_HW_2_2_CHIP_ID_REV }, -++ { QCA6174_2_1_DEVICE_ID, QCA6174_HW_3_0_CHIP_ID_REV }, -++ { QCA6174_2_1_DEVICE_ID, QCA6174_HW_3_1_CHIP_ID_REV }, -++ { QCA6174_2_1_DEVICE_ID, QCA6174_HW_3_2_CHIP_ID_REV }, -++}; -+ -+-static int ath10k_pci_post_rx(struct ath10k *ar); -+-static int ath10k_pci_post_rx_pipe(struct ath10k_pci_pipe *pipe_info, -+- int num); -+-static void ath10k_pci_rx_pipe_cleanup(struct ath10k_pci_pipe *pipe_info); -++static void ath10k_pci_buffer_cleanup(struct ath10k *ar); -+ static int ath10k_pci_cold_reset(struct ath10k *ar); -+ static int ath10k_pci_warm_reset(struct ath10k *ar); -+ static int ath10k_pci_wait_for_target_init(struct ath10k *ar); -+@@ -98,7 +104,7 @@ static const struct ce_attr host_ce_conf -+ { -+ .flags = CE_ATTR_FLAGS, -+ .src_nentries = 0, -+- .src_sz_max = 512, -++ .src_sz_max = 2048, -+ .dest_nentries = 512, -+ }, -+ -+@@ -155,79 +161,175 @@ static const struct ce_attr host_ce_conf -+ static const struct ce_pipe_config target_ce_config_wlan[] = { -+ /* CE0: host->target HTC control and raw streams */ -+ { -+- .pipenum = 0, -+- .pipedir = PIPEDIR_OUT, -+- .nentries = 32, -+- .nbytes_max = 256, -+- .flags = CE_ATTR_FLAGS, -+- .reserved = 0, -++ .pipenum = __cpu_to_le32(0), -++ .pipedir = __cpu_to_le32(PIPEDIR_OUT), -++ .nentries = __cpu_to_le32(32), -++ .nbytes_max = __cpu_to_le32(256), -++ .flags = __cpu_to_le32(CE_ATTR_FLAGS), -++ .reserved = __cpu_to_le32(0), -+ }, -+ -+ /* CE1: target->host HTT + HTC control */ -+ { -+- .pipenum = 1, -+- .pipedir = PIPEDIR_IN, -+- .nentries = 32, -+- .nbytes_max = 512, -+- .flags = CE_ATTR_FLAGS, -+- .reserved = 0, -++ .pipenum = __cpu_to_le32(1), -++ .pipedir = __cpu_to_le32(PIPEDIR_IN), -++ .nentries = __cpu_to_le32(32), -++ .nbytes_max = __cpu_to_le32(2048), -++ .flags = __cpu_to_le32(CE_ATTR_FLAGS), -++ .reserved = __cpu_to_le32(0), -+ }, -+ -+ /* CE2: target->host WMI */ -+ { -+- .pipenum = 2, -+- .pipedir = PIPEDIR_IN, -+- .nentries = 32, -+- .nbytes_max = 2048, -+- .flags = CE_ATTR_FLAGS, -+- .reserved = 0, -++ .pipenum = __cpu_to_le32(2), -++ .pipedir = __cpu_to_le32(PIPEDIR_IN), -++ .nentries = __cpu_to_le32(32), -++ .nbytes_max = __cpu_to_le32(2048), -++ .flags = __cpu_to_le32(CE_ATTR_FLAGS), -++ .reserved = __cpu_to_le32(0), -+ }, -+ -+ /* CE3: host->target WMI */ -+ { -+- .pipenum = 3, -+- .pipedir = PIPEDIR_OUT, -+- .nentries = 32, -+- .nbytes_max = 2048, -+- .flags = CE_ATTR_FLAGS, -+- .reserved = 0, -++ .pipenum = __cpu_to_le32(3), -++ .pipedir = __cpu_to_le32(PIPEDIR_OUT), -++ .nentries = __cpu_to_le32(32), -++ .nbytes_max = __cpu_to_le32(2048), -++ .flags = __cpu_to_le32(CE_ATTR_FLAGS), -++ .reserved = __cpu_to_le32(0), -+ }, -+ -+ /* CE4: host->target HTT */ -+ { -+- .pipenum = 4, -+- .pipedir = PIPEDIR_OUT, -+- .nentries = 256, -+- .nbytes_max = 256, -+- .flags = CE_ATTR_FLAGS, -+- .reserved = 0, -++ .pipenum = __cpu_to_le32(4), -++ .pipedir = __cpu_to_le32(PIPEDIR_OUT), -++ .nentries = __cpu_to_le32(256), -++ .nbytes_max = __cpu_to_le32(256), -++ .flags = __cpu_to_le32(CE_ATTR_FLAGS), -++ .reserved = __cpu_to_le32(0), -+ }, -+ -+ /* NB: 50% of src nentries, since tx has 2 frags */ -+ -+ /* CE5: unused */ -+ { -+- .pipenum = 5, -+- .pipedir = PIPEDIR_OUT, -+- .nentries = 32, -+- .nbytes_max = 2048, -+- .flags = CE_ATTR_FLAGS, -+- .reserved = 0, -++ .pipenum = __cpu_to_le32(5), -++ .pipedir = __cpu_to_le32(PIPEDIR_OUT), -++ .nentries = __cpu_to_le32(32), -++ .nbytes_max = __cpu_to_le32(2048), -++ .flags = __cpu_to_le32(CE_ATTR_FLAGS), -++ .reserved = __cpu_to_le32(0), -+ }, -+ -+ /* CE6: Reserved for target autonomous hif_memcpy */ -+ { -+- .pipenum = 6, -+- .pipedir = PIPEDIR_INOUT, -+- .nentries = 32, -+- .nbytes_max = 4096, -+- .flags = CE_ATTR_FLAGS, -+- .reserved = 0, -++ .pipenum = __cpu_to_le32(6), -++ .pipedir = __cpu_to_le32(PIPEDIR_INOUT), -++ .nentries = __cpu_to_le32(32), -++ .nbytes_max = __cpu_to_le32(4096), -++ .flags = __cpu_to_le32(CE_ATTR_FLAGS), -++ .reserved = __cpu_to_le32(0), -+ }, -+ -+ /* CE7 used only by Host */ -+ }; -+ -++/* -++ * Map from service/endpoint to Copy Engine. -++ * This table is derived from the CE_PCI TABLE, above. -++ * It is passed to the Target at startup for use by firmware. -++ */ -++static const struct service_to_pipe target_service_to_ce_map_wlan[] = { -++ { -++ __cpu_to_le32(ATH10K_HTC_SVC_ID_WMI_DATA_VO), -++ __cpu_to_le32(PIPEDIR_OUT), /* out = UL = host -> target */ -++ __cpu_to_le32(3), -++ }, -++ { -++ __cpu_to_le32(ATH10K_HTC_SVC_ID_WMI_DATA_VO), -++ __cpu_to_le32(PIPEDIR_IN), /* in = DL = target -> host */ -++ __cpu_to_le32(2), -++ }, -++ { -++ __cpu_to_le32(ATH10K_HTC_SVC_ID_WMI_DATA_BK), -++ __cpu_to_le32(PIPEDIR_OUT), /* out = UL = host -> target */ -++ __cpu_to_le32(3), -++ }, -++ { -++ __cpu_to_le32(ATH10K_HTC_SVC_ID_WMI_DATA_BK), -++ __cpu_to_le32(PIPEDIR_IN), /* in = DL = target -> host */ -++ __cpu_to_le32(2), -++ }, -++ { -++ __cpu_to_le32(ATH10K_HTC_SVC_ID_WMI_DATA_BE), -++ __cpu_to_le32(PIPEDIR_OUT), /* out = UL = host -> target */ -++ __cpu_to_le32(3), -++ }, -++ { -++ __cpu_to_le32(ATH10K_HTC_SVC_ID_WMI_DATA_BE), -++ __cpu_to_le32(PIPEDIR_IN), /* in = DL = target -> host */ -++ __cpu_to_le32(2), -++ }, -++ { -++ __cpu_to_le32(ATH10K_HTC_SVC_ID_WMI_DATA_VI), -++ __cpu_to_le32(PIPEDIR_OUT), /* out = UL = host -> target */ -++ __cpu_to_le32(3), -++ }, -++ { -++ __cpu_to_le32(ATH10K_HTC_SVC_ID_WMI_DATA_VI), -++ __cpu_to_le32(PIPEDIR_IN), /* in = DL = target -> host */ -++ __cpu_to_le32(2), -++ }, -++ { -++ __cpu_to_le32(ATH10K_HTC_SVC_ID_WMI_CONTROL), -++ __cpu_to_le32(PIPEDIR_OUT), /* out = UL = host -> target */ -++ __cpu_to_le32(3), -++ }, -++ { -++ __cpu_to_le32(ATH10K_HTC_SVC_ID_WMI_CONTROL), -++ __cpu_to_le32(PIPEDIR_IN), /* in = DL = target -> host */ -++ __cpu_to_le32(2), -++ }, -++ { -++ __cpu_to_le32(ATH10K_HTC_SVC_ID_RSVD_CTRL), -++ __cpu_to_le32(PIPEDIR_OUT), /* out = UL = host -> target */ -++ __cpu_to_le32(0), -++ }, -++ { -++ __cpu_to_le32(ATH10K_HTC_SVC_ID_RSVD_CTRL), -++ __cpu_to_le32(PIPEDIR_IN), /* in = DL = target -> host */ -++ __cpu_to_le32(1), -++ }, -++ { /* not used */ -++ __cpu_to_le32(ATH10K_HTC_SVC_ID_TEST_RAW_STREAMS), -++ __cpu_to_le32(PIPEDIR_OUT), /* out = UL = host -> target */ -++ __cpu_to_le32(0), -++ }, -++ { /* not used */ -++ __cpu_to_le32(ATH10K_HTC_SVC_ID_TEST_RAW_STREAMS), -++ __cpu_to_le32(PIPEDIR_IN), /* in = DL = target -> host */ -++ __cpu_to_le32(1), -++ }, -++ { -++ __cpu_to_le32(ATH10K_HTC_SVC_ID_HTT_DATA_MSG), -++ __cpu_to_le32(PIPEDIR_OUT), /* out = UL = host -> target */ -++ __cpu_to_le32(4), -++ }, -++ { -++ __cpu_to_le32(ATH10K_HTC_SVC_ID_HTT_DATA_MSG), -++ __cpu_to_le32(PIPEDIR_IN), /* in = DL = target -> host */ -++ __cpu_to_le32(1), -++ }, -++ -++ /* (Additions here) */ -++ -++ { /* must be last */ -++ __cpu_to_le32(0), -++ __cpu_to_le32(0), -++ __cpu_to_le32(0), -++ }, -++}; -++ -+ static bool ath10k_pci_irq_pending(struct ath10k *ar) -+ { -+ u32 cause; -+@@ -253,8 +355,8 @@ static void ath10k_pci_disable_and_clear -+ -+ /* IMPORTANT: this extra read transaction is required to -+ * flush the posted write buffer. */ -+- (void) ath10k_pci_read32(ar, SOC_CORE_BASE_ADDRESS + -+- PCIE_INTR_ENABLE_ADDRESS); -++ (void)ath10k_pci_read32(ar, SOC_CORE_BASE_ADDRESS + -++ PCIE_INTR_ENABLE_ADDRESS); -+ } -+ -+ static void ath10k_pci_enable_legacy_irq(struct ath10k *ar) -+@@ -265,48 +367,116 @@ static void ath10k_pci_enable_legacy_irq -+ -+ /* IMPORTANT: this extra read transaction is required to -+ * flush the posted write buffer. */ -+- (void) ath10k_pci_read32(ar, SOC_CORE_BASE_ADDRESS + -+- PCIE_INTR_ENABLE_ADDRESS); -++ (void)ath10k_pci_read32(ar, SOC_CORE_BASE_ADDRESS + -++ PCIE_INTR_ENABLE_ADDRESS); -+ } -+ -+-static irqreturn_t ath10k_pci_early_irq_handler(int irq, void *arg) -++static inline const char *ath10k_pci_get_irq_method(struct ath10k *ar) -+ { -+- struct ath10k *ar = arg; -+ struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); -+ -+- if (ar_pci->num_msi_intrs == 0) { -+- if (!ath10k_pci_irq_pending(ar)) -+- return IRQ_NONE; -+- -+- ath10k_pci_disable_and_clear_legacy_irq(ar); -+- } -++ if (ar_pci->num_msi_intrs > 1) -++ return "msi-x"; -+ -+- tasklet_schedule(&ar_pci->early_irq_tasklet); -++ if (ar_pci->num_msi_intrs == 1) -++ return "msi"; -+ -+- return IRQ_HANDLED; -++ return "legacy"; -+ } -+ -+-static int ath10k_pci_request_early_irq(struct ath10k *ar) -++static int __ath10k_pci_rx_post_buf(struct ath10k_pci_pipe *pipe) -+ { -++ struct ath10k *ar = pipe->hif_ce_state; -+ struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); -++ struct ath10k_ce_pipe *ce_pipe = pipe->ce_hdl; -++ struct sk_buff *skb; -++ dma_addr_t paddr; -+ int ret; -+ -+- /* Regardless whether MSI-X/MSI/legacy irqs have been set up the first -+- * interrupt from irq vector is triggered in all cases for FW -+- * indication/errors */ -+- ret = request_irq(ar_pci->pdev->irq, ath10k_pci_early_irq_handler, -+- IRQF_SHARED, "ath10k_pci (early)", ar); -++ lockdep_assert_held(&ar_pci->ce_lock); -++ -++ skb = dev_alloc_skb(pipe->buf_sz); -++ if (!skb) -++ return -ENOMEM; -++ -++ WARN_ONCE((unsigned long)skb->data & 3, "unaligned skb"); -++ -++ paddr = dma_map_single(ar->dev, skb->data, -++ skb->len + skb_tailroom(skb), -++ DMA_FROM_DEVICE); -++ if (unlikely(dma_mapping_error(ar->dev, paddr))) { -++ ath10k_warn(ar, "failed to dma map pci rx buf\n"); -++ dev_kfree_skb_any(skb); -++ return -EIO; -++ } -++ -++ ATH10K_SKB_RXCB(skb)->paddr = paddr; -++ -++ ret = __ath10k_ce_rx_post_buf(ce_pipe, skb, paddr); -+ if (ret) { -+- ath10k_warn("failed to request early irq: %d\n", ret); -++ ath10k_warn(ar, "failed to post pci rx buf: %d\n", ret); -++ dma_unmap_single(ar->dev, paddr, skb->len + skb_tailroom(skb), -++ DMA_FROM_DEVICE); -++ dev_kfree_skb_any(skb); -+ return ret; -+ } -+ -+ return 0; -+ } -+ -+-static void ath10k_pci_free_early_irq(struct ath10k *ar) -++static void __ath10k_pci_rx_post_pipe(struct ath10k_pci_pipe *pipe) -++{ -++ struct ath10k *ar = pipe->hif_ce_state; -++ struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); -++ struct ath10k_ce_pipe *ce_pipe = pipe->ce_hdl; -++ int ret, num; -++ -++ lockdep_assert_held(&ar_pci->ce_lock); -++ -++ if (pipe->buf_sz == 0) -++ return; -++ -++ if (!ce_pipe->dest_ring) -++ return; -++ -++ num = __ath10k_ce_rx_num_free_bufs(ce_pipe); -++ while (num--) { -++ ret = __ath10k_pci_rx_post_buf(pipe); -++ if (ret) { -++ ath10k_warn(ar, "failed to post pci rx buf: %d\n", ret); -++ mod_timer(&ar_pci->rx_post_retry, jiffies + -++ ATH10K_PCI_RX_POST_RETRY_MS); -++ break; -++ } -++ } -++} -++ -++static void ath10k_pci_rx_post_pipe(struct ath10k_pci_pipe *pipe) -++{ -++ struct ath10k *ar = pipe->hif_ce_state; -++ struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); -++ -++ spin_lock_bh(&ar_pci->ce_lock); -++ __ath10k_pci_rx_post_pipe(pipe); -++ spin_unlock_bh(&ar_pci->ce_lock); -++} -++ -++static void ath10k_pci_rx_post(struct ath10k *ar) -++{ -++ struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); -++ int i; -++ -++ spin_lock_bh(&ar_pci->ce_lock); -++ for (i = 0; i < CE_COUNT; i++) -++ __ath10k_pci_rx_post_pipe(&ar_pci->pipe_info[i]); -++ spin_unlock_bh(&ar_pci->ce_lock); -++} -++ -++static void ath10k_pci_rx_replenish_retry(unsigned long ptr) -+ { -+- free_irq(ath10k_pci_priv(ar)->pdev->irq, ar); -++ struct ath10k *ar = (void *)ptr; -++ -++ ath10k_pci_rx_post(ar); -+ } -+ -+ /* -+@@ -330,24 +500,7 @@ static int ath10k_pci_diag_read_mem(stru -+ void *data_buf = NULL; -+ int i; -+ -+- /* -+- * This code cannot handle reads to non-memory space. Redirect to the -+- * register read fn but preserve the multi word read capability of -+- * this fn -+- */ -+- if (address < DRAM_BASE_ADDRESS) { -+- if (!IS_ALIGNED(address, 4) || -+- !IS_ALIGNED((unsigned long)data, 4)) -+- return -EIO; -+- -+- while ((nbytes >= 4) && ((ret = ath10k_pci_diag_read_access( -+- ar, address, (u32 *)data)) == 0)) { -+- nbytes -= sizeof(u32); -+- address += sizeof(u32); -+- data += sizeof(u32); -+- } -+- return ret; -+- } -++ spin_lock_bh(&ar_pci->ce_lock); -+ -+ ce_diag = ar_pci->ce_diag; -+ -+@@ -375,7 +528,7 @@ static int ath10k_pci_diag_read_mem(stru -+ nbytes = min_t(unsigned int, remaining_bytes, -+ DIAG_TRANSFER_LIMIT); -+ -+- ret = ath10k_ce_recv_buf_enqueue(ce_diag, NULL, ce_data); -++ ret = __ath10k_ce_rx_post_buf(ce_diag, NULL, ce_data); -+ if (ret != 0) -+ goto done; -+ -+@@ -388,20 +541,18 @@ static int ath10k_pci_diag_read_mem(stru -+ * convert it from Target CPU virtual address space -+ * to CE address space -+ */ -+- ath10k_pci_wake(ar); -+ address = TARG_CPU_SPACE_TO_CE_SPACE(ar, ar_pci->mem, -+ address); -+- ath10k_pci_sleep(ar); -+ -+- ret = ath10k_ce_send(ce_diag, NULL, (u32)address, nbytes, 0, -+- 0); -++ ret = ath10k_ce_send_nolock(ce_diag, NULL, (u32)address, nbytes, 0, -++ 0); -+ if (ret) -+ goto done; -+ -+ i = 0; -+- while (ath10k_ce_completed_send_next(ce_diag, NULL, &buf, -+- &completed_nbytes, -+- &id) != 0) { -++ while (ath10k_ce_completed_send_next_nolock(ce_diag, NULL, &buf, -++ &completed_nbytes, -++ &id) != 0) { -+ mdelay(1); -+ if (i++ > DIAG_ACCESS_CE_TIMEOUT_MS) { -+ ret = -EBUSY; -+@@ -414,15 +565,15 @@ static int ath10k_pci_diag_read_mem(stru -+ goto done; -+ } -+ -+- if (buf != (u32) address) { -++ if (buf != (u32)address) { -+ ret = -EIO; -+ goto done; -+ } -+ -+ i = 0; -+- while (ath10k_ce_completed_recv_next(ce_diag, NULL, &buf, -+- &completed_nbytes, -+- &id, &flags) != 0) { -++ while (ath10k_ce_completed_recv_next_nolock(ce_diag, NULL, &buf, -++ &completed_nbytes, -++ &id, &flags) != 0) { -+ mdelay(1); -+ -+ if (i++ > DIAG_ACCESS_CE_TIMEOUT_MS) { -+@@ -447,38 +598,60 @@ static int ath10k_pci_diag_read_mem(stru -+ } -+ -+ done: -+- if (ret == 0) { -+- /* Copy data from allocated DMA buf to caller's buf */ -+- WARN_ON_ONCE(orig_nbytes & 3); -+- for (i = 0; i < orig_nbytes / sizeof(__le32); i++) { -+- ((u32 *)data)[i] = -+- __le32_to_cpu(((__le32 *)data_buf)[i]); -+- } -+- } else -+- ath10k_warn("failed to read diag value at 0x%x: %d\n", -++ if (ret == 0) -++ memcpy(data, data_buf, orig_nbytes); -++ else -++ ath10k_warn(ar, "failed to read diag value at 0x%x: %d\n", -+ address, ret); -+ -+ if (data_buf) -+ dma_free_coherent(ar->dev, orig_nbytes, data_buf, -+ ce_data_base); -+ -++ spin_unlock_bh(&ar_pci->ce_lock); -++ -+ return ret; -+ } -+ -+-/* Read 4-byte aligned data from Target memory or register */ -+-static int ath10k_pci_diag_read_access(struct ath10k *ar, u32 address, -+- u32 *data) -+-{ -+- /* Assume range doesn't cross this boundary */ -+- if (address >= DRAM_BASE_ADDRESS) -+- return ath10k_pci_diag_read_mem(ar, address, data, sizeof(u32)); -++static int ath10k_pci_diag_read32(struct ath10k *ar, u32 address, u32 *value) -++{ -++ __le32 val = 0; -++ int ret; -++ -++ ret = ath10k_pci_diag_read_mem(ar, address, &val, sizeof(val)); -++ *value = __le32_to_cpu(val); -++ -++ return ret; -++} -++ -++static int __ath10k_pci_diag_read_hi(struct ath10k *ar, void *dest, -++ u32 src, u32 len) -++{ -++ u32 host_addr, addr; -++ int ret; -++ -++ host_addr = host_interest_item_address(src); -++ -++ ret = ath10k_pci_diag_read32(ar, host_addr, &addr); -++ if (ret != 0) { -++ ath10k_warn(ar, "failed to get memcpy hi address for firmware address %d: %d\n", -++ src, ret); -++ return ret; -++ } -++ -++ ret = ath10k_pci_diag_read_mem(ar, addr, dest, len); -++ if (ret != 0) { -++ ath10k_warn(ar, "failed to memcpy firmware memory from %d (%d B): %d\n", -++ addr, len, ret); -++ return ret; -++ } -+ -+- ath10k_pci_wake(ar); -+- *data = ath10k_pci_read32(ar, address); -+- ath10k_pci_sleep(ar); -+ return 0; -+ } -+ -++#define ath10k_pci_diag_read_hi(ar, dest, src, len) \ -++ __ath10k_pci_diag_read_hi(ar, dest, HI_ITEM(src), len) -++ -+ static int ath10k_pci_diag_write_mem(struct ath10k *ar, u32 address, -+ const void *data, int nbytes) -+ { -+@@ -494,6 +667,8 @@ static int ath10k_pci_diag_write_mem(str -+ dma_addr_t ce_data_base = 0; -+ int i; -+ -++ spin_lock_bh(&ar_pci->ce_lock); -++ -+ ce_diag = ar_pci->ce_diag; -+ -+ /* -+@@ -513,9 +688,7 @@ static int ath10k_pci_diag_write_mem(str -+ } -+ -+ /* Copy caller's data to allocated DMA buf */ -+- WARN_ON_ONCE(orig_nbytes & 3); -+- for (i = 0; i < orig_nbytes / sizeof(__le32); i++) -+- ((__le32 *)data_buf)[i] = __cpu_to_le32(((u32 *)data)[i]); -++ memcpy(data_buf, data, orig_nbytes); -+ -+ /* -+ * The address supplied by the caller is in the -+@@ -527,9 +700,7 @@ static int ath10k_pci_diag_write_mem(str -+ * to -+ * CE address space -+ */ -+- ath10k_pci_wake(ar); -+ address = TARG_CPU_SPACE_TO_CE_SPACE(ar, ar_pci->mem, address); -+- ath10k_pci_sleep(ar); -+ -+ remaining_bytes = orig_nbytes; -+ ce_data = ce_data_base; -+@@ -538,7 +709,7 @@ static int ath10k_pci_diag_write_mem(str -+ nbytes = min_t(int, remaining_bytes, DIAG_TRANSFER_LIMIT); -+ -+ /* Set up to receive directly into Target(!) address */ -+- ret = ath10k_ce_recv_buf_enqueue(ce_diag, NULL, address); -++ ret = __ath10k_ce_rx_post_buf(ce_diag, NULL, address); -+ if (ret != 0) -+ goto done; -+ -+@@ -546,15 +717,15 @@ static int ath10k_pci_diag_write_mem(str -+ * Request CE to send caller-supplied data that -+ * was copied to bounce buffer to Target(!) address. -+ */ -+- ret = ath10k_ce_send(ce_diag, NULL, (u32) ce_data, -+- nbytes, 0, 0); -++ ret = ath10k_ce_send_nolock(ce_diag, NULL, (u32)ce_data, -++ nbytes, 0, 0); -+ if (ret != 0) -+ goto done; -+ -+ i = 0; -+- while (ath10k_ce_completed_send_next(ce_diag, NULL, &buf, -+- &completed_nbytes, -+- &id) != 0) { -++ while (ath10k_ce_completed_send_next_nolock(ce_diag, NULL, &buf, -++ &completed_nbytes, -++ &id) != 0) { -+ mdelay(1); -+ -+ if (i++ > DIAG_ACCESS_CE_TIMEOUT_MS) { -+@@ -574,9 +745,9 @@ static int ath10k_pci_diag_write_mem(str -+ } -+ -+ i = 0; -+- while (ath10k_ce_completed_recv_next(ce_diag, NULL, &buf, -+- &completed_nbytes, -+- &id, &flags) != 0) { -++ while (ath10k_ce_completed_recv_next_nolock(ce_diag, NULL, &buf, -++ &completed_nbytes, -++ &id, &flags) != 0) { -+ mdelay(1); -+ -+ if (i++ > DIAG_ACCESS_CE_TIMEOUT_MS) { -+@@ -607,66 +778,36 @@ done: -+ } -+ -+ if (ret != 0) -+- ath10k_warn("failed to write diag value at 0x%x: %d\n", -++ ath10k_warn(ar, "failed to write diag value at 0x%x: %d\n", -+ address, ret); -+ -++ spin_unlock_bh(&ar_pci->ce_lock); -++ -+ return ret; -+ } -+ -+-/* Write 4B data to Target memory or register */ -+-static int ath10k_pci_diag_write_access(struct ath10k *ar, u32 address, -+- u32 data) -+-{ -+- /* Assume range doesn't cross this boundary */ -+- if (address >= DRAM_BASE_ADDRESS) -+- return ath10k_pci_diag_write_mem(ar, address, &data, -+- sizeof(u32)); -++static int ath10k_pci_diag_write32(struct ath10k *ar, u32 address, u32 value) -++{ -++ __le32 val = __cpu_to_le32(value); -+ -+- ath10k_pci_wake(ar); -+- ath10k_pci_write32(ar, address, data); -+- ath10k_pci_sleep(ar); -+- return 0; -++ return ath10k_pci_diag_write_mem(ar, address, &val, sizeof(val)); -+ } -+ -+-static bool ath10k_pci_target_is_awake(struct ath10k *ar) -++static bool ath10k_pci_is_awake(struct ath10k *ar) -+ { -+- void __iomem *mem = ath10k_pci_priv(ar)->mem; -+- u32 val; -+- val = ioread32(mem + PCIE_LOCAL_BASE_ADDRESS + -+- RTC_STATE_ADDRESS); -+- return (RTC_STATE_V_GET(val) == RTC_STATE_V_ON); -++ u32 val = ath10k_pci_reg_read32(ar, RTC_STATE_ADDRESS); -++ -++ return RTC_STATE_V_GET(val) == RTC_STATE_V_ON; -+ } -+ -+-int ath10k_do_pci_wake(struct ath10k *ar) -++static int ath10k_pci_wake_wait(struct ath10k *ar) -+ { -+- struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); -+- void __iomem *pci_addr = ar_pci->mem; -+ int tot_delay = 0; -+ int curr_delay = 5; -+ -+- if (atomic_read(&ar_pci->keep_awake_count) == 0) { -+- /* Force AWAKE */ -+- iowrite32(PCIE_SOC_WAKE_V_MASK, -+- pci_addr + PCIE_LOCAL_BASE_ADDRESS + -+- PCIE_SOC_WAKE_ADDRESS); -+- } -+- atomic_inc(&ar_pci->keep_awake_count); -+- -+- if (ar_pci->verified_awake) -+- return 0; -+- -+- for (;;) { -+- if (ath10k_pci_target_is_awake(ar)) { -+- ar_pci->verified_awake = true; -++ while (tot_delay < PCIE_WAKE_TIMEOUT) { -++ if (ath10k_pci_is_awake(ar)) -+ return 0; -+- } -+- -+- if (tot_delay > PCIE_WAKE_TIMEOUT) { -+- ath10k_warn("target took longer %d us to wake up (awake count %d)\n", -+- PCIE_WAKE_TIMEOUT, -+- atomic_read(&ar_pci->keep_awake_count)); -+- return -ETIMEDOUT; -+- } -+ -+ udelay(curr_delay); -+ tot_delay += curr_delay; -+@@ -674,20 +815,21 @@ int ath10k_do_pci_wake(struct ath10k *ar -+ if (curr_delay < 50) -+ curr_delay += 5; -+ } -++ -++ return -ETIMEDOUT; -+ } -+ -+-void ath10k_do_pci_sleep(struct ath10k *ar) -++static int ath10k_pci_wake(struct ath10k *ar) -+ { -+- struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); -+- void __iomem *pci_addr = ar_pci->mem; -++ ath10k_pci_reg_write32(ar, PCIE_SOC_WAKE_ADDRESS, -++ PCIE_SOC_WAKE_V_MASK); -++ return ath10k_pci_wake_wait(ar); -++} -+ -+- if (atomic_dec_and_test(&ar_pci->keep_awake_count)) { -+- /* Allow sleep */ -+- ar_pci->verified_awake = false; -+- iowrite32(PCIE_SOC_WAKE_RESET, -+- pci_addr + PCIE_LOCAL_BASE_ADDRESS + -+- PCIE_SOC_WAKE_ADDRESS); -+- } -++static void ath10k_pci_sleep(struct ath10k *ar) -++{ -++ ath10k_pci_reg_write32(ar, PCIE_SOC_WAKE_ADDRESS, -++ PCIE_SOC_WAKE_RESET); -+ } -+ -+ /* Called by lower (CE) layer when a send to Target completes. */ -+@@ -696,20 +838,24 @@ static void ath10k_pci_ce_send_done(stru -+ struct ath10k *ar = ce_state->ar; -+ struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); -+ struct ath10k_hif_cb *cb = &ar_pci->msg_callbacks_current; -+- void *transfer_context; -++ struct sk_buff_head list; -++ struct sk_buff *skb; -+ u32 ce_data; -+ unsigned int nbytes; -+ unsigned int transfer_id; -+ -+- while (ath10k_ce_completed_send_next(ce_state, &transfer_context, -+- &ce_data, &nbytes, -+- &transfer_id) == 0) { -++ __skb_queue_head_init(&list); -++ while (ath10k_ce_completed_send_next(ce_state, (void **)&skb, &ce_data, -++ &nbytes, &transfer_id) == 0) { -+ /* no need to call tx completion for NULL pointers */ -+- if (transfer_context == NULL) -++ if (skb == NULL) -+ continue; -+ -+- cb->tx_completion(ar, transfer_context, transfer_id); -++ __skb_queue_tail(&list, skb); -+ } -++ -++ while ((skb = __skb_dequeue(&list))) -++ cb->tx_completion(ar, skb); -+ } -+ -+ /* Called by lower (CE) layer when data is received from the Target. */ -+@@ -720,38 +866,43 @@ static void ath10k_pci_ce_recv_data(stru -+ struct ath10k_pci_pipe *pipe_info = &ar_pci->pipe_info[ce_state->id]; -+ struct ath10k_hif_cb *cb = &ar_pci->msg_callbacks_current; -+ struct sk_buff *skb; -++ struct sk_buff_head list; -+ void *transfer_context; -+ u32 ce_data; -+ unsigned int nbytes, max_nbytes; -+ unsigned int transfer_id; -+ unsigned int flags; -+- int err; -+ -++ __skb_queue_head_init(&list); -+ while (ath10k_ce_completed_recv_next(ce_state, &transfer_context, -+ &ce_data, &nbytes, &transfer_id, -+ &flags) == 0) { -+- err = ath10k_pci_post_rx_pipe(pipe_info, 1); -+- if (unlikely(err)) { -+- /* FIXME: retry */ -+- ath10k_warn("failed to replenish CE rx ring %d: %d\n", -+- pipe_info->pipe_num, err); -+- } -+- -+ skb = transfer_context; -+ max_nbytes = skb->len + skb_tailroom(skb); -+- dma_unmap_single(ar->dev, ATH10K_SKB_CB(skb)->paddr, -++ dma_unmap_single(ar->dev, ATH10K_SKB_RXCB(skb)->paddr, -+ max_nbytes, DMA_FROM_DEVICE); -+ -+ if (unlikely(max_nbytes < nbytes)) { -+- ath10k_warn("rxed more than expected (nbytes %d, max %d)", -++ ath10k_warn(ar, "rxed more than expected (nbytes %d, max %d)", -+ nbytes, max_nbytes); -+ dev_kfree_skb_any(skb); -+ continue; -+ } -+ -+ skb_put(skb, nbytes); -+- cb->rx_completion(ar, skb, pipe_info->pipe_num); -++ __skb_queue_tail(&list, skb); -++ } -++ -++ while ((skb = __skb_dequeue(&list))) { -++ ath10k_dbg(ar, ATH10K_DBG_PCI, "pci rx ce pipe %d len %d\n", -++ ce_state->id, skb->len); -++ ath10k_dbg_dump(ar, ATH10K_DBG_PCI_DUMP, NULL, "pci rx: ", -++ skb->data, skb->len); -++ -++ cb->rx_completion(ar, skb); -+ } -++ -++ ath10k_pci_rx_post_pipe(pipe_info); -+ } -+ -+ static int ath10k_pci_hif_tx_sg(struct ath10k *ar, u8 pipe_id, -+@@ -761,24 +912,28 @@ static int ath10k_pci_hif_tx_sg(struct a -+ struct ath10k_pci_pipe *pci_pipe = &ar_pci->pipe_info[pipe_id]; -+ struct ath10k_ce_pipe *ce_pipe = pci_pipe->ce_hdl; -+ struct ath10k_ce_ring *src_ring = ce_pipe->src_ring; -+- unsigned int nentries_mask = src_ring->nentries_mask; -+- unsigned int sw_index = src_ring->sw_index; -+- unsigned int write_index = src_ring->write_index; -+- int err, i; -++ unsigned int nentries_mask; -++ unsigned int sw_index; -++ unsigned int write_index; -++ int err, i = 0; -+ -+ spin_lock_bh(&ar_pci->ce_lock); -+ -++ nentries_mask = src_ring->nentries_mask; -++ sw_index = src_ring->sw_index; -++ write_index = src_ring->write_index; -++ -+ if (unlikely(CE_RING_DELTA(nentries_mask, -+ write_index, sw_index - 1) < n_items)) { -+ err = -ENOBUFS; -+- goto unlock; -++ goto err; -+ } -+ -+ for (i = 0; i < n_items - 1; i++) { -+- ath10k_dbg(ATH10K_DBG_PCI, -++ ath10k_dbg(ar, ATH10K_DBG_PCI, -+ "pci tx item %d paddr 0x%08x len %d n_items %d\n", -+ i, items[i].paddr, items[i].len, n_items); -+- ath10k_dbg_dump(ATH10K_DBG_PCI_DUMP, NULL, "item data: ", -++ ath10k_dbg_dump(ar, ATH10K_DBG_PCI_DUMP, NULL, "pci tx data: ", -+ items[i].vaddr, items[i].len); -+ -+ err = ath10k_ce_send_nolock(ce_pipe, -+@@ -788,15 +943,15 @@ static int ath10k_pci_hif_tx_sg(struct a -+ items[i].transfer_id, -+ CE_SEND_FLAG_GATHER); -+ if (err) -+- goto unlock; -++ goto err; -+ } -+ -+ /* `i` is equal to `n_items -1` after for() */ -+ -+- ath10k_dbg(ATH10K_DBG_PCI, -++ ath10k_dbg(ar, ATH10K_DBG_PCI, -+ "pci tx item %d paddr 0x%08x len %d n_items %d\n", -+ i, items[i].paddr, items[i].len, n_items); -+- ath10k_dbg_dump(ATH10K_DBG_PCI_DUMP, NULL, "item data: ", -++ ath10k_dbg_dump(ar, ATH10K_DBG_PCI_DUMP, NULL, "pci tx data: ", -+ items[i].vaddr, items[i].len); -+ -+ err = ath10k_ce_send_nolock(ce_pipe, -+@@ -806,64 +961,89 @@ static int ath10k_pci_hif_tx_sg(struct a -+ items[i].transfer_id, -+ 0); -+ if (err) -+- goto unlock; -++ goto err; -++ -++ spin_unlock_bh(&ar_pci->ce_lock); -++ return 0; -++ -++err: -++ for (; i > 0; i--) -++ __ath10k_ce_send_revert(ce_pipe); -+ -+- err = 0; -+-unlock: -+ spin_unlock_bh(&ar_pci->ce_lock); -+ return err; -+ } -+ -++static int ath10k_pci_hif_diag_read(struct ath10k *ar, u32 address, void *buf, -++ size_t buf_len) -++{ -++ return ath10k_pci_diag_read_mem(ar, address, buf, buf_len); -++} -++ -+ static u16 ath10k_pci_hif_get_free_queue_number(struct ath10k *ar, u8 pipe) -+ { -+ struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); -+ -+- ath10k_dbg(ATH10K_DBG_PCI, "pci hif get free queue number\n"); -++ ath10k_dbg(ar, ATH10K_DBG_PCI, "pci hif get free queue number\n"); -+ -+ return ath10k_ce_num_free_src_entries(ar_pci->pipe_info[pipe].ce_hdl); -+ } -+ -+-static void ath10k_pci_hif_dump_area(struct ath10k *ar) -++static void ath10k_pci_dump_registers(struct ath10k *ar, -++ struct ath10k_fw_crash_data *crash_data) -+ { -+- u32 reg_dump_area = 0; -+- u32 reg_dump_values[REG_DUMP_COUNT_QCA988X] = {}; -+- u32 host_addr; -+- int ret; -+- u32 i; -+- -+- ath10k_err("firmware crashed!\n"); -+- ath10k_err("hardware name %s version 0x%x\n", -+- ar->hw_params.name, ar->target_version); -+- ath10k_err("firmware version: %s\n", ar->hw->wiphy->fw_version); -+- -+- host_addr = host_interest_item_address(HI_ITEM(hi_failure_state)); -+- ret = ath10k_pci_diag_read_mem(ar, host_addr, -+- ®_dump_area, sizeof(u32)); -+- if (ret) { -+- ath10k_err("failed to read FW dump area address: %d\n", ret); -+- return; -+- } -++ __le32 reg_dump_values[REG_DUMP_COUNT_QCA988X] = {}; -++ int i, ret; -+ -+- ath10k_err("target register Dump Location: 0x%08X\n", reg_dump_area); -++ lockdep_assert_held(&ar->data_lock); -+ -+- ret = ath10k_pci_diag_read_mem(ar, reg_dump_area, -+- ®_dump_values[0], -+- REG_DUMP_COUNT_QCA988X * sizeof(u32)); -+- if (ret != 0) { -+- ath10k_err("failed to read FW dump area: %d\n", ret); -++ ret = ath10k_pci_diag_read_hi(ar, ®_dump_values[0], -++ hi_failure_state, -++ REG_DUMP_COUNT_QCA988X * sizeof(__le32)); -++ if (ret) { -++ ath10k_err(ar, "failed to read firmware dump area: %d\n", ret); -+ return; -+ } -+ -+ BUILD_BUG_ON(REG_DUMP_COUNT_QCA988X % 4); -+ -+- ath10k_err("target Register Dump\n"); -++ ath10k_err(ar, "firmware register dump:\n"); -+ for (i = 0; i < REG_DUMP_COUNT_QCA988X; i += 4) -+- ath10k_err("[%02d]: 0x%08X 0x%08X 0x%08X 0x%08X\n", -++ ath10k_err(ar, "[%02d]: 0x%08X 0x%08X 0x%08X 0x%08X\n", -+ i, -+- reg_dump_values[i], -+- reg_dump_values[i + 1], -+- reg_dump_values[i + 2], -+- reg_dump_values[i + 3]); -++ __le32_to_cpu(reg_dump_values[i]), -++ __le32_to_cpu(reg_dump_values[i + 1]), -++ __le32_to_cpu(reg_dump_values[i + 2]), -++ __le32_to_cpu(reg_dump_values[i + 3])); -++ -++ if (!crash_data) -++ return; -++ -++ for (i = 0; i < REG_DUMP_COUNT_QCA988X; i++) -++ crash_data->registers[i] = reg_dump_values[i]; -++} -++ -++static void ath10k_pci_fw_crashed_dump(struct ath10k *ar) -++{ -++ struct ath10k_fw_crash_data *crash_data; -++ char uuid[50]; -++ -++ spin_lock_bh(&ar->data_lock); -++ -++ ar->stats.fw_crash_counter++; -++ -++ crash_data = ath10k_debug_get_new_fw_crash_data(ar); -++ -++ if (crash_data) -++ scnprintf(uuid, sizeof(uuid), "%pUl", &crash_data->uuid); -++ else -++ scnprintf(uuid, sizeof(uuid), "n/a"); -++ -++ ath10k_err(ar, "firmware crashed! (uuid %s)\n", uuid); -++ ath10k_print_driver_info(ar); -++ ath10k_pci_dump_registers(ar, crash_data); -++ -++ spin_unlock_bh(&ar->data_lock); -+ -+ queue_work(ar->workqueue, &ar->restart_work); -+ } -+@@ -871,7 +1051,7 @@ static void ath10k_pci_hif_dump_area(str -+ static void ath10k_pci_hif_send_complete_check(struct ath10k *ar, u8 pipe, -+ int force) -+ { -+- ath10k_dbg(ATH10K_DBG_PCI, "pci hif send complete check\n"); -++ ath10k_dbg(ar, ATH10K_DBG_PCI, "pci hif send complete check\n"); -+ -+ if (!force) { -+ int resources; -+@@ -899,43 +1079,12 @@ static void ath10k_pci_hif_set_callbacks -+ { -+ struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); -+ -+- ath10k_dbg(ATH10K_DBG_PCI, "pci hif set callbacks\n"); -++ ath10k_dbg(ar, ATH10K_DBG_PCI, "pci hif set callbacks\n"); -+ -+ memcpy(&ar_pci->msg_callbacks_current, callbacks, -+ sizeof(ar_pci->msg_callbacks_current)); -+ } -+ -+-static int ath10k_pci_setup_ce_irq(struct ath10k *ar) -+-{ -+- struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); -+- const struct ce_attr *attr; -+- struct ath10k_pci_pipe *pipe_info; -+- int pipe_num, disable_interrupts; -+- -+- for (pipe_num = 0; pipe_num < CE_COUNT; pipe_num++) { -+- pipe_info = &ar_pci->pipe_info[pipe_num]; -+- -+- /* Handle Diagnostic CE specially */ -+- if (pipe_info->ce_hdl == ar_pci->ce_diag) -+- continue; -+- -+- attr = &host_ce_config_wlan[pipe_num]; -+- -+- if (attr->src_nentries) { -+- disable_interrupts = attr->flags & CE_ATTR_DIS_INTR; -+- ath10k_ce_send_cb_register(pipe_info->ce_hdl, -+- ath10k_pci_ce_send_done, -+- disable_interrupts); -+- } -+- -+- if (attr->dest_nentries) -+- ath10k_ce_recv_cb_register(pipe_info->ce_hdl, -+- ath10k_pci_ce_recv_data); -+- } -+- -+- return 0; -+-} -+- -+ static void ath10k_pci_kill_tasklet(struct ath10k *ar) -+ { -+ struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); -+@@ -943,82 +1092,72 @@ static void ath10k_pci_kill_tasklet(stru -+ -+ tasklet_kill(&ar_pci->intr_tq); -+ tasklet_kill(&ar_pci->msi_fw_err); -+- tasklet_kill(&ar_pci->early_irq_tasklet); -+ -+ for (i = 0; i < CE_COUNT; i++) -+ tasklet_kill(&ar_pci->pipe_info[i].intr); -++ -++ del_timer_sync(&ar_pci->rx_post_retry); -+ } -+ -+-/* TODO - temporary mapping while we have too few CE's */ -+ static int ath10k_pci_hif_map_service_to_pipe(struct ath10k *ar, -+ u16 service_id, u8 *ul_pipe, -+ u8 *dl_pipe, int *ul_is_polled, -+ int *dl_is_polled) -+ { -+- int ret = 0; -++ const struct service_to_pipe *entry; -++ bool ul_set = false, dl_set = false; -++ int i; -+ -+- ath10k_dbg(ATH10K_DBG_PCI, "pci hif map service\n"); -++ ath10k_dbg(ar, ATH10K_DBG_PCI, "pci hif map service\n"); -+ -+ /* polling for received messages not supported */ -+ *dl_is_polled = 0; -+ -+- switch (service_id) { -+- case ATH10K_HTC_SVC_ID_HTT_DATA_MSG: -+- /* -+- * Host->target HTT gets its own pipe, so it can be polled -+- * while other pipes are interrupt driven. -+- */ -+- *ul_pipe = 4; -+- /* -+- * Use the same target->host pipe for HTC ctrl, HTC raw -+- * streams, and HTT. -+- */ -+- *dl_pipe = 1; -+- break; -++ for (i = 0; i < ARRAY_SIZE(target_service_to_ce_map_wlan); i++) { -++ entry = &target_service_to_ce_map_wlan[i]; -+ -+- case ATH10K_HTC_SVC_ID_RSVD_CTRL: -+- case ATH10K_HTC_SVC_ID_TEST_RAW_STREAMS: -+- /* -+- * Note: HTC_RAW_STREAMS_SVC is currently unused, and -+- * HTC_CTRL_RSVD_SVC could share the same pipe as the -+- * WMI services. So, if another CE is needed, change -+- * this to *ul_pipe = 3, which frees up CE 0. -+- */ -+- /* *ul_pipe = 3; */ -+- *ul_pipe = 0; -+- *dl_pipe = 1; -+- break; -++ if (__le32_to_cpu(entry->service_id) != service_id) -++ continue; -+ -+- case ATH10K_HTC_SVC_ID_WMI_DATA_BK: -+- case ATH10K_HTC_SVC_ID_WMI_DATA_BE: -+- case ATH10K_HTC_SVC_ID_WMI_DATA_VI: -+- case ATH10K_HTC_SVC_ID_WMI_DATA_VO: -+- -+- case ATH10K_HTC_SVC_ID_WMI_CONTROL: -+- *ul_pipe = 3; -+- *dl_pipe = 2; -+- break; -++ switch (__le32_to_cpu(entry->pipedir)) { -++ case PIPEDIR_NONE: -++ break; -++ case PIPEDIR_IN: -++ WARN_ON(dl_set); -++ *dl_pipe = __le32_to_cpu(entry->pipenum); -++ dl_set = true; -++ break; -++ case PIPEDIR_OUT: -++ WARN_ON(ul_set); -++ *ul_pipe = __le32_to_cpu(entry->pipenum); -++ ul_set = true; -++ break; -++ case PIPEDIR_INOUT: -++ WARN_ON(dl_set); -++ WARN_ON(ul_set); -++ *dl_pipe = __le32_to_cpu(entry->pipenum); -++ *ul_pipe = __le32_to_cpu(entry->pipenum); -++ dl_set = true; -++ ul_set = true; -++ break; -++ } -++ } -+ -+- /* pipe 5 unused */ -+- /* pipe 6 reserved */ -+- /* pipe 7 reserved */ -++ if (WARN_ON(!ul_set || !dl_set)) -++ return -ENOENT; -+ -+- default: -+- ret = -1; -+- break; -+- } -+ *ul_is_polled = -+ (host_ce_config_wlan[*ul_pipe].flags & CE_ATTR_DIS_INTR) != 0; -+ -+- return ret; -++ return 0; -+ } -+ -+ static void ath10k_pci_hif_get_default_pipe(struct ath10k *ar, -+- u8 *ul_pipe, u8 *dl_pipe) -++ u8 *ul_pipe, u8 *dl_pipe) -+ { -+ int ul_is_polled, dl_is_polled; -+ -+- ath10k_dbg(ATH10K_DBG_PCI, "pci hif get default pipe\n"); -++ ath10k_dbg(ar, ATH10K_DBG_PCI, "pci hif get default pipe\n"); -+ -+ (void)ath10k_pci_hif_map_service_to_pipe(ar, -+ ATH10K_HTC_SVC_ID_RSVD_CTRL, -+@@ -1028,209 +1167,127 @@ static void ath10k_pci_hif_get_default_p -+ &dl_is_polled); -+ } -+ -+-static int ath10k_pci_post_rx_pipe(struct ath10k_pci_pipe *pipe_info, -+- int num) -++static void ath10k_pci_irq_msi_fw_mask(struct ath10k *ar) -+ { -+- struct ath10k *ar = pipe_info->hif_ce_state; -+- struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); -+- struct ath10k_ce_pipe *ce_state = pipe_info->ce_hdl; -+- struct sk_buff *skb; -+- dma_addr_t ce_data; -+- int i, ret = 0; -++ u32 val; -+ -+- if (pipe_info->buf_sz == 0) -+- return 0; -++ val = ath10k_pci_read32(ar, SOC_CORE_BASE_ADDRESS + CORE_CTRL_ADDRESS); -++ val &= ~CORE_CTRL_PCIE_REG_31_MASK; -+ -+- for (i = 0; i < num; i++) { -+- skb = dev_alloc_skb(pipe_info->buf_sz); -+- if (!skb) { -+- ath10k_warn("failed to allocate skbuff for pipe %d\n", -+- num); -+- ret = -ENOMEM; -+- goto err; -+- } -++ ath10k_pci_write32(ar, SOC_CORE_BASE_ADDRESS + CORE_CTRL_ADDRESS, val); -++} -+ -+- WARN_ONCE((unsigned long)skb->data & 3, "unaligned skb"); -++static void ath10k_pci_irq_msi_fw_unmask(struct ath10k *ar) -++{ -++ u32 val; -+ -+- ce_data = dma_map_single(ar->dev, skb->data, -+- skb->len + skb_tailroom(skb), -+- DMA_FROM_DEVICE); -++ val = ath10k_pci_read32(ar, SOC_CORE_BASE_ADDRESS + CORE_CTRL_ADDRESS); -++ val |= CORE_CTRL_PCIE_REG_31_MASK; -+ -+- if (unlikely(dma_mapping_error(ar->dev, ce_data))) { -+- ath10k_warn("failed to DMA map sk_buff\n"); -+- dev_kfree_skb_any(skb); -+- ret = -EIO; -+- goto err; -+- } -++ ath10k_pci_write32(ar, SOC_CORE_BASE_ADDRESS + CORE_CTRL_ADDRESS, val); -++} -+ -+- ATH10K_SKB_CB(skb)->paddr = ce_data; -++static void ath10k_pci_irq_disable(struct ath10k *ar) -++{ -++ ath10k_ce_disable_interrupts(ar); -++ ath10k_pci_disable_and_clear_legacy_irq(ar); -++ ath10k_pci_irq_msi_fw_mask(ar); -++} -+ -+- pci_dma_sync_single_for_device(ar_pci->pdev, ce_data, -+- pipe_info->buf_sz, -+- PCI_DMA_FROMDEVICE); -+- -+- ret = ath10k_ce_recv_buf_enqueue(ce_state, (void *)skb, -+- ce_data); -+- if (ret) { -+- ath10k_warn("failed to enqueue to pipe %d: %d\n", -+- num, ret); -+- goto err; -+- } -+- } -+- -+- return ret; -+- -+-err: -+- ath10k_pci_rx_pipe_cleanup(pipe_info); -+- return ret; -+-} -+- -+-static int ath10k_pci_post_rx(struct ath10k *ar) -++static void ath10k_pci_irq_sync(struct ath10k *ar) -+ { -+ struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); -+- struct ath10k_pci_pipe *pipe_info; -+- const struct ce_attr *attr; -+- int pipe_num, ret = 0; -+- -+- for (pipe_num = 0; pipe_num < CE_COUNT; pipe_num++) { -+- pipe_info = &ar_pci->pipe_info[pipe_num]; -+- attr = &host_ce_config_wlan[pipe_num]; -+- -+- if (attr->dest_nentries == 0) -+- continue; -+- -+- ret = ath10k_pci_post_rx_pipe(pipe_info, -+- attr->dest_nentries - 1); -+- if (ret) { -+- ath10k_warn("failed to post RX buffer for pipe %d: %d\n", -+- pipe_num, ret); -++ int i; -+ -+- for (; pipe_num >= 0; pipe_num--) { -+- pipe_info = &ar_pci->pipe_info[pipe_num]; -+- ath10k_pci_rx_pipe_cleanup(pipe_info); -+- } -+- return ret; -+- } -+- } -++ for (i = 0; i < max(1, ar_pci->num_msi_intrs); i++) -++ synchronize_irq(ar_pci->pdev->irq + i); -++} -+ -+- return 0; -++static void ath10k_pci_irq_enable(struct ath10k *ar) -++{ -++ ath10k_ce_enable_interrupts(ar); -++ ath10k_pci_enable_legacy_irq(ar); -++ ath10k_pci_irq_msi_fw_unmask(ar); -+ } -+ -+ static int ath10k_pci_hif_start(struct ath10k *ar) -+ { -+- struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); -+- int ret, ret_early; -+- -+- ath10k_dbg(ATH10K_DBG_BOOT, "boot hif start\n"); -+- -+- ath10k_pci_free_early_irq(ar); -+- ath10k_pci_kill_tasklet(ar); -+- -+- ret = ath10k_pci_request_irq(ar); -+- if (ret) { -+- ath10k_warn("failed to post RX buffers for all pipes: %d\n", -+- ret); -+- goto err_early_irq; -+- } -+- -+- ret = ath10k_pci_setup_ce_irq(ar); -+- if (ret) { -+- ath10k_warn("failed to setup CE interrupts: %d\n", ret); -+- goto err_stop; -+- } -++ ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot hif start\n"); -+ -+- /* Post buffers once to start things off. */ -+- ret = ath10k_pci_post_rx(ar); -+- if (ret) { -+- ath10k_warn("failed to post RX buffers for all pipes: %d\n", -+- ret); -+- goto err_stop; -+- } -++ ath10k_pci_irq_enable(ar); -++ ath10k_pci_rx_post(ar); -+ -+- ar_pci->started = 1; -+ return 0; -+- -+-err_stop: -+- ath10k_ce_disable_interrupts(ar); -+- ath10k_pci_free_irq(ar); -+- ath10k_pci_kill_tasklet(ar); -+-err_early_irq: -+- /* Though there should be no interrupts (device was reset) -+- * power_down() expects the early IRQ to be installed as per the -+- * driver lifecycle. */ -+- ret_early = ath10k_pci_request_early_irq(ar); -+- if (ret_early) -+- ath10k_warn("failed to re-enable early irq: %d\n", ret_early); -+- -+- return ret; -+ } -+ -+-static void ath10k_pci_rx_pipe_cleanup(struct ath10k_pci_pipe *pipe_info) -++static void ath10k_pci_rx_pipe_cleanup(struct ath10k_pci_pipe *pci_pipe) -+ { -+ struct ath10k *ar; -+- struct ath10k_pci *ar_pci; -+- struct ath10k_ce_pipe *ce_hdl; -+- u32 buf_sz; -+- struct sk_buff *netbuf; -+- u32 ce_data; -++ struct ath10k_ce_pipe *ce_pipe; -++ struct ath10k_ce_ring *ce_ring; -++ struct sk_buff *skb; -++ int i; -+ -+- buf_sz = pipe_info->buf_sz; -++ ar = pci_pipe->hif_ce_state; -++ ce_pipe = pci_pipe->ce_hdl; -++ ce_ring = ce_pipe->dest_ring; -+ -+- /* Unused Copy Engine */ -+- if (buf_sz == 0) -++ if (!ce_ring) -+ return; -+ -+- ar = pipe_info->hif_ce_state; -+- ar_pci = ath10k_pci_priv(ar); -+- -+- if (!ar_pci->started) -++ if (!pci_pipe->buf_sz) -+ return; -+ -+- ce_hdl = pipe_info->ce_hdl; -++ for (i = 0; i < ce_ring->nentries; i++) { -++ skb = ce_ring->per_transfer_context[i]; -++ if (!skb) -++ continue; -++ -++ ce_ring->per_transfer_context[i] = NULL; -+ -+- while (ath10k_ce_revoke_recv_next(ce_hdl, (void **)&netbuf, -+- &ce_data) == 0) { -+- dma_unmap_single(ar->dev, ATH10K_SKB_CB(netbuf)->paddr, -+- netbuf->len + skb_tailroom(netbuf), -++ dma_unmap_single(ar->dev, ATH10K_SKB_RXCB(skb)->paddr, -++ skb->len + skb_tailroom(skb), -+ DMA_FROM_DEVICE); -+- dev_kfree_skb_any(netbuf); -++ dev_kfree_skb_any(skb); -+ } -+ } -+ -+-static void ath10k_pci_tx_pipe_cleanup(struct ath10k_pci_pipe *pipe_info) -++static void ath10k_pci_tx_pipe_cleanup(struct ath10k_pci_pipe *pci_pipe) -+ { -+ struct ath10k *ar; -+ struct ath10k_pci *ar_pci; -+- struct ath10k_ce_pipe *ce_hdl; -+- struct sk_buff *netbuf; -+- u32 ce_data; -+- unsigned int nbytes; -++ struct ath10k_ce_pipe *ce_pipe; -++ struct ath10k_ce_ring *ce_ring; -++ struct ce_desc *ce_desc; -++ struct sk_buff *skb; -+ unsigned int id; -+- u32 buf_sz; -++ int i; -+ -+- buf_sz = pipe_info->buf_sz; -++ ar = pci_pipe->hif_ce_state; -++ ar_pci = ath10k_pci_priv(ar); -++ ce_pipe = pci_pipe->ce_hdl; -++ ce_ring = ce_pipe->src_ring; -+ -+- /* Unused Copy Engine */ -+- if (buf_sz == 0) -++ if (!ce_ring) -+ return; -+ -+- ar = pipe_info->hif_ce_state; -+- ar_pci = ath10k_pci_priv(ar); -+- -+- if (!ar_pci->started) -++ if (!pci_pipe->buf_sz) -+ return; -+ -+- ce_hdl = pipe_info->ce_hdl; -++ ce_desc = ce_ring->shadow_base; -++ if (WARN_ON(!ce_desc)) -++ return; -+ -+- while (ath10k_ce_cancel_send_next(ce_hdl, (void **)&netbuf, -+- &ce_data, &nbytes, &id) == 0) { -+- /* no need to call tx completion for NULL pointers */ -+- if (!netbuf) -++ for (i = 0; i < ce_ring->nentries; i++) { -++ skb = ce_ring->per_transfer_context[i]; -++ if (!skb) -+ continue; -+ -+- ar_pci->msg_callbacks_current.tx_completion(ar, -+- netbuf, -+- id); -++ ce_ring->per_transfer_context[i] = NULL; -++ id = MS(__le16_to_cpu(ce_desc[i].flags), -++ CE_DESC_FLAGS_META_DATA); -++ -++ ar_pci->msg_callbacks_current.tx_completion(ar, skb); -+ } -+ } -+ -+@@ -1264,38 +1321,32 @@ static void ath10k_pci_ce_deinit(struct -+ ath10k_ce_deinit_pipe(ar, i); -+ } -+ -+-static void ath10k_pci_hif_stop(struct ath10k *ar) -++static void ath10k_pci_flush(struct ath10k *ar) -+ { -+- struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); -+- int ret; -+- -+- ath10k_dbg(ATH10K_DBG_BOOT, "boot hif stop\n"); -+- -+- ret = ath10k_ce_disable_interrupts(ar); -+- if (ret) -+- ath10k_warn("failed to disable CE interrupts: %d\n", ret); -+- -+- ath10k_pci_free_irq(ar); -+ ath10k_pci_kill_tasklet(ar); -+- -+- ret = ath10k_pci_request_early_irq(ar); -+- if (ret) -+- ath10k_warn("failed to re-enable early irq: %d\n", ret); -+- -+- /* At this point, asynchronous threads are stopped, the target should -+- * not DMA nor interrupt. We process the leftovers and then free -+- * everything else up. */ -+- -+ ath10k_pci_buffer_cleanup(ar); -++} -+ -+- /* Make the sure the device won't access any structures on the host by -+- * resetting it. The device was fed with PCI CE ringbuffer -+- * configuration during init. If ringbuffers are freed and the device -+- * were to access them this could lead to memory corruption on the -+- * host. */ -++static void ath10k_pci_hif_stop(struct ath10k *ar) -++{ -++ ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot hif stop\n"); -++ -++ /* Most likely the device has HTT Rx ring configured. The only way to -++ * prevent the device from accessing (and possible corrupting) host -++ * memory is to reset the chip now. -++ * -++ * There's also no known way of masking MSI interrupts on the device. -++ * For ranged MSI the CE-related interrupts can be masked. However -++ * regardless how many MSI interrupts are assigned the first one -++ * is always used for firmware indications (crashes) and cannot be -++ * masked. To prevent the device from asserting the interrupt reset it -++ * before proceeding with cleanup. -++ */ -+ ath10k_pci_warm_reset(ar); -+ -+- ar_pci->started = 0; -++ ath10k_pci_irq_disable(ar); -++ ath10k_pci_irq_sync(ar); -++ ath10k_pci_flush(ar); -+ } -+ -+ static int ath10k_pci_hif_exchange_bmi_msg(struct ath10k *ar, -+@@ -1346,11 +1397,9 @@ static int ath10k_pci_hif_exchange_bmi_m -+ xfer.wait_for_resp = true; -+ xfer.resp_len = 0; -+ -+- ath10k_ce_recv_buf_enqueue(ce_rx, &xfer, resp_paddr); -++ ath10k_ce_rx_post_buf(ce_rx, &xfer, resp_paddr); -+ } -+ -+- init_completion(&xfer.done); -+- -+ ret = ath10k_ce_send(ce_tx, &xfer, req_paddr, req_len, -1, 0); -+ if (ret) -+ goto err_resp; -+@@ -1401,14 +1450,12 @@ static void ath10k_pci_bmi_send_done(str -+ &nbytes, &transfer_id)) -+ return; -+ -+- if (xfer->wait_for_resp) -+- return; -+- -+- complete(&xfer->done); -++ xfer->tx_done = true; -+ } -+ -+ static void ath10k_pci_bmi_recv_data(struct ath10k_ce_pipe *ce_state) -+ { -++ struct ath10k *ar = ce_state->ar; -+ struct bmi_xfer *xfer; -+ u32 ce_data; -+ unsigned int nbytes; -+@@ -1419,13 +1466,16 @@ static void ath10k_pci_bmi_recv_data(str -+ &nbytes, &transfer_id, &flags)) -+ return; -+ -++ if (WARN_ON_ONCE(!xfer)) -++ return; -++ -+ if (!xfer->wait_for_resp) { -+- ath10k_warn("unexpected: BMI data received; ignoring\n"); -++ ath10k_warn(ar, "unexpected: BMI data received; ignoring\n"); -+ return; -+ } -+ -+ xfer->resp_len = nbytes; -+- complete(&xfer->done); -++ xfer->rx_done = true; -+ } -+ -+ static int ath10k_pci_bmi_wait(struct ath10k_ce_pipe *tx_pipe, -+@@ -1438,7 +1488,7 @@ static int ath10k_pci_bmi_wait(struct at -+ ath10k_pci_bmi_send_done(tx_pipe); -+ ath10k_pci_bmi_recv_data(rx_pipe); -+ -+- if (completion_done(&xfer->done)) -++ if (xfer->tx_done && (xfer->rx_done == xfer->wait_for_resp)) -+ return 0; -+ -+ schedule(); -+@@ -1448,131 +1498,48 @@ static int ath10k_pci_bmi_wait(struct at -+ } -+ -+ /* -+- * Map from service/endpoint to Copy Engine. -+- * This table is derived from the CE_PCI TABLE, above. -+- * It is passed to the Target at startup for use by firmware. -+- */ -+-static const struct service_to_pipe target_service_to_ce_map_wlan[] = { -+- { -+- ATH10K_HTC_SVC_ID_WMI_DATA_VO, -+- PIPEDIR_OUT, /* out = UL = host -> target */ -+- 3, -+- }, -+- { -+- ATH10K_HTC_SVC_ID_WMI_DATA_VO, -+- PIPEDIR_IN, /* in = DL = target -> host */ -+- 2, -+- }, -+- { -+- ATH10K_HTC_SVC_ID_WMI_DATA_BK, -+- PIPEDIR_OUT, /* out = UL = host -> target */ -+- 3, -+- }, -+- { -+- ATH10K_HTC_SVC_ID_WMI_DATA_BK, -+- PIPEDIR_IN, /* in = DL = target -> host */ -+- 2, -+- }, -+- { -+- ATH10K_HTC_SVC_ID_WMI_DATA_BE, -+- PIPEDIR_OUT, /* out = UL = host -> target */ -+- 3, -+- }, -+- { -+- ATH10K_HTC_SVC_ID_WMI_DATA_BE, -+- PIPEDIR_IN, /* in = DL = target -> host */ -+- 2, -+- }, -+- { -+- ATH10K_HTC_SVC_ID_WMI_DATA_VI, -+- PIPEDIR_OUT, /* out = UL = host -> target */ -+- 3, -+- }, -+- { -+- ATH10K_HTC_SVC_ID_WMI_DATA_VI, -+- PIPEDIR_IN, /* in = DL = target -> host */ -+- 2, -+- }, -+- { -+- ATH10K_HTC_SVC_ID_WMI_CONTROL, -+- PIPEDIR_OUT, /* out = UL = host -> target */ -+- 3, -+- }, -+- { -+- ATH10K_HTC_SVC_ID_WMI_CONTROL, -+- PIPEDIR_IN, /* in = DL = target -> host */ -+- 2, -+- }, -+- { -+- ATH10K_HTC_SVC_ID_RSVD_CTRL, -+- PIPEDIR_OUT, /* out = UL = host -> target */ -+- 0, /* could be moved to 3 (share with WMI) */ -+- }, -+- { -+- ATH10K_HTC_SVC_ID_RSVD_CTRL, -+- PIPEDIR_IN, /* in = DL = target -> host */ -+- 1, -+- }, -+- { -+- ATH10K_HTC_SVC_ID_TEST_RAW_STREAMS, /* not currently used */ -+- PIPEDIR_OUT, /* out = UL = host -> target */ -+- 0, -+- }, -+- { -+- ATH10K_HTC_SVC_ID_TEST_RAW_STREAMS, /* not currently used */ -+- PIPEDIR_IN, /* in = DL = target -> host */ -+- 1, -+- }, -+- { -+- ATH10K_HTC_SVC_ID_HTT_DATA_MSG, -+- PIPEDIR_OUT, /* out = UL = host -> target */ -+- 4, -+- }, -+- { -+- ATH10K_HTC_SVC_ID_HTT_DATA_MSG, -+- PIPEDIR_IN, /* in = DL = target -> host */ -+- 1, -+- }, -+- -+- /* (Additions here) */ -+- -+- { /* Must be last */ -+- 0, -+- 0, -+- 0, -+- }, -+-}; -+- -+-/* -+ * Send an interrupt to the device to wake up the Target CPU -+ * so it has an opportunity to notice any changed state. -+ */ -+ static int ath10k_pci_wake_target_cpu(struct ath10k *ar) -+ { -+- int ret; -+- u32 core_ctrl; -++ u32 addr, val; -+ -+- ret = ath10k_pci_diag_read_access(ar, SOC_CORE_BASE_ADDRESS | -+- CORE_CTRL_ADDRESS, -+- &core_ctrl); -+- if (ret) { -+- ath10k_warn("failed to read core_ctrl: %d\n", ret); -+- return ret; -+- } -++ addr = SOC_CORE_BASE_ADDRESS | CORE_CTRL_ADDRESS; -++ val = ath10k_pci_read32(ar, addr); -++ val |= CORE_CTRL_CPU_INTR_MASK; -++ ath10k_pci_write32(ar, addr, val); -+ -+- /* A_INUM_FIRMWARE interrupt to Target CPU */ -+- core_ctrl |= CORE_CTRL_CPU_INTR_MASK; -++ return 0; -++} -+ -+- ret = ath10k_pci_diag_write_access(ar, SOC_CORE_BASE_ADDRESS | -+- CORE_CTRL_ADDRESS, -+- core_ctrl); -+- if (ret) { -+- ath10k_warn("failed to set target CPU interrupt mask: %d\n", -+- ret); -+- return ret; -++static int ath10k_pci_get_num_banks(struct ath10k *ar) -++{ -++ struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); -++ -++ switch (ar_pci->pdev->device) { -++ case QCA988X_2_0_DEVICE_ID: -++ return 1; -++ case QCA6174_2_1_DEVICE_ID: -++ switch (MS(ar->chip_id, SOC_CHIP_ID_REV)) { -++ case QCA6174_HW_1_0_CHIP_ID_REV: -++ case QCA6174_HW_1_1_CHIP_ID_REV: -++ return 3; -++ case QCA6174_HW_1_3_CHIP_ID_REV: -++ return 2; -++ case QCA6174_HW_2_1_CHIP_ID_REV: -++ case QCA6174_HW_2_2_CHIP_ID_REV: -++ return 6; -++ case QCA6174_HW_3_0_CHIP_ID_REV: -++ case QCA6174_HW_3_1_CHIP_ID_REV: -++ case QCA6174_HW_3_2_CHIP_ID_REV: -++ return 9; -++ } -++ break; -+ } -+ -+- return 0; -++ ath10k_warn(ar, "unknown number of banks, assuming 1\n"); -++ return 1; -+ } -+ -+ static int ath10k_pci_init_config(struct ath10k *ar) -+@@ -1593,144 +1560,162 @@ static int ath10k_pci_init_config(struct -+ host_interest_item_address(HI_ITEM(hi_interconnect_state)); -+ -+ /* Supply Target-side CE configuration */ -+- ret = ath10k_pci_diag_read_access(ar, interconnect_targ_addr, -+- &pcie_state_targ_addr); -++ ret = ath10k_pci_diag_read32(ar, interconnect_targ_addr, -++ &pcie_state_targ_addr); -+ if (ret != 0) { -+- ath10k_err("Failed to get pcie state addr: %d\n", ret); -++ ath10k_err(ar, "Failed to get pcie state addr: %d\n", ret); -+ return ret; -+ } -+ -+ if (pcie_state_targ_addr == 0) { -+ ret = -EIO; -+- ath10k_err("Invalid pcie state addr\n"); -++ ath10k_err(ar, "Invalid pcie state addr\n"); -+ return ret; -+ } -+ -+- ret = ath10k_pci_diag_read_access(ar, pcie_state_targ_addr + -++ ret = ath10k_pci_diag_read32(ar, (pcie_state_targ_addr + -+ offsetof(struct pcie_state, -+- pipe_cfg_addr), -+- &pipe_cfg_targ_addr); -++ pipe_cfg_addr)), -++ &pipe_cfg_targ_addr); -+ if (ret != 0) { -+- ath10k_err("Failed to get pipe cfg addr: %d\n", ret); -++ ath10k_err(ar, "Failed to get pipe cfg addr: %d\n", ret); -+ return ret; -+ } -+ -+ if (pipe_cfg_targ_addr == 0) { -+ ret = -EIO; -+- ath10k_err("Invalid pipe cfg addr\n"); -++ ath10k_err(ar, "Invalid pipe cfg addr\n"); -+ return ret; -+ } -+ -+ ret = ath10k_pci_diag_write_mem(ar, pipe_cfg_targ_addr, -+- target_ce_config_wlan, -+- sizeof(target_ce_config_wlan)); -++ target_ce_config_wlan, -++ sizeof(target_ce_config_wlan)); -+ -+ if (ret != 0) { -+- ath10k_err("Failed to write pipe cfg: %d\n", ret); -++ ath10k_err(ar, "Failed to write pipe cfg: %d\n", ret); -+ return ret; -+ } -+ -+- ret = ath10k_pci_diag_read_access(ar, pcie_state_targ_addr + -++ ret = ath10k_pci_diag_read32(ar, (pcie_state_targ_addr + -+ offsetof(struct pcie_state, -+- svc_to_pipe_map), -+- &svc_to_pipe_map); -++ svc_to_pipe_map)), -++ &svc_to_pipe_map); -+ if (ret != 0) { -+- ath10k_err("Failed to get svc/pipe map: %d\n", ret); -++ ath10k_err(ar, "Failed to get svc/pipe map: %d\n", ret); -+ return ret; -+ } -+ -+ if (svc_to_pipe_map == 0) { -+ ret = -EIO; -+- ath10k_err("Invalid svc_to_pipe map\n"); -++ ath10k_err(ar, "Invalid svc_to_pipe map\n"); -+ return ret; -+ } -+ -+ ret = ath10k_pci_diag_write_mem(ar, svc_to_pipe_map, -+- target_service_to_ce_map_wlan, -+- sizeof(target_service_to_ce_map_wlan)); -++ target_service_to_ce_map_wlan, -++ sizeof(target_service_to_ce_map_wlan)); -+ if (ret != 0) { -+- ath10k_err("Failed to write svc/pipe map: %d\n", ret); -++ ath10k_err(ar, "Failed to write svc/pipe map: %d\n", ret); -+ return ret; -+ } -+ -+- ret = ath10k_pci_diag_read_access(ar, pcie_state_targ_addr + -++ ret = ath10k_pci_diag_read32(ar, (pcie_state_targ_addr + -+ offsetof(struct pcie_state, -+- config_flags), -+- &pcie_config_flags); -++ config_flags)), -++ &pcie_config_flags); -+ if (ret != 0) { -+- ath10k_err("Failed to get pcie config_flags: %d\n", ret); -++ ath10k_err(ar, "Failed to get pcie config_flags: %d\n", ret); -+ return ret; -+ } -+ -+ pcie_config_flags &= ~PCIE_CONFIG_FLAG_ENABLE_L1; -+ -+- ret = ath10k_pci_diag_write_mem(ar, pcie_state_targ_addr + -+- offsetof(struct pcie_state, config_flags), -+- &pcie_config_flags, -+- sizeof(pcie_config_flags)); -++ ret = ath10k_pci_diag_write32(ar, (pcie_state_targ_addr + -++ offsetof(struct pcie_state, -++ config_flags)), -++ pcie_config_flags); -+ if (ret != 0) { -+- ath10k_err("Failed to write pcie config_flags: %d\n", ret); -++ ath10k_err(ar, "Failed to write pcie config_flags: %d\n", ret); -+ return ret; -+ } -+ -+ /* configure early allocation */ -+ ealloc_targ_addr = host_interest_item_address(HI_ITEM(hi_early_alloc)); -+ -+- ret = ath10k_pci_diag_read_access(ar, ealloc_targ_addr, &ealloc_value); -++ ret = ath10k_pci_diag_read32(ar, ealloc_targ_addr, &ealloc_value); -+ if (ret != 0) { -+- ath10k_err("Faile to get early alloc val: %d\n", ret); -++ ath10k_err(ar, "Faile to get early alloc val: %d\n", ret); -+ return ret; -+ } -+ -+ /* first bank is switched to IRAM */ -+ ealloc_value |= ((HI_EARLY_ALLOC_MAGIC << HI_EARLY_ALLOC_MAGIC_SHIFT) & -+ HI_EARLY_ALLOC_MAGIC_MASK); -+- ealloc_value |= ((1 << HI_EARLY_ALLOC_IRAM_BANKS_SHIFT) & -++ ealloc_value |= ((ath10k_pci_get_num_banks(ar) << -++ HI_EARLY_ALLOC_IRAM_BANKS_SHIFT) & -+ HI_EARLY_ALLOC_IRAM_BANKS_MASK); -+ -+- ret = ath10k_pci_diag_write_access(ar, ealloc_targ_addr, ealloc_value); -++ ret = ath10k_pci_diag_write32(ar, ealloc_targ_addr, ealloc_value); -+ if (ret != 0) { -+- ath10k_err("Failed to set early alloc val: %d\n", ret); -++ ath10k_err(ar, "Failed to set early alloc val: %d\n", ret); -+ return ret; -+ } -+ -+ /* Tell Target to proceed with initialization */ -+ flag2_targ_addr = host_interest_item_address(HI_ITEM(hi_option_flag2)); -+ -+- ret = ath10k_pci_diag_read_access(ar, flag2_targ_addr, &flag2_value); -++ ret = ath10k_pci_diag_read32(ar, flag2_targ_addr, &flag2_value); -+ if (ret != 0) { -+- ath10k_err("Failed to get option val: %d\n", ret); -++ ath10k_err(ar, "Failed to get option val: %d\n", ret); -+ return ret; -+ } -+ -+ flag2_value |= HI_OPTION_EARLY_CFG_DONE; -+ -+- ret = ath10k_pci_diag_write_access(ar, flag2_targ_addr, flag2_value); -++ ret = ath10k_pci_diag_write32(ar, flag2_targ_addr, flag2_value); -+ if (ret != 0) { -+- ath10k_err("Failed to set option val: %d\n", ret); -++ ath10k_err(ar, "Failed to set option val: %d\n", ret); -+ return ret; -+ } -+ -+ return 0; -+ } -+ -+-static int ath10k_pci_alloc_ce(struct ath10k *ar) -++static int ath10k_pci_alloc_pipes(struct ath10k *ar) -+ { -++ struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); -++ struct ath10k_pci_pipe *pipe; -+ int i, ret; -+ -+ for (i = 0; i < CE_COUNT; i++) { -+- ret = ath10k_ce_alloc_pipe(ar, i, &host_ce_config_wlan[i]); -++ pipe = &ar_pci->pipe_info[i]; -++ pipe->ce_hdl = &ar_pci->ce_states[i]; -++ pipe->pipe_num = i; -++ pipe->hif_ce_state = ar; -++ -++ ret = ath10k_ce_alloc_pipe(ar, i, &host_ce_config_wlan[i], -++ ath10k_pci_ce_send_done, -++ ath10k_pci_ce_recv_data); -+ if (ret) { -+- ath10k_err("failed to allocate copy engine pipe %d: %d\n", -++ ath10k_err(ar, "failed to allocate copy engine pipe %d: %d\n", -+ i, ret); -+ return ret; -+ } -++ -++ /* Last CE is Diagnostic Window */ -++ if (i == CE_COUNT - 1) { -++ ar_pci->ce_diag = pipe->ce_hdl; -++ continue; -++ } -++ -++ pipe->buf_sz = (size_t)(host_ce_config_wlan[i].src_sz_max); -+ } -+ -+ return 0; -+ } -+ -+-static void ath10k_pci_free_ce(struct ath10k *ar) -++static void ath10k_pci_free_pipes(struct ath10k *ar) -+ { -+ int i; -+ -+@@ -1738,305 +1723,319 @@ static void ath10k_pci_free_ce(struct at -+ ath10k_ce_free_pipe(ar, i); -+ } -+ -+-static int ath10k_pci_ce_init(struct ath10k *ar) -++static int ath10k_pci_init_pipes(struct ath10k *ar) -+ { -+- struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); -+- struct ath10k_pci_pipe *pipe_info; -+- const struct ce_attr *attr; -+- int pipe_num, ret; -+- -+- for (pipe_num = 0; pipe_num < CE_COUNT; pipe_num++) { -+- pipe_info = &ar_pci->pipe_info[pipe_num]; -+- pipe_info->ce_hdl = &ar_pci->ce_states[pipe_num]; -+- pipe_info->pipe_num = pipe_num; -+- pipe_info->hif_ce_state = ar; -+- attr = &host_ce_config_wlan[pipe_num]; -++ int i, ret; -+ -+- ret = ath10k_ce_init_pipe(ar, pipe_num, attr); -++ for (i = 0; i < CE_COUNT; i++) { -++ ret = ath10k_ce_init_pipe(ar, i, &host_ce_config_wlan[i]); -+ if (ret) { -+- ath10k_err("failed to initialize copy engine pipe %d: %d\n", -+- pipe_num, ret); -++ ath10k_err(ar, "failed to initialize copy engine pipe %d: %d\n", -++ i, ret); -+ return ret; -+ } -+- -+- if (pipe_num == CE_COUNT - 1) { -+- /* -+- * Reserve the ultimate CE for -+- * diagnostic Window support -+- */ -+- ar_pci->ce_diag = pipe_info->ce_hdl; -+- continue; -+- } -+- -+- pipe_info->buf_sz = (size_t) (attr->src_sz_max); -+ } -+ -+ return 0; -+ } -+ -+-static void ath10k_pci_fw_interrupt_handler(struct ath10k *ar) -++static bool ath10k_pci_has_fw_crashed(struct ath10k *ar) -+ { -+- struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); -+- u32 fw_indicator; -+- -+- ath10k_pci_wake(ar); -+- -+- fw_indicator = ath10k_pci_read32(ar, FW_INDICATOR_ADDRESS); -+- -+- if (fw_indicator & FW_IND_EVENT_PENDING) { -+- /* ACK: clear Target-side pending event */ -+- ath10k_pci_write32(ar, FW_INDICATOR_ADDRESS, -+- fw_indicator & ~FW_IND_EVENT_PENDING); -+- -+- if (ar_pci->started) { -+- ath10k_pci_hif_dump_area(ar); -+- } else { -+- /* -+- * Probable Target failure before we're prepared -+- * to handle it. Generally unexpected. -+- */ -+- ath10k_warn("early firmware event indicated\n"); -+- } -+- } -+- -+- ath10k_pci_sleep(ar); -++ return ath10k_pci_read32(ar, FW_INDICATOR_ADDRESS) & -++ FW_IND_EVENT_PENDING; -+ } -+ -+-static int ath10k_pci_warm_reset(struct ath10k *ar) -++static void ath10k_pci_fw_crashed_clear(struct ath10k *ar) -+ { -+- int ret = 0; -+ u32 val; -+ -+- ath10k_dbg(ATH10K_DBG_BOOT, "boot warm reset\n"); -++ val = ath10k_pci_read32(ar, FW_INDICATOR_ADDRESS); -++ val &= ~FW_IND_EVENT_PENDING; -++ ath10k_pci_write32(ar, FW_INDICATOR_ADDRESS, val); -++} -+ -+- ret = ath10k_do_pci_wake(ar); -+- if (ret) { -+- ath10k_err("failed to wake up target: %d\n", ret); -+- return ret; -+- } -++/* this function effectively clears target memory controller assert line */ -++static void ath10k_pci_warm_reset_si0(struct ath10k *ar) -++{ -++ u32 val; -+ -+- /* debug */ -+- val = ath10k_pci_read32(ar, SOC_CORE_BASE_ADDRESS + -+- PCIE_INTR_CAUSE_ADDRESS); -+- ath10k_dbg(ATH10K_DBG_BOOT, "boot host cpu intr cause: 0x%08x\n", val); -++ val = ath10k_pci_soc_read32(ar, SOC_RESET_CONTROL_ADDRESS); -++ ath10k_pci_soc_write32(ar, SOC_RESET_CONTROL_ADDRESS, -++ val | SOC_RESET_CONTROL_SI0_RST_MASK); -++ val = ath10k_pci_soc_read32(ar, SOC_RESET_CONTROL_ADDRESS); -+ -+- val = ath10k_pci_read32(ar, SOC_CORE_BASE_ADDRESS + -+- CPU_INTR_ADDRESS); -+- ath10k_dbg(ATH10K_DBG_BOOT, "boot target cpu intr cause: 0x%08x\n", -+- val); -++ msleep(10); -+ -+- /* disable pending irqs */ -+- ath10k_pci_write32(ar, SOC_CORE_BASE_ADDRESS + -+- PCIE_INTR_ENABLE_ADDRESS, 0); -++ val = ath10k_pci_soc_read32(ar, SOC_RESET_CONTROL_ADDRESS); -++ ath10k_pci_soc_write32(ar, SOC_RESET_CONTROL_ADDRESS, -++ val & ~SOC_RESET_CONTROL_SI0_RST_MASK); -++ val = ath10k_pci_soc_read32(ar, SOC_RESET_CONTROL_ADDRESS); -+ -+- ath10k_pci_write32(ar, SOC_CORE_BASE_ADDRESS + -+- PCIE_INTR_CLR_ADDRESS, ~0); -++ msleep(10); -++} -+ -+- msleep(100); -++static void ath10k_pci_warm_reset_cpu(struct ath10k *ar) -++{ -++ u32 val; -+ -+- /* clear fw indicator */ -+ ath10k_pci_write32(ar, FW_INDICATOR_ADDRESS, 0); -+ -+- /* clear target LF timer interrupts */ -+ val = ath10k_pci_read32(ar, RTC_SOC_BASE_ADDRESS + -+- SOC_LF_TIMER_CONTROL0_ADDRESS); -+- ath10k_pci_write32(ar, RTC_SOC_BASE_ADDRESS + -+- SOC_LF_TIMER_CONTROL0_ADDRESS, -+- val & ~SOC_LF_TIMER_CONTROL0_ENABLE_MASK); -++ SOC_RESET_CONTROL_ADDRESS); -++ ath10k_pci_write32(ar, RTC_SOC_BASE_ADDRESS + SOC_RESET_CONTROL_ADDRESS, -++ val | SOC_RESET_CONTROL_CPU_WARM_RST_MASK); -++} -++ -++static void ath10k_pci_warm_reset_ce(struct ath10k *ar) -++{ -++ u32 val; -+ -+- /* reset CE */ -+ val = ath10k_pci_read32(ar, RTC_SOC_BASE_ADDRESS + -+ SOC_RESET_CONTROL_ADDRESS); -++ -+ ath10k_pci_write32(ar, RTC_SOC_BASE_ADDRESS + SOC_RESET_CONTROL_ADDRESS, -+ val | SOC_RESET_CONTROL_CE_RST_MASK); -+- val = ath10k_pci_read32(ar, RTC_SOC_BASE_ADDRESS + -+- SOC_RESET_CONTROL_ADDRESS); -+ msleep(10); -+- -+- /* unreset CE */ -+ ath10k_pci_write32(ar, RTC_SOC_BASE_ADDRESS + SOC_RESET_CONTROL_ADDRESS, -+ val & ~SOC_RESET_CONTROL_CE_RST_MASK); -+- val = ath10k_pci_read32(ar, RTC_SOC_BASE_ADDRESS + -+- SOC_RESET_CONTROL_ADDRESS); -+- msleep(10); -++} -+ -+- /* debug */ -+- val = ath10k_pci_read32(ar, SOC_CORE_BASE_ADDRESS + -+- PCIE_INTR_CAUSE_ADDRESS); -+- ath10k_dbg(ATH10K_DBG_BOOT, "boot host cpu intr cause: 0x%08x\n", val); -+- -+- val = ath10k_pci_read32(ar, SOC_CORE_BASE_ADDRESS + -+- CPU_INTR_ADDRESS); -+- ath10k_dbg(ATH10K_DBG_BOOT, "boot target cpu intr cause: 0x%08x\n", -+- val); -++static void ath10k_pci_warm_reset_clear_lf(struct ath10k *ar) -++{ -++ u32 val; -+ -+- /* CPU warm reset */ -+ val = ath10k_pci_read32(ar, RTC_SOC_BASE_ADDRESS + -+- SOC_RESET_CONTROL_ADDRESS); -+- ath10k_pci_write32(ar, RTC_SOC_BASE_ADDRESS + SOC_RESET_CONTROL_ADDRESS, -+- val | SOC_RESET_CONTROL_CPU_WARM_RST_MASK); -++ SOC_LF_TIMER_CONTROL0_ADDRESS); -++ ath10k_pci_write32(ar, RTC_SOC_BASE_ADDRESS + -++ SOC_LF_TIMER_CONTROL0_ADDRESS, -++ val & ~SOC_LF_TIMER_CONTROL0_ENABLE_MASK); -++} -+ -+- val = ath10k_pci_read32(ar, RTC_SOC_BASE_ADDRESS + -+- SOC_RESET_CONTROL_ADDRESS); -+- ath10k_dbg(ATH10K_DBG_BOOT, "boot target reset state: 0x%08x\n", val); -++static int ath10k_pci_warm_reset(struct ath10k *ar) -++{ -++ int ret; -+ -+- msleep(100); -++ ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot warm reset\n"); -+ -+- ath10k_dbg(ATH10K_DBG_BOOT, "boot warm reset complete\n"); -++ spin_lock_bh(&ar->data_lock); -++ ar->stats.fw_warm_reset_counter++; -++ spin_unlock_bh(&ar->data_lock); -++ -++ ath10k_pci_irq_disable(ar); -++ -++ /* Make sure the target CPU is not doing anything dangerous, e.g. if it -++ * were to access copy engine while host performs copy engine reset -++ * then it is possible for the device to confuse pci-e controller to -++ * the point of bringing host system to a complete stop (i.e. hang). -++ */ -++ ath10k_pci_warm_reset_si0(ar); -++ ath10k_pci_warm_reset_cpu(ar); -++ ath10k_pci_init_pipes(ar); -++ ath10k_pci_wait_for_target_init(ar); -++ -++ ath10k_pci_warm_reset_clear_lf(ar); -++ ath10k_pci_warm_reset_ce(ar); -++ ath10k_pci_warm_reset_cpu(ar); -++ ath10k_pci_init_pipes(ar); -+ -+- ath10k_do_pci_sleep(ar); -+- return ret; -++ ret = ath10k_pci_wait_for_target_init(ar); -++ if (ret) { -++ ath10k_warn(ar, "failed to wait for target init: %d\n", ret); -++ return ret; -++ } -++ -++ ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot warm reset complete\n"); -++ -++ return 0; -+ } -+ -+-static int __ath10k_pci_hif_power_up(struct ath10k *ar, bool cold_reset) -++static int ath10k_pci_qca988x_chip_reset(struct ath10k *ar) -+ { -+- struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); -+- const char *irq_mode; -+- int ret; -++ int i, ret; -++ u32 val; -+ -+- /* -+- * Bring the target up cleanly. -++ ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot 988x chip reset\n"); -++ -++ /* Some hardware revisions (e.g. CUS223v2) has issues with cold reset. -++ * It is thus preferred to use warm reset which is safer but may not be -++ * able to recover the device from all possible fail scenarios. -+ * -+- * The target may be in an undefined state with an AUX-powered Target -+- * and a Host in WoW mode. If the Host crashes, loses power, or is -+- * restarted (without unloading the driver) then the Target is left -+- * (aux) powered and running. On a subsequent driver load, the Target -+- * is in an unexpected state. We try to catch that here in order to -+- * reset the Target and retry the probe. -++ * Warm reset doesn't always work on first try so attempt it a few -++ * times before giving up. -+ */ -+- if (cold_reset) -+- ret = ath10k_pci_cold_reset(ar); -+- else -++ for (i = 0; i < ATH10K_PCI_NUM_WARM_RESET_ATTEMPTS; i++) { -+ ret = ath10k_pci_warm_reset(ar); -++ if (ret) { -++ ath10k_warn(ar, "failed to warm reset attempt %d of %d: %d\n", -++ i + 1, ATH10K_PCI_NUM_WARM_RESET_ATTEMPTS, -++ ret); -++ continue; -++ } -++ -++ /* FIXME: Sometimes copy engine doesn't recover after warm -++ * reset. In most cases this needs cold reset. In some of these -++ * cases the device is in such a state that a cold reset may -++ * lock up the host. -++ * -++ * Reading any host interest register via copy engine is -++ * sufficient to verify if device is capable of booting -++ * firmware blob. -++ */ -++ ret = ath10k_pci_init_pipes(ar); -++ if (ret) { -++ ath10k_warn(ar, "failed to init copy engine: %d\n", -++ ret); -++ continue; -++ } -++ -++ ret = ath10k_pci_diag_read32(ar, QCA988X_HOST_INTEREST_ADDRESS, -++ &val); -++ if (ret) { -++ ath10k_warn(ar, "failed to poke copy engine: %d\n", -++ ret); -++ continue; -++ } -++ -++ ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot chip reset complete (warm)\n"); -++ return 0; -++ } -+ -++ if (ath10k_pci_reset_mode == ATH10K_PCI_RESET_WARM_ONLY) { -++ ath10k_warn(ar, "refusing cold reset as requested\n"); -++ return -EPERM; -++ } -++ -++ ret = ath10k_pci_cold_reset(ar); -+ if (ret) { -+- ath10k_err("failed to reset target: %d\n", ret); -+- goto err; -++ ath10k_warn(ar, "failed to cold reset: %d\n", ret); -++ return ret; -++ } -++ -++ ret = ath10k_pci_wait_for_target_init(ar); -++ if (ret) { -++ ath10k_warn(ar, "failed to wait for target after cold reset: %d\n", -++ ret); -++ return ret; -+ } -+ -+- if (!test_bit(ATH10K_PCI_FEATURE_SOC_POWER_SAVE, ar_pci->features)) -+- /* Force AWAKE forever */ -+- ath10k_do_pci_wake(ar); -++ ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot qca988x chip reset complete (cold)\n"); -+ -+- ret = ath10k_pci_ce_init(ar); -++ return 0; -++} -++ -++static int ath10k_pci_qca6174_chip_reset(struct ath10k *ar) -++{ -++ int ret; -++ -++ ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot qca6174 chip reset\n"); -++ -++ /* FIXME: QCA6174 requires cold + warm reset to work. */ -++ -++ ret = ath10k_pci_cold_reset(ar); -+ if (ret) { -+- ath10k_err("failed to initialize CE: %d\n", ret); -+- goto err_ps; -++ ath10k_warn(ar, "failed to cold reset: %d\n", ret); -++ return ret; -+ } -+ -+- ret = ath10k_ce_disable_interrupts(ar); -++ ret = ath10k_pci_wait_for_target_init(ar); -+ if (ret) { -+- ath10k_err("failed to disable CE interrupts: %d\n", ret); -+- goto err_ce; -++ ath10k_warn(ar, "failed to wait for target after cold reset: %d\n", -++ ret); -++ return ret; -+ } -+ -+- ret = ath10k_pci_init_irq(ar); -++ ret = ath10k_pci_warm_reset(ar); -++ if (ret) { -++ ath10k_warn(ar, "failed to warm reset: %d\n", ret); -++ return ret; -++ } -++ -++ ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot qca6174 chip reset complete (cold)\n"); -++ -++ return 0; -++} -++ -++static int ath10k_pci_chip_reset(struct ath10k *ar) -++{ -++ if (QCA_REV_988X(ar)) -++ return ath10k_pci_qca988x_chip_reset(ar); -++ else if (QCA_REV_6174(ar)) -++ return ath10k_pci_qca6174_chip_reset(ar); -++ else -++ return -ENOTSUPP; -++} -++ -++static int ath10k_pci_hif_power_up(struct ath10k *ar) -++{ -++ int ret; -++ -++ ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot hif power up\n"); -++ -++ ret = ath10k_pci_wake(ar); -++ if (ret) { -++ ath10k_err(ar, "failed to wake up target: %d\n", ret); -++ return ret; -++ } -++ -++ /* -++ * Bring the target up cleanly. -++ * -++ * The target may be in an undefined state with an AUX-powered Target -++ * and a Host in WoW mode. If the Host crashes, loses power, or is -++ * restarted (without unloading the driver) then the Target is left -++ * (aux) powered and running. On a subsequent driver load, the Target -++ * is in an unexpected state. We try to catch that here in order to -++ * reset the Target and retry the probe. -++ */ -++ ret = ath10k_pci_chip_reset(ar); -+ if (ret) { -+- ath10k_err("failed to init irqs: %d\n", ret); -+- goto err_ce; -+- } -++ if (ath10k_pci_has_fw_crashed(ar)) { -++ ath10k_warn(ar, "firmware crashed during chip reset\n"); -++ ath10k_pci_fw_crashed_clear(ar); -++ ath10k_pci_fw_crashed_dump(ar); -++ } -+ -+- ret = ath10k_pci_request_early_irq(ar); -+- if (ret) { -+- ath10k_err("failed to request early irq: %d\n", ret); -+- goto err_deinit_irq; -++ ath10k_err(ar, "failed to reset chip: %d\n", ret); -++ goto err_sleep; -+ } -+ -+- ret = ath10k_pci_wait_for_target_init(ar); -++ ret = ath10k_pci_init_pipes(ar); -+ if (ret) { -+- ath10k_err("failed to wait for target to init: %d\n", ret); -+- goto err_free_early_irq; -++ ath10k_err(ar, "failed to initialize CE: %d\n", ret); -++ goto err_sleep; -+ } -+ -+ ret = ath10k_pci_init_config(ar); -+ if (ret) { -+- ath10k_err("failed to setup init config: %d\n", ret); -+- goto err_free_early_irq; -++ ath10k_err(ar, "failed to setup init config: %d\n", ret); -++ goto err_ce; -+ } -+ -+ ret = ath10k_pci_wake_target_cpu(ar); -+ if (ret) { -+- ath10k_err("could not wake up target CPU: %d\n", ret); -+- goto err_free_early_irq; -++ ath10k_err(ar, "could not wake up target CPU: %d\n", ret); -++ goto err_ce; -+ } -+ -+- if (ar_pci->num_msi_intrs > 1) -+- irq_mode = "MSI-X"; -+- else if (ar_pci->num_msi_intrs == 1) -+- irq_mode = "MSI"; -+- else -+- irq_mode = "legacy"; -+- -+- if (!test_bit(ATH10K_FLAG_FIRST_BOOT_DONE, &ar->dev_flags)) -+- ath10k_info("pci irq %s irq_mode %d reset_mode %d\n", -+- irq_mode, ath10k_pci_irq_mode, -+- ath10k_pci_reset_mode); -+- -+ return 0; -+ -+-err_free_early_irq: -+- ath10k_pci_free_early_irq(ar); -+-err_deinit_irq: -+- ath10k_pci_deinit_irq(ar); -+ err_ce: -+ ath10k_pci_ce_deinit(ar); -+- ath10k_pci_warm_reset(ar); -+-err_ps: -+- if (!test_bit(ATH10K_PCI_FEATURE_SOC_POWER_SAVE, ar_pci->features)) -+- ath10k_do_pci_sleep(ar); -+-err: -+- return ret; -+-} -+- -+-static int ath10k_pci_hif_power_up(struct ath10k *ar) -+-{ -+- int ret; -+- -+- ath10k_dbg(ATH10K_DBG_BOOT, "boot hif power up\n"); -+- -+- /* -+- * Hardware CUS232 version 2 has some issues with cold reset and the -+- * preferred (and safer) way to perform a device reset is through a -+- * warm reset. -+- * -+- * Warm reset doesn't always work though (notably after a firmware -+- * crash) so fall back to cold reset if necessary. -+- */ -+- ret = __ath10k_pci_hif_power_up(ar, false); -+- if (ret) { -+- ath10k_warn("failed to power up target using warm reset: %d\n", -+- ret); -+- -+- if (ath10k_pci_reset_mode == ATH10K_PCI_RESET_WARM_ONLY) -+- return ret; -+ -+- ath10k_warn("trying cold reset\n"); -+- -+- ret = __ath10k_pci_hif_power_up(ar, true); -+- if (ret) { -+- ath10k_err("failed to power up target using cold reset too (%d)\n", -+- ret); -+- return ret; -+- } -+- } -+- -+- return 0; -++err_sleep: -++ ath10k_pci_sleep(ar); -++ return ret; -+ } -+ -+ static void ath10k_pci_hif_power_down(struct ath10k *ar) -+ { -+- struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); -++ ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot hif power down\n"); -+ -+- ath10k_dbg(ATH10K_DBG_BOOT, "boot hif power down\n"); -+- -+- ath10k_pci_free_early_irq(ar); -+- ath10k_pci_kill_tasklet(ar); -+- ath10k_pci_deinit_irq(ar); -+- ath10k_pci_ce_deinit(ar); -+- ath10k_pci_warm_reset(ar); -++ /* Currently hif_power_up performs effectively a reset and hif_stop -++ * resets the chip as well so there's no point in resetting here. -++ */ -+ -+- if (!test_bit(ATH10K_PCI_FEATURE_SOC_POWER_SAVE, ar_pci->features)) -+- ath10k_do_pci_sleep(ar); -++ ath10k_pci_sleep(ar); -+ } -+ -+ #ifdef CONFIG_PM -+@@ -2090,6 +2089,8 @@ static int ath10k_pci_hif_resume(struct -+ -+ static const struct ath10k_hif_ops ath10k_pci_hif_ops = { -+ .tx_sg = ath10k_pci_hif_tx_sg, -++ .diag_read = ath10k_pci_hif_diag_read, -++ .diag_write = ath10k_pci_diag_write_mem, -+ .exchange_bmi_msg = ath10k_pci_hif_exchange_bmi_msg, -+ .start = ath10k_pci_hif_start, -+ .stop = ath10k_pci_hif_stop, -+@@ -2100,6 +2101,8 @@ static const struct ath10k_hif_ops ath10 -+ .get_free_queue_number = ath10k_pci_hif_get_free_queue_number, -+ .power_up = ath10k_pci_hif_power_up, -+ .power_down = ath10k_pci_hif_power_down, -++ .read32 = ath10k_pci_read32, -++ .write32 = ath10k_pci_write32, -+ #ifdef CONFIG_PM -+ .suspend = ath10k_pci_hif_suspend, -+ .resume = ath10k_pci_hif_resume, -+@@ -2118,7 +2121,14 @@ static void ath10k_msi_err_tasklet(unsig -+ { -+ struct ath10k *ar = (struct ath10k *)data; -+ -+- ath10k_pci_fw_interrupt_handler(ar); -++ if (!ath10k_pci_has_fw_crashed(ar)) { -++ ath10k_warn(ar, "received unsolicited fw crash interrupt\n"); -++ return; -++ } -++ -++ ath10k_pci_irq_disable(ar); -++ ath10k_pci_fw_crashed_clear(ar); -++ ath10k_pci_fw_crashed_dump(ar); -+ } -+ -+ /* -+@@ -2132,7 +2142,8 @@ static irqreturn_t ath10k_pci_per_engine -+ int ce_id = irq - ar_pci->pdev->irq - MSI_ASSIGN_CE_INITIAL; -+ -+ if (ce_id < 0 || ce_id >= ARRAY_SIZE(ar_pci->pipe_info)) { -+- ath10k_warn("unexpected/invalid irq %d ce_id %d\n", irq, ce_id); -++ ath10k_warn(ar, "unexpected/invalid irq %d ce_id %d\n", irq, -++ ce_id); -+ return IRQ_HANDLED; -+ } -+ -+@@ -2179,39 +2190,18 @@ static irqreturn_t ath10k_pci_interrupt_ -+ return IRQ_HANDLED; -+ } -+ -+-static void ath10k_pci_early_irq_tasklet(unsigned long data) -++static void ath10k_pci_tasklet(unsigned long data) -+ { -+ struct ath10k *ar = (struct ath10k *)data; -+- u32 fw_ind; -+- int ret; -++ struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); -+ -+- ret = ath10k_pci_wake(ar); -+- if (ret) { -+- ath10k_warn("failed to wake target in early irq tasklet: %d\n", -+- ret); -++ if (ath10k_pci_has_fw_crashed(ar)) { -++ ath10k_pci_irq_disable(ar); -++ ath10k_pci_fw_crashed_clear(ar); -++ ath10k_pci_fw_crashed_dump(ar); -+ return; -+ } -+ -+- fw_ind = ath10k_pci_read32(ar, FW_INDICATOR_ADDRESS); -+- if (fw_ind & FW_IND_EVENT_PENDING) { -+- ath10k_pci_write32(ar, FW_INDICATOR_ADDRESS, -+- fw_ind & ~FW_IND_EVENT_PENDING); -+- -+- /* Some structures are unavailable during early boot or at -+- * driver teardown so just print that the device has crashed. */ -+- ath10k_warn("device crashed - no diagnostics available\n"); -+- } -+- -+- ath10k_pci_sleep(ar); -+- ath10k_pci_enable_legacy_irq(ar); -+-} -+- -+-static void ath10k_pci_tasklet(unsigned long data) -+-{ -+- struct ath10k *ar = (struct ath10k *)data; -+- struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); -+- -+- ath10k_pci_fw_interrupt_handler(ar); /* FIXME: Handle FW error */ -+ ath10k_ce_per_engine_service_any(ar); -+ -+ /* Re-enable legacy irq that was disabled in the irq handler */ -+@@ -2228,7 +2218,7 @@ static int ath10k_pci_request_irq_msix(s -+ ath10k_pci_msi_fw_handler, -+ IRQF_SHARED, "ath10k_pci", ar); -+ if (ret) { -+- ath10k_warn("failed to request MSI-X fw irq %d: %d\n", -++ ath10k_warn(ar, "failed to request MSI-X fw irq %d: %d\n", -+ ar_pci->pdev->irq + MSI_ASSIGN_FW, ret); -+ return ret; -+ } -+@@ -2238,7 +2228,7 @@ static int ath10k_pci_request_irq_msix(s -+ ath10k_pci_per_engine_handler, -+ IRQF_SHARED, "ath10k_pci", ar); -+ if (ret) { -+- ath10k_warn("failed to request MSI-X ce irq %d: %d\n", -++ ath10k_warn(ar, "failed to request MSI-X ce irq %d: %d\n", -+ ar_pci->pdev->irq + i, ret); -+ -+ for (i--; i >= MSI_ASSIGN_CE_INITIAL; i--) -+@@ -2261,7 +2251,7 @@ static int ath10k_pci_request_irq_msi(st -+ ath10k_pci_interrupt_handler, -+ IRQF_SHARED, "ath10k_pci", ar); -+ if (ret) { -+- ath10k_warn("failed to request MSI irq %d: %d\n", -++ ath10k_warn(ar, "failed to request MSI irq %d: %d\n", -+ ar_pci->pdev->irq, ret); -+ return ret; -+ } -+@@ -2278,7 +2268,7 @@ static int ath10k_pci_request_irq_legacy -+ ath10k_pci_interrupt_handler, -+ IRQF_SHARED, "ath10k_pci", ar); -+ if (ret) { -+- ath10k_warn("failed to request legacy irq %d: %d\n", -++ ath10k_warn(ar, "failed to request legacy irq %d: %d\n", -+ ar_pci->pdev->irq, ret); -+ return ret; -+ } -+@@ -2299,7 +2289,7 @@ static int ath10k_pci_request_irq(struct -+ return ath10k_pci_request_irq_msix(ar); -+ } -+ -+- ath10k_warn("unknown irq configuration upon request\n"); -++ ath10k_warn(ar, "unknown irq configuration upon request\n"); -+ return -EINVAL; -+ } -+ -+@@ -2322,8 +2312,6 @@ static void ath10k_pci_init_irq_tasklets -+ tasklet_init(&ar_pci->intr_tq, ath10k_pci_tasklet, (unsigned long)ar); -+ tasklet_init(&ar_pci->msi_fw_err, ath10k_msi_err_tasklet, -+ (unsigned long)ar); -+- tasklet_init(&ar_pci->early_irq_tasklet, ath10k_pci_early_irq_tasklet, -+- (unsigned long)ar); -+ -+ for (i = 0; i < CE_COUNT; i++) { -+ ar_pci->pipe_info[i].ar_pci = ar_pci; -+@@ -2335,21 +2323,19 @@ static void ath10k_pci_init_irq_tasklets -+ static int ath10k_pci_init_irq(struct ath10k *ar) -+ { -+ struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); -+- bool msix_supported = test_bit(ATH10K_PCI_FEATURE_MSI_X, -+- ar_pci->features); -+ int ret; -+ -+ ath10k_pci_init_irq_tasklets(ar); -+ -+- if (ath10k_pci_irq_mode != ATH10K_PCI_IRQ_AUTO && -+- !test_bit(ATH10K_FLAG_FIRST_BOOT_DONE, &ar->dev_flags)) -+- ath10k_info("limiting irq mode to: %d\n", ath10k_pci_irq_mode); -++ if (ath10k_pci_irq_mode != ATH10K_PCI_IRQ_AUTO) -++ ath10k_info(ar, "limiting irq mode to: %d\n", -++ ath10k_pci_irq_mode); -+ -+ /* Try MSI-X */ -+- if (ath10k_pci_irq_mode == ATH10K_PCI_IRQ_AUTO && msix_supported) { -++ if (ath10k_pci_irq_mode == ATH10K_PCI_IRQ_AUTO) { -+ ar_pci->num_msi_intrs = MSI_NUM_REQUEST; -+ ret = pci_enable_msi_range(ar_pci->pdev, ar_pci->num_msi_intrs, -+- ar_pci->num_msi_intrs); -++ ar_pci->num_msi_intrs); -+ if (ret > 0) -+ return 0; -+ -+@@ -2376,34 +2362,16 @@ static int ath10k_pci_init_irq(struct at -+ * synchronization checking. */ -+ ar_pci->num_msi_intrs = 0; -+ -+- ret = ath10k_pci_wake(ar); -+- if (ret) { -+- ath10k_warn("failed to wake target: %d\n", ret); -+- return ret; -+- } -+- -+ ath10k_pci_write32(ar, SOC_CORE_BASE_ADDRESS + PCIE_INTR_ENABLE_ADDRESS, -+ PCIE_INTR_FIRMWARE_MASK | PCIE_INTR_CE_MASK_ALL); -+- ath10k_pci_sleep(ar); -+ -+ return 0; -+ } -+ -+-static int ath10k_pci_deinit_irq_legacy(struct ath10k *ar) -++static void ath10k_pci_deinit_irq_legacy(struct ath10k *ar) -+ { -+- int ret; -+- -+- ret = ath10k_pci_wake(ar); -+- if (ret) { -+- ath10k_warn("failed to wake target: %d\n", ret); -+- return ret; -+- } -+- -+ ath10k_pci_write32(ar, SOC_CORE_BASE_ADDRESS + PCIE_INTR_ENABLE_ADDRESS, -+ 0); -+- ath10k_pci_sleep(ar); -+- -+- return 0; -+ } -+ -+ static int ath10k_pci_deinit_irq(struct ath10k *ar) -+@@ -2412,7 +2380,8 @@ static int ath10k_pci_deinit_irq(struct -+ -+ switch (ar_pci->num_msi_intrs) { -+ case 0: -+- return ath10k_pci_deinit_irq_legacy(ar); -++ ath10k_pci_deinit_irq_legacy(ar); -++ return 0; -+ case 1: -+ /* fall-through */ -+ case MSI_NUM_REQUEST: -+@@ -2422,7 +2391,7 @@ static int ath10k_pci_deinit_irq(struct -+ pci_disable_msi(ar_pci->pdev); -+ } -+ -+- ath10k_warn("unknown irq configuration upon deinit\n"); -++ ath10k_warn(ar, "unknown irq configuration upon deinit\n"); -+ return -EINVAL; -+ } -+ -+@@ -2430,23 +2399,17 @@ static int ath10k_pci_wait_for_target_in -+ { -+ struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); -+ unsigned long timeout; -+- int ret; -+ u32 val; -+ -+- ath10k_dbg(ATH10K_DBG_BOOT, "boot waiting target to initialise\n"); -+- -+- ret = ath10k_pci_wake(ar); -+- if (ret) { -+- ath10k_err("failed to wake up target for init: %d\n", ret); -+- return ret; -+- } -++ ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot waiting target to initialise\n"); -+ -+ timeout = jiffies + msecs_to_jiffies(ATH10K_PCI_TARGET_WAIT); -+ -+ do { -+ val = ath10k_pci_read32(ar, FW_INDICATOR_ADDRESS); -+ -+- ath10k_dbg(ATH10K_DBG_BOOT, "boot target indicator %x\n", val); -++ ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot target indicator %x\n", -++ val); -+ -+ /* target should never return this */ -+ if (val == 0xffffffff) -+@@ -2461,52 +2424,46 @@ static int ath10k_pci_wait_for_target_in -+ -+ if (ar_pci->num_msi_intrs == 0) -+ /* Fix potential race by repeating CORE_BASE writes */ -+- ath10k_pci_soc_write32(ar, PCIE_INTR_ENABLE_ADDRESS, -+- PCIE_INTR_FIRMWARE_MASK | -+- PCIE_INTR_CE_MASK_ALL); -++ ath10k_pci_enable_legacy_irq(ar); -+ -+ mdelay(10); -+ } while (time_before(jiffies, timeout)); -+ -++ ath10k_pci_disable_and_clear_legacy_irq(ar); -++ ath10k_pci_irq_msi_fw_mask(ar); -++ -+ if (val == 0xffffffff) { -+- ath10k_err("failed to read device register, device is gone\n"); -+- ret = -EIO; -+- goto out; -++ ath10k_err(ar, "failed to read device register, device is gone\n"); -++ return -EIO; -+ } -+ -+ if (val & FW_IND_EVENT_PENDING) { -+- ath10k_warn("device has crashed during init\n"); -+- ret = -ECOMM; -+- goto out; -++ ath10k_warn(ar, "device has crashed during init\n"); -++ return -ECOMM; -+ } -+ -+ if (!(val & FW_IND_INITIALIZED)) { -+- ath10k_err("failed to receive initialized event from target: %08x\n", -++ ath10k_err(ar, "failed to receive initialized event from target: %08x\n", -+ val); -+- ret = -ETIMEDOUT; -+- goto out; -++ return -ETIMEDOUT; -+ } -+ -+- ath10k_dbg(ATH10K_DBG_BOOT, "boot target initialised\n"); -+- -+-out: -+- ath10k_pci_sleep(ar); -+- return ret; -++ ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot target initialised\n"); -++ return 0; -+ } -+ -+ static int ath10k_pci_cold_reset(struct ath10k *ar) -+ { -+- int i, ret; -++ int i; -+ u32 val; -+ -+- ath10k_dbg(ATH10K_DBG_BOOT, "boot cold reset\n"); -++ ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot cold reset\n"); -+ -+- ret = ath10k_do_pci_wake(ar); -+- if (ret) { -+- ath10k_err("failed to wake up target: %d\n", -+- ret); -+- return ret; -+- } -++ spin_lock_bh(&ar->data_lock); -++ -++ ar->stats.fw_cold_reset_counter++; -++ -++ spin_unlock_bh(&ar->data_lock); -+ -+ /* Put Target, including PCIe, into RESET. */ -+ val = ath10k_pci_reg_read32(ar, SOC_GLOBAL_RESET_ADDRESS); -+@@ -2531,181 +2488,227 @@ static int ath10k_pci_cold_reset(struct -+ msleep(1); -+ } -+ -+- ath10k_do_pci_sleep(ar); -++ ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot cold reset complete\n"); -++ -++ return 0; -++} -++ -++static int ath10k_pci_claim(struct ath10k *ar) -++{ -++ struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); -++ struct pci_dev *pdev = ar_pci->pdev; -++ u32 lcr_val; -++ int ret; -++ -++ pci_set_drvdata(pdev, ar); -++ -++ ret = pci_enable_device(pdev); -++ if (ret) { -++ ath10k_err(ar, "failed to enable pci device: %d\n", ret); -++ return ret; -++ } -++ -++ ret = pci_request_region(pdev, BAR_NUM, "ath"); -++ if (ret) { -++ ath10k_err(ar, "failed to request region BAR%d: %d\n", BAR_NUM, -++ ret); -++ goto err_device; -++ } -++ -++ /* Target expects 32 bit DMA. Enforce it. */ -++ ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)); -++ if (ret) { -++ ath10k_err(ar, "failed to set dma mask to 32-bit: %d\n", ret); -++ goto err_region; -++ } -++ -++ ret = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32)); -++ if (ret) { -++ ath10k_err(ar, "failed to set consistent dma mask to 32-bit: %d\n", -++ ret); -++ goto err_region; -++ } -++ -++ pci_set_master(pdev); -++ -++ /* Workaround: Disable ASPM */ -++ pci_read_config_dword(pdev, 0x80, &lcr_val); -++ pci_write_config_dword(pdev, 0x80, (lcr_val & 0xffffff00)); -+ -+- ath10k_dbg(ATH10K_DBG_BOOT, "boot cold reset complete\n"); -++ /* Arrange for access to Target SoC registers. */ -++ ar_pci->mem = pci_iomap(pdev, BAR_NUM, 0); -++ if (!ar_pci->mem) { -++ ath10k_err(ar, "failed to iomap BAR%d\n", BAR_NUM); -++ ret = -EIO; -++ goto err_master; -++ } -+ -++ ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot pci_mem 0x%p\n", ar_pci->mem); -+ return 0; -++ -++err_master: -++ pci_clear_master(pdev); -++ -++err_region: -++ pci_release_region(pdev, BAR_NUM); -++ -++err_device: -++ pci_disable_device(pdev); -++ -++ return ret; -+ } -+ -+-static void ath10k_pci_dump_features(struct ath10k_pci *ar_pci) -++static void ath10k_pci_release(struct ath10k *ar) -+ { -++ struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); -++ struct pci_dev *pdev = ar_pci->pdev; -++ -++ pci_iounmap(pdev, ar_pci->mem); -++ pci_release_region(pdev, BAR_NUM); -++ pci_clear_master(pdev); -++ pci_disable_device(pdev); -++} -++ -++static bool ath10k_pci_chip_is_supported(u32 dev_id, u32 chip_id) -++{ -++ const struct ath10k_pci_supp_chip *supp_chip; -+ int i; -++ u32 rev_id = MS(chip_id, SOC_CHIP_ID_REV); -+ -+- for (i = 0; i < ATH10K_PCI_FEATURE_COUNT; i++) { -+- if (!test_bit(i, ar_pci->features)) -+- continue; -++ for (i = 0; i < ARRAY_SIZE(ath10k_pci_supp_chips); i++) { -++ supp_chip = &ath10k_pci_supp_chips[i]; -+ -+- switch (i) { -+- case ATH10K_PCI_FEATURE_MSI_X: -+- ath10k_dbg(ATH10K_DBG_BOOT, "device supports MSI-X\n"); -+- break; -+- case ATH10K_PCI_FEATURE_SOC_POWER_SAVE: -+- ath10k_dbg(ATH10K_DBG_BOOT, "QCA98XX SoC power save enabled\n"); -+- break; -+- } -++ if (supp_chip->dev_id == dev_id && -++ supp_chip->rev_id == rev_id) -++ return true; -+ } -++ -++ return false; -+ } -+ -+ static int ath10k_pci_probe(struct pci_dev *pdev, -+ const struct pci_device_id *pci_dev) -+ { -+- void __iomem *mem; -+ int ret = 0; -+ struct ath10k *ar; -+ struct ath10k_pci *ar_pci; -+- u32 lcr_val, chip_id; -+- -+- ath10k_dbg(ATH10K_DBG_PCI, "pci probe\n"); -+- -+- ar_pci = kzalloc(sizeof(*ar_pci), GFP_KERNEL); -+- if (ar_pci == NULL) -+- return -ENOMEM; -+- -+- ar_pci->pdev = pdev; -+- ar_pci->dev = &pdev->dev; -++ enum ath10k_hw_rev hw_rev; -++ u32 chip_id; -+ -+ switch (pci_dev->device) { -+ case QCA988X_2_0_DEVICE_ID: -+- set_bit(ATH10K_PCI_FEATURE_MSI_X, ar_pci->features); -++ hw_rev = ATH10K_HW_QCA988X; -++ break; -++ case QCA6174_2_1_DEVICE_ID: -++ hw_rev = ATH10K_HW_QCA6174; -+ break; -+ default: -+- ret = -ENODEV; -+- ath10k_err("Unknown device ID: %d\n", pci_dev->device); -+- goto err_ar_pci; -++ WARN_ON(1); -++ return -ENOTSUPP; -+ } -+ -+- if (ath10k_pci_target_ps) -+- set_bit(ATH10K_PCI_FEATURE_SOC_POWER_SAVE, ar_pci->features); -+- -+- ath10k_pci_dump_features(ar_pci); -+- -+- ar = ath10k_core_create(ar_pci, ar_pci->dev, &ath10k_pci_hif_ops); -++ ar = ath10k_core_create(sizeof(*ar_pci), &pdev->dev, ATH10K_BUS_PCI, -++ hw_rev, &ath10k_pci_hif_ops); -+ if (!ar) { -+- ath10k_err("failed to create driver core\n"); -+- ret = -EINVAL; -+- goto err_ar_pci; -++ dev_err(&pdev->dev, "failed to allocate core\n"); -++ return -ENOMEM; -+ } -+ -++ ath10k_dbg(ar, ATH10K_DBG_PCI, "pci probe\n"); -++ -++ ar_pci = ath10k_pci_priv(ar); -++ ar_pci->pdev = pdev; -++ ar_pci->dev = &pdev->dev; -+ ar_pci->ar = ar; -+- atomic_set(&ar_pci->keep_awake_count, 0); -+ -+- pci_set_drvdata(pdev, ar); -++ spin_lock_init(&ar_pci->ce_lock); -++ setup_timer(&ar_pci->rx_post_retry, ath10k_pci_rx_replenish_retry, -++ (unsigned long)ar); -+ -+- /* -+- * Without any knowledge of the Host, the Target may have been reset or -+- * power cycled and its Config Space may no longer reflect the PCI -+- * address space that was assigned earlier by the PCI infrastructure. -+- * Refresh it now. -+- */ -+- ret = pci_assign_resource(pdev, BAR_NUM); -++ ret = ath10k_pci_claim(ar); -+ if (ret) { -+- ath10k_err("failed to assign PCI space: %d\n", ret); -+- goto err_ar; -++ ath10k_err(ar, "failed to claim device: %d\n", ret); -++ goto err_core_destroy; -+ } -+ -+- ret = pci_enable_device(pdev); -++ ret = ath10k_pci_wake(ar); -+ if (ret) { -+- ath10k_err("failed to enable PCI device: %d\n", ret); -+- goto err_ar; -++ ath10k_err(ar, "failed to wake up: %d\n", ret); -++ goto err_release; -+ } -+ -+- /* Request MMIO resources */ -+- ret = pci_request_region(pdev, BAR_NUM, "ath"); -++ ret = ath10k_pci_alloc_pipes(ar); -+ if (ret) { -+- ath10k_err("failed to request MMIO region: %d\n", ret); -+- goto err_device; -++ ath10k_err(ar, "failed to allocate copy engine pipes: %d\n", -++ ret); -++ goto err_sleep; -+ } -+ -+- /* -+- * Target structures have a limit of 32 bit DMA pointers. -+- * DMA pointers can be wider than 32 bits by default on some systems. -+- */ -+- ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)); -+- if (ret) { -+- ath10k_err("failed to set DMA mask to 32-bit: %d\n", ret); -+- goto err_region; -+- } -++ ath10k_pci_ce_deinit(ar); -++ ath10k_pci_irq_disable(ar); -+ -+- ret = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32)); -++ ret = ath10k_pci_init_irq(ar); -+ if (ret) { -+- ath10k_err("failed to set consistent DMA mask to 32-bit\n"); -+- goto err_region; -++ ath10k_err(ar, "failed to init irqs: %d\n", ret); -++ goto err_free_pipes; -+ } -+ -+- /* Set bus master bit in PCI_COMMAND to enable DMA */ -+- pci_set_master(pdev); -+- -+- /* -+- * Temporary FIX: disable ASPM -+- * Will be removed after the OTP is programmed -+- */ -+- pci_read_config_dword(pdev, 0x80, &lcr_val); -+- pci_write_config_dword(pdev, 0x80, (lcr_val & 0xffffff00)); -++ ath10k_info(ar, "pci irq %s interrupts %d irq_mode %d reset_mode %d\n", -++ ath10k_pci_get_irq_method(ar), ar_pci->num_msi_intrs, -++ ath10k_pci_irq_mode, ath10k_pci_reset_mode); -+ -+- /* Arrange for access to Target SoC registers. */ -+- mem = pci_iomap(pdev, BAR_NUM, 0); -+- if (!mem) { -+- ath10k_err("failed to perform IOMAP for BAR%d\n", BAR_NUM); -+- ret = -EIO; -+- goto err_master; -++ ret = ath10k_pci_request_irq(ar); -++ if (ret) { -++ ath10k_warn(ar, "failed to request irqs: %d\n", ret); -++ goto err_deinit_irq; -+ } -+ -+- ar_pci->mem = mem; -+- -+- spin_lock_init(&ar_pci->ce_lock); -+- -+- ret = ath10k_do_pci_wake(ar); -++ ret = ath10k_pci_chip_reset(ar); -+ if (ret) { -+- ath10k_err("Failed to get chip id: %d\n", ret); -+- goto err_iomap; -++ ath10k_err(ar, "failed to reset chip: %d\n", ret); -++ goto err_free_irq; -+ } -+ -+ chip_id = ath10k_pci_soc_read32(ar, SOC_CHIP_ID_ADDRESS); -++ if (chip_id == 0xffffffff) { -++ ath10k_err(ar, "failed to get chip id\n"); -++ goto err_free_irq; -++ } -+ -+- ath10k_do_pci_sleep(ar); -+- -+- ret = ath10k_pci_alloc_ce(ar); -+- if (ret) { -+- ath10k_err("failed to allocate copy engine pipes: %d\n", ret); -+- goto err_iomap; -++ if (!ath10k_pci_chip_is_supported(pdev->device, chip_id)) { -++ ath10k_err(ar, "device %04x with chip_id %08x isn't supported\n", -++ pdev->device, chip_id); -++ goto err_sleep; -+ } -+ -+- ath10k_dbg(ATH10K_DBG_BOOT, "boot pci_mem 0x%p\n", ar_pci->mem); -++ ath10k_pci_sleep(ar); -+ -+ ret = ath10k_core_register(ar, chip_id); -+ if (ret) { -+- ath10k_err("failed to register driver core: %d\n", ret); -+- goto err_free_ce; -++ ath10k_err(ar, "failed to register driver core: %d\n", ret); -++ goto err_free_irq; -+ } -+ -+ return 0; -+ -+-err_free_ce: -+- ath10k_pci_free_ce(ar); -+-err_iomap: -+- pci_iounmap(pdev, mem); -+-err_master: -+- pci_clear_master(pdev); -+-err_region: -+- pci_release_region(pdev, BAR_NUM); -+-err_device: -+- pci_disable_device(pdev); -+-err_ar: -++err_free_irq: -++ ath10k_pci_free_irq(ar); -++ ath10k_pci_kill_tasklet(ar); -++ -++err_deinit_irq: -++ ath10k_pci_deinit_irq(ar); -++ -++err_free_pipes: -++ ath10k_pci_free_pipes(ar); -++ -++err_sleep: -++ ath10k_pci_sleep(ar); -++ -++err_release: -++ ath10k_pci_release(ar); -++ -++err_core_destroy: -+ ath10k_core_destroy(ar); -+-err_ar_pci: -+- /* call HIF PCI free here */ -+- kfree(ar_pci); -+ -+ return ret; -+ } -+@@ -2715,7 +2718,7 @@ static void ath10k_pci_remove(struct pci -+ struct ath10k *ar = pci_get_drvdata(pdev); -+ struct ath10k_pci *ar_pci; -+ -+- ath10k_dbg(ATH10K_DBG_PCI, "pci remove\n"); -++ ath10k_dbg(ar, ATH10K_DBG_PCI, "pci remove\n"); -+ -+ if (!ar) -+ return; -+@@ -2725,18 +2728,14 @@ static void ath10k_pci_remove(struct pci -+ if (!ar_pci) -+ return; -+ -+- tasklet_kill(&ar_pci->msi_fw_err); -+- -+ ath10k_core_unregister(ar); -+- ath10k_pci_free_ce(ar); -+- -+- pci_iounmap(pdev, ar_pci->mem); -+- pci_release_region(pdev, BAR_NUM); -+- pci_clear_master(pdev); -+- pci_disable_device(pdev); -+- -++ ath10k_pci_free_irq(ar); -++ ath10k_pci_kill_tasklet(ar); -++ ath10k_pci_deinit_irq(ar); -++ ath10k_pci_ce_deinit(ar); -++ ath10k_pci_free_pipes(ar); -++ ath10k_pci_release(ar); -+ ath10k_core_destroy(ar); -+- kfree(ar_pci); -+ } -+ -+ MODULE_DEVICE_TABLE(pci, ath10k_pci_id_table); -+@@ -2754,7 +2753,8 @@ static int __init ath10k_pci_init(void) -+ -+ ret = pci_register_driver(&ath10k_pci_driver); -+ if (ret) -+- ath10k_err("failed to register PCI driver: %d\n", ret); -++ printk(KERN_ERR "failed to register ath10k pci driver: %d\n", -++ ret); -+ -+ return ret; -+ } -+@@ -2770,5 +2770,7 @@ module_exit(ath10k_pci_exit); -+ MODULE_AUTHOR("Qualcomm Atheros"); -+ MODULE_DESCRIPTION("Driver support for Atheros QCA988X PCIe devices"); -+ MODULE_LICENSE("Dual BSD/GPL"); -+-MODULE_FIRMWARE(QCA988X_HW_2_0_FW_DIR "/" QCA988X_HW_2_0_FW_2_FILE); -++MODULE_FIRMWARE(QCA988X_HW_2_0_FW_DIR "/" QCA988X_HW_2_0_FW_FILE); -++MODULE_FIRMWARE(QCA988X_HW_2_0_FW_DIR "/" ATH10K_FW_API2_FILE); -++MODULE_FIRMWARE(QCA988X_HW_2_0_FW_DIR "/" ATH10K_FW_API3_FILE); -+ MODULE_FIRMWARE(QCA988X_HW_2_0_FW_DIR "/" QCA988X_HW_2_0_BOARD_DATA_FILE); -+--- a/drivers/net/wireless/ath/ath10k/pci.h -++++ b/drivers/net/wireless/ath/ath10k/pci.h -+@@ -23,9 +23,6 @@ -+ #include "hw.h" -+ #include "ce.h" -+ -+-/* FW dump area */ -+-#define REG_DUMP_COUNT_QCA988X 60 -+- -+ /* -+ * maximum number of bytes that can be handled atomically by DiagRead/DiagWrite -+ */ -+@@ -38,7 +35,8 @@ -+ #define DIAG_TRANSFER_LIMIT 2048 -+ -+ struct bmi_xfer { -+- struct completion done; -++ bool tx_done; -++ bool rx_done; -+ bool wait_for_resp; -+ u32 resp_len; -+ }; -+@@ -102,12 +100,12 @@ struct pcie_state { -+ * NOTE: Structure is shared between Host software and Target firmware! -+ */ -+ struct ce_pipe_config { -+- u32 pipenum; -+- u32 pipedir; -+- u32 nentries; -+- u32 nbytes_max; -+- u32 flags; -+- u32 reserved; -++ __le32 pipenum; -++ __le32 pipedir; -++ __le32 nentries; -++ __le32 nbytes_max; -++ __le32 flags; -++ __le32 reserved; -+ }; -+ -+ /* -+@@ -129,17 +127,9 @@ struct ce_pipe_config { -+ -+ /* Establish a mapping between a service/direction and a pipe. */ -+ struct service_to_pipe { -+- u32 service_id; -+- u32 pipedir; -+- u32 pipenum; -+-}; -+- -+-enum ath10k_pci_features { -+- ATH10K_PCI_FEATURE_MSI_X = 0, -+- ATH10K_PCI_FEATURE_SOC_POWER_SAVE = 1, -+- -+- /* keep last */ -+- ATH10K_PCI_FEATURE_COUNT -++ __le32 service_id; -++ __le32 pipedir; -++ __le32 pipenum; -+ }; -+ -+ /* Per-pipe state. */ -+@@ -162,14 +152,17 @@ struct ath10k_pci_pipe { -+ struct tasklet_struct intr; -+ }; -+ -++struct ath10k_pci_supp_chip { -++ u32 dev_id; -++ u32 rev_id; -++}; -++ -+ struct ath10k_pci { -+ struct pci_dev *pdev; -+ struct device *dev; -+ struct ath10k *ar; -+ void __iomem *mem; -+ -+- DECLARE_BITMAP(features, ATH10K_PCI_FEATURE_COUNT); -+- -+ /* -+ * Number of MSI interrupts granted, 0 --> using legacy PCI line -+ * interrupts. -+@@ -178,12 +171,6 @@ struct ath10k_pci { -+ -+ struct tasklet_struct intr_tq; -+ struct tasklet_struct msi_fw_err; -+- struct tasklet_struct early_irq_tasklet; -+- -+- int started; -+- -+- atomic_t keep_awake_count; -+- bool verified_awake; -+ -+ struct ath10k_pci_pipe pipe_info[CE_COUNT_MAX]; -+ -+@@ -197,29 +184,17 @@ struct ath10k_pci { -+ -+ /* Map CE id to ce_state */ -+ struct ath10k_ce_pipe ce_states[CE_COUNT_MAX]; -++ struct timer_list rx_post_retry; -+ }; -+ -+ static inline struct ath10k_pci *ath10k_pci_priv(struct ath10k *ar) -+ { -+- return ar->hif.priv; -+-} -+- -+-static inline u32 ath10k_pci_reg_read32(struct ath10k *ar, u32 addr) -+-{ -+- struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); -+- -+- return ioread32(ar_pci->mem + PCIE_LOCAL_BASE_ADDRESS + addr); -+-} -+- -+-static inline void ath10k_pci_reg_write32(struct ath10k *ar, u32 addr, u32 val) -+-{ -+- struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); -+- -+- iowrite32(val, ar_pci->mem + PCIE_LOCAL_BASE_ADDRESS + addr); -++ return (struct ath10k_pci *)ar->drv_priv; -+ } -+ -++#define ATH10K_PCI_RX_POST_RETRY_MS 50 -+ #define ATH_PCI_RESET_WAIT_MAX 10 /* ms */ -+-#define PCIE_WAKE_TIMEOUT 5000 /* 5ms */ -++#define PCIE_WAKE_TIMEOUT 10000 /* 10ms */ -+ -+ #define BAR_NUM 0 -+ -+@@ -241,35 +216,17 @@ static inline void ath10k_pci_reg_write3 -+ /* Wait up to this many Ms for a Diagnostic Access CE operation to complete */ -+ #define DIAG_ACCESS_CE_TIMEOUT_MS 10 -+ -+-/* -+- * This API allows the Host to access Target registers directly -+- * and relatively efficiently over PCIe. -+- * This allows the Host to avoid extra overhead associated with -+- * sending a message to firmware and waiting for a response message -+- * from firmware, as is done on other interconnects. -+- * -+- * Yet there is some complexity with direct accesses because the -+- * Target's power state is not known a priori. The Host must issue -+- * special PCIe reads/writes in order to explicitly wake the Target -+- * and to verify that it is awake and will remain awake. -+- * -+- * Usage: -++/* Target exposes its registers for direct access. However before host can -++ * access them it needs to make sure the target is awake (ath10k_pci_wake, -++ * ath10k_pci_wake_wait, ath10k_pci_is_awake). Once target is awake it won't go -++ * to sleep unless host tells it to (ath10k_pci_sleep). -+ * -+- * Use ath10k_pci_read32 and ath10k_pci_write32 to access Target space. -+- * These calls must be bracketed by ath10k_pci_wake and -+- * ath10k_pci_sleep. A single BEGIN/END pair is adequate for -+- * multiple READ/WRITE operations. -++ * If host tries to access target registers without waking it up it can -++ * scribble over host memory. -+ * -+- * Use ath10k_pci_wake to put the Target in a state in -+- * which it is legal for the Host to directly access it. This -+- * may involve waking the Target from a low power state, which -+- * may take up to 2Ms! -+- * -+- * Use ath10k_pci_sleep to tell the Target that as far as -+- * this code path is concerned, it no longer needs to remain -+- * directly accessible. BEGIN/END is under a reference counter; -+- * multiple code paths may issue BEGIN/END on a single targid. -++ * If target is asleep waking it up may take up to even 2ms. -+ */ -++ -+ static inline void ath10k_pci_write32(struct ath10k *ar, u32 offset, -+ u32 value) -+ { -+@@ -295,25 +252,18 @@ static inline void ath10k_pci_soc_write3 -+ ath10k_pci_write32(ar, RTC_SOC_BASE_ADDRESS + addr, val); -+ } -+ -+-int ath10k_do_pci_wake(struct ath10k *ar); -+-void ath10k_do_pci_sleep(struct ath10k *ar); -+- -+-static inline int ath10k_pci_wake(struct ath10k *ar) -++static inline u32 ath10k_pci_reg_read32(struct ath10k *ar, u32 addr) -+ { -+ struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); -+ -+- if (test_bit(ATH10K_PCI_FEATURE_SOC_POWER_SAVE, ar_pci->features)) -+- return ath10k_do_pci_wake(ar); -+- -+- return 0; -++ return ioread32(ar_pci->mem + PCIE_LOCAL_BASE_ADDRESS + addr); -+ } -+ -+-static inline void ath10k_pci_sleep(struct ath10k *ar) -++static inline void ath10k_pci_reg_write32(struct ath10k *ar, u32 addr, u32 val) -+ { -+ struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); -+ -+- if (test_bit(ATH10K_PCI_FEATURE_SOC_POWER_SAVE, ar_pci->features)) -+- ath10k_do_pci_sleep(ar); -++ iowrite32(val, ar_pci->mem + PCIE_LOCAL_BASE_ADDRESS + addr); -+ } -+ -+ #endif /* _PCI_H_ */ -+--- a/drivers/net/wireless/ath/ath10k/rx_desc.h -++++ b/drivers/net/wireless/ath/ath10k/rx_desc.h -+@@ -839,7 +839,6 @@ struct rx_ppdu_start { -+ * Reserved: HW should fill with 0, FW should ignore. -+ */ -+ -+- -+ #define RX_PPDU_END_FLAGS_PHY_ERR (1 << 0) -+ #define RX_PPDU_END_FLAGS_RX_LOCATION (1 << 1) -+ #define RX_PPDU_END_FLAGS_TXBF_H_INFO (1 << 2) -+@@ -851,7 +850,7 @@ struct rx_ppdu_start { -+ -+ #define RX_PPDU_END_INFO1_PPDU_DONE (1 << 15) -+ -+-struct rx_ppdu_end { -++struct rx_ppdu_end_common { -+ __le32 evm_p0; -+ __le32 evm_p1; -+ __le32 evm_p2; -+@@ -874,10 +873,33 @@ struct rx_ppdu_end { -+ u8 phy_err_code; -+ __le16 flags; /* %RX_PPDU_END_FLAGS_ */ -+ __le32 info0; /* %RX_PPDU_END_INFO0_ */ -++} __packed; -++ -++struct rx_ppdu_end_qca988x { -++ __le16 bb_length; -++ __le16 info1; /* %RX_PPDU_END_INFO1_ */ -++} __packed; -++ -++#define RX_PPDU_END_RTT_CORRELATION_VALUE_MASK 0x00ffffff -++#define RX_PPDU_END_RTT_CORRELATION_VALUE_LSB 0 -++#define RX_PPDU_END_RTT_UNUSED_MASK 0x7f000000 -++#define RX_PPDU_END_RTT_UNUSED_LSB 24 -++#define RX_PPDU_END_RTT_NORMAL_MODE BIT(31) -++ -++struct rx_ppdu_end_qca6174 { -++ __le32 rtt; /* %RX_PPDU_END_RTT_ */ -+ __le16 bb_length; -+ __le16 info1; /* %RX_PPDU_END_INFO1_ */ -+ } __packed; -+ -++struct rx_ppdu_end { -++ struct rx_ppdu_end_common common; -++ union { -++ struct rx_ppdu_end_qca988x qca988x; -++ struct rx_ppdu_end_qca6174 qca6174; -++ } __packed; -++} __packed; -++ -+ /* -+ * evm_p0 -+ * EVM for pilot 0. Contain EVM for streams: 0, 1, 2 and 3. -+--- a/drivers/net/wireless/ath/ath10k/targaddrs.h -++++ b/drivers/net/wireless/ath/ath10k/targaddrs.h -+@@ -18,6 +18,8 @@ -+ #ifndef __TARGADDRS_H__ -+ #define __TARGADDRS_H__ -+ -++#include "hw.h" -++ -+ /* -+ * xxx_HOST_INTEREST_ADDRESS is the address in Target RAM of the -+ * host_interest structure. It must match the address of the _host_interest -+@@ -284,7 +286,6 @@ Fw Mode/SubMode Mask -+ #define HI_OPTION_ALL_FW_SUBMODE_MASK 0xFF00 -+ #define HI_OPTION_ALL_FW_SUBMODE_SHIFT 0x8 -+ -+- -+ /* hi_option_flag2 options */ -+ #define HI_OPTION_OFFLOAD_AMSDU 0x01 -+ #define HI_OPTION_DFS_SUPPORT 0x02 /* Enable DFS support */ -+@@ -446,4 +447,7 @@ Fw Mode/SubMode Mask -+ #define QCA988X_BOARD_DATA_SZ 7168 -+ #define QCA988X_BOARD_EXT_DATA_SZ 0 -+ -++#define QCA6174_BOARD_DATA_SZ 8192 -++#define QCA6174_BOARD_EXT_DATA_SZ 0 -++ -+ #endif /* __TARGADDRS_H__ */ -+--- a/drivers/net/wireless/ath/ath10k/trace.h -++++ b/drivers/net/wireless/ath/ath10k/trace.h -+@@ -18,6 +18,16 @@ -+ #if !defined(_TRACE_H_) || defined(TRACE_HEADER_MULTI_READ) -+ -+ #include -++#include "core.h" -++ -++#if !defined(_TRACE_H_) -++static inline u32 ath10k_frm_hdr_len(const void *buf) -++{ -++ const struct ieee80211_hdr *hdr = buf; -++ -++ return ieee80211_hdrlen(hdr->frame_control); -++} -++#endif -+ -+ #define _TRACE_H_ -+ -+@@ -39,59 +49,79 @@ static inline void trace_ ## name(proto) -+ #define ATH10K_MSG_MAX 200 -+ -+ DECLARE_EVENT_CLASS(ath10k_log_event, -+- TP_PROTO(struct va_format *vaf), -+- TP_ARGS(vaf), -++ TP_PROTO(struct ath10k *ar, struct va_format *vaf), -++ TP_ARGS(ar, vaf), -+ TP_STRUCT__entry( -++ __string(device, dev_name(ar->dev)) -++ __string(driver, dev_driver_string(ar->dev)) -+ __dynamic_array(char, msg, ATH10K_MSG_MAX) -+ ), -+ TP_fast_assign( -++ __assign_str(device, dev_name(ar->dev)); -++ __assign_str(driver, dev_driver_string(ar->dev)); -+ WARN_ON_ONCE(vsnprintf(__get_dynamic_array(msg), -+ ATH10K_MSG_MAX, -+ vaf->fmt, -+ *vaf->va) >= ATH10K_MSG_MAX); -+ ), -+- TP_printk("%s", __get_str(msg)) -++ TP_printk( -++ "%s %s %s", -++ __get_str(driver), -++ __get_str(device), -++ __get_str(msg) -++ ) -+ ); -+ -+ DEFINE_EVENT(ath10k_log_event, ath10k_log_err, -+- TP_PROTO(struct va_format *vaf), -+- TP_ARGS(vaf) -++ TP_PROTO(struct ath10k *ar, struct va_format *vaf), -++ TP_ARGS(ar, vaf) -+ ); -+ -+ DEFINE_EVENT(ath10k_log_event, ath10k_log_warn, -+- TP_PROTO(struct va_format *vaf), -+- TP_ARGS(vaf) -++ TP_PROTO(struct ath10k *ar, struct va_format *vaf), -++ TP_ARGS(ar, vaf) -+ ); -+ -+ DEFINE_EVENT(ath10k_log_event, ath10k_log_info, -+- TP_PROTO(struct va_format *vaf), -+- TP_ARGS(vaf) -++ TP_PROTO(struct ath10k *ar, struct va_format *vaf), -++ TP_ARGS(ar, vaf) -+ ); -+ -+ TRACE_EVENT(ath10k_log_dbg, -+- TP_PROTO(unsigned int level, struct va_format *vaf), -+- TP_ARGS(level, vaf), -++ TP_PROTO(struct ath10k *ar, unsigned int level, struct va_format *vaf), -++ TP_ARGS(ar, level, vaf), -+ TP_STRUCT__entry( -++ __string(device, dev_name(ar->dev)) -++ __string(driver, dev_driver_string(ar->dev)) -+ __field(unsigned int, level) -+ __dynamic_array(char, msg, ATH10K_MSG_MAX) -+ ), -+ TP_fast_assign( -++ __assign_str(device, dev_name(ar->dev)); -++ __assign_str(driver, dev_driver_string(ar->dev)); -+ __entry->level = level; -+ WARN_ON_ONCE(vsnprintf(__get_dynamic_array(msg), -+ ATH10K_MSG_MAX, -+ vaf->fmt, -+ *vaf->va) >= ATH10K_MSG_MAX); -+ ), -+- TP_printk("%s", __get_str(msg)) -++ TP_printk( -++ "%s %s %s", -++ __get_str(driver), -++ __get_str(device), -++ __get_str(msg) -++ ) -+ ); -+ -+ TRACE_EVENT(ath10k_log_dbg_dump, -+- TP_PROTO(const char *msg, const char *prefix, -++ TP_PROTO(struct ath10k *ar, const char *msg, const char *prefix, -+ const void *buf, size_t buf_len), -+ -+- TP_ARGS(msg, prefix, buf, buf_len), -++ TP_ARGS(ar, msg, prefix, buf, buf_len), -+ -+ TP_STRUCT__entry( -++ __string(device, dev_name(ar->dev)) -++ __string(driver, dev_driver_string(ar->dev)) -+ __string(msg, msg) -+ __string(prefix, prefix) -+ __field(size_t, buf_len) -+@@ -99,6 +129,8 @@ TRACE_EVENT(ath10k_log_dbg_dump, -+ ), -+ -+ TP_fast_assign( -++ __assign_str(device, dev_name(ar->dev)); -++ __assign_str(driver, dev_driver_string(ar->dev)); -+ __assign_str(msg, msg); -+ __assign_str(prefix, prefix); -+ __entry->buf_len = buf_len; -+@@ -106,16 +138,23 @@ TRACE_EVENT(ath10k_log_dbg_dump, -+ ), -+ -+ TP_printk( -+- "%s/%s\n", __get_str(prefix), __get_str(msg) -++ "%s %s %s/%s\n", -++ __get_str(driver), -++ __get_str(device), -++ __get_str(prefix), -++ __get_str(msg) -+ ) -+ ); -+ -+ TRACE_EVENT(ath10k_wmi_cmd, -+- TP_PROTO(int id, void *buf, size_t buf_len, int ret), -++ TP_PROTO(struct ath10k *ar, int id, const void *buf, size_t buf_len, -++ int ret), -+ -+- TP_ARGS(id, buf, buf_len, ret), -++ TP_ARGS(ar, id, buf, buf_len, ret), -+ -+ TP_STRUCT__entry( -++ __string(device, dev_name(ar->dev)) -++ __string(driver, dev_driver_string(ar->dev)) -+ __field(unsigned int, id) -+ __field(size_t, buf_len) -+ __dynamic_array(u8, buf, buf_len) -+@@ -123,6 +162,8 @@ TRACE_EVENT(ath10k_wmi_cmd, -+ ), -+ -+ TP_fast_assign( -++ __assign_str(device, dev_name(ar->dev)); -++ __assign_str(driver, dev_driver_string(ar->dev)); -+ __entry->id = id; -+ __entry->buf_len = buf_len; -+ __entry->ret = ret; -+@@ -130,7 +171,9 @@ TRACE_EVENT(ath10k_wmi_cmd, -+ ), -+ -+ TP_printk( -+- "id %d len %zu ret %d", -++ "%s %s id %d len %zu ret %d", -++ __get_str(driver), -++ __get_str(device), -+ __entry->id, -+ __entry->buf_len, -+ __entry->ret -+@@ -138,71 +181,346 @@ TRACE_EVENT(ath10k_wmi_cmd, -+ ); -+ -+ TRACE_EVENT(ath10k_wmi_event, -+- TP_PROTO(int id, void *buf, size_t buf_len), -++ TP_PROTO(struct ath10k *ar, int id, const void *buf, size_t buf_len), -+ -+- TP_ARGS(id, buf, buf_len), -++ TP_ARGS(ar, id, buf, buf_len), -+ -+ TP_STRUCT__entry( -++ __string(device, dev_name(ar->dev)) -++ __string(driver, dev_driver_string(ar->dev)) -+ __field(unsigned int, id) -+ __field(size_t, buf_len) -+ __dynamic_array(u8, buf, buf_len) -+ ), -+ -+ TP_fast_assign( -++ __assign_str(device, dev_name(ar->dev)); -++ __assign_str(driver, dev_driver_string(ar->dev)); -+ __entry->id = id; -+ __entry->buf_len = buf_len; -+ memcpy(__get_dynamic_array(buf), buf, buf_len); -+ ), -+ -+ TP_printk( -+- "id %d len %zu", -++ "%s %s id %d len %zu", -++ __get_str(driver), -++ __get_str(device), -+ __entry->id, -+ __entry->buf_len -+ ) -+ ); -+ -+ TRACE_EVENT(ath10k_htt_stats, -+- TP_PROTO(void *buf, size_t buf_len), -++ TP_PROTO(struct ath10k *ar, const void *buf, size_t buf_len), -+ -+- TP_ARGS(buf, buf_len), -++ TP_ARGS(ar, buf, buf_len), -+ -+ TP_STRUCT__entry( -++ __string(device, dev_name(ar->dev)) -++ __string(driver, dev_driver_string(ar->dev)) -+ __field(size_t, buf_len) -+ __dynamic_array(u8, buf, buf_len) -+ ), -+ -+ TP_fast_assign( -++ __assign_str(device, dev_name(ar->dev)); -++ __assign_str(driver, dev_driver_string(ar->dev)); -+ __entry->buf_len = buf_len; -+ memcpy(__get_dynamic_array(buf), buf, buf_len); -+ ), -+ -+ TP_printk( -+- "len %zu", -++ "%s %s len %zu", -++ __get_str(driver), -++ __get_str(device), -+ __entry->buf_len -+ ) -+ ); -+ -+ TRACE_EVENT(ath10k_wmi_dbglog, -+- TP_PROTO(void *buf, size_t buf_len), -++ TP_PROTO(struct ath10k *ar, const void *buf, size_t buf_len), -+ -+- TP_ARGS(buf, buf_len), -++ TP_ARGS(ar, buf, buf_len), -+ -+ TP_STRUCT__entry( -++ __string(device, dev_name(ar->dev)) -++ __string(driver, dev_driver_string(ar->dev)) -+ __field(size_t, buf_len) -+ __dynamic_array(u8, buf, buf_len) -+ ), -+ -+ TP_fast_assign( -++ __assign_str(device, dev_name(ar->dev)); -++ __assign_str(driver, dev_driver_string(ar->dev)); -+ __entry->buf_len = buf_len; -+ memcpy(__get_dynamic_array(buf), buf, buf_len); -+ ), -+ -+ TP_printk( -+- "len %zu", -++ "%s %s len %zu", -++ __get_str(driver), -++ __get_str(device), -+ __entry->buf_len -+ ) -+ ); -+ -++TRACE_EVENT(ath10k_htt_pktlog, -++ TP_PROTO(struct ath10k *ar, const void *buf, u16 buf_len), -++ -++ TP_ARGS(ar, buf, buf_len), -++ -++ TP_STRUCT__entry( -++ __string(device, dev_name(ar->dev)) -++ __string(driver, dev_driver_string(ar->dev)) -++ __field(u16, buf_len) -++ __dynamic_array(u8, pktlog, buf_len) -++ ), -++ -++ TP_fast_assign( -++ __assign_str(device, dev_name(ar->dev)); -++ __assign_str(driver, dev_driver_string(ar->dev)); -++ __entry->buf_len = buf_len; -++ memcpy(__get_dynamic_array(pktlog), buf, buf_len); -++ ), -++ -++ TP_printk( -++ "%s %s size %hu", -++ __get_str(driver), -++ __get_str(device), -++ __entry->buf_len -++ ) -++); -++ -++TRACE_EVENT(ath10k_htt_tx, -++ TP_PROTO(struct ath10k *ar, u16 msdu_id, u16 msdu_len, -++ u8 vdev_id, u8 tid), -++ -++ TP_ARGS(ar, msdu_id, msdu_len, vdev_id, tid), -++ -++ TP_STRUCT__entry( -++ __string(device, dev_name(ar->dev)) -++ __string(driver, dev_driver_string(ar->dev)) -++ __field(u16, msdu_id) -++ __field(u16, msdu_len) -++ __field(u8, vdev_id) -++ __field(u8, tid) -++ ), -++ -++ TP_fast_assign( -++ __assign_str(device, dev_name(ar->dev)); -++ __assign_str(driver, dev_driver_string(ar->dev)); -++ __entry->msdu_id = msdu_id; -++ __entry->msdu_len = msdu_len; -++ __entry->vdev_id = vdev_id; -++ __entry->tid = tid; -++ ), -++ -++ TP_printk( -++ "%s %s msdu_id %d msdu_len %d vdev_id %d tid %d", -++ __get_str(driver), -++ __get_str(device), -++ __entry->msdu_id, -++ __entry->msdu_len, -++ __entry->vdev_id, -++ __entry->tid -++ ) -++); -++ -++TRACE_EVENT(ath10k_txrx_tx_unref, -++ TP_PROTO(struct ath10k *ar, u16 msdu_id), -++ -++ TP_ARGS(ar, msdu_id), -++ -++ TP_STRUCT__entry( -++ __string(device, dev_name(ar->dev)) -++ __string(driver, dev_driver_string(ar->dev)) -++ __field(u16, msdu_id) -++ ), -++ -++ TP_fast_assign( -++ __assign_str(device, dev_name(ar->dev)); -++ __assign_str(driver, dev_driver_string(ar->dev)); -++ __entry->msdu_id = msdu_id; -++ ), -++ -++ TP_printk( -++ "%s %s msdu_id %d", -++ __get_str(driver), -++ __get_str(device), -++ __entry->msdu_id -++ ) -++); -++ -++DECLARE_EVENT_CLASS(ath10k_hdr_event, -++ TP_PROTO(struct ath10k *ar, const void *data, size_t len), -++ -++ TP_ARGS(ar, data, len), -++ -++ TP_STRUCT__entry( -++ __string(device, dev_name(ar->dev)) -++ __string(driver, dev_driver_string(ar->dev)) -++ __field(size_t, len) -++ __dynamic_array(u8, data, ath10k_frm_hdr_len(data)) -++ ), -++ -++ TP_fast_assign( -++ __assign_str(device, dev_name(ar->dev)); -++ __assign_str(driver, dev_driver_string(ar->dev)); -++ __entry->len = ath10k_frm_hdr_len(data); -++ memcpy(__get_dynamic_array(data), data, __entry->len); -++ ), -++ -++ TP_printk( -++ "%s %s len %zu\n", -++ __get_str(driver), -++ __get_str(device), -++ __entry->len -++ ) -++); -++ -++DECLARE_EVENT_CLASS(ath10k_payload_event, -++ TP_PROTO(struct ath10k *ar, const void *data, size_t len), -++ -++ TP_ARGS(ar, data, len), -++ -++ TP_STRUCT__entry( -++ __string(device, dev_name(ar->dev)) -++ __string(driver, dev_driver_string(ar->dev)) -++ __field(size_t, len) -++ __dynamic_array(u8, payload, (len - ath10k_frm_hdr_len(data))) -++ ), -++ -++ TP_fast_assign( -++ __assign_str(device, dev_name(ar->dev)); -++ __assign_str(driver, dev_driver_string(ar->dev)); -++ __entry->len = len - ath10k_frm_hdr_len(data); -++ memcpy(__get_dynamic_array(payload), -++ data + ath10k_frm_hdr_len(data), __entry->len); -++ ), -++ -++ TP_printk( -++ "%s %s len %zu\n", -++ __get_str(driver), -++ __get_str(device), -++ __entry->len -++ ) -++); -++ -++DEFINE_EVENT(ath10k_hdr_event, ath10k_tx_hdr, -++ TP_PROTO(struct ath10k *ar, const void *data, size_t len), -++ TP_ARGS(ar, data, len) -++); -++ -++DEFINE_EVENT(ath10k_payload_event, ath10k_tx_payload, -++ TP_PROTO(struct ath10k *ar, const void *data, size_t len), -++ TP_ARGS(ar, data, len) -++); -++ -++DEFINE_EVENT(ath10k_hdr_event, ath10k_rx_hdr, -++ TP_PROTO(struct ath10k *ar, const void *data, size_t len), -++ TP_ARGS(ar, data, len) -++); -++ -++DEFINE_EVENT(ath10k_payload_event, ath10k_rx_payload, -++ TP_PROTO(struct ath10k *ar, const void *data, size_t len), -++ TP_ARGS(ar, data, len) -++); -++ -++TRACE_EVENT(ath10k_htt_rx_desc, -++ TP_PROTO(struct ath10k *ar, const void *data, size_t len), -++ -++ TP_ARGS(ar, data, len), -++ -++ TP_STRUCT__entry( -++ __string(device, dev_name(ar->dev)) -++ __string(driver, dev_driver_string(ar->dev)) -++ __field(u16, len) -++ __dynamic_array(u8, rxdesc, len) -++ ), -++ -++ TP_fast_assign( -++ __assign_str(device, dev_name(ar->dev)); -++ __assign_str(driver, dev_driver_string(ar->dev)); -++ __entry->len = len; -++ memcpy(__get_dynamic_array(rxdesc), data, len); -++ ), -++ -++ TP_printk( -++ "%s %s rxdesc len %d", -++ __get_str(driver), -++ __get_str(device), -++ __entry->len -++ ) -++); -++ -++TRACE_EVENT(ath10k_wmi_diag_container, -++ TP_PROTO(struct ath10k *ar, -++ u8 type, -++ u32 timestamp, -++ u32 code, -++ u16 len, -++ const void *data), -++ -++ TP_ARGS(ar, type, timestamp, code, len, data), -++ -++ TP_STRUCT__entry( -++ __string(device, dev_name(ar->dev)) -++ __string(driver, dev_driver_string(ar->dev)) -++ __field(u8, type) -++ __field(u32, timestamp) -++ __field(u32, code) -++ __field(u16, len) -++ __dynamic_array(u8, data, len) -++ ), -++ -++ TP_fast_assign( -++ __assign_str(device, dev_name(ar->dev)); -++ __assign_str(driver, dev_driver_string(ar->dev)); -++ __entry->type = type; -++ __entry->timestamp = timestamp; -++ __entry->code = code; -++ __entry->len = len; -++ memcpy(__get_dynamic_array(data), data, len); -++ ), -++ -++ TP_printk( -++ "%s %s diag container type %hhu timestamp %u code %u len %d", -++ __get_str(driver), -++ __get_str(device), -++ __entry->type, -++ __entry->timestamp, -++ __entry->code, -++ __entry->len -++ ) -++); -++ -++TRACE_EVENT(ath10k_wmi_diag, -++ TP_PROTO(struct ath10k *ar, const void *data, size_t len), -++ -++ TP_ARGS(ar, data, len), -++ -++ TP_STRUCT__entry( -++ __string(device, dev_name(ar->dev)) -++ __string(driver, dev_driver_string(ar->dev)) -++ __field(u16, len) -++ __dynamic_array(u8, data, len) -++ ), -++ -++ TP_fast_assign( -++ __assign_str(device, dev_name(ar->dev)); -++ __assign_str(driver, dev_driver_string(ar->dev)); -++ __entry->len = len; -++ memcpy(__get_dynamic_array(data), data, len); -++ ), -++ -++ TP_printk( -++ "%s %s tlv diag len %d", -++ __get_str(driver), -++ __get_str(device), -++ __entry->len -++ ) -++); -++ -+ #endif /* _TRACE_H_ || TRACE_HEADER_MULTI_READ*/ -+ -+ /* we don't want to use include/trace/events */ -+--- a/drivers/net/wireless/ath/ath10k/txrx.c -++++ b/drivers/net/wireless/ath/ath10k/txrx.c -+@@ -32,14 +32,14 @@ static void ath10k_report_offchan_tx(str -+ * offchan_tx_skb. */ -+ spin_lock_bh(&ar->data_lock); -+ if (ar->offchan_tx_skb != skb) { -+- ath10k_warn("completed old offchannel frame\n"); -++ ath10k_warn(ar, "completed old offchannel frame\n"); -+ goto out; -+ } -+ -+ complete(&ar->offchan_tx_completed); -+ ar->offchan_tx_skb = NULL; /* just for sanity */ -+ -+- ath10k_dbg(ATH10K_DBG_HTT, "completed offchannel skb %p\n", skb); -++ ath10k_dbg(ar, ATH10K_DBG_HTT, "completed offchannel skb %p\n", skb); -+ out: -+ spin_unlock_bh(&ar->data_lock); -+ } -+@@ -47,23 +47,30 @@ out: -+ void ath10k_txrx_tx_unref(struct ath10k_htt *htt, -+ const struct htt_tx_done *tx_done) -+ { -+- struct device *dev = htt->ar->dev; -++ struct ath10k *ar = htt->ar; -++ struct device *dev = ar->dev; -+ struct ieee80211_tx_info *info; -+ struct ath10k_skb_cb *skb_cb; -+ struct sk_buff *msdu; -+ -+ lockdep_assert_held(&htt->tx_lock); -+ -+- ath10k_dbg(ATH10K_DBG_HTT, "htt tx completion msdu_id %u discard %d no_ack %d\n", -++ ath10k_dbg(ar, ATH10K_DBG_HTT, "htt tx completion msdu_id %u discard %d no_ack %d\n", -+ tx_done->msdu_id, !!tx_done->discard, !!tx_done->no_ack); -+ -+ if (tx_done->msdu_id >= htt->max_num_pending_tx) { -+- ath10k_warn("warning: msdu_id %d too big, ignoring\n", -++ ath10k_warn(ar, "warning: msdu_id %d too big, ignoring\n", -++ tx_done->msdu_id); -++ return; -++ } -++ -++ msdu = idr_find(&htt->pending_tx, tx_done->msdu_id); -++ if (!msdu) { -++ ath10k_warn(ar, "received tx completion for invalid msdu_id: %d\n", -+ tx_done->msdu_id); -+ return; -+ } -+ -+- msdu = htt->pending_tx[tx_done->msdu_id]; -+ skb_cb = ATH10K_SKB_CB(msdu); -+ -+ dma_unmap_single(dev, skb_cb->paddr, msdu->len, DMA_TO_DEVICE); -+@@ -77,6 +84,7 @@ void ath10k_txrx_tx_unref(struct ath10k_ -+ -+ info = IEEE80211_SKB_CB(msdu); -+ memset(&info->status, 0, sizeof(info->status)); -++ trace_ath10k_txrx_tx_unref(ar, tx_done->msdu_id); -+ -+ if (tx_done->discard) { -+ ieee80211_free_txskb(htt->ar->hw, msdu); -+@@ -93,7 +101,6 @@ void ath10k_txrx_tx_unref(struct ath10k_ -+ /* we do not own the msdu anymore */ -+ -+ exit: -+- htt->pending_tx[tx_done->msdu_id] = NULL; -+ ath10k_htt_tx_free_msdu_id(htt, tx_done->msdu_id); -+ __ath10k_htt_tx_dec_pending(htt); -+ if (htt->num_pending_tx == 0) -+@@ -119,8 +126,7 @@ struct ath10k_peer *ath10k_peer_find(str -+ return NULL; -+ } -+ -+-static struct ath10k_peer *ath10k_peer_find_by_id(struct ath10k *ar, -+- int peer_id) -++struct ath10k_peer *ath10k_peer_find_by_id(struct ath10k *ar, int peer_id) -+ { -+ struct ath10k_peer *peer; -+ -+@@ -145,7 +151,8 @@ static int ath10k_wait_for_peer_common(s -+ mapped = !!ath10k_peer_find(ar, vdev_id, addr); -+ spin_unlock_bh(&ar->data_lock); -+ -+- mapped == expect_mapped; -++ (mapped == expect_mapped || -++ test_bit(ATH10K_FLAG_CRASH_FLUSH, &ar->dev_flags)); -+ }), 3*HZ); -+ -+ if (ret <= 0) -+@@ -178,12 +185,12 @@ void ath10k_peer_map_event(struct ath10k -+ goto exit; -+ -+ peer->vdev_id = ev->vdev_id; -+- memcpy(peer->addr, ev->addr, ETH_ALEN); -++ ether_addr_copy(peer->addr, ev->addr); -+ list_add(&peer->list, &ar->peers); -+ wake_up(&ar->peer_mapping_wq); -+ } -+ -+- ath10k_dbg(ATH10K_DBG_HTT, "htt peer map vdev %d peer %pM id %d\n", -++ ath10k_dbg(ar, ATH10K_DBG_HTT, "htt peer map vdev %d peer %pM id %d\n", -+ ev->vdev_id, ev->addr, ev->peer_id); -+ -+ set_bit(ev->peer_id, peer->peer_ids); -+@@ -200,12 +207,12 @@ void ath10k_peer_unmap_event(struct ath1 -+ spin_lock_bh(&ar->data_lock); -+ peer = ath10k_peer_find_by_id(ar, ev->peer_id); -+ if (!peer) { -+- ath10k_warn("peer-unmap-event: unknown peer id %d\n", -++ ath10k_warn(ar, "peer-unmap-event: unknown peer id %d\n", -+ ev->peer_id); -+ goto exit; -+ } -+ -+- ath10k_dbg(ATH10K_DBG_HTT, "htt peer unmap vdev %d peer %pM id %d\n", -++ ath10k_dbg(ar, ATH10K_DBG_HTT, "htt peer unmap vdev %d peer %pM id %d\n", -+ peer->vdev_id, peer->addr, ev->peer_id); -+ -+ clear_bit(ev->peer_id, peer->peer_ids); -+--- a/drivers/net/wireless/ath/ath10k/txrx.h -++++ b/drivers/net/wireless/ath/ath10k/txrx.h -+@@ -24,6 +24,7 @@ void ath10k_txrx_tx_unref(struct ath10k_ -+ -+ struct ath10k_peer *ath10k_peer_find(struct ath10k *ar, int vdev_id, -+ const u8 *addr); -++struct ath10k_peer *ath10k_peer_find_by_id(struct ath10k *ar, int peer_id); -+ int ath10k_wait_for_peer_created(struct ath10k *ar, int vdev_id, -+ const u8 *addr); -+ int ath10k_wait_for_peer_deleted(struct ath10k *ar, int vdev_id, -+--- a/drivers/net/wireless/ath/ath10k/wmi.c -++++ b/drivers/net/wireless/ath/ath10k/wmi.c -+@@ -22,7 +22,10 @@ -+ #include "htc.h" -+ #include "debug.h" -+ #include "wmi.h" -++#include "wmi-tlv.h" -+ #include "mac.h" -++#include "testmode.h" -++#include "wmi-ops.h" -+ -+ /* MAIN WMI cmd track */ -+ static struct wmi_cmd_map wmi_cmd_map = { -+@@ -142,6 +145,7 @@ static struct wmi_cmd_map wmi_cmd_map = -+ .force_fw_hang_cmdid = WMI_FORCE_FW_HANG_CMDID, -+ .gpio_config_cmdid = WMI_GPIO_CONFIG_CMDID, -+ .gpio_output_cmdid = WMI_GPIO_OUTPUT_CMDID, -++ .pdev_get_temperature_cmdid = WMI_CMD_UNSUPPORTED, -+ }; -+ -+ /* 10.X WMI cmd track */ -+@@ -264,6 +268,129 @@ static struct wmi_cmd_map wmi_10x_cmd_ma -+ .force_fw_hang_cmdid = WMI_CMD_UNSUPPORTED, -+ .gpio_config_cmdid = WMI_10X_GPIO_CONFIG_CMDID, -+ .gpio_output_cmdid = WMI_10X_GPIO_OUTPUT_CMDID, -++ .pdev_get_temperature_cmdid = WMI_CMD_UNSUPPORTED, -++}; -++ -++/* 10.2.4 WMI cmd track */ -++static struct wmi_cmd_map wmi_10_2_4_cmd_map = { -++ .init_cmdid = WMI_10_2_INIT_CMDID, -++ .start_scan_cmdid = WMI_10_2_START_SCAN_CMDID, -++ .stop_scan_cmdid = WMI_10_2_STOP_SCAN_CMDID, -++ .scan_chan_list_cmdid = WMI_10_2_SCAN_CHAN_LIST_CMDID, -++ .scan_sch_prio_tbl_cmdid = WMI_CMD_UNSUPPORTED, -++ .pdev_set_regdomain_cmdid = WMI_10_2_PDEV_SET_REGDOMAIN_CMDID, -++ .pdev_set_channel_cmdid = WMI_10_2_PDEV_SET_CHANNEL_CMDID, -++ .pdev_set_param_cmdid = WMI_10_2_PDEV_SET_PARAM_CMDID, -++ .pdev_pktlog_enable_cmdid = WMI_10_2_PDEV_PKTLOG_ENABLE_CMDID, -++ .pdev_pktlog_disable_cmdid = WMI_10_2_PDEV_PKTLOG_DISABLE_CMDID, -++ .pdev_set_wmm_params_cmdid = WMI_10_2_PDEV_SET_WMM_PARAMS_CMDID, -++ .pdev_set_ht_cap_ie_cmdid = WMI_10_2_PDEV_SET_HT_CAP_IE_CMDID, -++ .pdev_set_vht_cap_ie_cmdid = WMI_10_2_PDEV_SET_VHT_CAP_IE_CMDID, -++ .pdev_set_quiet_mode_cmdid = WMI_10_2_PDEV_SET_QUIET_MODE_CMDID, -++ .pdev_green_ap_ps_enable_cmdid = WMI_10_2_PDEV_GREEN_AP_PS_ENABLE_CMDID, -++ .pdev_get_tpc_config_cmdid = WMI_10_2_PDEV_GET_TPC_CONFIG_CMDID, -++ .pdev_set_base_macaddr_cmdid = WMI_10_2_PDEV_SET_BASE_MACADDR_CMDID, -++ .vdev_create_cmdid = WMI_10_2_VDEV_CREATE_CMDID, -++ .vdev_delete_cmdid = WMI_10_2_VDEV_DELETE_CMDID, -++ .vdev_start_request_cmdid = WMI_10_2_VDEV_START_REQUEST_CMDID, -++ .vdev_restart_request_cmdid = WMI_10_2_VDEV_RESTART_REQUEST_CMDID, -++ .vdev_up_cmdid = WMI_10_2_VDEV_UP_CMDID, -++ .vdev_stop_cmdid = WMI_10_2_VDEV_STOP_CMDID, -++ .vdev_down_cmdid = WMI_10_2_VDEV_DOWN_CMDID, -++ .vdev_set_param_cmdid = WMI_10_2_VDEV_SET_PARAM_CMDID, -++ .vdev_install_key_cmdid = WMI_10_2_VDEV_INSTALL_KEY_CMDID, -++ .peer_create_cmdid = WMI_10_2_PEER_CREATE_CMDID, -++ .peer_delete_cmdid = WMI_10_2_PEER_DELETE_CMDID, -++ .peer_flush_tids_cmdid = WMI_10_2_PEER_FLUSH_TIDS_CMDID, -++ .peer_set_param_cmdid = WMI_10_2_PEER_SET_PARAM_CMDID, -++ .peer_assoc_cmdid = WMI_10_2_PEER_ASSOC_CMDID, -++ .peer_add_wds_entry_cmdid = WMI_10_2_PEER_ADD_WDS_ENTRY_CMDID, -++ .peer_remove_wds_entry_cmdid = WMI_10_2_PEER_REMOVE_WDS_ENTRY_CMDID, -++ .peer_mcast_group_cmdid = WMI_10_2_PEER_MCAST_GROUP_CMDID, -++ .bcn_tx_cmdid = WMI_10_2_BCN_TX_CMDID, -++ .pdev_send_bcn_cmdid = WMI_10_2_PDEV_SEND_BCN_CMDID, -++ .bcn_tmpl_cmdid = WMI_CMD_UNSUPPORTED, -++ .bcn_filter_rx_cmdid = WMI_10_2_BCN_FILTER_RX_CMDID, -++ .prb_req_filter_rx_cmdid = WMI_10_2_PRB_REQ_FILTER_RX_CMDID, -++ .mgmt_tx_cmdid = WMI_10_2_MGMT_TX_CMDID, -++ .prb_tmpl_cmdid = WMI_CMD_UNSUPPORTED, -++ .addba_clear_resp_cmdid = WMI_10_2_ADDBA_CLEAR_RESP_CMDID, -++ .addba_send_cmdid = WMI_10_2_ADDBA_SEND_CMDID, -++ .addba_status_cmdid = WMI_10_2_ADDBA_STATUS_CMDID, -++ .delba_send_cmdid = WMI_10_2_DELBA_SEND_CMDID, -++ .addba_set_resp_cmdid = WMI_10_2_ADDBA_SET_RESP_CMDID, -++ .send_singleamsdu_cmdid = WMI_10_2_SEND_SINGLEAMSDU_CMDID, -++ .sta_powersave_mode_cmdid = WMI_10_2_STA_POWERSAVE_MODE_CMDID, -++ .sta_powersave_param_cmdid = WMI_10_2_STA_POWERSAVE_PARAM_CMDID, -++ .sta_mimo_ps_mode_cmdid = WMI_10_2_STA_MIMO_PS_MODE_CMDID, -++ .pdev_dfs_enable_cmdid = WMI_10_2_PDEV_DFS_ENABLE_CMDID, -++ .pdev_dfs_disable_cmdid = WMI_10_2_PDEV_DFS_DISABLE_CMDID, -++ .roam_scan_mode = WMI_10_2_ROAM_SCAN_MODE, -++ .roam_scan_rssi_threshold = WMI_10_2_ROAM_SCAN_RSSI_THRESHOLD, -++ .roam_scan_period = WMI_10_2_ROAM_SCAN_PERIOD, -++ .roam_scan_rssi_change_threshold = -++ WMI_10_2_ROAM_SCAN_RSSI_CHANGE_THRESHOLD, -++ .roam_ap_profile = WMI_10_2_ROAM_AP_PROFILE, -++ .ofl_scan_add_ap_profile = WMI_10_2_OFL_SCAN_ADD_AP_PROFILE, -++ .ofl_scan_remove_ap_profile = WMI_10_2_OFL_SCAN_REMOVE_AP_PROFILE, -++ .ofl_scan_period = WMI_10_2_OFL_SCAN_PERIOD, -++ .p2p_dev_set_device_info = WMI_10_2_P2P_DEV_SET_DEVICE_INFO, -++ .p2p_dev_set_discoverability = WMI_10_2_P2P_DEV_SET_DISCOVERABILITY, -++ .p2p_go_set_beacon_ie = WMI_10_2_P2P_GO_SET_BEACON_IE, -++ .p2p_go_set_probe_resp_ie = WMI_10_2_P2P_GO_SET_PROBE_RESP_IE, -++ .p2p_set_vendor_ie_data_cmdid = WMI_CMD_UNSUPPORTED, -++ .ap_ps_peer_param_cmdid = WMI_10_2_AP_PS_PEER_PARAM_CMDID, -++ .ap_ps_peer_uapsd_coex_cmdid = WMI_CMD_UNSUPPORTED, -++ .peer_rate_retry_sched_cmdid = WMI_10_2_PEER_RATE_RETRY_SCHED_CMDID, -++ .wlan_profile_trigger_cmdid = WMI_10_2_WLAN_PROFILE_TRIGGER_CMDID, -++ .wlan_profile_set_hist_intvl_cmdid = -++ WMI_10_2_WLAN_PROFILE_SET_HIST_INTVL_CMDID, -++ .wlan_profile_get_profile_data_cmdid = -++ WMI_10_2_WLAN_PROFILE_GET_PROFILE_DATA_CMDID, -++ .wlan_profile_enable_profile_id_cmdid = -++ WMI_10_2_WLAN_PROFILE_ENABLE_PROFILE_ID_CMDID, -++ .wlan_profile_list_profile_id_cmdid = -++ WMI_10_2_WLAN_PROFILE_LIST_PROFILE_ID_CMDID, -++ .pdev_suspend_cmdid = WMI_10_2_PDEV_SUSPEND_CMDID, -++ .pdev_resume_cmdid = WMI_10_2_PDEV_RESUME_CMDID, -++ .add_bcn_filter_cmdid = WMI_10_2_ADD_BCN_FILTER_CMDID, -++ .rmv_bcn_filter_cmdid = WMI_10_2_RMV_BCN_FILTER_CMDID, -++ .wow_add_wake_pattern_cmdid = WMI_10_2_WOW_ADD_WAKE_PATTERN_CMDID, -++ .wow_del_wake_pattern_cmdid = WMI_10_2_WOW_DEL_WAKE_PATTERN_CMDID, -++ .wow_enable_disable_wake_event_cmdid = -++ WMI_10_2_WOW_ENABLE_DISABLE_WAKE_EVENT_CMDID, -++ .wow_enable_cmdid = WMI_10_2_WOW_ENABLE_CMDID, -++ .wow_hostwakeup_from_sleep_cmdid = -++ WMI_10_2_WOW_HOSTWAKEUP_FROM_SLEEP_CMDID, -++ .rtt_measreq_cmdid = WMI_10_2_RTT_MEASREQ_CMDID, -++ .rtt_tsf_cmdid = WMI_10_2_RTT_TSF_CMDID, -++ .vdev_spectral_scan_configure_cmdid = -++ WMI_10_2_VDEV_SPECTRAL_SCAN_CONFIGURE_CMDID, -++ .vdev_spectral_scan_enable_cmdid = -++ WMI_10_2_VDEV_SPECTRAL_SCAN_ENABLE_CMDID, -++ .request_stats_cmdid = WMI_10_2_REQUEST_STATS_CMDID, -++ .set_arp_ns_offload_cmdid = WMI_CMD_UNSUPPORTED, -++ .network_list_offload_config_cmdid = WMI_CMD_UNSUPPORTED, -++ .gtk_offload_cmdid = WMI_CMD_UNSUPPORTED, -++ .csa_offload_enable_cmdid = WMI_CMD_UNSUPPORTED, -++ .csa_offload_chanswitch_cmdid = WMI_CMD_UNSUPPORTED, -++ .chatter_set_mode_cmdid = WMI_CMD_UNSUPPORTED, -++ .peer_tid_addba_cmdid = WMI_CMD_UNSUPPORTED, -++ .peer_tid_delba_cmdid = WMI_CMD_UNSUPPORTED, -++ .sta_dtim_ps_method_cmdid = WMI_CMD_UNSUPPORTED, -++ .sta_uapsd_auto_trig_cmdid = WMI_CMD_UNSUPPORTED, -++ .sta_keepalive_cmd = WMI_CMD_UNSUPPORTED, -++ .echo_cmdid = WMI_10_2_ECHO_CMDID, -++ .pdev_utf_cmdid = WMI_10_2_PDEV_UTF_CMDID, -++ .dbglog_cfg_cmdid = WMI_10_2_DBGLOG_CFG_CMDID, -++ .pdev_qvit_cmdid = WMI_10_2_PDEV_QVIT_CMDID, -++ .pdev_ftm_intg_cmdid = WMI_CMD_UNSUPPORTED, -++ .vdev_set_keepalive_cmdid = WMI_CMD_UNSUPPORTED, -++ .vdev_get_keepalive_cmdid = WMI_CMD_UNSUPPORTED, -++ .force_fw_hang_cmdid = WMI_CMD_UNSUPPORTED, -++ .gpio_config_cmdid = WMI_10_2_GPIO_CONFIG_CMDID, -++ .gpio_output_cmdid = WMI_10_2_GPIO_OUTPUT_CMDID, -++ .pdev_get_temperature_cmdid = WMI_10_2_PDEV_GET_TEMPERATURE_CMDID, -+ }; -+ -+ /* MAIN WMI VDEV param map */ -+@@ -384,6 +511,64 @@ static struct wmi_vdev_param_map wmi_10x -+ WMI_10X_VDEV_PARAM_AP_DETECT_OUT_OF_SYNC_SLEEPING_STA_TIME_SECS, -+ }; -+ -++static struct wmi_vdev_param_map wmi_10_2_4_vdev_param_map = { -++ .rts_threshold = WMI_10X_VDEV_PARAM_RTS_THRESHOLD, -++ .fragmentation_threshold = WMI_10X_VDEV_PARAM_FRAGMENTATION_THRESHOLD, -++ .beacon_interval = WMI_10X_VDEV_PARAM_BEACON_INTERVAL, -++ .listen_interval = WMI_10X_VDEV_PARAM_LISTEN_INTERVAL, -++ .multicast_rate = WMI_10X_VDEV_PARAM_MULTICAST_RATE, -++ .mgmt_tx_rate = WMI_10X_VDEV_PARAM_MGMT_TX_RATE, -++ .slot_time = WMI_10X_VDEV_PARAM_SLOT_TIME, -++ .preamble = WMI_10X_VDEV_PARAM_PREAMBLE, -++ .swba_time = WMI_10X_VDEV_PARAM_SWBA_TIME, -++ .wmi_vdev_stats_update_period = WMI_10X_VDEV_STATS_UPDATE_PERIOD, -++ .wmi_vdev_pwrsave_ageout_time = WMI_10X_VDEV_PWRSAVE_AGEOUT_TIME, -++ .wmi_vdev_host_swba_interval = WMI_10X_VDEV_HOST_SWBA_INTERVAL, -++ .dtim_period = WMI_10X_VDEV_PARAM_DTIM_PERIOD, -++ .wmi_vdev_oc_scheduler_air_time_limit = -++ WMI_10X_VDEV_OC_SCHEDULER_AIR_TIME_LIMIT, -++ .wds = WMI_10X_VDEV_PARAM_WDS, -++ .atim_window = WMI_10X_VDEV_PARAM_ATIM_WINDOW, -++ .bmiss_count_max = WMI_10X_VDEV_PARAM_BMISS_COUNT_MAX, -++ .bmiss_first_bcnt = WMI_VDEV_PARAM_UNSUPPORTED, -++ .bmiss_final_bcnt = WMI_VDEV_PARAM_UNSUPPORTED, -++ .feature_wmm = WMI_10X_VDEV_PARAM_FEATURE_WMM, -++ .chwidth = WMI_10X_VDEV_PARAM_CHWIDTH, -++ .chextoffset = WMI_10X_VDEV_PARAM_CHEXTOFFSET, -++ .disable_htprotection = WMI_10X_VDEV_PARAM_DISABLE_HTPROTECTION, -++ .sta_quickkickout = WMI_10X_VDEV_PARAM_STA_QUICKKICKOUT, -++ .mgmt_rate = WMI_10X_VDEV_PARAM_MGMT_RATE, -++ .protection_mode = WMI_10X_VDEV_PARAM_PROTECTION_MODE, -++ .fixed_rate = WMI_10X_VDEV_PARAM_FIXED_RATE, -++ .sgi = WMI_10X_VDEV_PARAM_SGI, -++ .ldpc = WMI_10X_VDEV_PARAM_LDPC, -++ .tx_stbc = WMI_10X_VDEV_PARAM_TX_STBC, -++ .rx_stbc = WMI_10X_VDEV_PARAM_RX_STBC, -++ .intra_bss_fwd = WMI_10X_VDEV_PARAM_INTRA_BSS_FWD, -++ .def_keyid = WMI_10X_VDEV_PARAM_DEF_KEYID, -++ .nss = WMI_10X_VDEV_PARAM_NSS, -++ .bcast_data_rate = WMI_10X_VDEV_PARAM_BCAST_DATA_RATE, -++ .mcast_data_rate = WMI_10X_VDEV_PARAM_MCAST_DATA_RATE, -++ .mcast_indicate = WMI_10X_VDEV_PARAM_MCAST_INDICATE, -++ .dhcp_indicate = WMI_10X_VDEV_PARAM_DHCP_INDICATE, -++ .unknown_dest_indicate = WMI_10X_VDEV_PARAM_UNKNOWN_DEST_INDICATE, -++ .ap_keepalive_min_idle_inactive_time_secs = -++ WMI_10X_VDEV_PARAM_AP_KEEPALIVE_MIN_IDLE_INACTIVE_TIME_SECS, -++ .ap_keepalive_max_idle_inactive_time_secs = -++ WMI_10X_VDEV_PARAM_AP_KEEPALIVE_MAX_IDLE_INACTIVE_TIME_SECS, -++ .ap_keepalive_max_unresponsive_time_secs = -++ WMI_10X_VDEV_PARAM_AP_KEEPALIVE_MAX_UNRESPONSIVE_TIME_SECS, -++ .ap_enable_nawds = WMI_10X_VDEV_PARAM_AP_ENABLE_NAWDS, -++ .mcast2ucast_set = WMI_10X_VDEV_PARAM_MCAST2UCAST_SET, -++ .enable_rtscts = WMI_10X_VDEV_PARAM_ENABLE_RTSCTS, -++ .txbf = WMI_VDEV_PARAM_UNSUPPORTED, -++ .packet_powersave = WMI_VDEV_PARAM_UNSUPPORTED, -++ .drop_unencry = WMI_VDEV_PARAM_UNSUPPORTED, -++ .tx_encap_type = WMI_VDEV_PARAM_UNSUPPORTED, -++ .ap_detect_out_of_sync_sleeping_sta_time_secs = -++ WMI_10X_VDEV_PARAM_AP_DETECT_OUT_OF_SYNC_SLEEPING_STA_TIME_SECS, -++}; -++ -+ static struct wmi_pdev_param_map wmi_pdev_param_map = { -+ .tx_chain_mask = WMI_PDEV_PARAM_TX_CHAIN_MASK, -+ .rx_chain_mask = WMI_PDEV_PARAM_RX_CHAIN_MASK, -+@@ -433,6 +618,7 @@ static struct wmi_pdev_param_map wmi_pde -+ .fast_channel_reset = WMI_PDEV_PARAM_UNSUPPORTED, -+ .burst_dur = WMI_PDEV_PARAM_UNSUPPORTED, -+ .burst_enable = WMI_PDEV_PARAM_UNSUPPORTED, -++ .cal_period = WMI_PDEV_PARAM_UNSUPPORTED, -+ }; -+ -+ static struct wmi_pdev_param_map wmi_10x_pdev_param_map = { -+@@ -485,11 +671,221 @@ static struct wmi_pdev_param_map wmi_10x -+ .fast_channel_reset = WMI_10X_PDEV_PARAM_FAST_CHANNEL_RESET, -+ .burst_dur = WMI_10X_PDEV_PARAM_BURST_DUR, -+ .burst_enable = WMI_10X_PDEV_PARAM_BURST_ENABLE, -++ .cal_period = WMI_10X_PDEV_PARAM_CAL_PERIOD, -++}; -++ -++static struct wmi_pdev_param_map wmi_10_2_4_pdev_param_map = { -++ .tx_chain_mask = WMI_10X_PDEV_PARAM_TX_CHAIN_MASK, -++ .rx_chain_mask = WMI_10X_PDEV_PARAM_RX_CHAIN_MASK, -++ .txpower_limit2g = WMI_10X_PDEV_PARAM_TXPOWER_LIMIT2G, -++ .txpower_limit5g = WMI_10X_PDEV_PARAM_TXPOWER_LIMIT5G, -++ .txpower_scale = WMI_10X_PDEV_PARAM_TXPOWER_SCALE, -++ .beacon_gen_mode = WMI_10X_PDEV_PARAM_BEACON_GEN_MODE, -++ .beacon_tx_mode = WMI_10X_PDEV_PARAM_BEACON_TX_MODE, -++ .resmgr_offchan_mode = WMI_10X_PDEV_PARAM_RESMGR_OFFCHAN_MODE, -++ .protection_mode = WMI_10X_PDEV_PARAM_PROTECTION_MODE, -++ .dynamic_bw = WMI_10X_PDEV_PARAM_DYNAMIC_BW, -++ .non_agg_sw_retry_th = WMI_10X_PDEV_PARAM_NON_AGG_SW_RETRY_TH, -++ .agg_sw_retry_th = WMI_10X_PDEV_PARAM_AGG_SW_RETRY_TH, -++ .sta_kickout_th = WMI_10X_PDEV_PARAM_STA_KICKOUT_TH, -++ .ac_aggrsize_scaling = WMI_10X_PDEV_PARAM_AC_AGGRSIZE_SCALING, -++ .ltr_enable = WMI_10X_PDEV_PARAM_LTR_ENABLE, -++ .ltr_ac_latency_be = WMI_10X_PDEV_PARAM_LTR_AC_LATENCY_BE, -++ .ltr_ac_latency_bk = WMI_10X_PDEV_PARAM_LTR_AC_LATENCY_BK, -++ .ltr_ac_latency_vi = WMI_10X_PDEV_PARAM_LTR_AC_LATENCY_VI, -++ .ltr_ac_latency_vo = WMI_10X_PDEV_PARAM_LTR_AC_LATENCY_VO, -++ .ltr_ac_latency_timeout = WMI_10X_PDEV_PARAM_LTR_AC_LATENCY_TIMEOUT, -++ .ltr_sleep_override = WMI_10X_PDEV_PARAM_LTR_SLEEP_OVERRIDE, -++ .ltr_rx_override = WMI_10X_PDEV_PARAM_LTR_RX_OVERRIDE, -++ .ltr_tx_activity_timeout = WMI_10X_PDEV_PARAM_LTR_TX_ACTIVITY_TIMEOUT, -++ .l1ss_enable = WMI_10X_PDEV_PARAM_L1SS_ENABLE, -++ .dsleep_enable = WMI_10X_PDEV_PARAM_DSLEEP_ENABLE, -++ .pcielp_txbuf_flush = WMI_PDEV_PARAM_UNSUPPORTED, -++ .pcielp_txbuf_watermark = WMI_PDEV_PARAM_UNSUPPORTED, -++ .pcielp_txbuf_tmo_en = WMI_PDEV_PARAM_UNSUPPORTED, -++ .pcielp_txbuf_tmo_value = WMI_PDEV_PARAM_UNSUPPORTED, -++ .pdev_stats_update_period = WMI_10X_PDEV_PARAM_PDEV_STATS_UPDATE_PERIOD, -++ .vdev_stats_update_period = WMI_10X_PDEV_PARAM_VDEV_STATS_UPDATE_PERIOD, -++ .peer_stats_update_period = WMI_10X_PDEV_PARAM_PEER_STATS_UPDATE_PERIOD, -++ .bcnflt_stats_update_period = -++ WMI_10X_PDEV_PARAM_BCNFLT_STATS_UPDATE_PERIOD, -++ .pmf_qos = WMI_10X_PDEV_PARAM_PMF_QOS, -++ .arp_ac_override = WMI_10X_PDEV_PARAM_ARPDHCP_AC_OVERRIDE, -++ .dcs = WMI_10X_PDEV_PARAM_DCS, -++ .ani_enable = WMI_10X_PDEV_PARAM_ANI_ENABLE, -++ .ani_poll_period = WMI_10X_PDEV_PARAM_ANI_POLL_PERIOD, -++ .ani_listen_period = WMI_10X_PDEV_PARAM_ANI_LISTEN_PERIOD, -++ .ani_ofdm_level = WMI_10X_PDEV_PARAM_ANI_OFDM_LEVEL, -++ .ani_cck_level = WMI_10X_PDEV_PARAM_ANI_CCK_LEVEL, -++ .dyntxchain = WMI_10X_PDEV_PARAM_DYNTXCHAIN, -++ .proxy_sta = WMI_PDEV_PARAM_UNSUPPORTED, -++ .idle_ps_config = WMI_PDEV_PARAM_UNSUPPORTED, -++ .power_gating_sleep = WMI_PDEV_PARAM_UNSUPPORTED, -++ .fast_channel_reset = WMI_10X_PDEV_PARAM_FAST_CHANNEL_RESET, -++ .burst_dur = WMI_10X_PDEV_PARAM_BURST_DUR, -++ .burst_enable = WMI_10X_PDEV_PARAM_BURST_ENABLE, -++ .cal_period = WMI_10X_PDEV_PARAM_CAL_PERIOD, -++}; -++ -++/* firmware 10.2 specific mappings */ -++static struct wmi_cmd_map wmi_10_2_cmd_map = { -++ .init_cmdid = WMI_10_2_INIT_CMDID, -++ .start_scan_cmdid = WMI_10_2_START_SCAN_CMDID, -++ .stop_scan_cmdid = WMI_10_2_STOP_SCAN_CMDID, -++ .scan_chan_list_cmdid = WMI_10_2_SCAN_CHAN_LIST_CMDID, -++ .scan_sch_prio_tbl_cmdid = WMI_CMD_UNSUPPORTED, -++ .pdev_set_regdomain_cmdid = WMI_10_2_PDEV_SET_REGDOMAIN_CMDID, -++ .pdev_set_channel_cmdid = WMI_10_2_PDEV_SET_CHANNEL_CMDID, -++ .pdev_set_param_cmdid = WMI_10_2_PDEV_SET_PARAM_CMDID, -++ .pdev_pktlog_enable_cmdid = WMI_10_2_PDEV_PKTLOG_ENABLE_CMDID, -++ .pdev_pktlog_disable_cmdid = WMI_10_2_PDEV_PKTLOG_DISABLE_CMDID, -++ .pdev_set_wmm_params_cmdid = WMI_10_2_PDEV_SET_WMM_PARAMS_CMDID, -++ .pdev_set_ht_cap_ie_cmdid = WMI_10_2_PDEV_SET_HT_CAP_IE_CMDID, -++ .pdev_set_vht_cap_ie_cmdid = WMI_10_2_PDEV_SET_VHT_CAP_IE_CMDID, -++ .pdev_set_quiet_mode_cmdid = WMI_10_2_PDEV_SET_QUIET_MODE_CMDID, -++ .pdev_green_ap_ps_enable_cmdid = WMI_10_2_PDEV_GREEN_AP_PS_ENABLE_CMDID, -++ .pdev_get_tpc_config_cmdid = WMI_10_2_PDEV_GET_TPC_CONFIG_CMDID, -++ .pdev_set_base_macaddr_cmdid = WMI_10_2_PDEV_SET_BASE_MACADDR_CMDID, -++ .vdev_create_cmdid = WMI_10_2_VDEV_CREATE_CMDID, -++ .vdev_delete_cmdid = WMI_10_2_VDEV_DELETE_CMDID, -++ .vdev_start_request_cmdid = WMI_10_2_VDEV_START_REQUEST_CMDID, -++ .vdev_restart_request_cmdid = WMI_10_2_VDEV_RESTART_REQUEST_CMDID, -++ .vdev_up_cmdid = WMI_10_2_VDEV_UP_CMDID, -++ .vdev_stop_cmdid = WMI_10_2_VDEV_STOP_CMDID, -++ .vdev_down_cmdid = WMI_10_2_VDEV_DOWN_CMDID, -++ .vdev_set_param_cmdid = WMI_10_2_VDEV_SET_PARAM_CMDID, -++ .vdev_install_key_cmdid = WMI_10_2_VDEV_INSTALL_KEY_CMDID, -++ .peer_create_cmdid = WMI_10_2_PEER_CREATE_CMDID, -++ .peer_delete_cmdid = WMI_10_2_PEER_DELETE_CMDID, -++ .peer_flush_tids_cmdid = WMI_10_2_PEER_FLUSH_TIDS_CMDID, -++ .peer_set_param_cmdid = WMI_10_2_PEER_SET_PARAM_CMDID, -++ .peer_assoc_cmdid = WMI_10_2_PEER_ASSOC_CMDID, -++ .peer_add_wds_entry_cmdid = WMI_10_2_PEER_ADD_WDS_ENTRY_CMDID, -++ .peer_remove_wds_entry_cmdid = WMI_10_2_PEER_REMOVE_WDS_ENTRY_CMDID, -++ .peer_mcast_group_cmdid = WMI_10_2_PEER_MCAST_GROUP_CMDID, -++ .bcn_tx_cmdid = WMI_10_2_BCN_TX_CMDID, -++ .pdev_send_bcn_cmdid = WMI_10_2_PDEV_SEND_BCN_CMDID, -++ .bcn_tmpl_cmdid = WMI_CMD_UNSUPPORTED, -++ .bcn_filter_rx_cmdid = WMI_10_2_BCN_FILTER_RX_CMDID, -++ .prb_req_filter_rx_cmdid = WMI_10_2_PRB_REQ_FILTER_RX_CMDID, -++ .mgmt_tx_cmdid = WMI_10_2_MGMT_TX_CMDID, -++ .prb_tmpl_cmdid = WMI_CMD_UNSUPPORTED, -++ .addba_clear_resp_cmdid = WMI_10_2_ADDBA_CLEAR_RESP_CMDID, -++ .addba_send_cmdid = WMI_10_2_ADDBA_SEND_CMDID, -++ .addba_status_cmdid = WMI_10_2_ADDBA_STATUS_CMDID, -++ .delba_send_cmdid = WMI_10_2_DELBA_SEND_CMDID, -++ .addba_set_resp_cmdid = WMI_10_2_ADDBA_SET_RESP_CMDID, -++ .send_singleamsdu_cmdid = WMI_10_2_SEND_SINGLEAMSDU_CMDID, -++ .sta_powersave_mode_cmdid = WMI_10_2_STA_POWERSAVE_MODE_CMDID, -++ .sta_powersave_param_cmdid = WMI_10_2_STA_POWERSAVE_PARAM_CMDID, -++ .sta_mimo_ps_mode_cmdid = WMI_10_2_STA_MIMO_PS_MODE_CMDID, -++ .pdev_dfs_enable_cmdid = WMI_10_2_PDEV_DFS_ENABLE_CMDID, -++ .pdev_dfs_disable_cmdid = WMI_10_2_PDEV_DFS_DISABLE_CMDID, -++ .roam_scan_mode = WMI_10_2_ROAM_SCAN_MODE, -++ .roam_scan_rssi_threshold = WMI_10_2_ROAM_SCAN_RSSI_THRESHOLD, -++ .roam_scan_period = WMI_10_2_ROAM_SCAN_PERIOD, -++ .roam_scan_rssi_change_threshold = -++ WMI_10_2_ROAM_SCAN_RSSI_CHANGE_THRESHOLD, -++ .roam_ap_profile = WMI_10_2_ROAM_AP_PROFILE, -++ .ofl_scan_add_ap_profile = WMI_10_2_OFL_SCAN_ADD_AP_PROFILE, -++ .ofl_scan_remove_ap_profile = WMI_10_2_OFL_SCAN_REMOVE_AP_PROFILE, -++ .ofl_scan_period = WMI_10_2_OFL_SCAN_PERIOD, -++ .p2p_dev_set_device_info = WMI_10_2_P2P_DEV_SET_DEVICE_INFO, -++ .p2p_dev_set_discoverability = WMI_10_2_P2P_DEV_SET_DISCOVERABILITY, -++ .p2p_go_set_beacon_ie = WMI_10_2_P2P_GO_SET_BEACON_IE, -++ .p2p_go_set_probe_resp_ie = WMI_10_2_P2P_GO_SET_PROBE_RESP_IE, -++ .p2p_set_vendor_ie_data_cmdid = WMI_CMD_UNSUPPORTED, -++ .ap_ps_peer_param_cmdid = WMI_10_2_AP_PS_PEER_PARAM_CMDID, -++ .ap_ps_peer_uapsd_coex_cmdid = WMI_CMD_UNSUPPORTED, -++ .peer_rate_retry_sched_cmdid = WMI_10_2_PEER_RATE_RETRY_SCHED_CMDID, -++ .wlan_profile_trigger_cmdid = WMI_10_2_WLAN_PROFILE_TRIGGER_CMDID, -++ .wlan_profile_set_hist_intvl_cmdid = -++ WMI_10_2_WLAN_PROFILE_SET_HIST_INTVL_CMDID, -++ .wlan_profile_get_profile_data_cmdid = -++ WMI_10_2_WLAN_PROFILE_GET_PROFILE_DATA_CMDID, -++ .wlan_profile_enable_profile_id_cmdid = -++ WMI_10_2_WLAN_PROFILE_ENABLE_PROFILE_ID_CMDID, -++ .wlan_profile_list_profile_id_cmdid = -++ WMI_10_2_WLAN_PROFILE_LIST_PROFILE_ID_CMDID, -++ .pdev_suspend_cmdid = WMI_10_2_PDEV_SUSPEND_CMDID, -++ .pdev_resume_cmdid = WMI_10_2_PDEV_RESUME_CMDID, -++ .add_bcn_filter_cmdid = WMI_10_2_ADD_BCN_FILTER_CMDID, -++ .rmv_bcn_filter_cmdid = WMI_10_2_RMV_BCN_FILTER_CMDID, -++ .wow_add_wake_pattern_cmdid = WMI_10_2_WOW_ADD_WAKE_PATTERN_CMDID, -++ .wow_del_wake_pattern_cmdid = WMI_10_2_WOW_DEL_WAKE_PATTERN_CMDID, -++ .wow_enable_disable_wake_event_cmdid = -++ WMI_10_2_WOW_ENABLE_DISABLE_WAKE_EVENT_CMDID, -++ .wow_enable_cmdid = WMI_10_2_WOW_ENABLE_CMDID, -++ .wow_hostwakeup_from_sleep_cmdid = -++ WMI_10_2_WOW_HOSTWAKEUP_FROM_SLEEP_CMDID, -++ .rtt_measreq_cmdid = WMI_10_2_RTT_MEASREQ_CMDID, -++ .rtt_tsf_cmdid = WMI_10_2_RTT_TSF_CMDID, -++ .vdev_spectral_scan_configure_cmdid = -++ WMI_10_2_VDEV_SPECTRAL_SCAN_CONFIGURE_CMDID, -++ .vdev_spectral_scan_enable_cmdid = -++ WMI_10_2_VDEV_SPECTRAL_SCAN_ENABLE_CMDID, -++ .request_stats_cmdid = WMI_10_2_REQUEST_STATS_CMDID, -++ .set_arp_ns_offload_cmdid = WMI_CMD_UNSUPPORTED, -++ .network_list_offload_config_cmdid = WMI_CMD_UNSUPPORTED, -++ .gtk_offload_cmdid = WMI_CMD_UNSUPPORTED, -++ .csa_offload_enable_cmdid = WMI_CMD_UNSUPPORTED, -++ .csa_offload_chanswitch_cmdid = WMI_CMD_UNSUPPORTED, -++ .chatter_set_mode_cmdid = WMI_CMD_UNSUPPORTED, -++ .peer_tid_addba_cmdid = WMI_CMD_UNSUPPORTED, -++ .peer_tid_delba_cmdid = WMI_CMD_UNSUPPORTED, -++ .sta_dtim_ps_method_cmdid = WMI_CMD_UNSUPPORTED, -++ .sta_uapsd_auto_trig_cmdid = WMI_CMD_UNSUPPORTED, -++ .sta_keepalive_cmd = WMI_CMD_UNSUPPORTED, -++ .echo_cmdid = WMI_10_2_ECHO_CMDID, -++ .pdev_utf_cmdid = WMI_10_2_PDEV_UTF_CMDID, -++ .dbglog_cfg_cmdid = WMI_10_2_DBGLOG_CFG_CMDID, -++ .pdev_qvit_cmdid = WMI_10_2_PDEV_QVIT_CMDID, -++ .pdev_ftm_intg_cmdid = WMI_CMD_UNSUPPORTED, -++ .vdev_set_keepalive_cmdid = WMI_CMD_UNSUPPORTED, -++ .vdev_get_keepalive_cmdid = WMI_CMD_UNSUPPORTED, -++ .force_fw_hang_cmdid = WMI_CMD_UNSUPPORTED, -++ .gpio_config_cmdid = WMI_10_2_GPIO_CONFIG_CMDID, -++ .gpio_output_cmdid = WMI_10_2_GPIO_OUTPUT_CMDID, -++ .pdev_get_temperature_cmdid = WMI_CMD_UNSUPPORTED, -+ }; -+ -++void ath10k_wmi_put_wmi_channel(struct wmi_channel *ch, -++ const struct wmi_channel_arg *arg) -++{ -++ u32 flags = 0; -++ -++ memset(ch, 0, sizeof(*ch)); -++ -++ if (arg->passive) -++ flags |= WMI_CHAN_FLAG_PASSIVE; -++ if (arg->allow_ibss) -++ flags |= WMI_CHAN_FLAG_ADHOC_ALLOWED; -++ if (arg->allow_ht) -++ flags |= WMI_CHAN_FLAG_ALLOW_HT; -++ if (arg->allow_vht) -++ flags |= WMI_CHAN_FLAG_ALLOW_VHT; -++ if (arg->ht40plus) -++ flags |= WMI_CHAN_FLAG_HT40_PLUS; -++ if (arg->chan_radar) -++ flags |= WMI_CHAN_FLAG_DFS; -++ -++ ch->mhz = __cpu_to_le32(arg->freq); -++ ch->band_center_freq1 = __cpu_to_le32(arg->band_center_freq1); -++ ch->band_center_freq2 = 0; -++ ch->min_power = arg->min_power; -++ ch->max_power = arg->max_power; -++ ch->reg_power = arg->max_reg_power; -++ ch->antenna_max = arg->max_antenna_gain; -++ -++ /* mode & flags share storage */ -++ ch->mode = arg->mode; -++ ch->flags |= __cpu_to_le32(flags); -++} -++ -+ int ath10k_wmi_wait_for_service_ready(struct ath10k *ar) -+ { -+ int ret; -++ -+ ret = wait_for_completion_timeout(&ar->wmi.service_ready, -+ WMI_SERVICE_READY_TIMEOUT_HZ); -+ return ret; -+@@ -498,23 +894,24 @@ int ath10k_wmi_wait_for_service_ready(st -+ int ath10k_wmi_wait_for_unified_ready(struct ath10k *ar) -+ { -+ int ret; -++ -+ ret = wait_for_completion_timeout(&ar->wmi.unified_ready, -+ WMI_UNIFIED_READY_TIMEOUT_HZ); -+ return ret; -+ } -+ -+-static struct sk_buff *ath10k_wmi_alloc_skb(u32 len) -++struct sk_buff *ath10k_wmi_alloc_skb(struct ath10k *ar, u32 len) -+ { -+ struct sk_buff *skb; -+ u32 round_len = roundup(len, 4); -+ -+- skb = ath10k_htc_alloc_skb(WMI_SKB_HEADROOM + round_len); -++ skb = ath10k_htc_alloc_skb(ar, WMI_SKB_HEADROOM + round_len); -+ if (!skb) -+ return NULL; -+ -+ skb_reserve(skb, WMI_SKB_HEADROOM); -+ if (!IS_ALIGNED((unsigned long)skb->data, 4)) -+- ath10k_warn("Unaligned WMI skb\n"); -++ ath10k_warn(ar, "Unaligned WMI skb\n"); -+ -+ skb_put(skb, round_len); -+ memset(skb->data, 0, round_len); -+@@ -527,8 +924,8 @@ static void ath10k_wmi_htc_tx_complete(s -+ dev_kfree_skb(skb); -+ } -+ -+-static int ath10k_wmi_cmd_send_nowait(struct ath10k *ar, struct sk_buff *skb, -+- u32 cmd_id) -++int ath10k_wmi_cmd_send_nowait(struct ath10k *ar, struct sk_buff *skb, -++ u32 cmd_id) -+ { -+ struct ath10k_skb_cb *skb_cb = ATH10K_SKB_CB(skb); -+ struct wmi_cmd_hdr *cmd_hdr; -+@@ -545,7 +942,7 @@ static int ath10k_wmi_cmd_send_nowait(st -+ -+ memset(skb_cb, 0, sizeof(*skb_cb)); -+ ret = ath10k_htc_send(&ar->htc, ar->wmi.eid, skb); -+- trace_ath10k_wmi_cmd(cmd_id, skb->data, skb->len, ret); -++ trace_ath10k_wmi_cmd(ar, cmd_id, skb->data, skb->len, ret); -+ -+ if (ret) -+ goto err_pull; -+@@ -559,23 +956,45 @@ err_pull: -+ -+ static void ath10k_wmi_tx_beacon_nowait(struct ath10k_vif *arvif) -+ { -++ struct ath10k *ar = arvif->ar; -++ struct ath10k_skb_cb *cb; -++ struct sk_buff *bcn; -+ int ret; -+ -+- lockdep_assert_held(&arvif->ar->data_lock); -++ spin_lock_bh(&ar->data_lock); -+ -+- if (arvif->beacon == NULL) -+- return; -++ bcn = arvif->beacon; -+ -+- if (arvif->beacon_sent) -+- return; -++ if (!bcn) -++ goto unlock; -+ -+- ret = ath10k_wmi_beacon_send_ref_nowait(arvif); -+- if (ret) -+- return; -++ cb = ATH10K_SKB_CB(bcn); -++ -++ switch (arvif->beacon_state) { -++ case ATH10K_BEACON_SENDING: -++ case ATH10K_BEACON_SENT: -++ break; -++ case ATH10K_BEACON_SCHEDULED: -++ arvif->beacon_state = ATH10K_BEACON_SENDING; -++ spin_unlock_bh(&ar->data_lock); -++ -++ ret = ath10k_wmi_beacon_send_ref_nowait(arvif->ar, -++ arvif->vdev_id, -++ bcn->data, bcn->len, -++ cb->paddr, -++ cb->bcn.dtim_zero, -++ cb->bcn.deliver_cab); -++ -++ spin_lock_bh(&ar->data_lock); -+ -+- /* We need to retain the arvif->beacon reference for DMA unmapping and -+- * freeing the skbuff later. */ -+- arvif->beacon_sent = true; -++ if (ret == 0) -++ arvif->beacon_state = ATH10K_BEACON_SENT; -++ else -++ arvif->beacon_state = ATH10K_BEACON_SCHEDULED; -++ } -++ -++unlock: -++ spin_unlock_bh(&ar->data_lock); -+ } -+ -+ static void ath10k_wmi_tx_beacons_iter(void *data, u8 *mac, -+@@ -588,12 +1007,10 @@ static void ath10k_wmi_tx_beacons_iter(v -+ -+ static void ath10k_wmi_tx_beacons_nowait(struct ath10k *ar) -+ { -+- spin_lock_bh(&ar->data_lock); -+ ieee80211_iterate_active_interfaces_atomic(ar->hw, -+ IEEE80211_IFACE_ITER_NORMAL, -+ ath10k_wmi_tx_beacons_iter, -+ NULL); -+- spin_unlock_bh(&ar->data_lock); -+ } -+ -+ static void ath10k_wmi_op_ep_tx_credits(struct ath10k *ar) -+@@ -604,15 +1021,14 @@ static void ath10k_wmi_op_ep_tx_credits( -+ wake_up(&ar->wmi.tx_credits_wq); -+ } -+ -+-static int ath10k_wmi_cmd_send(struct ath10k *ar, struct sk_buff *skb, -+- u32 cmd_id) -++int ath10k_wmi_cmd_send(struct ath10k *ar, struct sk_buff *skb, u32 cmd_id) -+ { -+ int ret = -EOPNOTSUPP; -+ -+ might_sleep(); -+ -+ if (cmd_id == WMI_CMD_UNSUPPORTED) { -+- ath10k_warn("wmi command %d is not supported by firmware\n", -++ ath10k_warn(ar, "wmi command %d is not supported by firmware\n", -+ cmd_id); -+ return ret; -+ } -+@@ -622,6 +1038,10 @@ static int ath10k_wmi_cmd_send(struct at -+ ath10k_wmi_tx_beacons_nowait(ar); -+ -+ ret = ath10k_wmi_cmd_send_nowait(ar, skb, cmd_id); -++ -++ if (ret && test_bit(ATH10K_FLAG_CRASH_FLUSH, &ar->dev_flags)) -++ ret = -ESHUTDOWN; -++ -+ (ret != -EAGAIN); -+ }), 3*HZ); -+ -+@@ -631,147 +1051,270 @@ static int ath10k_wmi_cmd_send(struct at -+ return ret; -+ } -+ -+-int ath10k_wmi_mgmt_tx(struct ath10k *ar, struct sk_buff *skb) -++static struct sk_buff * -++ath10k_wmi_op_gen_mgmt_tx(struct ath10k *ar, struct sk_buff *msdu) -+ { -+- int ret = 0; -+ struct wmi_mgmt_tx_cmd *cmd; -+ struct ieee80211_hdr *hdr; -+- struct sk_buff *wmi_skb; -+- struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); -++ struct sk_buff *skb; -+ int len; -++ u32 buf_len = msdu->len; -+ u16 fc; -+ -+- hdr = (struct ieee80211_hdr *)skb->data; -++ hdr = (struct ieee80211_hdr *)msdu->data; -+ fc = le16_to_cpu(hdr->frame_control); -+ -+ if (WARN_ON_ONCE(!ieee80211_is_mgmt(hdr->frame_control))) -+- return -EINVAL; -++ return ERR_PTR(-EINVAL); -++ -++ len = sizeof(cmd->hdr) + msdu->len; -++ -++ if ((ieee80211_is_action(hdr->frame_control) || -++ ieee80211_is_deauth(hdr->frame_control) || -++ ieee80211_is_disassoc(hdr->frame_control)) && -++ ieee80211_has_protected(hdr->frame_control)) { -++ len += IEEE80211_CCMP_MIC_LEN; -++ buf_len += IEEE80211_CCMP_MIC_LEN; -++ } -+ -+- len = sizeof(cmd->hdr) + skb->len; -+ len = round_up(len, 4); -+ -+- wmi_skb = ath10k_wmi_alloc_skb(len); -+- if (!wmi_skb) -+- return -ENOMEM; -++ skb = ath10k_wmi_alloc_skb(ar, len); -++ if (!skb) -++ return ERR_PTR(-ENOMEM); -+ -+- cmd = (struct wmi_mgmt_tx_cmd *)wmi_skb->data; -++ cmd = (struct wmi_mgmt_tx_cmd *)skb->data; -+ -+- cmd->hdr.vdev_id = __cpu_to_le32(ATH10K_SKB_CB(skb)->vdev_id); -++ cmd->hdr.vdev_id = __cpu_to_le32(ATH10K_SKB_CB(msdu)->vdev_id); -+ cmd->hdr.tx_rate = 0; -+ cmd->hdr.tx_power = 0; -+- cmd->hdr.buf_len = __cpu_to_le32((u32)(skb->len)); -++ cmd->hdr.buf_len = __cpu_to_le32(buf_len); -+ -+- memcpy(cmd->hdr.peer_macaddr.addr, ieee80211_get_DA(hdr), ETH_ALEN); -+- memcpy(cmd->buf, skb->data, skb->len); -++ ether_addr_copy(cmd->hdr.peer_macaddr.addr, ieee80211_get_DA(hdr)); -++ memcpy(cmd->buf, msdu->data, msdu->len); -+ -+- ath10k_dbg(ATH10K_DBG_WMI, "wmi mgmt tx skb %p len %d ftype %02x stype %02x\n", -+- wmi_skb, wmi_skb->len, fc & IEEE80211_FCTL_FTYPE, -++ ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi mgmt tx skb %p len %d ftype %02x stype %02x\n", -++ msdu, skb->len, fc & IEEE80211_FCTL_FTYPE, -+ fc & IEEE80211_FCTL_STYPE); -++ trace_ath10k_tx_hdr(ar, skb->data, skb->len); -++ trace_ath10k_tx_payload(ar, skb->data, skb->len); -+ -+- /* Send the management frame buffer to the target */ -+- ret = ath10k_wmi_cmd_send(ar, wmi_skb, ar->wmi.cmd->mgmt_tx_cmdid); -+- if (ret) -+- return ret; -+- -+- /* TODO: report tx status to mac80211 - temporary just ACK */ -+- info->flags |= IEEE80211_TX_STAT_ACK; -+- ieee80211_tx_status_irqsafe(ar->hw, skb); -+- -+- return ret; -++ return skb; -+ } -+ -+-static int ath10k_wmi_event_scan(struct ath10k *ar, struct sk_buff *skb) -++static void ath10k_wmi_event_scan_started(struct ath10k *ar) -+ { -+- struct wmi_scan_event *event = (struct wmi_scan_event *)skb->data; -+- enum wmi_scan_event_type event_type; -+- enum wmi_scan_completion_reason reason; -+- u32 freq; -+- u32 req_id; -+- u32 scan_id; -+- u32 vdev_id; -+- -+- event_type = __le32_to_cpu(event->event_type); -+- reason = __le32_to_cpu(event->reason); -+- freq = __le32_to_cpu(event->channel_freq); -+- req_id = __le32_to_cpu(event->scan_req_id); -+- scan_id = __le32_to_cpu(event->scan_id); -+- vdev_id = __le32_to_cpu(event->vdev_id); -+- -+- ath10k_dbg(ATH10K_DBG_WMI, "WMI_SCAN_EVENTID\n"); -+- ath10k_dbg(ATH10K_DBG_WMI, -+- "scan event type %d reason %d freq %d req_id %d " -+- "scan_id %d vdev_id %d\n", -+- event_type, reason, freq, req_id, scan_id, vdev_id); -++ lockdep_assert_held(&ar->data_lock); -+ -+- spin_lock_bh(&ar->data_lock); -++ switch (ar->scan.state) { -++ case ATH10K_SCAN_IDLE: -++ case ATH10K_SCAN_RUNNING: -++ case ATH10K_SCAN_ABORTING: -++ ath10k_warn(ar, "received scan started event in an invalid scan state: %s (%d)\n", -++ ath10k_scan_state_str(ar->scan.state), -++ ar->scan.state); -++ break; -++ case ATH10K_SCAN_STARTING: -++ ar->scan.state = ATH10K_SCAN_RUNNING; -+ -+- switch (event_type) { -+- case WMI_SCAN_EVENT_STARTED: -+- ath10k_dbg(ATH10K_DBG_WMI, "SCAN_EVENT_STARTED\n"); -+- if (ar->scan.in_progress && ar->scan.is_roc) -++ if (ar->scan.is_roc) -+ ieee80211_ready_on_channel(ar->hw); -+ -+ complete(&ar->scan.started); -+ break; -+- case WMI_SCAN_EVENT_COMPLETED: -+- ath10k_dbg(ATH10K_DBG_WMI, "SCAN_EVENT_COMPLETED\n"); -+- switch (reason) { -+- case WMI_SCAN_REASON_COMPLETED: -+- ath10k_dbg(ATH10K_DBG_WMI, "SCAN_REASON_COMPLETED\n"); -+- break; -+- case WMI_SCAN_REASON_CANCELLED: -+- ath10k_dbg(ATH10K_DBG_WMI, "SCAN_REASON_CANCELED\n"); -+- break; -+- case WMI_SCAN_REASON_PREEMPTED: -+- ath10k_dbg(ATH10K_DBG_WMI, "SCAN_REASON_PREEMPTED\n"); -+- break; -+- case WMI_SCAN_REASON_TIMEDOUT: -+- ath10k_dbg(ATH10K_DBG_WMI, "SCAN_REASON_TIMEDOUT\n"); -+- break; -+- default: -+- break; -+- } -+- -+- ar->scan_channel = NULL; -+- if (!ar->scan.in_progress) { -+- ath10k_warn("no scan requested, ignoring\n"); -+- break; -+- } -+- -+- if (ar->scan.is_roc) { -+- ath10k_offchan_tx_purge(ar); -++ } -++} -+ -+- if (!ar->scan.aborting) -+- ieee80211_remain_on_channel_expired(ar->hw); -+- } else { -+- ieee80211_scan_completed(ar->hw, ar->scan.aborting); -+- } -++static void ath10k_wmi_event_scan_start_failed(struct ath10k *ar) -++{ -++ lockdep_assert_held(&ar->data_lock); -+ -+- del_timer(&ar->scan.timeout); -+- complete_all(&ar->scan.completed); -+- ar->scan.in_progress = false; -++ switch (ar->scan.state) { -++ case ATH10K_SCAN_IDLE: -++ case ATH10K_SCAN_RUNNING: -++ case ATH10K_SCAN_ABORTING: -++ ath10k_warn(ar, "received scan start failed event in an invalid scan state: %s (%d)\n", -++ ath10k_scan_state_str(ar->scan.state), -++ ar->scan.state); -+ break; -+- case WMI_SCAN_EVENT_BSS_CHANNEL: -+- ath10k_dbg(ATH10K_DBG_WMI, "SCAN_EVENT_BSS_CHANNEL\n"); -+- ar->scan_channel = NULL; -++ case ATH10K_SCAN_STARTING: -++ complete(&ar->scan.started); -++ __ath10k_scan_finish(ar); -+ break; -+- case WMI_SCAN_EVENT_FOREIGN_CHANNEL: -+- ath10k_dbg(ATH10K_DBG_WMI, "SCAN_EVENT_FOREIGN_CHANNEL\n"); -++ } -++} -++ -++static void ath10k_wmi_event_scan_completed(struct ath10k *ar) -++{ -++ lockdep_assert_held(&ar->data_lock); -++ -++ switch (ar->scan.state) { -++ case ATH10K_SCAN_IDLE: -++ case ATH10K_SCAN_STARTING: -++ /* One suspected reason scan can be completed while starting is -++ * if firmware fails to deliver all scan events to the host, -++ * e.g. when transport pipe is full. This has been observed -++ * with spectral scan phyerr events starving wmi transport -++ * pipe. In such case the "scan completed" event should be (and -++ * is) ignored by the host as it may be just firmware's scan -++ * state machine recovering. -++ */ -++ ath10k_warn(ar, "received scan completed event in an invalid scan state: %s (%d)\n", -++ ath10k_scan_state_str(ar->scan.state), -++ ar->scan.state); -++ break; -++ case ATH10K_SCAN_RUNNING: -++ case ATH10K_SCAN_ABORTING: -++ __ath10k_scan_finish(ar); -++ break; -++ } -++} -++ -++static void ath10k_wmi_event_scan_bss_chan(struct ath10k *ar) -++{ -++ lockdep_assert_held(&ar->data_lock); -++ -++ switch (ar->scan.state) { -++ case ATH10K_SCAN_IDLE: -++ case ATH10K_SCAN_STARTING: -++ ath10k_warn(ar, "received scan bss chan event in an invalid scan state: %s (%d)\n", -++ ath10k_scan_state_str(ar->scan.state), -++ ar->scan.state); -++ break; -++ case ATH10K_SCAN_RUNNING: -++ case ATH10K_SCAN_ABORTING: -++ ar->scan_channel = NULL; -++ break; -++ } -++} -++ -++static void ath10k_wmi_event_scan_foreign_chan(struct ath10k *ar, u32 freq) -++{ -++ lockdep_assert_held(&ar->data_lock); -++ -++ switch (ar->scan.state) { -++ case ATH10K_SCAN_IDLE: -++ case ATH10K_SCAN_STARTING: -++ ath10k_warn(ar, "received scan foreign chan event in an invalid scan state: %s (%d)\n", -++ ath10k_scan_state_str(ar->scan.state), -++ ar->scan.state); -++ break; -++ case ATH10K_SCAN_RUNNING: -++ case ATH10K_SCAN_ABORTING: -+ ar->scan_channel = ieee80211_get_channel(ar->hw->wiphy, freq); -+- if (ar->scan.in_progress && ar->scan.is_roc && -+- ar->scan.roc_freq == freq) { -++ -++ if (ar->scan.is_roc && ar->scan.roc_freq == freq) -+ complete(&ar->scan.on_channel); -+- } -+ break; -++ } -++} -++ -++static const char * -++ath10k_wmi_event_scan_type_str(enum wmi_scan_event_type type, -++ enum wmi_scan_completion_reason reason) -++{ -++ switch (type) { -++ case WMI_SCAN_EVENT_STARTED: -++ return "started"; -++ case WMI_SCAN_EVENT_COMPLETED: -++ switch (reason) { -++ case WMI_SCAN_REASON_COMPLETED: -++ return "completed"; -++ case WMI_SCAN_REASON_CANCELLED: -++ return "completed [cancelled]"; -++ case WMI_SCAN_REASON_PREEMPTED: -++ return "completed [preempted]"; -++ case WMI_SCAN_REASON_TIMEDOUT: -++ return "completed [timedout]"; -++ case WMI_SCAN_REASON_MAX: -++ break; -++ } -++ return "completed [unknown]"; -++ case WMI_SCAN_EVENT_BSS_CHANNEL: -++ return "bss channel"; -++ case WMI_SCAN_EVENT_FOREIGN_CHANNEL: -++ return "foreign channel"; -+ case WMI_SCAN_EVENT_DEQUEUED: -+- ath10k_dbg(ATH10K_DBG_WMI, "SCAN_EVENT_DEQUEUED\n"); -+- break; -++ return "dequeued"; -+ case WMI_SCAN_EVENT_PREEMPTED: -+- ath10k_dbg(ATH10K_DBG_WMI, "WMI_SCAN_EVENT_PREEMPTED\n"); -++ return "preempted"; -++ case WMI_SCAN_EVENT_START_FAILED: -++ return "start failed"; -++ default: -++ return "unknown"; -++ } -++} -++ -++static int ath10k_wmi_op_pull_scan_ev(struct ath10k *ar, struct sk_buff *skb, -++ struct wmi_scan_ev_arg *arg) -++{ -++ struct wmi_scan_event *ev = (void *)skb->data; -++ -++ if (skb->len < sizeof(*ev)) -++ return -EPROTO; -++ -++ skb_pull(skb, sizeof(*ev)); -++ arg->event_type = ev->event_type; -++ arg->reason = ev->reason; -++ arg->channel_freq = ev->channel_freq; -++ arg->scan_req_id = ev->scan_req_id; -++ arg->scan_id = ev->scan_id; -++ arg->vdev_id = ev->vdev_id; -++ -++ return 0; -++} -++ -++int ath10k_wmi_event_scan(struct ath10k *ar, struct sk_buff *skb) -++{ -++ struct wmi_scan_ev_arg arg = {}; -++ enum wmi_scan_event_type event_type; -++ enum wmi_scan_completion_reason reason; -++ u32 freq; -++ u32 req_id; -++ u32 scan_id; -++ u32 vdev_id; -++ int ret; -++ -++ ret = ath10k_wmi_pull_scan(ar, skb, &arg); -++ if (ret) { -++ ath10k_warn(ar, "failed to parse scan event: %d\n", ret); -++ return ret; -++ } -++ -++ event_type = __le32_to_cpu(arg.event_type); -++ reason = __le32_to_cpu(arg.reason); -++ freq = __le32_to_cpu(arg.channel_freq); -++ req_id = __le32_to_cpu(arg.scan_req_id); -++ scan_id = __le32_to_cpu(arg.scan_id); -++ vdev_id = __le32_to_cpu(arg.vdev_id); -++ -++ spin_lock_bh(&ar->data_lock); -++ -++ ath10k_dbg(ar, ATH10K_DBG_WMI, -++ "scan event %s type %d reason %d freq %d req_id %d scan_id %d vdev_id %d state %s (%d)\n", -++ ath10k_wmi_event_scan_type_str(event_type, reason), -++ event_type, reason, freq, req_id, scan_id, vdev_id, -++ ath10k_scan_state_str(ar->scan.state), ar->scan.state); -++ -++ switch (event_type) { -++ case WMI_SCAN_EVENT_STARTED: -++ ath10k_wmi_event_scan_started(ar); -++ break; -++ case WMI_SCAN_EVENT_COMPLETED: -++ ath10k_wmi_event_scan_completed(ar); -++ break; -++ case WMI_SCAN_EVENT_BSS_CHANNEL: -++ ath10k_wmi_event_scan_bss_chan(ar); -++ break; -++ case WMI_SCAN_EVENT_FOREIGN_CHANNEL: -++ ath10k_wmi_event_scan_foreign_chan(ar, freq); -+ break; -+ case WMI_SCAN_EVENT_START_FAILED: -+- ath10k_dbg(ATH10K_DBG_WMI, "WMI_SCAN_EVENT_START_FAILED\n"); -++ ath10k_warn(ar, "received scan start failure event\n"); -++ ath10k_wmi_event_scan_start_failed(ar); -+ break; -++ case WMI_SCAN_EVENT_DEQUEUED: -++ case WMI_SCAN_EVENT_PREEMPTED: -+ default: -+ break; -+ } -+@@ -865,13 +1408,86 @@ static inline u8 get_rate_idx(u32 rate, -+ return rate_idx; -+ } -+ -+-static int ath10k_wmi_event_mgmt_rx(struct ath10k *ar, struct sk_buff *skb) -++/* If keys are configured, HW decrypts all frames -++ * with protected bit set. Mark such frames as decrypted. -++ */ -++static void ath10k_wmi_handle_wep_reauth(struct ath10k *ar, -++ struct sk_buff *skb, -++ struct ieee80211_rx_status *status) -++{ -++ struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; -++ unsigned int hdrlen; -++ bool peer_key; -++ u8 *addr, keyidx; -++ -++ if (!ieee80211_is_auth(hdr->frame_control) || -++ !ieee80211_has_protected(hdr->frame_control)) -++ return; -++ -++ hdrlen = ieee80211_hdrlen(hdr->frame_control); -++ if (skb->len < (hdrlen + IEEE80211_WEP_IV_LEN)) -++ return; -++ -++ keyidx = skb->data[hdrlen + (IEEE80211_WEP_IV_LEN - 1)] >> WEP_KEYID_SHIFT; -++ addr = ieee80211_get_SA(hdr); -++ -++ spin_lock_bh(&ar->data_lock); -++ peer_key = ath10k_mac_is_peer_wep_key_set(ar, addr, keyidx); -++ spin_unlock_bh(&ar->data_lock); -++ -++ if (peer_key) { -++ ath10k_dbg(ar, ATH10K_DBG_MAC, -++ "mac wep key present for peer %pM\n", addr); -++ status->flag |= RX_FLAG_DECRYPTED; -++ } -++} -++ -++static int ath10k_wmi_op_pull_mgmt_rx_ev(struct ath10k *ar, struct sk_buff *skb, -++ struct wmi_mgmt_rx_ev_arg *arg) -+ { -+ struct wmi_mgmt_rx_event_v1 *ev_v1; -+ struct wmi_mgmt_rx_event_v2 *ev_v2; -+ struct wmi_mgmt_rx_hdr_v1 *ev_hdr; -++ size_t pull_len; -++ u32 msdu_len; -++ -++ if (test_bit(ATH10K_FW_FEATURE_EXT_WMI_MGMT_RX, ar->fw_features)) { -++ ev_v2 = (struct wmi_mgmt_rx_event_v2 *)skb->data; -++ ev_hdr = &ev_v2->hdr.v1; -++ pull_len = sizeof(*ev_v2); -++ } else { -++ ev_v1 = (struct wmi_mgmt_rx_event_v1 *)skb->data; -++ ev_hdr = &ev_v1->hdr; -++ pull_len = sizeof(*ev_v1); -++ } -++ -++ if (skb->len < pull_len) -++ return -EPROTO; -++ -++ skb_pull(skb, pull_len); -++ arg->channel = ev_hdr->channel; -++ arg->buf_len = ev_hdr->buf_len; -++ arg->status = ev_hdr->status; -++ arg->snr = ev_hdr->snr; -++ arg->phy_mode = ev_hdr->phy_mode; -++ arg->rate = ev_hdr->rate; -++ -++ msdu_len = __le32_to_cpu(arg->buf_len); -++ if (skb->len < msdu_len) -++ return -EPROTO; -++ -++ /* the WMI buffer might've ended up being padded to 4 bytes due to HTC -++ * trailer with credit update. Trim the excess garbage. -++ */ -++ skb_trim(skb, msdu_len); -++ -++ return 0; -++} -++ -++int ath10k_wmi_event_mgmt_rx(struct ath10k *ar, struct sk_buff *skb) -++{ -++ struct wmi_mgmt_rx_ev_arg arg = {}; -+ struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); -+- struct ieee80211_channel *ch; -+ struct ieee80211_hdr *hdr; -+ u32 rx_status; -+ u32 channel; -+@@ -880,28 +1496,24 @@ static int ath10k_wmi_event_mgmt_rx(stru -+ u32 rate; -+ u32 buf_len; -+ u16 fc; -+- int pull_len; -++ int ret; -+ -+- if (test_bit(ATH10K_FW_FEATURE_EXT_WMI_MGMT_RX, ar->fw_features)) { -+- ev_v2 = (struct wmi_mgmt_rx_event_v2 *)skb->data; -+- ev_hdr = &ev_v2->hdr.v1; -+- pull_len = sizeof(*ev_v2); -+- } else { -+- ev_v1 = (struct wmi_mgmt_rx_event_v1 *)skb->data; -+- ev_hdr = &ev_v1->hdr; -+- pull_len = sizeof(*ev_v1); -++ ret = ath10k_wmi_pull_mgmt_rx(ar, skb, &arg); -++ if (ret) { -++ ath10k_warn(ar, "failed to parse mgmt rx event: %d\n", ret); -++ return ret; -+ } -+ -+- channel = __le32_to_cpu(ev_hdr->channel); -+- buf_len = __le32_to_cpu(ev_hdr->buf_len); -+- rx_status = __le32_to_cpu(ev_hdr->status); -+- snr = __le32_to_cpu(ev_hdr->snr); -+- phy_mode = __le32_to_cpu(ev_hdr->phy_mode); -+- rate = __le32_to_cpu(ev_hdr->rate); -++ channel = __le32_to_cpu(arg.channel); -++ buf_len = __le32_to_cpu(arg.buf_len); -++ rx_status = __le32_to_cpu(arg.status); -++ snr = __le32_to_cpu(arg.snr); -++ phy_mode = __le32_to_cpu(arg.phy_mode); -++ rate = __le32_to_cpu(arg.rate); -+ -+ memset(status, 0, sizeof(*status)); -+ -+- ath10k_dbg(ATH10K_DBG_MGMT, -++ ath10k_dbg(ar, ATH10K_DBG_MGMT, -+ "event mgmt rx status %08x\n", rx_status); -+ -+ if (test_bit(ATH10K_CAC_RUNNING, &ar->dev_flags)) { -+@@ -919,66 +1531,70 @@ static int ath10k_wmi_event_mgmt_rx(stru -+ return 0; -+ } -+ -+- if (rx_status & WMI_RX_STATUS_ERR_CRC) -+- status->flag |= RX_FLAG_FAILED_FCS_CRC; -++ if (rx_status & WMI_RX_STATUS_ERR_CRC) { -++ dev_kfree_skb(skb); -++ return 0; -++ } -++ -+ if (rx_status & WMI_RX_STATUS_ERR_MIC) -+ status->flag |= RX_FLAG_MMIC_ERROR; -+ -+- /* HW can Rx CCK rates on 5GHz. In that case phy_mode is set to -++ /* Hardware can Rx CCK rates on 5GHz. In that case phy_mode is set to -+ * MODE_11B. This means phy_mode is not a reliable source for the band -+- * of mgmt rx. */ -+- -+- ch = ar->scan_channel; -+- if (!ch) -+- ch = ar->rx_channel; -+- -+- if (ch) { -+- status->band = ch->band; -+- -+- if (phy_mode == MODE_11B && -+- status->band == IEEE80211_BAND_5GHZ) -+- ath10k_dbg(ATH10K_DBG_MGMT, "wmi mgmt rx 11b (CCK) on 5GHz\n"); -++ * of mgmt rx. -++ */ -++ if (channel >= 1 && channel <= 14) { -++ status->band = IEEE80211_BAND_2GHZ; -++ } else if (channel >= 36 && channel <= 165) { -++ status->band = IEEE80211_BAND_5GHZ; -+ } else { -+- ath10k_warn("using (unreliable) phy_mode to extract band for mgmt rx\n"); -+- status->band = phy_mode_to_band(phy_mode); -++ /* Shouldn't happen unless list of advertised channels to -++ * mac80211 has been changed. -++ */ -++ WARN_ON_ONCE(1); -++ dev_kfree_skb(skb); -++ return 0; -+ } -+ -++ if (phy_mode == MODE_11B && status->band == IEEE80211_BAND_5GHZ) -++ ath10k_dbg(ar, ATH10K_DBG_MGMT, "wmi mgmt rx 11b (CCK) on 5GHz\n"); -++ -+ status->freq = ieee80211_channel_to_frequency(channel, status->band); -+ status->signal = snr + ATH10K_DEFAULT_NOISE_FLOOR; -+ status->rate_idx = get_rate_idx(rate, status->band); -+ -+- skb_pull(skb, pull_len); -+- -+ hdr = (struct ieee80211_hdr *)skb->data; -+ fc = le16_to_cpu(hdr->frame_control); -+ -++ ath10k_wmi_handle_wep_reauth(ar, skb, status); -++ -+ /* FW delivers WEP Shared Auth frame with Protected Bit set and -+ * encrypted payload. However in case of PMF it delivers decrypted -+ * frames with Protected Bit set. */ -+ if (ieee80211_has_protected(hdr->frame_control) && -+ !ieee80211_is_auth(hdr->frame_control)) { -+- status->flag |= RX_FLAG_DECRYPTED | RX_FLAG_IV_STRIPPED | -+- RX_FLAG_MMIC_STRIPPED; -+- hdr->frame_control = __cpu_to_le16(fc & -++ status->flag |= RX_FLAG_DECRYPTED; -++ -++ if (!ieee80211_is_action(hdr->frame_control) && -++ !ieee80211_is_deauth(hdr->frame_control) && -++ !ieee80211_is_disassoc(hdr->frame_control)) { -++ status->flag |= RX_FLAG_IV_STRIPPED | -++ RX_FLAG_MMIC_STRIPPED; -++ hdr->frame_control = __cpu_to_le16(fc & -+ ~IEEE80211_FCTL_PROTECTED); -++ } -+ } -+ -+- ath10k_dbg(ATH10K_DBG_MGMT, -++ ath10k_dbg(ar, ATH10K_DBG_MGMT, -+ "event mgmt rx skb %p len %d ftype %02x stype %02x\n", -+ skb, skb->len, -+ fc & IEEE80211_FCTL_FTYPE, fc & IEEE80211_FCTL_STYPE); -+ -+- ath10k_dbg(ATH10K_DBG_MGMT, -++ ath10k_dbg(ar, ATH10K_DBG_MGMT, -+ "event mgmt rx freq %d band %d snr %d, rate_idx %d\n", -+ status->freq, status->band, status->signal, -+ status->rate_idx); -+ -+- /* -+- * packets from HTC come aligned to 4byte boundaries -+- * because they can originally come in along with a trailer -+- */ -+- skb_trim(skb, buf_len); -+- -+ ieee80211_rx(ar->hw, skb); -+ return 0; -+ } -+@@ -1002,37 +1618,65 @@ exit: -+ return idx; -+ } -+ -+-static void ath10k_wmi_event_chan_info(struct ath10k *ar, struct sk_buff *skb) -++static int ath10k_wmi_op_pull_ch_info_ev(struct ath10k *ar, struct sk_buff *skb, -++ struct wmi_ch_info_ev_arg *arg) -++{ -++ struct wmi_chan_info_event *ev = (void *)skb->data; -++ -++ if (skb->len < sizeof(*ev)) -++ return -EPROTO; -++ -++ skb_pull(skb, sizeof(*ev)); -++ arg->err_code = ev->err_code; -++ arg->freq = ev->freq; -++ arg->cmd_flags = ev->cmd_flags; -++ arg->noise_floor = ev->noise_floor; -++ arg->rx_clear_count = ev->rx_clear_count; -++ arg->cycle_count = ev->cycle_count; -++ -++ return 0; -++} -++ -++void ath10k_wmi_event_chan_info(struct ath10k *ar, struct sk_buff *skb) -+ { -+- struct wmi_chan_info_event *ev; -++ struct wmi_ch_info_ev_arg arg = {}; -+ struct survey_info *survey; -+ u32 err_code, freq, cmd_flags, noise_floor, rx_clear_count, cycle_count; -+- int idx; -++ int idx, ret; -+ -+- ev = (struct wmi_chan_info_event *)skb->data; -++ ret = ath10k_wmi_pull_ch_info(ar, skb, &arg); -++ if (ret) { -++ ath10k_warn(ar, "failed to parse chan info event: %d\n", ret); -++ return; -++ } -+ -+- err_code = __le32_to_cpu(ev->err_code); -+- freq = __le32_to_cpu(ev->freq); -+- cmd_flags = __le32_to_cpu(ev->cmd_flags); -+- noise_floor = __le32_to_cpu(ev->noise_floor); -+- rx_clear_count = __le32_to_cpu(ev->rx_clear_count); -+- cycle_count = __le32_to_cpu(ev->cycle_count); -++ err_code = __le32_to_cpu(arg.err_code); -++ freq = __le32_to_cpu(arg.freq); -++ cmd_flags = __le32_to_cpu(arg.cmd_flags); -++ noise_floor = __le32_to_cpu(arg.noise_floor); -++ rx_clear_count = __le32_to_cpu(arg.rx_clear_count); -++ cycle_count = __le32_to_cpu(arg.cycle_count); -+ -+- ath10k_dbg(ATH10K_DBG_WMI, -++ ath10k_dbg(ar, ATH10K_DBG_WMI, -+ "chan info err_code %d freq %d cmd_flags %d noise_floor %d rx_clear_count %d cycle_count %d\n", -+ err_code, freq, cmd_flags, noise_floor, rx_clear_count, -+ cycle_count); -+ -+ spin_lock_bh(&ar->data_lock); -+ -+- if (!ar->scan.in_progress) { -+- ath10k_warn("chan info event without a scan request?\n"); -++ switch (ar->scan.state) { -++ case ATH10K_SCAN_IDLE: -++ case ATH10K_SCAN_STARTING: -++ ath10k_warn(ar, "received chan info event without a scan request, ignoring\n"); -+ goto exit; -++ case ATH10K_SCAN_RUNNING: -++ case ATH10K_SCAN_ABORTING: -++ break; -+ } -+ -+ idx = freq_to_idx(ar, freq); -+ if (idx >= ARRAY_SIZE(ar->survey)) { -+- ath10k_warn("chan info: invalid frequency %d (idx %d out of bounds)\n", -++ ath10k_warn(ar, "chan info: invalid frequency %d (idx %d out of bounds)\n", -+ freq, idx); -+ goto exit; -+ } -+@@ -1061,191 +1705,579 @@ exit: -+ spin_unlock_bh(&ar->data_lock); -+ } -+ -+-static void ath10k_wmi_event_echo(struct ath10k *ar, struct sk_buff *skb) -++void ath10k_wmi_event_echo(struct ath10k *ar, struct sk_buff *skb) -+ { -+- ath10k_dbg(ATH10K_DBG_WMI, "WMI_ECHO_EVENTID\n"); -++ ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_ECHO_EVENTID\n"); -+ } -+ -+-static int ath10k_wmi_event_debug_mesg(struct ath10k *ar, struct sk_buff *skb) -++int ath10k_wmi_event_debug_mesg(struct ath10k *ar, struct sk_buff *skb) -+ { -+- ath10k_dbg(ATH10K_DBG_WMI, "wmi event debug mesg len %d\n", -++ ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi event debug mesg len %d\n", -+ skb->len); -+ -+- trace_ath10k_wmi_dbglog(skb->data, skb->len); -++ trace_ath10k_wmi_dbglog(ar, skb->data, skb->len); -+ -+ return 0; -+ } -+ -+-static void ath10k_wmi_event_update_stats(struct ath10k *ar, -+- struct sk_buff *skb) -++void ath10k_wmi_pull_pdev_stats_base(const struct wmi_pdev_stats_base *src, -++ struct ath10k_fw_stats_pdev *dst) -+ { -+- struct wmi_stats_event *ev = (struct wmi_stats_event *)skb->data; -+- -+- ath10k_dbg(ATH10K_DBG_WMI, "WMI_UPDATE_STATS_EVENTID\n"); -+- -+- ath10k_debug_read_target_stats(ar, ev); -+-} -+- -+-static void ath10k_wmi_event_vdev_start_resp(struct ath10k *ar, -+- struct sk_buff *skb) -++ dst->ch_noise_floor = __le32_to_cpu(src->chan_nf); -++ dst->tx_frame_count = __le32_to_cpu(src->tx_frame_count); -++ dst->rx_frame_count = __le32_to_cpu(src->rx_frame_count); -++ dst->rx_clear_count = __le32_to_cpu(src->rx_clear_count); -++ dst->cycle_count = __le32_to_cpu(src->cycle_count); -++ dst->phy_err_count = __le32_to_cpu(src->phy_err_count); -++ dst->chan_tx_power = __le32_to_cpu(src->chan_tx_pwr); -++} -++ -++void ath10k_wmi_pull_pdev_stats_tx(const struct wmi_pdev_stats_tx *src, -++ struct ath10k_fw_stats_pdev *dst) -++{ -++ dst->comp_queued = __le32_to_cpu(src->comp_queued); -++ dst->comp_delivered = __le32_to_cpu(src->comp_delivered); -++ dst->msdu_enqued = __le32_to_cpu(src->msdu_enqued); -++ dst->mpdu_enqued = __le32_to_cpu(src->mpdu_enqued); -++ dst->wmm_drop = __le32_to_cpu(src->wmm_drop); -++ dst->local_enqued = __le32_to_cpu(src->local_enqued); -++ dst->local_freed = __le32_to_cpu(src->local_freed); -++ dst->hw_queued = __le32_to_cpu(src->hw_queued); -++ dst->hw_reaped = __le32_to_cpu(src->hw_reaped); -++ dst->underrun = __le32_to_cpu(src->underrun); -++ dst->tx_abort = __le32_to_cpu(src->tx_abort); -++ dst->mpdus_requed = __le32_to_cpu(src->mpdus_requed); -++ dst->tx_ko = __le32_to_cpu(src->tx_ko); -++ dst->data_rc = __le32_to_cpu(src->data_rc); -++ dst->self_triggers = __le32_to_cpu(src->self_triggers); -++ dst->sw_retry_failure = __le32_to_cpu(src->sw_retry_failure); -++ dst->illgl_rate_phy_err = __le32_to_cpu(src->illgl_rate_phy_err); -++ dst->pdev_cont_xretry = __le32_to_cpu(src->pdev_cont_xretry); -++ dst->pdev_tx_timeout = __le32_to_cpu(src->pdev_tx_timeout); -++ dst->pdev_resets = __le32_to_cpu(src->pdev_resets); -++ dst->phy_underrun = __le32_to_cpu(src->phy_underrun); -++ dst->txop_ovf = __le32_to_cpu(src->txop_ovf); -++} -++ -++void ath10k_wmi_pull_pdev_stats_rx(const struct wmi_pdev_stats_rx *src, -++ struct ath10k_fw_stats_pdev *dst) -++{ -++ dst->mid_ppdu_route_change = __le32_to_cpu(src->mid_ppdu_route_change); -++ dst->status_rcvd = __le32_to_cpu(src->status_rcvd); -++ dst->r0_frags = __le32_to_cpu(src->r0_frags); -++ dst->r1_frags = __le32_to_cpu(src->r1_frags); -++ dst->r2_frags = __le32_to_cpu(src->r2_frags); -++ dst->r3_frags = __le32_to_cpu(src->r3_frags); -++ dst->htt_msdus = __le32_to_cpu(src->htt_msdus); -++ dst->htt_mpdus = __le32_to_cpu(src->htt_mpdus); -++ dst->loc_msdus = __le32_to_cpu(src->loc_msdus); -++ dst->loc_mpdus = __le32_to_cpu(src->loc_mpdus); -++ dst->oversize_amsdu = __le32_to_cpu(src->oversize_amsdu); -++ dst->phy_errs = __le32_to_cpu(src->phy_errs); -++ dst->phy_err_drop = __le32_to_cpu(src->phy_err_drop); -++ dst->mpdu_errs = __le32_to_cpu(src->mpdu_errs); -++} -++ -++void ath10k_wmi_pull_pdev_stats_extra(const struct wmi_pdev_stats_extra *src, -++ struct ath10k_fw_stats_pdev *dst) -++{ -++ dst->ack_rx_bad = __le32_to_cpu(src->ack_rx_bad); -++ dst->rts_bad = __le32_to_cpu(src->rts_bad); -++ dst->rts_good = __le32_to_cpu(src->rts_good); -++ dst->fcs_bad = __le32_to_cpu(src->fcs_bad); -++ dst->no_beacons = __le32_to_cpu(src->no_beacons); -++ dst->mib_int_count = __le32_to_cpu(src->mib_int_count); -++} -++ -++void ath10k_wmi_pull_peer_stats(const struct wmi_peer_stats *src, -++ struct ath10k_fw_stats_peer *dst) -++{ -++ ether_addr_copy(dst->peer_macaddr, src->peer_macaddr.addr); -++ dst->peer_rssi = __le32_to_cpu(src->peer_rssi); -++ dst->peer_tx_rate = __le32_to_cpu(src->peer_tx_rate); -++} -++ -++static int ath10k_wmi_main_op_pull_fw_stats(struct ath10k *ar, -++ struct sk_buff *skb, -++ struct ath10k_fw_stats *stats) -+ { -+- struct wmi_vdev_start_response_event *ev; -++ const struct wmi_stats_event *ev = (void *)skb->data; -++ u32 num_pdev_stats, num_vdev_stats, num_peer_stats; -++ int i; -+ -+- ath10k_dbg(ATH10K_DBG_WMI, "WMI_VDEV_START_RESP_EVENTID\n"); -++ if (!skb_pull(skb, sizeof(*ev))) -++ return -EPROTO; -+ -+- ev = (struct wmi_vdev_start_response_event *)skb->data; -++ num_pdev_stats = __le32_to_cpu(ev->num_pdev_stats); -++ num_vdev_stats = __le32_to_cpu(ev->num_vdev_stats); -++ num_peer_stats = __le32_to_cpu(ev->num_peer_stats); -++ -++ for (i = 0; i < num_pdev_stats; i++) { -++ const struct wmi_pdev_stats *src; -++ struct ath10k_fw_stats_pdev *dst; -++ -++ src = (void *)skb->data; -++ if (!skb_pull(skb, sizeof(*src))) -++ return -EPROTO; -+ -+- if (WARN_ON(__le32_to_cpu(ev->status))) -+- return; -++ dst = kzalloc(sizeof(*dst), GFP_ATOMIC); -++ if (!dst) -++ continue; -+ -+- complete(&ar->vdev_setup_done); -+-} -++ ath10k_wmi_pull_pdev_stats_base(&src->base, dst); -++ ath10k_wmi_pull_pdev_stats_tx(&src->tx, dst); -++ ath10k_wmi_pull_pdev_stats_rx(&src->rx, dst); -+ -+-static void ath10k_wmi_event_vdev_stopped(struct ath10k *ar, -+- struct sk_buff *skb) -+-{ -+- ath10k_dbg(ATH10K_DBG_WMI, "WMI_VDEV_STOPPED_EVENTID\n"); -+- complete(&ar->vdev_setup_done); -+-} -++ list_add_tail(&dst->list, &stats->pdevs); -++ } -+ -+-static void ath10k_wmi_event_peer_sta_kickout(struct ath10k *ar, -+- struct sk_buff *skb) -+-{ -+- struct wmi_peer_sta_kickout_event *ev; -+- struct ieee80211_sta *sta; -++ /* fw doesn't implement vdev stats */ -+ -+- ev = (struct wmi_peer_sta_kickout_event *)skb->data; -++ for (i = 0; i < num_peer_stats; i++) { -++ const struct wmi_peer_stats *src; -++ struct ath10k_fw_stats_peer *dst; -+ -+- ath10k_dbg(ATH10K_DBG_WMI, "wmi event peer sta kickout %pM\n", -+- ev->peer_macaddr.addr); -++ src = (void *)skb->data; -++ if (!skb_pull(skb, sizeof(*src))) -++ return -EPROTO; -+ -+- rcu_read_lock(); -++ dst = kzalloc(sizeof(*dst), GFP_ATOMIC); -++ if (!dst) -++ continue; -+ -+- sta = ieee80211_find_sta_by_ifaddr(ar->hw, ev->peer_macaddr.addr, NULL); -+- if (!sta) { -+- ath10k_warn("Spurious quick kickout for STA %pM\n", -+- ev->peer_macaddr.addr); -+- goto exit; -++ ath10k_wmi_pull_peer_stats(src, dst); -++ list_add_tail(&dst->list, &stats->peers); -+ } -+ -+- ieee80211_report_low_ack(sta, 10); -+- -+-exit: -+- rcu_read_unlock(); -++ return 0; -+ } -+ -+-/* -+- * FIXME -+- * -+- * We don't report to mac80211 sleep state of connected -+- * stations. Due to this mac80211 can't fill in TIM IE -+- * correctly. -+- * -+- * I know of no way of getting nullfunc frames that contain -+- * sleep transition from connected stations - these do not -+- * seem to be sent from the target to the host. There also -+- * doesn't seem to be a dedicated event for that. So the -+- * only way left to do this would be to read tim_bitmap -+- * during SWBA. -+- * -+- * We could probably try using tim_bitmap from SWBA to tell -+- * mac80211 which stations are asleep and which are not. The -+- * problem here is calling mac80211 functions so many times -+- * could take too long and make us miss the time to submit -+- * the beacon to the target. -+- * -+- * So as a workaround we try to extend the TIM IE if there -+- * is unicast buffered for stations with aid > 7 and fill it -+- * in ourselves. -+- */ -+-static void ath10k_wmi_update_tim(struct ath10k *ar, -+- struct ath10k_vif *arvif, -+- struct sk_buff *bcn, -+- struct wmi_bcn_info *bcn_info) -++static int ath10k_wmi_10x_op_pull_fw_stats(struct ath10k *ar, -++ struct sk_buff *skb, -++ struct ath10k_fw_stats *stats) -+ { -+- struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)bcn->data; -+- struct ieee80211_tim_ie *tim; -+- u8 *ies, *ie; -+- u8 ie_len, pvm_len; -++ const struct wmi_stats_event *ev = (void *)skb->data; -++ u32 num_pdev_stats, num_vdev_stats, num_peer_stats; -++ int i; -+ -+- /* if next SWBA has no tim_changed the tim_bitmap is garbage. -+- * we must copy the bitmap upon change and reuse it later */ -+- if (__le32_to_cpu(bcn_info->tim_info.tim_changed)) { -+- int i; -++ if (!skb_pull(skb, sizeof(*ev))) -++ return -EPROTO; -+ -+- BUILD_BUG_ON(sizeof(arvif->u.ap.tim_bitmap) != -+- sizeof(bcn_info->tim_info.tim_bitmap)); -++ num_pdev_stats = __le32_to_cpu(ev->num_pdev_stats); -++ num_vdev_stats = __le32_to_cpu(ev->num_vdev_stats); -++ num_peer_stats = __le32_to_cpu(ev->num_peer_stats); -++ -++ for (i = 0; i < num_pdev_stats; i++) { -++ const struct wmi_10x_pdev_stats *src; -++ struct ath10k_fw_stats_pdev *dst; -++ -++ src = (void *)skb->data; -++ if (!skb_pull(skb, sizeof(*src))) -++ return -EPROTO; -+ -+- for (i = 0; i < sizeof(arvif->u.ap.tim_bitmap); i++) { -+- __le32 t = bcn_info->tim_info.tim_bitmap[i / 4]; -+- u32 v = __le32_to_cpu(t); -+- arvif->u.ap.tim_bitmap[i] = (v >> ((i % 4) * 8)) & 0xFF; -+- } -++ dst = kzalloc(sizeof(*dst), GFP_ATOMIC); -++ if (!dst) -++ continue; -+ -+- /* FW reports either length 0 or 16 -+- * so we calculate this on our own */ -+- arvif->u.ap.tim_len = 0; -+- for (i = 0; i < sizeof(arvif->u.ap.tim_bitmap); i++) -+- if (arvif->u.ap.tim_bitmap[i]) -+- arvif->u.ap.tim_len = i; -++ ath10k_wmi_pull_pdev_stats_base(&src->base, dst); -++ ath10k_wmi_pull_pdev_stats_tx(&src->tx, dst); -++ ath10k_wmi_pull_pdev_stats_rx(&src->rx, dst); -++ ath10k_wmi_pull_pdev_stats_extra(&src->extra, dst); -+ -+- arvif->u.ap.tim_len++; -++ list_add_tail(&dst->list, &stats->pdevs); -+ } -+ -+- ies = bcn->data; -+- ies += ieee80211_hdrlen(hdr->frame_control); -+- ies += 12; /* fixed parameters */ -++ /* fw doesn't implement vdev stats */ -+ -+- ie = (u8 *)cfg80211_find_ie(WLAN_EID_TIM, ies, -+- (u8 *)skb_tail_pointer(bcn) - ies); -+- if (!ie) { -+- if (arvif->vdev_type != WMI_VDEV_TYPE_IBSS) -+- ath10k_warn("no tim ie found;\n"); -+- return; -+- } -++ for (i = 0; i < num_peer_stats; i++) { -++ const struct wmi_10x_peer_stats *src; -++ struct ath10k_fw_stats_peer *dst; -+ -+- tim = (void *)ie + 2; -+- ie_len = ie[1]; -+- pvm_len = ie_len - 3; /* exclude dtim count, dtim period, bmap ctl */ -++ src = (void *)skb->data; -++ if (!skb_pull(skb, sizeof(*src))) -++ return -EPROTO; -+ -+- if (pvm_len < arvif->u.ap.tim_len) { -+- int expand_size = sizeof(arvif->u.ap.tim_bitmap) - pvm_len; -+- int move_size = skb_tail_pointer(bcn) - (ie + 2 + ie_len); -+- void *next_ie = ie + 2 + ie_len; -++ dst = kzalloc(sizeof(*dst), GFP_ATOMIC); -++ if (!dst) -++ continue; -+ -+- if (skb_put(bcn, expand_size)) { -+- memmove(next_ie + expand_size, next_ie, move_size); -++ ath10k_wmi_pull_peer_stats(&src->old, dst); -+ -+- ie[1] += expand_size; -+- ie_len += expand_size; -+- pvm_len += expand_size; -+- } else { -+- ath10k_warn("tim expansion failed\n"); -+- } -+- } -++ dst->peer_rx_rate = __le32_to_cpu(src->peer_rx_rate); -+ -+- if (pvm_len > sizeof(arvif->u.ap.tim_bitmap)) { -+- ath10k_warn("tim pvm length is too great (%d)\n", pvm_len); -+- return; -++ list_add_tail(&dst->list, &stats->peers); -+ } -+ -+- tim->bitmap_ctrl = !!__le32_to_cpu(bcn_info->tim_info.tim_mcast); -+- memcpy(tim->virtual_map, arvif->u.ap.tim_bitmap, pvm_len); -++ return 0; -++} -+ -+- if (tim->dtim_count == 0) { -+- ATH10K_SKB_CB(bcn)->bcn.dtim_zero = true; -++static int ath10k_wmi_10_2_op_pull_fw_stats(struct ath10k *ar, -++ struct sk_buff *skb, -++ struct ath10k_fw_stats *stats) -++{ -++ const struct wmi_10_2_stats_event *ev = (void *)skb->data; -++ u32 num_pdev_stats; -++ u32 num_pdev_ext_stats; -++ u32 num_vdev_stats; -++ u32 num_peer_stats; -++ int i; -+ -+- if (__le32_to_cpu(bcn_info->tim_info.tim_mcast) == 1) -+- ATH10K_SKB_CB(bcn)->bcn.deliver_cab = true; -+- } -++ if (!skb_pull(skb, sizeof(*ev))) -++ return -EPROTO; -+ -+- ath10k_dbg(ATH10K_DBG_MGMT, "dtim %d/%d mcast %d pvmlen %d\n", -+- tim->dtim_count, tim->dtim_period, -+- tim->bitmap_ctrl, pvm_len); -++ num_pdev_stats = __le32_to_cpu(ev->num_pdev_stats); -++ num_pdev_ext_stats = __le32_to_cpu(ev->num_pdev_ext_stats); -++ num_vdev_stats = __le32_to_cpu(ev->num_vdev_stats); -++ num_peer_stats = __le32_to_cpu(ev->num_peer_stats); -++ -++ for (i = 0; i < num_pdev_stats; i++) { -++ const struct wmi_10_2_pdev_stats *src; -++ struct ath10k_fw_stats_pdev *dst; -++ -++ src = (void *)skb->data; -++ if (!skb_pull(skb, sizeof(*src))) -++ return -EPROTO; -++ -++ dst = kzalloc(sizeof(*dst), GFP_ATOMIC); -++ if (!dst) -++ continue; -++ -++ ath10k_wmi_pull_pdev_stats_base(&src->base, dst); -++ ath10k_wmi_pull_pdev_stats_tx(&src->tx, dst); -++ ath10k_wmi_pull_pdev_stats_rx(&src->rx, dst); -++ ath10k_wmi_pull_pdev_stats_extra(&src->extra, dst); -++ /* FIXME: expose 10.2 specific values */ -++ -++ list_add_tail(&dst->list, &stats->pdevs); -++ } -++ -++ for (i = 0; i < num_pdev_ext_stats; i++) { -++ const struct wmi_10_2_pdev_ext_stats *src; -++ -++ src = (void *)skb->data; -++ if (!skb_pull(skb, sizeof(*src))) -++ return -EPROTO; -++ -++ /* FIXME: expose values to userspace -++ * -++ * Note: Even though this loop seems to do nothing it is -++ * required to parse following sub-structures properly. -++ */ -++ } -++ -++ /* fw doesn't implement vdev stats */ -++ -++ for (i = 0; i < num_peer_stats; i++) { -++ const struct wmi_10_2_peer_stats *src; -++ struct ath10k_fw_stats_peer *dst; -++ -++ src = (void *)skb->data; -++ if (!skb_pull(skb, sizeof(*src))) -++ return -EPROTO; -++ -++ dst = kzalloc(sizeof(*dst), GFP_ATOMIC); -++ if (!dst) -++ continue; -++ -++ ath10k_wmi_pull_peer_stats(&src->old, dst); -++ -++ dst->peer_rx_rate = __le32_to_cpu(src->peer_rx_rate); -++ /* FIXME: expose 10.2 specific values */ -++ -++ list_add_tail(&dst->list, &stats->peers); -++ } -++ -++ return 0; -++} -++ -++static int ath10k_wmi_10_2_4_op_pull_fw_stats(struct ath10k *ar, -++ struct sk_buff *skb, -++ struct ath10k_fw_stats *stats) -++{ -++ const struct wmi_10_2_stats_event *ev = (void *)skb->data; -++ u32 num_pdev_stats; -++ u32 num_pdev_ext_stats; -++ u32 num_vdev_stats; -++ u32 num_peer_stats; -++ int i; -++ -++ if (!skb_pull(skb, sizeof(*ev))) -++ return -EPROTO; -++ -++ num_pdev_stats = __le32_to_cpu(ev->num_pdev_stats); -++ num_pdev_ext_stats = __le32_to_cpu(ev->num_pdev_ext_stats); -++ num_vdev_stats = __le32_to_cpu(ev->num_vdev_stats); -++ num_peer_stats = __le32_to_cpu(ev->num_peer_stats); -++ -++ for (i = 0; i < num_pdev_stats; i++) { -++ const struct wmi_10_2_pdev_stats *src; -++ struct ath10k_fw_stats_pdev *dst; -++ -++ src = (void *)skb->data; -++ if (!skb_pull(skb, sizeof(*src))) -++ return -EPROTO; -++ -++ dst = kzalloc(sizeof(*dst), GFP_ATOMIC); -++ if (!dst) -++ continue; -++ -++ ath10k_wmi_pull_pdev_stats_base(&src->base, dst); -++ ath10k_wmi_pull_pdev_stats_tx(&src->tx, dst); -++ ath10k_wmi_pull_pdev_stats_rx(&src->rx, dst); -++ ath10k_wmi_pull_pdev_stats_extra(&src->extra, dst); -++ /* FIXME: expose 10.2 specific values */ -++ -++ list_add_tail(&dst->list, &stats->pdevs); -++ } -++ -++ for (i = 0; i < num_pdev_ext_stats; i++) { -++ const struct wmi_10_2_pdev_ext_stats *src; -++ -++ src = (void *)skb->data; -++ if (!skb_pull(skb, sizeof(*src))) -++ return -EPROTO; -++ -++ /* FIXME: expose values to userspace -++ * -++ * Note: Even though this loop seems to do nothing it is -++ * required to parse following sub-structures properly. -++ */ -++ } -++ -++ /* fw doesn't implement vdev stats */ -++ -++ for (i = 0; i < num_peer_stats; i++) { -++ const struct wmi_10_2_4_peer_stats *src; -++ struct ath10k_fw_stats_peer *dst; -++ -++ src = (void *)skb->data; -++ if (!skb_pull(skb, sizeof(*src))) -++ return -EPROTO; -++ -++ dst = kzalloc(sizeof(*dst), GFP_ATOMIC); -++ if (!dst) -++ continue; -++ -++ ath10k_wmi_pull_peer_stats(&src->common.old, dst); -++ -++ dst->peer_rx_rate = __le32_to_cpu(src->common.peer_rx_rate); -++ /* FIXME: expose 10.2 specific values */ -++ -++ list_add_tail(&dst->list, &stats->peers); -++ } -++ -++ return 0; -++} -++ -++void ath10k_wmi_event_update_stats(struct ath10k *ar, struct sk_buff *skb) -++{ -++ ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_UPDATE_STATS_EVENTID\n"); -++ ath10k_debug_fw_stats_process(ar, skb); -++} -++ -++static int -++ath10k_wmi_op_pull_vdev_start_ev(struct ath10k *ar, struct sk_buff *skb, -++ struct wmi_vdev_start_ev_arg *arg) -++{ -++ struct wmi_vdev_start_response_event *ev = (void *)skb->data; -++ -++ if (skb->len < sizeof(*ev)) -++ return -EPROTO; -++ -++ skb_pull(skb, sizeof(*ev)); -++ arg->vdev_id = ev->vdev_id; -++ arg->req_id = ev->req_id; -++ arg->resp_type = ev->resp_type; -++ arg->status = ev->status; -++ -++ return 0; -++} -++ -++void ath10k_wmi_event_vdev_start_resp(struct ath10k *ar, struct sk_buff *skb) -++{ -++ struct wmi_vdev_start_ev_arg arg = {}; -++ int ret; -++ -++ ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_VDEV_START_RESP_EVENTID\n"); -++ -++ ret = ath10k_wmi_pull_vdev_start(ar, skb, &arg); -++ if (ret) { -++ ath10k_warn(ar, "failed to parse vdev start event: %d\n", ret); -++ return; -++ } -++ -++ if (WARN_ON(__le32_to_cpu(arg.status))) -++ return; -++ -++ complete(&ar->vdev_setup_done); -++} -++ -++void ath10k_wmi_event_vdev_stopped(struct ath10k *ar, struct sk_buff *skb) -++{ -++ ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_VDEV_STOPPED_EVENTID\n"); -++ complete(&ar->vdev_setup_done); -++} -++ -++static int -++ath10k_wmi_op_pull_peer_kick_ev(struct ath10k *ar, struct sk_buff *skb, -++ struct wmi_peer_kick_ev_arg *arg) -++{ -++ struct wmi_peer_sta_kickout_event *ev = (void *)skb->data; -++ -++ if (skb->len < sizeof(*ev)) -++ return -EPROTO; -++ -++ skb_pull(skb, sizeof(*ev)); -++ arg->mac_addr = ev->peer_macaddr.addr; -++ -++ return 0; -++} -++ -++void ath10k_wmi_event_peer_sta_kickout(struct ath10k *ar, struct sk_buff *skb) -++{ -++ struct wmi_peer_kick_ev_arg arg = {}; -++ struct ieee80211_sta *sta; -++ int ret; -++ -++ ret = ath10k_wmi_pull_peer_kick(ar, skb, &arg); -++ if (ret) { -++ ath10k_warn(ar, "failed to parse peer kickout event: %d\n", -++ ret); -++ return; -++ } -++ -++ ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi event peer sta kickout %pM\n", -++ arg.mac_addr); -++ -++ rcu_read_lock(); -++ -++ sta = ieee80211_find_sta_by_ifaddr(ar->hw, arg.mac_addr, NULL); -++ if (!sta) { -++ ath10k_warn(ar, "Spurious quick kickout for STA %pM\n", -++ arg.mac_addr); -++ goto exit; -++ } -++ -++ ieee80211_report_low_ack(sta, 10); -++ -++exit: -++ rcu_read_unlock(); -++} -++ -++/* -++ * FIXME -++ * -++ * We don't report to mac80211 sleep state of connected -++ * stations. Due to this mac80211 can't fill in TIM IE -++ * correctly. -++ * -++ * I know of no way of getting nullfunc frames that contain -++ * sleep transition from connected stations - these do not -++ * seem to be sent from the target to the host. There also -++ * doesn't seem to be a dedicated event for that. So the -++ * only way left to do this would be to read tim_bitmap -++ * during SWBA. -++ * -++ * We could probably try using tim_bitmap from SWBA to tell -++ * mac80211 which stations are asleep and which are not. The -++ * problem here is calling mac80211 functions so many times -++ * could take too long and make us miss the time to submit -++ * the beacon to the target. -++ * -++ * So as a workaround we try to extend the TIM IE if there -++ * is unicast buffered for stations with aid > 7 and fill it -++ * in ourselves. -++ */ -++static void ath10k_wmi_update_tim(struct ath10k *ar, -++ struct ath10k_vif *arvif, -++ struct sk_buff *bcn, -++ const struct wmi_tim_info *tim_info) -++{ -++ struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)bcn->data; -++ struct ieee80211_tim_ie *tim; -++ u8 *ies, *ie; -++ u8 ie_len, pvm_len; -++ __le32 t; -++ u32 v; -++ -++ /* if next SWBA has no tim_changed the tim_bitmap is garbage. -++ * we must copy the bitmap upon change and reuse it later */ -++ if (__le32_to_cpu(tim_info->tim_changed)) { -++ int i; -++ -++ BUILD_BUG_ON(sizeof(arvif->u.ap.tim_bitmap) != -++ sizeof(tim_info->tim_bitmap)); -++ -++ for (i = 0; i < sizeof(arvif->u.ap.tim_bitmap); i++) { -++ t = tim_info->tim_bitmap[i / 4]; -++ v = __le32_to_cpu(t); -++ arvif->u.ap.tim_bitmap[i] = (v >> ((i % 4) * 8)) & 0xFF; -++ } -++ -++ /* FW reports either length 0 or 16 -++ * so we calculate this on our own */ -++ arvif->u.ap.tim_len = 0; -++ for (i = 0; i < sizeof(arvif->u.ap.tim_bitmap); i++) -++ if (arvif->u.ap.tim_bitmap[i]) -++ arvif->u.ap.tim_len = i; -++ -++ arvif->u.ap.tim_len++; -++ } -++ -++ ies = bcn->data; -++ ies += ieee80211_hdrlen(hdr->frame_control); -++ ies += 12; /* fixed parameters */ -++ -++ ie = (u8 *)cfg80211_find_ie(WLAN_EID_TIM, ies, -++ (u8 *)skb_tail_pointer(bcn) - ies); -++ if (!ie) { -++ if (arvif->vdev_type != WMI_VDEV_TYPE_IBSS) -++ ath10k_warn(ar, "no tim ie found;\n"); -++ return; -++ } -++ -++ tim = (void *)ie + 2; -++ ie_len = ie[1]; -++ pvm_len = ie_len - 3; /* exclude dtim count, dtim period, bmap ctl */ -++ -++ if (pvm_len < arvif->u.ap.tim_len) { -++ int expand_size = sizeof(arvif->u.ap.tim_bitmap) - pvm_len; -++ int move_size = skb_tail_pointer(bcn) - (ie + 2 + ie_len); -++ void *next_ie = ie + 2 + ie_len; -++ -++ if (skb_put(bcn, expand_size)) { -++ memmove(next_ie + expand_size, next_ie, move_size); -++ -++ ie[1] += expand_size; -++ ie_len += expand_size; -++ pvm_len += expand_size; -++ } else { -++ ath10k_warn(ar, "tim expansion failed\n"); -++ } -++ } -++ -++ if (pvm_len > sizeof(arvif->u.ap.tim_bitmap)) { -++ ath10k_warn(ar, "tim pvm length is too great (%d)\n", pvm_len); -++ return; -++ } -++ -++ tim->bitmap_ctrl = !!__le32_to_cpu(tim_info->tim_mcast); -++ memcpy(tim->virtual_map, arvif->u.ap.tim_bitmap, pvm_len); -++ -++ if (tim->dtim_count == 0) { -++ ATH10K_SKB_CB(bcn)->bcn.dtim_zero = true; -++ -++ if (__le32_to_cpu(tim_info->tim_mcast) == 1) -++ ATH10K_SKB_CB(bcn)->bcn.deliver_cab = true; -++ } -++ -++ ath10k_dbg(ar, ATH10K_DBG_MGMT, "dtim %d/%d mcast %d pvmlen %d\n", -++ tim->dtim_count, tim->dtim_period, -++ tim->bitmap_ctrl, pvm_len); -+ } -+ -+ static void ath10k_p2p_fill_noa_ie(u8 *data, u32 len, -+- struct wmi_p2p_noa_info *noa) -++ const struct wmi_p2p_noa_info *noa) -+ { -+ struct ieee80211_p2p_noa_attr *noa_attr; -+ u8 ctwindow_oppps = noa->ctwindow_oppps; -+@@ -1287,14 +2319,13 @@ static void ath10k_p2p_fill_noa_ie(u8 *d -+ *noa_attr_len = __cpu_to_le16(attr_len); -+ } -+ -+-static u32 ath10k_p2p_calc_noa_ie_len(struct wmi_p2p_noa_info *noa) -++static u32 ath10k_p2p_calc_noa_ie_len(const struct wmi_p2p_noa_info *noa) -+ { -+ u32 len = 0; -+ u8 noa_descriptors = noa->num_descriptors; -+ u8 opp_ps_info = noa->ctwindow_oppps; -+ bool opps_enabled = !!(opp_ps_info & WMI_P2P_OPPPS_ENABLE_BIT); -+ -+- -+ if (!noa_descriptors && !opps_enabled) -+ return len; -+ -+@@ -1308,16 +2339,15 @@ static u32 ath10k_p2p_calc_noa_ie_len(st -+ -+ static void ath10k_wmi_update_noa(struct ath10k *ar, struct ath10k_vif *arvif, -+ struct sk_buff *bcn, -+- struct wmi_bcn_info *bcn_info) -++ const struct wmi_p2p_noa_info *noa) -+ { -+- struct wmi_p2p_noa_info *noa = &bcn_info->p2p_noa_info; -+ u8 *new_data, *old_data = arvif->u.ap.noa_data; -+ u32 new_len; -+ -+ if (arvif->vdev_subtype != WMI_VDEV_SUBTYPE_P2P_GO) -+ return; -+ -+- ath10k_dbg(ATH10K_DBG_MGMT, "noa changed: %d\n", noa->changed); -++ ath10k_dbg(ar, ATH10K_DBG_MGMT, "noa changed: %d\n", noa->changed); -+ if (noa->changed & WMI_P2P_NOA_CHANGED_BIT) { -+ new_len = ath10k_p2p_calc_noa_ie_len(noa); -+ if (!new_len) -+@@ -1351,22 +2381,59 @@ cleanup: -+ kfree(old_data); -+ } -+ -++static int ath10k_wmi_op_pull_swba_ev(struct ath10k *ar, struct sk_buff *skb, -++ struct wmi_swba_ev_arg *arg) -++{ -++ struct wmi_host_swba_event *ev = (void *)skb->data; -++ u32 map; -++ size_t i; -++ -++ if (skb->len < sizeof(*ev)) -++ return -EPROTO; -++ -++ skb_pull(skb, sizeof(*ev)); -++ arg->vdev_map = ev->vdev_map; -++ -++ for (i = 0, map = __le32_to_cpu(ev->vdev_map); map; map >>= 1) { -++ if (!(map & BIT(0))) -++ continue; -++ -++ /* If this happens there were some changes in firmware and -++ * ath10k should update the max size of tim_info array. -++ */ -++ if (WARN_ON_ONCE(i == ARRAY_SIZE(arg->tim_info))) -++ break; -++ -++ arg->tim_info[i] = &ev->bcn_info[i].tim_info; -++ arg->noa_info[i] = &ev->bcn_info[i].p2p_noa_info; -++ i++; -++ } -++ -++ return 0; -++} -+ -+-static void ath10k_wmi_event_host_swba(struct ath10k *ar, struct sk_buff *skb) -++void ath10k_wmi_event_host_swba(struct ath10k *ar, struct sk_buff *skb) -+ { -+- struct wmi_host_swba_event *ev; -++ struct wmi_swba_ev_arg arg = {}; -+ u32 map; -+ int i = -1; -+- struct wmi_bcn_info *bcn_info; -++ const struct wmi_tim_info *tim_info; -++ const struct wmi_p2p_noa_info *noa_info; -+ struct ath10k_vif *arvif; -+ struct sk_buff *bcn; -++ dma_addr_t paddr; -+ int ret, vdev_id = 0; -+ -+- ev = (struct wmi_host_swba_event *)skb->data; -+- map = __le32_to_cpu(ev->vdev_map); -++ ret = ath10k_wmi_pull_swba(ar, skb, &arg); -++ if (ret) { -++ ath10k_warn(ar, "failed to parse swba event: %d\n", ret); -++ return; -++ } -++ -++ map = __le32_to_cpu(arg.vdev_map); -+ -+- ath10k_dbg(ATH10K_DBG_MGMT, "mgmt swba vdev_map 0x%x\n", -+- ev->vdev_map); -++ ath10k_dbg(ar, ATH10K_DBG_MGMT, "mgmt swba vdev_map 0x%x\n", -++ map); -+ -+ for (; map; map >>= 1, vdev_id++) { -+ if (!(map & 0x1)) -+@@ -1375,27 +2442,29 @@ static void ath10k_wmi_event_host_swba(s -+ i++; -+ -+ if (i >= WMI_MAX_AP_VDEV) { -+- ath10k_warn("swba has corrupted vdev map\n"); -++ ath10k_warn(ar, "swba has corrupted vdev map\n"); -+ break; -+ } -+ -+- bcn_info = &ev->bcn_info[i]; -++ tim_info = arg.tim_info[i]; -++ noa_info = arg.noa_info[i]; -+ -+- ath10k_dbg(ATH10K_DBG_MGMT, -++ ath10k_dbg(ar, ATH10K_DBG_MGMT, -+ "mgmt event bcn_info %d tim_len %d mcast %d changed %d num_ps_pending %d bitmap 0x%08x%08x%08x%08x\n", -+ i, -+- __le32_to_cpu(bcn_info->tim_info.tim_len), -+- __le32_to_cpu(bcn_info->tim_info.tim_mcast), -+- __le32_to_cpu(bcn_info->tim_info.tim_changed), -+- __le32_to_cpu(bcn_info->tim_info.tim_num_ps_pending), -+- __le32_to_cpu(bcn_info->tim_info.tim_bitmap[3]), -+- __le32_to_cpu(bcn_info->tim_info.tim_bitmap[2]), -+- __le32_to_cpu(bcn_info->tim_info.tim_bitmap[1]), -+- __le32_to_cpu(bcn_info->tim_info.tim_bitmap[0])); -++ __le32_to_cpu(tim_info->tim_len), -++ __le32_to_cpu(tim_info->tim_mcast), -++ __le32_to_cpu(tim_info->tim_changed), -++ __le32_to_cpu(tim_info->tim_num_ps_pending), -++ __le32_to_cpu(tim_info->tim_bitmap[3]), -++ __le32_to_cpu(tim_info->tim_bitmap[2]), -++ __le32_to_cpu(tim_info->tim_bitmap[1]), -++ __le32_to_cpu(tim_info->tim_bitmap[0])); -+ -+ arvif = ath10k_get_arvif(ar, vdev_id); -+ if (arvif == NULL) { -+- ath10k_warn("no vif for vdev_id %d found\n", vdev_id); -++ ath10k_warn(ar, "no vif for vdev_id %d found\n", -++ vdev_id); -+ continue; -+ } -+ -+@@ -1412,57 +2481,77 @@ static void ath10k_wmi_event_host_swba(s -+ -+ bcn = ieee80211_beacon_get(ar->hw, arvif->vif); -+ if (!bcn) { -+- ath10k_warn("could not get mac80211 beacon\n"); -++ ath10k_warn(ar, "could not get mac80211 beacon\n"); -+ continue; -+ } -+ -+- ath10k_tx_h_seq_no(bcn); -+- ath10k_wmi_update_tim(ar, arvif, bcn, bcn_info); -+- ath10k_wmi_update_noa(ar, arvif, bcn, bcn_info); -++ ath10k_tx_h_seq_no(arvif->vif, bcn); -++ ath10k_wmi_update_tim(ar, arvif, bcn, tim_info); -++ ath10k_wmi_update_noa(ar, arvif, bcn, noa_info); -+ -+ spin_lock_bh(&ar->data_lock); -+ -+ if (arvif->beacon) { -+- if (!arvif->beacon_sent) -+- ath10k_warn("SWBA overrun on vdev %d\n", -++ switch (arvif->beacon_state) { -++ case ATH10K_BEACON_SENT: -++ break; -++ case ATH10K_BEACON_SCHEDULED: -++ ath10k_warn(ar, "SWBA overrun on vdev %d, skipped old beacon\n", -+ arvif->vdev_id); -++ break; -++ case ATH10K_BEACON_SENDING: -++ ath10k_warn(ar, "SWBA overrun on vdev %d, skipped new beacon\n", -++ arvif->vdev_id); -++ dev_kfree_skb(bcn); -++ goto skip; -++ } -+ -+- dma_unmap_single(arvif->ar->dev, -+- ATH10K_SKB_CB(arvif->beacon)->paddr, -+- arvif->beacon->len, DMA_TO_DEVICE); -+- dev_kfree_skb_any(arvif->beacon); -+- arvif->beacon = NULL; -++ ath10k_mac_vif_beacon_free(arvif); -+ } -+ -+- ATH10K_SKB_CB(bcn)->paddr = dma_map_single(arvif->ar->dev, -+- bcn->data, bcn->len, -+- DMA_TO_DEVICE); -+- ret = dma_mapping_error(arvif->ar->dev, -+- ATH10K_SKB_CB(bcn)->paddr); -+- if (ret) { -+- ath10k_warn("failed to map beacon: %d\n", ret); -+- dev_kfree_skb_any(bcn); -+- goto skip; -++ if (!arvif->beacon_buf) { -++ paddr = dma_map_single(arvif->ar->dev, bcn->data, -++ bcn->len, DMA_TO_DEVICE); -++ ret = dma_mapping_error(arvif->ar->dev, paddr); -++ if (ret) { -++ ath10k_warn(ar, "failed to map beacon: %d\n", -++ ret); -++ dev_kfree_skb_any(bcn); -++ goto skip; -++ } -++ -++ ATH10K_SKB_CB(bcn)->paddr = paddr; -++ } else { -++ if (bcn->len > IEEE80211_MAX_FRAME_LEN) { -++ ath10k_warn(ar, "trimming beacon %d -> %d bytes!\n", -++ bcn->len, IEEE80211_MAX_FRAME_LEN); -++ skb_trim(bcn, IEEE80211_MAX_FRAME_LEN); -++ } -++ memcpy(arvif->beacon_buf, bcn->data, bcn->len); -++ ATH10K_SKB_CB(bcn)->paddr = arvif->beacon_paddr; -+ } -+ -+ arvif->beacon = bcn; -+- arvif->beacon_sent = false; -++ arvif->beacon_state = ATH10K_BEACON_SCHEDULED; -++ -++ trace_ath10k_tx_hdr(ar, bcn->data, bcn->len); -++ trace_ath10k_tx_payload(ar, bcn->data, bcn->len); -+ -+- ath10k_wmi_tx_beacon_nowait(arvif); -+ skip: -+ spin_unlock_bh(&ar->data_lock); -+ } -++ -++ ath10k_wmi_tx_beacons_nowait(ar); -+ } -+ -+-static void ath10k_wmi_event_tbttoffset_update(struct ath10k *ar, -+- struct sk_buff *skb) -++void ath10k_wmi_event_tbttoffset_update(struct ath10k *ar, struct sk_buff *skb) -+ { -+- ath10k_dbg(ATH10K_DBG_WMI, "WMI_TBTTOFFSET_UPDATE_EVENTID\n"); -++ ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_TBTTOFFSET_UPDATE_EVENTID\n"); -+ } -+ -+ static void ath10k_dfs_radar_report(struct ath10k *ar, -+- struct wmi_single_phyerr_rx_event *event, -+- struct phyerr_radar_report *rr, -++ const struct wmi_phyerr *phyerr, -++ const struct phyerr_radar_report *rr, -+ u64 tsf) -+ { -+ u32 reg0, reg1, tsf32l; -+@@ -1473,20 +2562,20 @@ static void ath10k_dfs_radar_report(stru -+ reg0 = __le32_to_cpu(rr->reg0); -+ reg1 = __le32_to_cpu(rr->reg1); -+ -+- ath10k_dbg(ATH10K_DBG_REGULATORY, -++ ath10k_dbg(ar, ATH10K_DBG_REGULATORY, -+ "wmi phyerr radar report chirp %d max_width %d agc_total_gain %d pulse_delta_diff %d\n", -+ MS(reg0, RADAR_REPORT_REG0_PULSE_IS_CHIRP), -+ MS(reg0, RADAR_REPORT_REG0_PULSE_IS_MAX_WIDTH), -+ MS(reg0, RADAR_REPORT_REG0_AGC_TOTAL_GAIN), -+ MS(reg0, RADAR_REPORT_REG0_PULSE_DELTA_DIFF)); -+- ath10k_dbg(ATH10K_DBG_REGULATORY, -++ ath10k_dbg(ar, ATH10K_DBG_REGULATORY, -+ "wmi phyerr radar report pulse_delta_pean %d pulse_sidx %d fft_valid %d agc_mb_gain %d subchan_mask %d\n", -+ MS(reg0, RADAR_REPORT_REG0_PULSE_DELTA_PEAK), -+ MS(reg0, RADAR_REPORT_REG0_PULSE_SIDX), -+ MS(reg1, RADAR_REPORT_REG1_PULSE_SRCH_FFT_VALID), -+ MS(reg1, RADAR_REPORT_REG1_PULSE_AGC_MB_GAIN), -+ MS(reg1, RADAR_REPORT_REG1_PULSE_SUBCHAN_MASK)); -+- ath10k_dbg(ATH10K_DBG_REGULATORY, -++ ath10k_dbg(ar, ATH10K_DBG_REGULATORY, -+ "wmi phyerr radar report pulse_tsf_offset 0x%X pulse_dur: %d\n", -+ MS(reg1, RADAR_REPORT_REG1_PULSE_TSF_OFFSET), -+ MS(reg1, RADAR_REPORT_REG1_PULSE_DUR)); -+@@ -1495,12 +2584,12 @@ static void ath10k_dfs_radar_report(stru -+ return; -+ -+ /* report event to DFS pattern detector */ -+- tsf32l = __le32_to_cpu(event->hdr.tsf_timestamp); -++ tsf32l = __le32_to_cpu(phyerr->tsf_timestamp); -+ tsf64 = tsf & (~0xFFFFFFFFULL); -+ tsf64 |= tsf32l; -+ -+ width = MS(reg1, RADAR_REPORT_REG1_PULSE_DUR); -+- rssi = event->hdr.rssi_combined; -++ rssi = phyerr->rssi_combined; -+ -+ /* hardware store this as 8 bit signed value, -+ * set to zero if negative number -+@@ -1513,25 +2602,25 @@ static void ath10k_dfs_radar_report(stru -+ pe.width = width; -+ pe.rssi = rssi; -+ -+- ath10k_dbg(ATH10K_DBG_REGULATORY, -++ ath10k_dbg(ar, ATH10K_DBG_REGULATORY, -+ "dfs add pulse freq: %d, width: %d, rssi %d, tsf: %llX\n", -+ pe.freq, pe.width, pe.rssi, pe.ts); -+ -+ ATH10K_DFS_STAT_INC(ar, pulses_detected); -+ -+ if (!ar->dfs_detector->add_pulse(ar->dfs_detector, &pe)) { -+- ath10k_dbg(ATH10K_DBG_REGULATORY, -++ ath10k_dbg(ar, ATH10K_DBG_REGULATORY, -+ "dfs no pulse pattern detected, yet\n"); -+ return; -+ } -+ -+- ath10k_dbg(ATH10K_DBG_REGULATORY, "dfs radar detected\n"); -++ ath10k_dbg(ar, ATH10K_DBG_REGULATORY, "dfs radar detected\n"); -+ ATH10K_DFS_STAT_INC(ar, radar_detected); -+ -+ /* Control radar events reporting in debugfs file -+ dfs_block_radar_events */ -+ if (ar->dfs_block_radar_events) { -+- ath10k_info("DFS Radar detected, but ignored as requested\n"); -++ ath10k_info(ar, "DFS Radar detected, but ignored as requested\n"); -+ return; -+ } -+ -+@@ -1539,8 +2628,8 @@ static void ath10k_dfs_radar_report(stru -+ } -+ -+ static int ath10k_dfs_fft_report(struct ath10k *ar, -+- struct wmi_single_phyerr_rx_event *event, -+- struct phyerr_fft_report *fftr, -++ const struct wmi_phyerr *phyerr, -++ const struct phyerr_fft_report *fftr, -+ u64 tsf) -+ { -+ u32 reg0, reg1; -+@@ -1548,15 +2637,15 @@ static int ath10k_dfs_fft_report(struct -+ -+ reg0 = __le32_to_cpu(fftr->reg0); -+ reg1 = __le32_to_cpu(fftr->reg1); -+- rssi = event->hdr.rssi_combined; -++ rssi = phyerr->rssi_combined; -+ -+- ath10k_dbg(ATH10K_DBG_REGULATORY, -++ ath10k_dbg(ar, ATH10K_DBG_REGULATORY, -+ "wmi phyerr fft report total_gain_db %d base_pwr_db %d fft_chn_idx %d peak_sidx %d\n", -+ MS(reg0, SEARCH_FFT_REPORT_REG0_TOTAL_GAIN_DB), -+ MS(reg0, SEARCH_FFT_REPORT_REG0_BASE_PWR_DB), -+ MS(reg0, SEARCH_FFT_REPORT_REG0_FFT_CHN_IDX), -+ MS(reg0, SEARCH_FFT_REPORT_REG0_PEAK_SIDX)); -+- ath10k_dbg(ATH10K_DBG_REGULATORY, -++ ath10k_dbg(ar, ATH10K_DBG_REGULATORY, -+ "wmi phyerr fft report rel_pwr_db %d avgpwr_db %d peak_mag %d num_store_bin %d\n", -+ MS(reg1, SEARCH_FFT_REPORT_REG1_RELPWR_DB), -+ MS(reg1, SEARCH_FFT_REPORT_REG1_AVGPWR_DB), -+@@ -1568,7 +2657,7 @@ static int ath10k_dfs_fft_report(struct -+ /* false event detection */ -+ if (rssi == DFS_RSSI_POSSIBLY_FALSE && -+ peak_mag < 2 * DFS_PEAK_MAG_THOLD_POSSIBLY_FALSE) { -+- ath10k_dbg(ATH10K_DBG_REGULATORY, "dfs false pulse detected\n"); -++ ath10k_dbg(ar, ATH10K_DBG_REGULATORY, "dfs false pulse detected\n"); -+ ATH10K_DFS_STAT_INC(ar, pulses_discarded); -+ return -EINVAL; -+ } -+@@ -1576,21 +2665,21 @@ static int ath10k_dfs_fft_report(struct -+ return 0; -+ } -+ -+-static void ath10k_wmi_event_dfs(struct ath10k *ar, -+- struct wmi_single_phyerr_rx_event *event, -+- u64 tsf) -++void ath10k_wmi_event_dfs(struct ath10k *ar, -++ const struct wmi_phyerr *phyerr, -++ u64 tsf) -+ { -+ int buf_len, tlv_len, res, i = 0; -+- struct phyerr_tlv *tlv; -+- struct phyerr_radar_report *rr; -+- struct phyerr_fft_report *fftr; -+- u8 *tlv_buf; -++ const struct phyerr_tlv *tlv; -++ const struct phyerr_radar_report *rr; -++ const struct phyerr_fft_report *fftr; -++ const u8 *tlv_buf; -+ -+- buf_len = __le32_to_cpu(event->hdr.buf_len); -+- ath10k_dbg(ATH10K_DBG_REGULATORY, -++ buf_len = __le32_to_cpu(phyerr->buf_len); -++ ath10k_dbg(ar, ATH10K_DBG_REGULATORY, -+ "wmi event dfs err_code %d rssi %d tsfl 0x%X tsf64 0x%llX len %d\n", -+- event->hdr.phy_err_code, event->hdr.rssi_combined, -+- __le32_to_cpu(event->hdr.tsf_timestamp), tsf, buf_len); -++ phyerr->phy_err_code, phyerr->rssi_combined, -++ __le32_to_cpu(phyerr->tsf_timestamp), tsf, buf_len); -+ -+ /* Skip event if DFS disabled */ -+ if (!config_enabled(CPTCFG_ATH10K_DFS_CERTIFIED)) -+@@ -1600,36 +2689,38 @@ static void ath10k_wmi_event_dfs(struct -+ -+ while (i < buf_len) { -+ if (i + sizeof(*tlv) > buf_len) { -+- ath10k_warn("too short buf for tlv header (%d)\n", i); -++ ath10k_warn(ar, "too short buf for tlv header (%d)\n", -++ i); -+ return; -+ } -+ -+- tlv = (struct phyerr_tlv *)&event->bufp[i]; -++ tlv = (struct phyerr_tlv *)&phyerr->buf[i]; -+ tlv_len = __le16_to_cpu(tlv->len); -+- tlv_buf = &event->bufp[i + sizeof(*tlv)]; -+- ath10k_dbg(ATH10K_DBG_REGULATORY, -++ tlv_buf = &phyerr->buf[i + sizeof(*tlv)]; -++ ath10k_dbg(ar, ATH10K_DBG_REGULATORY, -+ "wmi event dfs tlv_len %d tlv_tag 0x%02X tlv_sig 0x%02X\n", -+ tlv_len, tlv->tag, tlv->sig); -+ -+ switch (tlv->tag) { -+ case PHYERR_TLV_TAG_RADAR_PULSE_SUMMARY: -+ if (i + sizeof(*tlv) + sizeof(*rr) > buf_len) { -+- ath10k_warn("too short radar pulse summary (%d)\n", -++ ath10k_warn(ar, "too short radar pulse summary (%d)\n", -+ i); -+ return; -+ } -+ -+ rr = (struct phyerr_radar_report *)tlv_buf; -+- ath10k_dfs_radar_report(ar, event, rr, tsf); -++ ath10k_dfs_radar_report(ar, phyerr, rr, tsf); -+ break; -+ case PHYERR_TLV_TAG_SEARCH_FFT_REPORT: -+ if (i + sizeof(*tlv) + sizeof(*fftr) > buf_len) { -+- ath10k_warn("too short fft report (%d)\n", i); -++ ath10k_warn(ar, "too short fft report (%d)\n", -++ i); -+ return; -+ } -+ -+ fftr = (struct phyerr_fft_report *)tlv_buf; -+- res = ath10k_dfs_fft_report(ar, event, fftr, tsf); -++ res = ath10k_dfs_fft_report(ar, phyerr, fftr, tsf); -+ if (res) -+ return; -+ break; -+@@ -1639,58 +2730,122 @@ static void ath10k_wmi_event_dfs(struct -+ } -+ } -+ -+-static void ath10k_wmi_event_spectral_scan(struct ath10k *ar, -+- struct wmi_single_phyerr_rx_event *event, -+- u64 tsf) -+-{ -+- ath10k_dbg(ATH10K_DBG_WMI, "wmi event spectral scan\n"); -+-} -+- -+-static void ath10k_wmi_event_phyerr(struct ath10k *ar, struct sk_buff *skb) -++void ath10k_wmi_event_spectral_scan(struct ath10k *ar, -++ const struct wmi_phyerr *phyerr, -++ u64 tsf) -+ { -+- struct wmi_comb_phyerr_rx_event *comb_event; -+- struct wmi_single_phyerr_rx_event *event; -+- u32 count, i, buf_len, phy_err_code; -+- u64 tsf; -+- int left_len = skb->len; -+- -+- ATH10K_DFS_STAT_INC(ar, phy_errors); -+- -+- /* Check if combined event available */ -+- if (left_len < sizeof(*comb_event)) { -+- ath10k_warn("wmi phyerr combined event wrong len\n"); -+- return; -+- } -+- -+- left_len -= sizeof(*comb_event); -++ int buf_len, tlv_len, res, i = 0; -++ struct phyerr_tlv *tlv; -++ const void *tlv_buf; -++ const struct phyerr_fft_report *fftr; -++ size_t fftr_len; -+ -+- /* Check number of included events */ -+- comb_event = (struct wmi_comb_phyerr_rx_event *)skb->data; -+- count = __le32_to_cpu(comb_event->hdr.num_phyerr_events); -++ buf_len = __le32_to_cpu(phyerr->buf_len); -+ -+- tsf = __le32_to_cpu(comb_event->hdr.tsf_u32); -+- tsf <<= 32; -+- tsf |= __le32_to_cpu(comb_event->hdr.tsf_l32); -++ while (i < buf_len) { -++ if (i + sizeof(*tlv) > buf_len) { -++ ath10k_warn(ar, "failed to parse phyerr tlv header at byte %d\n", -++ i); -++ return; -++ } -+ -+- ath10k_dbg(ATH10K_DBG_WMI, -+- "wmi event phyerr count %d tsf64 0x%llX\n", -+- count, tsf); -++ tlv = (struct phyerr_tlv *)&phyerr->buf[i]; -++ tlv_len = __le16_to_cpu(tlv->len); -++ tlv_buf = &phyerr->buf[i + sizeof(*tlv)]; -+ -+- event = (struct wmi_single_phyerr_rx_event *)comb_event->bufp; -+- for (i = 0; i < count; i++) { -+- /* Check if we can read event header */ -+- if (left_len < sizeof(*event)) { -+- ath10k_warn("single event (%d) wrong head len\n", i); -++ if (i + sizeof(*tlv) + tlv_len > buf_len) { -++ ath10k_warn(ar, "failed to parse phyerr tlv payload at byte %d\n", -++ i); -+ return; -+ } -+ -+- left_len -= sizeof(*event); -+- -+- buf_len = __le32_to_cpu(event->hdr.buf_len); -+- phy_err_code = event->hdr.phy_err_code; -++ switch (tlv->tag) { -++ case PHYERR_TLV_TAG_SEARCH_FFT_REPORT: -++ if (sizeof(*fftr) > tlv_len) { -++ ath10k_warn(ar, "failed to parse fft report at byte %d\n", -++ i); -++ return; -++ } -++ -++ fftr_len = tlv_len - sizeof(*fftr); -++ fftr = tlv_buf; -++ res = ath10k_spectral_process_fft(ar, phyerr, -++ fftr, fftr_len, -++ tsf); -++ if (res < 0) { -++ ath10k_warn(ar, "failed to process fft report: %d\n", -++ res); -++ return; -++ } -++ break; -++ } -++ -++ i += sizeof(*tlv) + tlv_len; -++ } -++} -++ -++static int ath10k_wmi_op_pull_phyerr_ev(struct ath10k *ar, struct sk_buff *skb, -++ struct wmi_phyerr_ev_arg *arg) -++{ -++ struct wmi_phyerr_event *ev = (void *)skb->data; -++ -++ if (skb->len < sizeof(*ev)) -++ return -EPROTO; -++ -++ arg->num_phyerrs = ev->num_phyerrs; -++ arg->tsf_l32 = ev->tsf_l32; -++ arg->tsf_u32 = ev->tsf_u32; -++ arg->buf_len = __cpu_to_le32(skb->len - sizeof(*ev)); -++ arg->phyerrs = ev->phyerrs; -++ -++ return 0; -++} -++ -++void ath10k_wmi_event_phyerr(struct ath10k *ar, struct sk_buff *skb) -++{ -++ struct wmi_phyerr_ev_arg arg = {}; -++ const struct wmi_phyerr *phyerr; -++ u32 count, i, buf_len, phy_err_code; -++ u64 tsf; -++ int left_len, ret; -++ -++ ATH10K_DFS_STAT_INC(ar, phy_errors); -++ -++ ret = ath10k_wmi_pull_phyerr(ar, skb, &arg); -++ if (ret) { -++ ath10k_warn(ar, "failed to parse phyerr event: %d\n", ret); -++ return; -++ } -++ -++ left_len = __le32_to_cpu(arg.buf_len); -++ -++ /* Check number of included events */ -++ count = __le32_to_cpu(arg.num_phyerrs); -++ -++ tsf = __le32_to_cpu(arg.tsf_u32); -++ tsf <<= 32; -++ tsf |= __le32_to_cpu(arg.tsf_l32); -++ -++ ath10k_dbg(ar, ATH10K_DBG_WMI, -++ "wmi event phyerr count %d tsf64 0x%llX\n", -++ count, tsf); -++ -++ phyerr = arg.phyerrs; -++ for (i = 0; i < count; i++) { -++ /* Check if we can read event header */ -++ if (left_len < sizeof(*phyerr)) { -++ ath10k_warn(ar, "single event (%d) wrong head len\n", -++ i); -++ return; -++ } -++ -++ left_len -= sizeof(*phyerr); -++ -++ buf_len = __le32_to_cpu(phyerr->buf_len); -++ phy_err_code = phyerr->phy_err_code; -+ -+ if (left_len < buf_len) { -+- ath10k_warn("single event (%d) wrong buf len\n", i); -++ ath10k_warn(ar, "single event (%d) wrong buf len\n", i); -+ return; -+ } -+ -+@@ -1698,36 +2853,34 @@ static void ath10k_wmi_event_phyerr(stru -+ -+ switch (phy_err_code) { -+ case PHY_ERROR_RADAR: -+- ath10k_wmi_event_dfs(ar, event, tsf); -++ ath10k_wmi_event_dfs(ar, phyerr, tsf); -+ break; -+ case PHY_ERROR_SPECTRAL_SCAN: -+- ath10k_wmi_event_spectral_scan(ar, event, tsf); -++ ath10k_wmi_event_spectral_scan(ar, phyerr, tsf); -+ break; -+ case PHY_ERROR_FALSE_RADAR_EXT: -+- ath10k_wmi_event_dfs(ar, event, tsf); -+- ath10k_wmi_event_spectral_scan(ar, event, tsf); -++ ath10k_wmi_event_dfs(ar, phyerr, tsf); -++ ath10k_wmi_event_spectral_scan(ar, phyerr, tsf); -+ break; -+ default: -+ break; -+ } -+ -+- event += sizeof(*event) + buf_len; -++ phyerr = (void *)phyerr + sizeof(*phyerr) + buf_len; -+ } -+ } -+ -+-static void ath10k_wmi_event_roam(struct ath10k *ar, struct sk_buff *skb) -++void ath10k_wmi_event_roam(struct ath10k *ar, struct sk_buff *skb) -+ { -+- ath10k_dbg(ATH10K_DBG_WMI, "WMI_ROAM_EVENTID\n"); -++ ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_ROAM_EVENTID\n"); -+ } -+ -+-static void ath10k_wmi_event_profile_match(struct ath10k *ar, -+- struct sk_buff *skb) -++void ath10k_wmi_event_profile_match(struct ath10k *ar, struct sk_buff *skb) -+ { -+- ath10k_dbg(ATH10K_DBG_WMI, "WMI_PROFILE_MATCH\n"); -++ ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_PROFILE_MATCH\n"); -+ } -+ -+-static void ath10k_wmi_event_debug_print(struct ath10k *ar, -+- struct sk_buff *skb) -++void ath10k_wmi_event_debug_print(struct ath10k *ar, struct sk_buff *skb) -+ { -+ char buf[101], c; -+ int i; -+@@ -1748,7 +2901,7 @@ static void ath10k_wmi_event_debug_print -+ } -+ -+ if (i == sizeof(buf) - 1) -+- ath10k_warn("wmi debug print truncated: %d\n", skb->len); -++ ath10k_warn(ar, "wmi debug print truncated: %d\n", skb->len); -+ -+ /* for some reason the debug prints end with \n, remove that */ -+ if (skb->data[i - 1] == '\n') -+@@ -1757,112 +2910,99 @@ static void ath10k_wmi_event_debug_print -+ /* the last byte is always reserved for the null character */ -+ buf[i] = '\0'; -+ -+- ath10k_dbg(ATH10K_DBG_WMI, "wmi event debug print '%s'\n", buf); -++ ath10k_dbg(ar, ATH10K_DBG_WMI_PRINT, "wmi print '%s'\n", buf); -+ } -+ -+-static void ath10k_wmi_event_pdev_qvit(struct ath10k *ar, struct sk_buff *skb) -++void ath10k_wmi_event_pdev_qvit(struct ath10k *ar, struct sk_buff *skb) -+ { -+- ath10k_dbg(ATH10K_DBG_WMI, "WMI_PDEV_QVIT_EVENTID\n"); -++ ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_PDEV_QVIT_EVENTID\n"); -+ } -+ -+-static void ath10k_wmi_event_wlan_profile_data(struct ath10k *ar, -+- struct sk_buff *skb) -++void ath10k_wmi_event_wlan_profile_data(struct ath10k *ar, struct sk_buff *skb) -+ { -+- ath10k_dbg(ATH10K_DBG_WMI, "WMI_WLAN_PROFILE_DATA_EVENTID\n"); -++ ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_WLAN_PROFILE_DATA_EVENTID\n"); -+ } -+ -+-static void ath10k_wmi_event_rtt_measurement_report(struct ath10k *ar, -++void ath10k_wmi_event_rtt_measurement_report(struct ath10k *ar, -+ struct sk_buff *skb) -+ { -+- ath10k_dbg(ATH10K_DBG_WMI, "WMI_RTT_MEASUREMENT_REPORT_EVENTID\n"); -++ ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_RTT_MEASUREMENT_REPORT_EVENTID\n"); -+ } -+ -+-static void ath10k_wmi_event_tsf_measurement_report(struct ath10k *ar, -++void ath10k_wmi_event_tsf_measurement_report(struct ath10k *ar, -+ struct sk_buff *skb) -+ { -+- ath10k_dbg(ATH10K_DBG_WMI, "WMI_TSF_MEASUREMENT_REPORT_EVENTID\n"); -++ ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_TSF_MEASUREMENT_REPORT_EVENTID\n"); -+ } -+ -+-static void ath10k_wmi_event_rtt_error_report(struct ath10k *ar, -+- struct sk_buff *skb) -++void ath10k_wmi_event_rtt_error_report(struct ath10k *ar, struct sk_buff *skb) -+ { -+- ath10k_dbg(ATH10K_DBG_WMI, "WMI_RTT_ERROR_REPORT_EVENTID\n"); -++ ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_RTT_ERROR_REPORT_EVENTID\n"); -+ } -+ -+-static void ath10k_wmi_event_wow_wakeup_host(struct ath10k *ar, -+- struct sk_buff *skb) -++void ath10k_wmi_event_wow_wakeup_host(struct ath10k *ar, struct sk_buff *skb) -+ { -+- ath10k_dbg(ATH10K_DBG_WMI, "WMI_WOW_WAKEUP_HOST_EVENTID\n"); -++ ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_WOW_WAKEUP_HOST_EVENTID\n"); -+ } -+ -+-static void ath10k_wmi_event_dcs_interference(struct ath10k *ar, -+- struct sk_buff *skb) -++void ath10k_wmi_event_dcs_interference(struct ath10k *ar, struct sk_buff *skb) -+ { -+- ath10k_dbg(ATH10K_DBG_WMI, "WMI_DCS_INTERFERENCE_EVENTID\n"); -++ ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_DCS_INTERFERENCE_EVENTID\n"); -+ } -+ -+-static void ath10k_wmi_event_pdev_tpc_config(struct ath10k *ar, -+- struct sk_buff *skb) -++void ath10k_wmi_event_pdev_tpc_config(struct ath10k *ar, struct sk_buff *skb) -+ { -+- ath10k_dbg(ATH10K_DBG_WMI, "WMI_PDEV_TPC_CONFIG_EVENTID\n"); -++ ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_PDEV_TPC_CONFIG_EVENTID\n"); -+ } -+ -+-static void ath10k_wmi_event_pdev_ftm_intg(struct ath10k *ar, -+- struct sk_buff *skb) -++void ath10k_wmi_event_pdev_ftm_intg(struct ath10k *ar, struct sk_buff *skb) -+ { -+- ath10k_dbg(ATH10K_DBG_WMI, "WMI_PDEV_FTM_INTG_EVENTID\n"); -++ ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_PDEV_FTM_INTG_EVENTID\n"); -+ } -+ -+-static void ath10k_wmi_event_gtk_offload_status(struct ath10k *ar, -+- struct sk_buff *skb) -++void ath10k_wmi_event_gtk_offload_status(struct ath10k *ar, struct sk_buff *skb) -+ { -+- ath10k_dbg(ATH10K_DBG_WMI, "WMI_GTK_OFFLOAD_STATUS_EVENTID\n"); -++ ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_GTK_OFFLOAD_STATUS_EVENTID\n"); -+ } -+ -+-static void ath10k_wmi_event_gtk_rekey_fail(struct ath10k *ar, -+- struct sk_buff *skb) -++void ath10k_wmi_event_gtk_rekey_fail(struct ath10k *ar, struct sk_buff *skb) -+ { -+- ath10k_dbg(ATH10K_DBG_WMI, "WMI_GTK_REKEY_FAIL_EVENTID\n"); -++ ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_GTK_REKEY_FAIL_EVENTID\n"); -+ } -+ -+-static void ath10k_wmi_event_delba_complete(struct ath10k *ar, -+- struct sk_buff *skb) -++void ath10k_wmi_event_delba_complete(struct ath10k *ar, struct sk_buff *skb) -+ { -+- ath10k_dbg(ATH10K_DBG_WMI, "WMI_TX_DELBA_COMPLETE_EVENTID\n"); -++ ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_TX_DELBA_COMPLETE_EVENTID\n"); -+ } -+ -+-static void ath10k_wmi_event_addba_complete(struct ath10k *ar, -+- struct sk_buff *skb) -++void ath10k_wmi_event_addba_complete(struct ath10k *ar, struct sk_buff *skb) -+ { -+- ath10k_dbg(ATH10K_DBG_WMI, "WMI_TX_ADDBA_COMPLETE_EVENTID\n"); -++ ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_TX_ADDBA_COMPLETE_EVENTID\n"); -+ } -+ -+-static void ath10k_wmi_event_vdev_install_key_complete(struct ath10k *ar, -++void ath10k_wmi_event_vdev_install_key_complete(struct ath10k *ar, -+ struct sk_buff *skb) -+ { -+- ath10k_dbg(ATH10K_DBG_WMI, "WMI_VDEV_INSTALL_KEY_COMPLETE_EVENTID\n"); -++ ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_VDEV_INSTALL_KEY_COMPLETE_EVENTID\n"); -+ } -+ -+-static void ath10k_wmi_event_inst_rssi_stats(struct ath10k *ar, -+- struct sk_buff *skb) -++void ath10k_wmi_event_inst_rssi_stats(struct ath10k *ar, struct sk_buff *skb) -+ { -+- ath10k_dbg(ATH10K_DBG_WMI, "WMI_INST_RSSI_STATS_EVENTID\n"); -++ ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_INST_RSSI_STATS_EVENTID\n"); -+ } -+ -+-static void ath10k_wmi_event_vdev_standby_req(struct ath10k *ar, -+- struct sk_buff *skb) -++void ath10k_wmi_event_vdev_standby_req(struct ath10k *ar, struct sk_buff *skb) -+ { -+- ath10k_dbg(ATH10K_DBG_WMI, "WMI_VDEV_STANDBY_REQ_EVENTID\n"); -++ ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_VDEV_STANDBY_REQ_EVENTID\n"); -+ } -+ -+-static void ath10k_wmi_event_vdev_resume_req(struct ath10k *ar, -+- struct sk_buff *skb) -++void ath10k_wmi_event_vdev_resume_req(struct ath10k *ar, struct sk_buff *skb) -+ { -+- ath10k_dbg(ATH10K_DBG_WMI, "WMI_VDEV_RESUME_REQ_EVENTID\n"); -++ ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_VDEV_RESUME_REQ_EVENTID\n"); -+ } -+ -+ static int ath10k_wmi_alloc_host_mem(struct ath10k *ar, u32 req_id, -+- u32 num_units, u32 unit_len) -++ u32 num_units, u32 unit_len) -+ { -+ dma_addr_t paddr; -+ u32 pool_size; -+@@ -1878,7 +3018,7 @@ static int ath10k_wmi_alloc_host_mem(str -+ &paddr, -+ GFP_ATOMIC); -+ if (!ar->wmi.mem_chunks[idx].vaddr) { -+- ath10k_warn("failed to allocate memory chunk\n"); -++ ath10k_warn(ar, "failed to allocate memory chunk\n"); -+ return -ENOMEM; -+ } -+ -+@@ -1892,45 +3032,124 @@ static int ath10k_wmi_alloc_host_mem(str -+ return 0; -+ } -+ -+-static void ath10k_wmi_service_ready_event_rx(struct ath10k *ar, -+- struct sk_buff *skb) -++static int -++ath10k_wmi_main_op_pull_svc_rdy_ev(struct ath10k *ar, struct sk_buff *skb, -++ struct wmi_svc_rdy_ev_arg *arg) -++{ -++ struct wmi_service_ready_event *ev; -++ size_t i, n; -++ -++ if (skb->len < sizeof(*ev)) -++ return -EPROTO; -++ -++ ev = (void *)skb->data; -++ skb_pull(skb, sizeof(*ev)); -++ arg->min_tx_power = ev->hw_min_tx_power; -++ arg->max_tx_power = ev->hw_max_tx_power; -++ arg->ht_cap = ev->ht_cap_info; -++ arg->vht_cap = ev->vht_cap_info; -++ arg->sw_ver0 = ev->sw_version; -++ arg->sw_ver1 = ev->sw_version_1; -++ arg->phy_capab = ev->phy_capability; -++ arg->num_rf_chains = ev->num_rf_chains; -++ arg->eeprom_rd = ev->hal_reg_capabilities.eeprom_rd; -++ arg->num_mem_reqs = ev->num_mem_reqs; -++ arg->service_map = ev->wmi_service_bitmap; -++ arg->service_map_len = sizeof(ev->wmi_service_bitmap); -++ -++ n = min_t(size_t, __le32_to_cpu(arg->num_mem_reqs), -++ ARRAY_SIZE(arg->mem_reqs)); -++ for (i = 0; i < n; i++) -++ arg->mem_reqs[i] = &ev->mem_reqs[i]; -++ -++ if (skb->len < -++ __le32_to_cpu(arg->num_mem_reqs) * sizeof(arg->mem_reqs[0])) -++ return -EPROTO; -++ -++ return 0; -++} -++ -++static int -++ath10k_wmi_10x_op_pull_svc_rdy_ev(struct ath10k *ar, struct sk_buff *skb, -++ struct wmi_svc_rdy_ev_arg *arg) -++{ -++ struct wmi_10x_service_ready_event *ev; -++ int i, n; -++ -++ if (skb->len < sizeof(*ev)) -++ return -EPROTO; -++ -++ ev = (void *)skb->data; -++ skb_pull(skb, sizeof(*ev)); -++ arg->min_tx_power = ev->hw_min_tx_power; -++ arg->max_tx_power = ev->hw_max_tx_power; -++ arg->ht_cap = ev->ht_cap_info; -++ arg->vht_cap = ev->vht_cap_info; -++ arg->sw_ver0 = ev->sw_version; -++ arg->phy_capab = ev->phy_capability; -++ arg->num_rf_chains = ev->num_rf_chains; -++ arg->eeprom_rd = ev->hal_reg_capabilities.eeprom_rd; -++ arg->num_mem_reqs = ev->num_mem_reqs; -++ arg->service_map = ev->wmi_service_bitmap; -++ arg->service_map_len = sizeof(ev->wmi_service_bitmap); -++ -++ n = min_t(size_t, __le32_to_cpu(arg->num_mem_reqs), -++ ARRAY_SIZE(arg->mem_reqs)); -++ for (i = 0; i < n; i++) -++ arg->mem_reqs[i] = &ev->mem_reqs[i]; -++ -++ if (skb->len < -++ __le32_to_cpu(arg->num_mem_reqs) * sizeof(arg->mem_reqs[0])) -++ return -EPROTO; -++ -++ return 0; -++} -++ -++void ath10k_wmi_event_service_ready(struct ath10k *ar, struct sk_buff *skb) -+ { -+- struct wmi_service_ready_event *ev = (void *)skb->data; -++ struct wmi_svc_rdy_ev_arg arg = {}; -++ u32 num_units, req_id, unit_size, num_mem_reqs, num_unit_info, i; -++ int ret; -+ -+- if (skb->len < sizeof(*ev)) { -+- ath10k_warn("Service ready event was %d B but expected %zu B. Wrong firmware version?\n", -+- skb->len, sizeof(*ev)); -++ ret = ath10k_wmi_pull_svc_rdy(ar, skb, &arg); -++ if (ret) { -++ ath10k_warn(ar, "failed to parse service ready: %d\n", ret); -+ return; -+ } -+ -+- ar->hw_min_tx_power = __le32_to_cpu(ev->hw_min_tx_power); -+- ar->hw_max_tx_power = __le32_to_cpu(ev->hw_max_tx_power); -+- ar->ht_cap_info = __le32_to_cpu(ev->ht_cap_info); -+- ar->vht_cap_info = __le32_to_cpu(ev->vht_cap_info); -++ memset(&ar->wmi.svc_map, 0, sizeof(ar->wmi.svc_map)); -++ ath10k_wmi_map_svc(ar, arg.service_map, ar->wmi.svc_map, -++ arg.service_map_len); -++ -++ ar->hw_min_tx_power = __le32_to_cpu(arg.min_tx_power); -++ ar->hw_max_tx_power = __le32_to_cpu(arg.max_tx_power); -++ ar->ht_cap_info = __le32_to_cpu(arg.ht_cap); -++ ar->vht_cap_info = __le32_to_cpu(arg.vht_cap); -+ ar->fw_version_major = -+- (__le32_to_cpu(ev->sw_version) & 0xff000000) >> 24; -+- ar->fw_version_minor = (__le32_to_cpu(ev->sw_version) & 0x00ffffff); -++ (__le32_to_cpu(arg.sw_ver0) & 0xff000000) >> 24; -++ ar->fw_version_minor = (__le32_to_cpu(arg.sw_ver0) & 0x00ffffff); -+ ar->fw_version_release = -+- (__le32_to_cpu(ev->sw_version_1) & 0xffff0000) >> 16; -+- ar->fw_version_build = (__le32_to_cpu(ev->sw_version_1) & 0x0000ffff); -+- ar->phy_capability = __le32_to_cpu(ev->phy_capability); -+- ar->num_rf_chains = __le32_to_cpu(ev->num_rf_chains); -++ (__le32_to_cpu(arg.sw_ver1) & 0xffff0000) >> 16; -++ ar->fw_version_build = (__le32_to_cpu(arg.sw_ver1) & 0x0000ffff); -++ ar->phy_capability = __le32_to_cpu(arg.phy_capab); -++ ar->num_rf_chains = __le32_to_cpu(arg.num_rf_chains); -++ ar->ath_common.regulatory.current_rd = __le32_to_cpu(arg.eeprom_rd); -++ -++ ath10k_dbg_dump(ar, ATH10K_DBG_WMI, NULL, "wmi svc: ", -++ arg.service_map, arg.service_map_len); -+ -+ /* only manually set fw features when not using FW IE format */ -+ if (ar->fw_api == 1 && ar->fw_version_build > 636) -+ set_bit(ATH10K_FW_FEATURE_EXT_WMI_MGMT_RX, ar->fw_features); -+ -+ if (ar->num_rf_chains > WMI_MAX_SPATIAL_STREAM) { -+- ath10k_warn("hardware advertises support for more spatial streams than it should (%d > %d)\n", -++ ath10k_warn(ar, "hardware advertises support for more spatial streams than it should (%d > %d)\n", -+ ar->num_rf_chains, WMI_MAX_SPATIAL_STREAM); -+ ar->num_rf_chains = WMI_MAX_SPATIAL_STREAM; -+ } -+ -+- ar->ath_common.regulatory.current_rd = -+- __le32_to_cpu(ev->hal_reg_capabilities.eeprom_rd); -+- -+- ath10k_debug_read_service_map(ar, ev->wmi_service_bitmap, -+- sizeof(ev->wmi_service_bitmap)); -++ ar->supp_tx_chainmask = (1 << ar->num_rf_chains) - 1; -++ ar->supp_rx_chainmask = (1 << ar->num_rf_chains) - 1; -+ -+ if (strlen(ar->hw->wiphy->fw_version) == 0) { -+ snprintf(ar->hw->wiphy->fw_version, -+@@ -1942,90 +3161,18 @@ static void ath10k_wmi_service_ready_eve -+ ar->fw_version_build); -+ } -+ -+- /* FIXME: it probably should be better to support this */ -+- if (__le32_to_cpu(ev->num_mem_reqs) > 0) { -+- ath10k_warn("target requested %d memory chunks; ignoring\n", -+- __le32_to_cpu(ev->num_mem_reqs)); -+- } -+- -+- ath10k_dbg(ATH10K_DBG_WMI, -+- "wmi event service ready sw_ver 0x%08x sw_ver1 0x%08x abi_ver %u phy_cap 0x%08x ht_cap 0x%08x vht_cap 0x%08x vht_supp_msc 0x%08x sys_cap_info 0x%08x mem_reqs %u num_rf_chains %u\n", -+- __le32_to_cpu(ev->sw_version), -+- __le32_to_cpu(ev->sw_version_1), -+- __le32_to_cpu(ev->abi_version), -+- __le32_to_cpu(ev->phy_capability), -+- __le32_to_cpu(ev->ht_cap_info), -+- __le32_to_cpu(ev->vht_cap_info), -+- __le32_to_cpu(ev->vht_supp_mcs), -+- __le32_to_cpu(ev->sys_cap_info), -+- __le32_to_cpu(ev->num_mem_reqs), -+- __le32_to_cpu(ev->num_rf_chains)); -+- -+- complete(&ar->wmi.service_ready); -+-} -+- -+-static void ath10k_wmi_10x_service_ready_event_rx(struct ath10k *ar, -+- struct sk_buff *skb) -+-{ -+- u32 num_units, req_id, unit_size, num_mem_reqs, num_unit_info, i; -+- int ret; -+- struct wmi_service_ready_event_10x *ev = (void *)skb->data; -+- -+- if (skb->len < sizeof(*ev)) { -+- ath10k_warn("Service ready event was %d B but expected %zu B. Wrong firmware version?\n", -+- skb->len, sizeof(*ev)); -+- return; -+- } -+- -+- ar->hw_min_tx_power = __le32_to_cpu(ev->hw_min_tx_power); -+- ar->hw_max_tx_power = __le32_to_cpu(ev->hw_max_tx_power); -+- ar->ht_cap_info = __le32_to_cpu(ev->ht_cap_info); -+- ar->vht_cap_info = __le32_to_cpu(ev->vht_cap_info); -+- ar->fw_version_major = -+- (__le32_to_cpu(ev->sw_version) & 0xff000000) >> 24; -+- ar->fw_version_minor = (__le32_to_cpu(ev->sw_version) & 0x00ffffff); -+- ar->phy_capability = __le32_to_cpu(ev->phy_capability); -+- ar->num_rf_chains = __le32_to_cpu(ev->num_rf_chains); -+- -+- if (ar->num_rf_chains > WMI_MAX_SPATIAL_STREAM) { -+- ath10k_warn("hardware advertises support for more spatial streams than it should (%d > %d)\n", -+- ar->num_rf_chains, WMI_MAX_SPATIAL_STREAM); -+- ar->num_rf_chains = WMI_MAX_SPATIAL_STREAM; -+- } -+- -+- ar->ath_common.regulatory.current_rd = -+- __le32_to_cpu(ev->hal_reg_capabilities.eeprom_rd); -+- -+- ath10k_debug_read_service_map(ar, ev->wmi_service_bitmap, -+- sizeof(ev->wmi_service_bitmap)); -+- -+- if (strlen(ar->hw->wiphy->fw_version) == 0) { -+- snprintf(ar->hw->wiphy->fw_version, -+- sizeof(ar->hw->wiphy->fw_version), -+- "%u.%u", -+- ar->fw_version_major, -+- ar->fw_version_minor); -+- } -+- -+- num_mem_reqs = __le32_to_cpu(ev->num_mem_reqs); -+- -+- if (num_mem_reqs > ATH10K_MAX_MEM_REQS) { -+- ath10k_warn("requested memory chunks number (%d) exceeds the limit\n", -++ num_mem_reqs = __le32_to_cpu(arg.num_mem_reqs); -++ if (num_mem_reqs > WMI_MAX_MEM_REQS) { -++ ath10k_warn(ar, "requested memory chunks number (%d) exceeds the limit\n", -+ num_mem_reqs); -+ return; -+ } -+ -+- if (!num_mem_reqs) -+- goto exit; -+- -+- ath10k_dbg(ATH10K_DBG_WMI, "firmware has requested %d memory chunks\n", -+- num_mem_reqs); -+- -+ for (i = 0; i < num_mem_reqs; ++i) { -+- req_id = __le32_to_cpu(ev->mem_reqs[i].req_id); -+- num_units = __le32_to_cpu(ev->mem_reqs[i].num_units); -+- unit_size = __le32_to_cpu(ev->mem_reqs[i].unit_size); -+- num_unit_info = __le32_to_cpu(ev->mem_reqs[i].num_unit_info); -++ req_id = __le32_to_cpu(arg.mem_reqs[i]->req_id); -++ num_units = __le32_to_cpu(arg.mem_reqs[i]->num_units); -++ unit_size = __le32_to_cpu(arg.mem_reqs[i]->unit_size); -++ num_unit_info = __le32_to_cpu(arg.mem_reqs[i]->num_unit_info); -+ -+ if (num_unit_info & NUM_UNITS_IS_NUM_PEERS) -+ /* number of units to allocate is number of -+@@ -2036,10 +3183,10 @@ static void ath10k_wmi_10x_service_ready -+ else if (num_unit_info & NUM_UNITS_IS_NUM_VDEVS) -+ num_units = TARGET_10X_NUM_VDEVS + 1; -+ -+- ath10k_dbg(ATH10K_DBG_WMI, -++ ath10k_dbg(ar, ATH10K_DBG_WMI, -+ "wmi mem_req_id %d num_units %d num_unit_info %d unit size %d actual units %d\n", -+ req_id, -+- __le32_to_cpu(ev->mem_reqs[i].num_units), -++ __le32_to_cpu(arg.mem_reqs[i]->num_units), -+ num_unit_info, -+ unit_size, -+ num_units); -+@@ -2050,47 +3197,79 @@ static void ath10k_wmi_10x_service_ready -+ return; -+ } -+ -+-exit: -+- ath10k_dbg(ATH10K_DBG_WMI, -+- "wmi event service ready sw_ver 0x%08x abi_ver %u phy_cap 0x%08x ht_cap 0x%08x vht_cap 0x%08x vht_supp_msc 0x%08x sys_cap_info 0x%08x mem_reqs %u num_rf_chains %u\n", -+- __le32_to_cpu(ev->sw_version), -+- __le32_to_cpu(ev->abi_version), -+- __le32_to_cpu(ev->phy_capability), -+- __le32_to_cpu(ev->ht_cap_info), -+- __le32_to_cpu(ev->vht_cap_info), -+- __le32_to_cpu(ev->vht_supp_mcs), -+- __le32_to_cpu(ev->sys_cap_info), -+- __le32_to_cpu(ev->num_mem_reqs), -+- __le32_to_cpu(ev->num_rf_chains)); -++ ath10k_dbg(ar, ATH10K_DBG_WMI, -++ "wmi event service ready min_tx_power 0x%08x max_tx_power 0x%08x ht_cap 0x%08x vht_cap 0x%08x sw_ver0 0x%08x sw_ver1 0x%08x fw_build 0x%08x phy_capab 0x%08x num_rf_chains 0x%08x eeprom_rd 0x%08x num_mem_reqs 0x%08x\n", -++ __le32_to_cpu(arg.min_tx_power), -++ __le32_to_cpu(arg.max_tx_power), -++ __le32_to_cpu(arg.ht_cap), -++ __le32_to_cpu(arg.vht_cap), -++ __le32_to_cpu(arg.sw_ver0), -++ __le32_to_cpu(arg.sw_ver1), -++ __le32_to_cpu(arg.fw_build), -++ __le32_to_cpu(arg.phy_capab), -++ __le32_to_cpu(arg.num_rf_chains), -++ __le32_to_cpu(arg.eeprom_rd), -++ __le32_to_cpu(arg.num_mem_reqs)); -+ -+ complete(&ar->wmi.service_ready); -+ } -+ -+-static int ath10k_wmi_ready_event_rx(struct ath10k *ar, struct sk_buff *skb) -++static int ath10k_wmi_op_pull_rdy_ev(struct ath10k *ar, struct sk_buff *skb, -++ struct wmi_rdy_ev_arg *arg) -+ { -+- struct wmi_ready_event *ev = (struct wmi_ready_event *)skb->data; -++ struct wmi_ready_event *ev = (void *)skb->data; -+ -+- if (WARN_ON(skb->len < sizeof(*ev))) -+- return -EINVAL; -++ if (skb->len < sizeof(*ev)) -++ return -EPROTO; -++ -++ skb_pull(skb, sizeof(*ev)); -++ arg->sw_version = ev->sw_version; -++ arg->abi_version = ev->abi_version; -++ arg->status = ev->status; -++ arg->mac_addr = ev->mac_addr.addr; -++ -++ return 0; -++} -++ -++int ath10k_wmi_event_ready(struct ath10k *ar, struct sk_buff *skb) -++{ -++ struct wmi_rdy_ev_arg arg = {}; -++ int ret; -+ -+- memcpy(ar->mac_addr, ev->mac_addr.addr, ETH_ALEN); -++ ret = ath10k_wmi_pull_rdy(ar, skb, &arg); -++ if (ret) { -++ ath10k_warn(ar, "failed to parse ready event: %d\n", ret); -++ return ret; -++ } -+ -+- ath10k_dbg(ATH10K_DBG_WMI, -+- "wmi event ready sw_version %u abi_version %u mac_addr %pM status %d skb->len %i ev-sz %zu\n", -+- __le32_to_cpu(ev->sw_version), -+- __le32_to_cpu(ev->abi_version), -+- ev->mac_addr.addr, -+- __le32_to_cpu(ev->status), skb->len, sizeof(*ev)); -++ ath10k_dbg(ar, ATH10K_DBG_WMI, -++ "wmi event ready sw_version %u abi_version %u mac_addr %pM status %d\n", -++ __le32_to_cpu(arg.sw_version), -++ __le32_to_cpu(arg.abi_version), -++ arg.mac_addr, -++ __le32_to_cpu(arg.status)); -+ -++ ether_addr_copy(ar->mac_addr, arg.mac_addr); -+ complete(&ar->wmi.unified_ready); -+ return 0; -+ } -+ -+-static void ath10k_wmi_main_process_rx(struct ath10k *ar, struct sk_buff *skb) -++static int ath10k_wmi_event_temperature(struct ath10k *ar, struct sk_buff *skb) -++{ -++ const struct wmi_pdev_temperature_event *ev; -++ -++ ev = (struct wmi_pdev_temperature_event *)skb->data; -++ if (WARN_ON(skb->len < sizeof(*ev))) -++ return -EPROTO; -++ -++ ath10k_thermal_event_temperature(ar, __le32_to_cpu(ev->temperature)); -++ return 0; -++} -++ -++static void ath10k_wmi_op_rx(struct ath10k *ar, struct sk_buff *skb) -+ { -+ struct wmi_cmd_hdr *cmd_hdr; -+ enum wmi_event_id id; -+- u16 len; -+ -+ cmd_hdr = (struct wmi_cmd_hdr *)skb->data; -+ id = MS(__le32_to_cpu(cmd_hdr->cmd_id), WMI_CMD_HDR_CMD_ID); -+@@ -2098,9 +3277,7 @@ static void ath10k_wmi_main_process_rx(s -+ if (skb_pull(skb, sizeof(struct wmi_cmd_hdr)) == NULL) -+ return; -+ -+- len = skb->len; -+- -+- trace_ath10k_wmi_event(id, skb->data, skb->len); -++ trace_ath10k_wmi_event(ar, id, skb->data, skb->len); -+ -+ switch (id) { -+ case WMI_MGMT_RX_EVENTID: -+@@ -2192,24 +3369,24 @@ static void ath10k_wmi_main_process_rx(s -+ ath10k_wmi_event_vdev_install_key_complete(ar, skb); -+ break; -+ case WMI_SERVICE_READY_EVENTID: -+- ath10k_wmi_service_ready_event_rx(ar, skb); -++ ath10k_wmi_event_service_ready(ar, skb); -+ break; -+ case WMI_READY_EVENTID: -+- ath10k_wmi_ready_event_rx(ar, skb); -++ ath10k_wmi_event_ready(ar, skb); -+ break; -+ default: -+- ath10k_warn("Unknown eventid: %d\n", id); -++ ath10k_warn(ar, "Unknown eventid: %d\n", id); -+ break; -+ } -+ -+ dev_kfree_skb(skb); -+ } -+ -+-static void ath10k_wmi_10x_process_rx(struct ath10k *ar, struct sk_buff *skb) -++static void ath10k_wmi_10_1_op_rx(struct ath10k *ar, struct sk_buff *skb) -+ { -+ struct wmi_cmd_hdr *cmd_hdr; -+ enum wmi_10x_event_id id; -+- u16 len; -++ bool consumed; -+ -+ cmd_hdr = (struct wmi_cmd_hdr *)skb->data; -+ id = MS(__le32_to_cpu(cmd_hdr->cmd_id), WMI_CMD_HDR_CMD_ID); -+@@ -2217,9 +3394,19 @@ static void ath10k_wmi_10x_process_rx(st -+ if (skb_pull(skb, sizeof(struct wmi_cmd_hdr)) == NULL) -+ return; -+ -+- len = skb->len; -++ trace_ath10k_wmi_event(ar, id, skb->data, skb->len); -++ -++ consumed = ath10k_tm_event_wmi(ar, id, skb); -+ -+- trace_ath10k_wmi_event(id, skb->data, skb->len); -++ /* Ready event must be handled normally also in UTF mode so that we -++ * know the UTF firmware has booted, others we are just bypass WMI -++ * events to testmode. -++ */ -++ if (consumed && id != WMI_10X_READY_EVENTID) { -++ ath10k_dbg(ar, ATH10K_DBG_WMI, -++ "wmi testmode consumed 0x%x\n", id); -++ goto out; -++ } -+ -+ switch (id) { -+ case WMI_10X_MGMT_RX_EVENTID: -+@@ -2302,64 +3489,153 @@ static void ath10k_wmi_10x_process_rx(st -+ ath10k_wmi_event_vdev_resume_req(ar, skb); -+ break; -+ case WMI_10X_SERVICE_READY_EVENTID: -+- ath10k_wmi_10x_service_ready_event_rx(ar, skb); -++ ath10k_wmi_event_service_ready(ar, skb); -+ break; -+ case WMI_10X_READY_EVENTID: -+- ath10k_wmi_ready_event_rx(ar, skb); -++ ath10k_wmi_event_ready(ar, skb); -++ break; -++ case WMI_10X_PDEV_UTF_EVENTID: -++ /* ignore utf events */ -+ break; -+ default: -+- ath10k_warn("Unknown eventid: %d\n", id); -++ ath10k_warn(ar, "Unknown eventid: %d\n", id); -+ break; -+ } -+ -++out: -+ dev_kfree_skb(skb); -+ } -+ -+- -+-static void ath10k_wmi_process_rx(struct ath10k *ar, struct sk_buff *skb) -++static void ath10k_wmi_10_2_op_rx(struct ath10k *ar, struct sk_buff *skb) -+ { -+- if (test_bit(ATH10K_FW_FEATURE_WMI_10X, ar->fw_features)) -+- ath10k_wmi_10x_process_rx(ar, skb); -+- else -+- ath10k_wmi_main_process_rx(ar, skb); -+-} -++ struct wmi_cmd_hdr *cmd_hdr; -++ enum wmi_10_2_event_id id; -+ -+-/* WMI Initialization functions */ -+-int ath10k_wmi_attach(struct ath10k *ar) -+-{ -+- if (test_bit(ATH10K_FW_FEATURE_WMI_10X, ar->fw_features)) { -+- ar->wmi.cmd = &wmi_10x_cmd_map; -+- ar->wmi.vdev_param = &wmi_10x_vdev_param_map; -+- ar->wmi.pdev_param = &wmi_10x_pdev_param_map; -+- } else { -+- ar->wmi.cmd = &wmi_cmd_map; -+- ar->wmi.vdev_param = &wmi_vdev_param_map; -+- ar->wmi.pdev_param = &wmi_pdev_param_map; -+- } -++ cmd_hdr = (struct wmi_cmd_hdr *)skb->data; -++ id = MS(__le32_to_cpu(cmd_hdr->cmd_id), WMI_CMD_HDR_CMD_ID); -+ -+- init_completion(&ar->wmi.service_ready); -+- init_completion(&ar->wmi.unified_ready); -+- init_waitqueue_head(&ar->wmi.tx_credits_wq); -++ if (skb_pull(skb, sizeof(struct wmi_cmd_hdr)) == NULL) -++ return; -+ -+- return 0; -++ trace_ath10k_wmi_event(ar, id, skb->data, skb->len); -++ -++ switch (id) { -++ case WMI_10_2_MGMT_RX_EVENTID: -++ ath10k_wmi_event_mgmt_rx(ar, skb); -++ /* mgmt_rx() owns the skb now! */ -++ return; -++ case WMI_10_2_SCAN_EVENTID: -++ ath10k_wmi_event_scan(ar, skb); -++ break; -++ case WMI_10_2_CHAN_INFO_EVENTID: -++ ath10k_wmi_event_chan_info(ar, skb); -++ break; -++ case WMI_10_2_ECHO_EVENTID: -++ ath10k_wmi_event_echo(ar, skb); -++ break; -++ case WMI_10_2_DEBUG_MESG_EVENTID: -++ ath10k_wmi_event_debug_mesg(ar, skb); -++ break; -++ case WMI_10_2_UPDATE_STATS_EVENTID: -++ ath10k_wmi_event_update_stats(ar, skb); -++ break; -++ case WMI_10_2_VDEV_START_RESP_EVENTID: -++ ath10k_wmi_event_vdev_start_resp(ar, skb); -++ break; -++ case WMI_10_2_VDEV_STOPPED_EVENTID: -++ ath10k_wmi_event_vdev_stopped(ar, skb); -++ break; -++ case WMI_10_2_PEER_STA_KICKOUT_EVENTID: -++ ath10k_wmi_event_peer_sta_kickout(ar, skb); -++ break; -++ case WMI_10_2_HOST_SWBA_EVENTID: -++ ath10k_wmi_event_host_swba(ar, skb); -++ break; -++ case WMI_10_2_TBTTOFFSET_UPDATE_EVENTID: -++ ath10k_wmi_event_tbttoffset_update(ar, skb); -++ break; -++ case WMI_10_2_PHYERR_EVENTID: -++ ath10k_wmi_event_phyerr(ar, skb); -++ break; -++ case WMI_10_2_ROAM_EVENTID: -++ ath10k_wmi_event_roam(ar, skb); -++ break; -++ case WMI_10_2_PROFILE_MATCH: -++ ath10k_wmi_event_profile_match(ar, skb); -++ break; -++ case WMI_10_2_DEBUG_PRINT_EVENTID: -++ ath10k_wmi_event_debug_print(ar, skb); -++ break; -++ case WMI_10_2_PDEV_QVIT_EVENTID: -++ ath10k_wmi_event_pdev_qvit(ar, skb); -++ break; -++ case WMI_10_2_WLAN_PROFILE_DATA_EVENTID: -++ ath10k_wmi_event_wlan_profile_data(ar, skb); -++ break; -++ case WMI_10_2_RTT_MEASUREMENT_REPORT_EVENTID: -++ ath10k_wmi_event_rtt_measurement_report(ar, skb); -++ break; -++ case WMI_10_2_TSF_MEASUREMENT_REPORT_EVENTID: -++ ath10k_wmi_event_tsf_measurement_report(ar, skb); -++ break; -++ case WMI_10_2_RTT_ERROR_REPORT_EVENTID: -++ ath10k_wmi_event_rtt_error_report(ar, skb); -++ break; -++ case WMI_10_2_WOW_WAKEUP_HOST_EVENTID: -++ ath10k_wmi_event_wow_wakeup_host(ar, skb); -++ break; -++ case WMI_10_2_DCS_INTERFERENCE_EVENTID: -++ ath10k_wmi_event_dcs_interference(ar, skb); -++ break; -++ case WMI_10_2_PDEV_TPC_CONFIG_EVENTID: -++ ath10k_wmi_event_pdev_tpc_config(ar, skb); -++ break; -++ case WMI_10_2_INST_RSSI_STATS_EVENTID: -++ ath10k_wmi_event_inst_rssi_stats(ar, skb); -++ break; -++ case WMI_10_2_VDEV_STANDBY_REQ_EVENTID: -++ ath10k_wmi_event_vdev_standby_req(ar, skb); -++ break; -++ case WMI_10_2_VDEV_RESUME_REQ_EVENTID: -++ ath10k_wmi_event_vdev_resume_req(ar, skb); -++ break; -++ case WMI_10_2_SERVICE_READY_EVENTID: -++ ath10k_wmi_event_service_ready(ar, skb); -++ break; -++ case WMI_10_2_READY_EVENTID: -++ ath10k_wmi_event_ready(ar, skb); -++ break; -++ case WMI_10_2_PDEV_TEMPERATURE_EVENTID: -++ ath10k_wmi_event_temperature(ar, skb); -++ break; -++ case WMI_10_2_RTT_KEEPALIVE_EVENTID: -++ case WMI_10_2_GPIO_INPUT_EVENTID: -++ case WMI_10_2_PEER_RATECODE_LIST_EVENTID: -++ case WMI_10_2_GENERIC_BUFFER_EVENTID: -++ case WMI_10_2_MCAST_BUF_RELEASE_EVENTID: -++ case WMI_10_2_MCAST_LIST_AGEOUT_EVENTID: -++ case WMI_10_2_WDS_PEER_EVENTID: -++ ath10k_dbg(ar, ATH10K_DBG_WMI, -++ "received event id %d not implemented\n", id); -++ break; -++ default: -++ ath10k_warn(ar, "Unknown eventid: %d\n", id); -++ break; -++ } -++ -++ dev_kfree_skb(skb); -+ } -+ -+-void ath10k_wmi_detach(struct ath10k *ar) -++static void ath10k_wmi_process_rx(struct ath10k *ar, struct sk_buff *skb) -+ { -+- int i; -+- -+- /* free the host memory chunks requested by firmware */ -+- for (i = 0; i < ar->wmi.num_mem_chunks; i++) { -+- dma_free_coherent(ar->dev, -+- ar->wmi.mem_chunks[i].len, -+- ar->wmi.mem_chunks[i].vaddr, -+- ar->wmi.mem_chunks[i].paddr); -+- } -++ int ret; -+ -+- ar->wmi.num_mem_chunks = 0; -++ ret = ath10k_wmi_rx(ar, skb); -++ if (ret) -++ ath10k_warn(ar, "failed to process wmi rx: %d\n", ret); -+ } -+ -+-int ath10k_wmi_connect_htc_service(struct ath10k *ar) -++int ath10k_wmi_connect(struct ath10k *ar) -+ { -+ int status; -+ struct ath10k_htc_svc_conn_req conn_req; -+@@ -2378,7 +3654,7 @@ int ath10k_wmi_connect_htc_service(struc -+ -+ status = ath10k_htc_connect_service(&ar->htc, &conn_req, &conn_resp); -+ if (status) { -+- ath10k_warn("failed to connect to WMI CONTROL service status: %d\n", -++ ath10k_warn(ar, "failed to connect to WMI CONTROL service status: %d\n", -+ status); -+ return status; -+ } -+@@ -2387,16 +3663,17 @@ int ath10k_wmi_connect_htc_service(struc -+ return 0; -+ } -+ -+-static int ath10k_wmi_main_pdev_set_regdomain(struct ath10k *ar, u16 rd, -+- u16 rd2g, u16 rd5g, u16 ctl2g, -+- u16 ctl5g) -++static struct sk_buff * -++ath10k_wmi_op_gen_pdev_set_rd(struct ath10k *ar, u16 rd, u16 rd2g, u16 rd5g, -++ u16 ctl2g, u16 ctl5g, -++ enum wmi_dfs_region dfs_reg) -+ { -+ struct wmi_pdev_set_regdomain_cmd *cmd; -+ struct sk_buff *skb; -+ -+- skb = ath10k_wmi_alloc_skb(sizeof(*cmd)); -++ skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd)); -+ if (!skb) -+- return -ENOMEM; -++ return ERR_PTR(-ENOMEM); -+ -+ cmd = (struct wmi_pdev_set_regdomain_cmd *)skb->data; -+ cmd->reg_domain = __cpu_to_le32(rd); -+@@ -2405,25 +3682,23 @@ static int ath10k_wmi_main_pdev_set_regd -+ cmd->conformance_test_limit_2G = __cpu_to_le32(ctl2g); -+ cmd->conformance_test_limit_5G = __cpu_to_le32(ctl5g); -+ -+- ath10k_dbg(ATH10K_DBG_WMI, -++ ath10k_dbg(ar, ATH10K_DBG_WMI, -+ "wmi pdev regdomain rd %x rd2g %x rd5g %x ctl2g %x ctl5g %x\n", -+ rd, rd2g, rd5g, ctl2g, ctl5g); -+- -+- return ath10k_wmi_cmd_send(ar, skb, -+- ar->wmi.cmd->pdev_set_regdomain_cmdid); -++ return skb; -+ } -+ -+-static int ath10k_wmi_10x_pdev_set_regdomain(struct ath10k *ar, u16 rd, -+- u16 rd2g, u16 rd5g, -+- u16 ctl2g, u16 ctl5g, -+- enum wmi_dfs_region dfs_reg) -++static struct sk_buff * -++ath10k_wmi_10x_op_gen_pdev_set_rd(struct ath10k *ar, u16 rd, u16 rd2g, u16 -++ rd5g, u16 ctl2g, u16 ctl5g, -++ enum wmi_dfs_region dfs_reg) -+ { -+ struct wmi_pdev_set_regdomain_cmd_10x *cmd; -+ struct sk_buff *skb; -+ -+- skb = ath10k_wmi_alloc_skb(sizeof(*cmd)); -++ skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd)); -+ if (!skb) -+- return -ENOMEM; -++ return ERR_PTR(-ENOMEM); -+ -+ cmd = (struct wmi_pdev_set_regdomain_cmd_10x *)skb->data; -+ cmd->reg_domain = __cpu_to_le32(rd); -+@@ -2433,121 +3708,96 @@ static int ath10k_wmi_10x_pdev_set_regdo -+ cmd->conformance_test_limit_5G = __cpu_to_le32(ctl5g); -+ cmd->dfs_domain = __cpu_to_le32(dfs_reg); -+ -+- ath10k_dbg(ATH10K_DBG_WMI, -++ ath10k_dbg(ar, ATH10K_DBG_WMI, -+ "wmi pdev regdomain rd %x rd2g %x rd5g %x ctl2g %x ctl5g %x dfs_region %x\n", -+ rd, rd2g, rd5g, ctl2g, ctl5g, dfs_reg); -+- -+- return ath10k_wmi_cmd_send(ar, skb, -+- ar->wmi.cmd->pdev_set_regdomain_cmdid); -+-} -+- -+-int ath10k_wmi_pdev_set_regdomain(struct ath10k *ar, u16 rd, u16 rd2g, -+- u16 rd5g, u16 ctl2g, u16 ctl5g, -+- enum wmi_dfs_region dfs_reg) -+-{ -+- if (test_bit(ATH10K_FW_FEATURE_WMI_10X, ar->fw_features)) -+- return ath10k_wmi_10x_pdev_set_regdomain(ar, rd, rd2g, rd5g, -+- ctl2g, ctl5g, dfs_reg); -+- else -+- return ath10k_wmi_main_pdev_set_regdomain(ar, rd, rd2g, rd5g, -+- ctl2g, ctl5g); -+-} -+- -+-int ath10k_wmi_pdev_set_channel(struct ath10k *ar, -+- const struct wmi_channel_arg *arg) -+-{ -+- struct wmi_set_channel_cmd *cmd; -+- struct sk_buff *skb; -+- u32 ch_flags = 0; -+- -+- if (arg->passive) -+- return -EINVAL; -+- -+- skb = ath10k_wmi_alloc_skb(sizeof(*cmd)); -+- if (!skb) -+- return -ENOMEM; -+- -+- if (arg->chan_radar) -+- ch_flags |= WMI_CHAN_FLAG_DFS; -+- -+- cmd = (struct wmi_set_channel_cmd *)skb->data; -+- cmd->chan.mhz = __cpu_to_le32(arg->freq); -+- cmd->chan.band_center_freq1 = __cpu_to_le32(arg->freq); -+- cmd->chan.mode = arg->mode; -+- cmd->chan.flags |= __cpu_to_le32(ch_flags); -+- cmd->chan.min_power = arg->min_power; -+- cmd->chan.max_power = arg->max_power; -+- cmd->chan.reg_power = arg->max_reg_power; -+- cmd->chan.reg_classid = arg->reg_class_id; -+- cmd->chan.antenna_max = arg->max_antenna_gain; -+- -+- ath10k_dbg(ATH10K_DBG_WMI, -+- "wmi set channel mode %d freq %d\n", -+- arg->mode, arg->freq); -+- -+- return ath10k_wmi_cmd_send(ar, skb, -+- ar->wmi.cmd->pdev_set_channel_cmdid); -++ return skb; -+ } -+ -+-int ath10k_wmi_pdev_suspend_target(struct ath10k *ar, u32 suspend_opt) -++static struct sk_buff * -++ath10k_wmi_op_gen_pdev_suspend(struct ath10k *ar, u32 suspend_opt) -+ { -+ struct wmi_pdev_suspend_cmd *cmd; -+ struct sk_buff *skb; -+ -+- skb = ath10k_wmi_alloc_skb(sizeof(*cmd)); -++ skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd)); -+ if (!skb) -+- return -ENOMEM; -++ return ERR_PTR(-ENOMEM); -+ -+ cmd = (struct wmi_pdev_suspend_cmd *)skb->data; -+ cmd->suspend_opt = __cpu_to_le32(suspend_opt); -+ -+- return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->pdev_suspend_cmdid); -++ return skb; -+ } -+ -+-int ath10k_wmi_pdev_resume_target(struct ath10k *ar) -++static struct sk_buff * -++ath10k_wmi_op_gen_pdev_resume(struct ath10k *ar) -+ { -+ struct sk_buff *skb; -+ -+- skb = ath10k_wmi_alloc_skb(0); -+- if (skb == NULL) -+- return -ENOMEM; -++ skb = ath10k_wmi_alloc_skb(ar, 0); -++ if (!skb) -++ return ERR_PTR(-ENOMEM); -+ -+- return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->pdev_resume_cmdid); -++ return skb; -+ } -+ -+-int ath10k_wmi_pdev_set_param(struct ath10k *ar, u32 id, u32 value) -++static struct sk_buff * -++ath10k_wmi_op_gen_pdev_set_param(struct ath10k *ar, u32 id, u32 value) -+ { -+ struct wmi_pdev_set_param_cmd *cmd; -+ struct sk_buff *skb; -+ -+ if (id == WMI_PDEV_PARAM_UNSUPPORTED) { -+- ath10k_warn("pdev param %d not supported by firmware\n", id); -+- return -EOPNOTSUPP; -++ ath10k_warn(ar, "pdev param %d not supported by firmware\n", -++ id); -++ return ERR_PTR(-EOPNOTSUPP); -+ } -+ -+- skb = ath10k_wmi_alloc_skb(sizeof(*cmd)); -++ skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd)); -+ if (!skb) -+- return -ENOMEM; -++ return ERR_PTR(-ENOMEM); -+ -+ cmd = (struct wmi_pdev_set_param_cmd *)skb->data; -+ cmd->param_id = __cpu_to_le32(id); -+ cmd->param_value = __cpu_to_le32(value); -+ -+- ath10k_dbg(ATH10K_DBG_WMI, "wmi pdev set param %d value %d\n", -++ ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi pdev set param %d value %d\n", -+ id, value); -+- return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->pdev_set_param_cmdid); -++ return skb; -+ } -+ -+-static int ath10k_wmi_main_cmd_init(struct ath10k *ar) -++void ath10k_wmi_put_host_mem_chunks(struct ath10k *ar, -++ struct wmi_host_mem_chunks *chunks) -+ { -+- struct wmi_init_cmd *cmd; -+- struct sk_buff *buf; -+- struct wmi_resource_config config = {}; -+- u32 len, val; -++ struct host_memory_chunk *chunk; -+ int i; -+ -+- config.num_vdevs = __cpu_to_le32(TARGET_NUM_VDEVS); -+- config.num_peers = __cpu_to_le32(TARGET_NUM_PEERS + TARGET_NUM_VDEVS); -++ chunks->count = __cpu_to_le32(ar->wmi.num_mem_chunks); -++ -++ for (i = 0; i < ar->wmi.num_mem_chunks; i++) { -++ chunk = &chunks->items[i]; -++ chunk->ptr = __cpu_to_le32(ar->wmi.mem_chunks[i].paddr); -++ chunk->size = __cpu_to_le32(ar->wmi.mem_chunks[i].len); -++ chunk->req_id = __cpu_to_le32(ar->wmi.mem_chunks[i].req_id); -++ -++ ath10k_dbg(ar, ATH10K_DBG_WMI, -++ "wmi chunk %d len %d requested, addr 0x%llx\n", -++ i, -++ ar->wmi.mem_chunks[i].len, -++ (unsigned long long)ar->wmi.mem_chunks[i].paddr); -++ } -++} -++ -++static struct sk_buff *ath10k_wmi_op_gen_init(struct ath10k *ar) -++{ -++ struct wmi_init_cmd *cmd; -++ struct sk_buff *buf; -++ struct wmi_resource_config config = {}; -++ u32 len, val; -++ -++ config.num_vdevs = __cpu_to_le32(TARGET_NUM_VDEVS); -++ config.num_peers = __cpu_to_le32(TARGET_NUM_PEERS); -+ config.num_offload_peers = __cpu_to_le32(TARGET_NUM_OFFLOAD_PEERS); -+ -+ config.num_offload_reorder_bufs = -+@@ -2600,50 +3850,25 @@ static int ath10k_wmi_main_cmd_init(stru -+ len = sizeof(*cmd) + -+ (sizeof(struct host_memory_chunk) * ar->wmi.num_mem_chunks); -+ -+- buf = ath10k_wmi_alloc_skb(len); -++ buf = ath10k_wmi_alloc_skb(ar, len); -+ if (!buf) -+- return -ENOMEM; -++ return ERR_PTR(-ENOMEM); -+ -+ cmd = (struct wmi_init_cmd *)buf->data; -+ -+- if (ar->wmi.num_mem_chunks == 0) { -+- cmd->num_host_mem_chunks = 0; -+- goto out; -+- } -+- -+- ath10k_dbg(ATH10K_DBG_WMI, "wmi sending %d memory chunks info.\n", -+- ar->wmi.num_mem_chunks); -+- -+- cmd->num_host_mem_chunks = __cpu_to_le32(ar->wmi.num_mem_chunks); -+- -+- for (i = 0; i < ar->wmi.num_mem_chunks; i++) { -+- cmd->host_mem_chunks[i].ptr = -+- __cpu_to_le32(ar->wmi.mem_chunks[i].paddr); -+- cmd->host_mem_chunks[i].size = -+- __cpu_to_le32(ar->wmi.mem_chunks[i].len); -+- cmd->host_mem_chunks[i].req_id = -+- __cpu_to_le32(ar->wmi.mem_chunks[i].req_id); -+- -+- ath10k_dbg(ATH10K_DBG_WMI, -+- "wmi chunk %d len %d requested, addr 0x%llx\n", -+- i, -+- ar->wmi.mem_chunks[i].len, -+- (unsigned long long)ar->wmi.mem_chunks[i].paddr); -+- } -+-out: -+ memcpy(&cmd->resource_config, &config, sizeof(config)); -++ ath10k_wmi_put_host_mem_chunks(ar, &cmd->mem_chunks); -+ -+- ath10k_dbg(ATH10K_DBG_WMI, "wmi init\n"); -+- return ath10k_wmi_cmd_send(ar, buf, ar->wmi.cmd->init_cmdid); -++ ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi init\n"); -++ return buf; -+ } -+ -+-static int ath10k_wmi_10x_cmd_init(struct ath10k *ar) -++static struct sk_buff *ath10k_wmi_10_1_op_gen_init(struct ath10k *ar) -+ { -+ struct wmi_init_cmd_10x *cmd; -+ struct sk_buff *buf; -+ struct wmi_resource_config_10x config = {}; -+ u32 len, val; -+- int i; -+ -+ config.num_vdevs = __cpu_to_le32(TARGET_10X_NUM_VDEVS); -+ config.num_peers = __cpu_to_le32(TARGET_10X_NUM_PEERS); -+@@ -2691,101 +3916,132 @@ static int ath10k_wmi_10x_cmd_init(struc -+ len = sizeof(*cmd) + -+ (sizeof(struct host_memory_chunk) * ar->wmi.num_mem_chunks); -+ -+- buf = ath10k_wmi_alloc_skb(len); -++ buf = ath10k_wmi_alloc_skb(ar, len); -+ if (!buf) -+- return -ENOMEM; -++ return ERR_PTR(-ENOMEM); -+ -+ cmd = (struct wmi_init_cmd_10x *)buf->data; -+ -+- if (ar->wmi.num_mem_chunks == 0) { -+- cmd->num_host_mem_chunks = 0; -+- goto out; -+- } -++ memcpy(&cmd->resource_config, &config, sizeof(config)); -++ ath10k_wmi_put_host_mem_chunks(ar, &cmd->mem_chunks); -+ -+- ath10k_dbg(ATH10K_DBG_WMI, "wmi sending %d memory chunks info.\n", -+- ar->wmi.num_mem_chunks); -++ ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi init 10x\n"); -++ return buf; -++} -+ -+- cmd->num_host_mem_chunks = __cpu_to_le32(ar->wmi.num_mem_chunks); -++static struct sk_buff *ath10k_wmi_10_2_op_gen_init(struct ath10k *ar) -++{ -++ struct wmi_init_cmd_10_2 *cmd; -++ struct sk_buff *buf; -++ struct wmi_resource_config_10x config = {}; -++ u32 len, val, features; -+ -+- for (i = 0; i < ar->wmi.num_mem_chunks; i++) { -+- cmd->host_mem_chunks[i].ptr = -+- __cpu_to_le32(ar->wmi.mem_chunks[i].paddr); -+- cmd->host_mem_chunks[i].size = -+- __cpu_to_le32(ar->wmi.mem_chunks[i].len); -+- cmd->host_mem_chunks[i].req_id = -+- __cpu_to_le32(ar->wmi.mem_chunks[i].req_id); -++ config.num_vdevs = __cpu_to_le32(TARGET_10X_NUM_VDEVS); -++ config.num_peers = __cpu_to_le32(TARGET_10X_NUM_PEERS); -++ config.num_peer_keys = __cpu_to_le32(TARGET_10X_NUM_PEER_KEYS); -++ config.num_tids = __cpu_to_le32(TARGET_10X_NUM_TIDS); -++ config.ast_skid_limit = __cpu_to_le32(TARGET_10X_AST_SKID_LIMIT); -++ config.tx_chain_mask = __cpu_to_le32(TARGET_10X_TX_CHAIN_MASK); -++ config.rx_chain_mask = __cpu_to_le32(TARGET_10X_RX_CHAIN_MASK); -++ config.rx_timeout_pri_vo = __cpu_to_le32(TARGET_10X_RX_TIMEOUT_LO_PRI); -++ config.rx_timeout_pri_vi = __cpu_to_le32(TARGET_10X_RX_TIMEOUT_LO_PRI); -++ config.rx_timeout_pri_be = __cpu_to_le32(TARGET_10X_RX_TIMEOUT_LO_PRI); -++ config.rx_timeout_pri_bk = __cpu_to_le32(TARGET_10X_RX_TIMEOUT_HI_PRI); -++ config.rx_decap_mode = __cpu_to_le32(TARGET_10X_RX_DECAP_MODE); -+ -+- ath10k_dbg(ATH10K_DBG_WMI, -+- "wmi chunk %d len %d requested, addr 0x%llx\n", -+- i, -+- ar->wmi.mem_chunks[i].len, -+- (unsigned long long)ar->wmi.mem_chunks[i].paddr); -+- } -+-out: -+- memcpy(&cmd->resource_config, &config, sizeof(config)); -++ config.scan_max_pending_reqs = -++ __cpu_to_le32(TARGET_10X_SCAN_MAX_PENDING_REQS); -++ -++ config.bmiss_offload_max_vdev = -++ __cpu_to_le32(TARGET_10X_BMISS_OFFLOAD_MAX_VDEV); -++ -++ config.roam_offload_max_vdev = -++ __cpu_to_le32(TARGET_10X_ROAM_OFFLOAD_MAX_VDEV); -++ -++ config.roam_offload_max_ap_profiles = -++ __cpu_to_le32(TARGET_10X_ROAM_OFFLOAD_MAX_AP_PROFILES); -++ -++ config.num_mcast_groups = __cpu_to_le32(TARGET_10X_NUM_MCAST_GROUPS); -++ config.num_mcast_table_elems = -++ __cpu_to_le32(TARGET_10X_NUM_MCAST_TABLE_ELEMS); -++ -++ config.mcast2ucast_mode = __cpu_to_le32(TARGET_10X_MCAST2UCAST_MODE); -++ config.tx_dbg_log_size = __cpu_to_le32(TARGET_10X_TX_DBG_LOG_SIZE); -++ config.num_wds_entries = __cpu_to_le32(TARGET_10X_NUM_WDS_ENTRIES); -++ config.dma_burst_size = __cpu_to_le32(TARGET_10_2_DMA_BURST_SIZE); -++ config.mac_aggr_delim = __cpu_to_le32(TARGET_10X_MAC_AGGR_DELIM); -++ -++ val = TARGET_10X_RX_SKIP_DEFRAG_TIMEOUT_DUP_DETECTION_CHECK; -++ config.rx_skip_defrag_timeout_dup_detection_check = __cpu_to_le32(val); -++ -++ config.vow_config = __cpu_to_le32(TARGET_10X_VOW_CONFIG); -++ -++ config.num_msdu_desc = __cpu_to_le32(TARGET_10X_NUM_MSDU_DESC); -++ config.max_frag_entries = __cpu_to_le32(TARGET_10X_MAX_FRAG_ENTRIES); -+ -+- ath10k_dbg(ATH10K_DBG_WMI, "wmi init 10x\n"); -+- return ath10k_wmi_cmd_send(ar, buf, ar->wmi.cmd->init_cmdid); -++ len = sizeof(*cmd) + -++ (sizeof(struct host_memory_chunk) * ar->wmi.num_mem_chunks); -++ -++ buf = ath10k_wmi_alloc_skb(ar, len); -++ if (!buf) -++ return ERR_PTR(-ENOMEM); -++ -++ cmd = (struct wmi_init_cmd_10_2 *)buf->data; -++ -++ features = WMI_10_2_RX_BATCH_MODE; -++ cmd->resource_config.feature_mask = __cpu_to_le32(features); -++ -++ memcpy(&cmd->resource_config.common, &config, sizeof(config)); -++ ath10k_wmi_put_host_mem_chunks(ar, &cmd->mem_chunks); -++ -++ ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi init 10.2\n"); -++ return buf; -+ } -+ -+-int ath10k_wmi_cmd_init(struct ath10k *ar) -++int ath10k_wmi_start_scan_verify(const struct wmi_start_scan_arg *arg) -+ { -+- int ret; -++ if (arg->ie_len && !arg->ie) -++ return -EINVAL; -++ if (arg->n_channels && !arg->channels) -++ return -EINVAL; -++ if (arg->n_ssids && !arg->ssids) -++ return -EINVAL; -++ if (arg->n_bssids && !arg->bssids) -++ return -EINVAL; -+ -+- if (test_bit(ATH10K_FW_FEATURE_WMI_10X, ar->fw_features)) -+- ret = ath10k_wmi_10x_cmd_init(ar); -+- else -+- ret = ath10k_wmi_main_cmd_init(ar); -++ if (arg->ie_len > WLAN_SCAN_PARAMS_MAX_IE_LEN) -++ return -EINVAL; -++ if (arg->n_channels > ARRAY_SIZE(arg->channels)) -++ return -EINVAL; -++ if (arg->n_ssids > WLAN_SCAN_PARAMS_MAX_SSID) -++ return -EINVAL; -++ if (arg->n_bssids > WLAN_SCAN_PARAMS_MAX_BSSID) -++ return -EINVAL; -+ -+- return ret; -++ return 0; -+ } -+ -+-static int ath10k_wmi_start_scan_calc_len(struct ath10k *ar, -+- const struct wmi_start_scan_arg *arg) -++static size_t -++ath10k_wmi_start_scan_tlvs_len(const struct wmi_start_scan_arg *arg) -+ { -+- int len; -+- -+- if (test_bit(ATH10K_FW_FEATURE_WMI_10X, ar->fw_features)) -+- len = sizeof(struct wmi_start_scan_cmd_10x); -+- else -+- len = sizeof(struct wmi_start_scan_cmd); -++ int len = 0; -+ -+ if (arg->ie_len) { -+- if (!arg->ie) -+- return -EINVAL; -+- if (arg->ie_len > WLAN_SCAN_PARAMS_MAX_IE_LEN) -+- return -EINVAL; -+- -+ len += sizeof(struct wmi_ie_data); -+ len += roundup(arg->ie_len, 4); -+ } -+ -+ if (arg->n_channels) { -+- if (!arg->channels) -+- return -EINVAL; -+- if (arg->n_channels > ARRAY_SIZE(arg->channels)) -+- return -EINVAL; -+- -+ len += sizeof(struct wmi_chan_list); -+ len += sizeof(__le32) * arg->n_channels; -+ } -+ -+ if (arg->n_ssids) { -+- if (!arg->ssids) -+- return -EINVAL; -+- if (arg->n_ssids > WLAN_SCAN_PARAMS_MAX_SSID) -+- return -EINVAL; -+- -+ len += sizeof(struct wmi_ssid_list); -+ len += sizeof(struct wmi_ssid) * arg->n_ssids; -+ } -+ -+ if (arg->n_bssids) { -+- if (!arg->bssids) -+- return -EINVAL; -+- if (arg->n_bssids > WLAN_SCAN_PARAMS_MAX_BSSID) -+- return -EINVAL; -+- -+ len += sizeof(struct wmi_bssid_list); -+ len += sizeof(struct wmi_mac_addr) * arg->n_bssids; -+ } -+@@ -2793,28 +4049,11 @@ static int ath10k_wmi_start_scan_calc_le -+ return len; -+ } -+ -+-int ath10k_wmi_start_scan(struct ath10k *ar, -+- const struct wmi_start_scan_arg *arg) -++void ath10k_wmi_put_start_scan_common(struct wmi_start_scan_common *cmn, -++ const struct wmi_start_scan_arg *arg) -+ { -+- struct wmi_start_scan_cmd *cmd; -+- struct sk_buff *skb; -+- struct wmi_ie_data *ie; -+- struct wmi_chan_list *channels; -+- struct wmi_ssid_list *ssids; -+- struct wmi_bssid_list *bssids; -+ u32 scan_id; -+ u32 scan_req_id; -+- int off; -+- int len = 0; -+- int i; -+- -+- len = ath10k_wmi_start_scan_calc_len(ar, arg); -+- if (len < 0) -+- return len; /* len contains error code here */ -+- -+- skb = ath10k_wmi_alloc_skb(len); -+- if (!skb) -+- return -ENOMEM; -+ -+ scan_id = WMI_HOST_SCAN_REQ_ID_PREFIX; -+ scan_id |= arg->scan_id; -+@@ -2822,48 +4061,49 @@ int ath10k_wmi_start_scan(struct ath10k -+ scan_req_id = WMI_HOST_SCAN_REQUESTOR_ID_PREFIX; -+ scan_req_id |= arg->scan_req_id; -+ -+- cmd = (struct wmi_start_scan_cmd *)skb->data; -+- cmd->scan_id = __cpu_to_le32(scan_id); -+- cmd->scan_req_id = __cpu_to_le32(scan_req_id); -+- cmd->vdev_id = __cpu_to_le32(arg->vdev_id); -+- cmd->scan_priority = __cpu_to_le32(arg->scan_priority); -+- cmd->notify_scan_events = __cpu_to_le32(arg->notify_scan_events); -+- cmd->dwell_time_active = __cpu_to_le32(arg->dwell_time_active); -+- cmd->dwell_time_passive = __cpu_to_le32(arg->dwell_time_passive); -+- cmd->min_rest_time = __cpu_to_le32(arg->min_rest_time); -+- cmd->max_rest_time = __cpu_to_le32(arg->max_rest_time); -+- cmd->repeat_probe_time = __cpu_to_le32(arg->repeat_probe_time); -+- cmd->probe_spacing_time = __cpu_to_le32(arg->probe_spacing_time); -+- cmd->idle_time = __cpu_to_le32(arg->idle_time); -+- cmd->max_scan_time = __cpu_to_le32(arg->max_scan_time); -+- cmd->probe_delay = __cpu_to_le32(arg->probe_delay); -+- cmd->scan_ctrl_flags = __cpu_to_le32(arg->scan_ctrl_flags); -+- -+- /* TLV list starts after fields included in the struct */ -+- /* There's just one filed that differes the two start_scan -+- * structures - burst_duration, which we are not using btw, -+- no point to make the split here, just shift the buffer to fit with -+- given FW */ -+- if (test_bit(ATH10K_FW_FEATURE_WMI_10X, ar->fw_features)) -+- off = sizeof(struct wmi_start_scan_cmd_10x); -+- else -+- off = sizeof(struct wmi_start_scan_cmd); -++ cmn->scan_id = __cpu_to_le32(scan_id); -++ cmn->scan_req_id = __cpu_to_le32(scan_req_id); -++ cmn->vdev_id = __cpu_to_le32(arg->vdev_id); -++ cmn->scan_priority = __cpu_to_le32(arg->scan_priority); -++ cmn->notify_scan_events = __cpu_to_le32(arg->notify_scan_events); -++ cmn->dwell_time_active = __cpu_to_le32(arg->dwell_time_active); -++ cmn->dwell_time_passive = __cpu_to_le32(arg->dwell_time_passive); -++ cmn->min_rest_time = __cpu_to_le32(arg->min_rest_time); -++ cmn->max_rest_time = __cpu_to_le32(arg->max_rest_time); -++ cmn->repeat_probe_time = __cpu_to_le32(arg->repeat_probe_time); -++ cmn->probe_spacing_time = __cpu_to_le32(arg->probe_spacing_time); -++ cmn->idle_time = __cpu_to_le32(arg->idle_time); -++ cmn->max_scan_time = __cpu_to_le32(arg->max_scan_time); -++ cmn->probe_delay = __cpu_to_le32(arg->probe_delay); -++ cmn->scan_ctrl_flags = __cpu_to_le32(arg->scan_ctrl_flags); -++} -++ -++static void -++ath10k_wmi_put_start_scan_tlvs(struct wmi_start_scan_tlvs *tlvs, -++ const struct wmi_start_scan_arg *arg) -++{ -++ struct wmi_ie_data *ie; -++ struct wmi_chan_list *channels; -++ struct wmi_ssid_list *ssids; -++ struct wmi_bssid_list *bssids; -++ void *ptr = tlvs->tlvs; -++ int i; -+ -+ if (arg->n_channels) { -+- channels = (void *)skb->data + off; -++ channels = ptr; -+ channels->tag = __cpu_to_le32(WMI_CHAN_LIST_TAG); -+ channels->num_chan = __cpu_to_le32(arg->n_channels); -+ -+ for (i = 0; i < arg->n_channels; i++) -+- channels->channel_list[i] = -+- __cpu_to_le32(arg->channels[i]); -++ channels->channel_list[i].freq = -++ __cpu_to_le16(arg->channels[i]); -+ -+- off += sizeof(*channels); -+- off += sizeof(__le32) * arg->n_channels; -++ ptr += sizeof(*channels); -++ ptr += sizeof(__le32) * arg->n_channels; -+ } -+ -+ if (arg->n_ssids) { -+- ssids = (void *)skb->data + off; -++ ssids = ptr; -+ ssids->tag = __cpu_to_le32(WMI_SSID_LIST_TAG); -+ ssids->num_ssids = __cpu_to_le32(arg->n_ssids); -+ -+@@ -2875,12 +4115,12 @@ int ath10k_wmi_start_scan(struct ath10k -+ arg->ssids[i].len); -+ } -+ -+- off += sizeof(*ssids); -+- off += sizeof(struct wmi_ssid) * arg->n_ssids; -++ ptr += sizeof(*ssids); -++ ptr += sizeof(struct wmi_ssid) * arg->n_ssids; -+ } -+ -+ if (arg->n_bssids) { -+- bssids = (void *)skb->data + off; -++ bssids = ptr; -+ bssids->tag = __cpu_to_le32(WMI_BSSID_LIST_TAG); -+ bssids->num_bssid = __cpu_to_le32(arg->n_bssids); -+ -+@@ -2889,27 +4129,75 @@ int ath10k_wmi_start_scan(struct ath10k -+ arg->bssids[i].bssid, -+ ETH_ALEN); -+ -+- off += sizeof(*bssids); -+- off += sizeof(struct wmi_mac_addr) * arg->n_bssids; -++ ptr += sizeof(*bssids); -++ ptr += sizeof(struct wmi_mac_addr) * arg->n_bssids; -+ } -+ -+ if (arg->ie_len) { -+- ie = (void *)skb->data + off; -++ ie = ptr; -+ ie->tag = __cpu_to_le32(WMI_IE_TAG); -+ ie->ie_len = __cpu_to_le32(arg->ie_len); -+ memcpy(ie->ie_data, arg->ie, arg->ie_len); -+ -+- off += sizeof(*ie); -+- off += roundup(arg->ie_len, 4); -++ ptr += sizeof(*ie); -++ ptr += roundup(arg->ie_len, 4); -+ } -++} -+ -+- if (off != skb->len) { -+- dev_kfree_skb(skb); -+- return -EINVAL; -+- } -++static struct sk_buff * -++ath10k_wmi_op_gen_start_scan(struct ath10k *ar, -++ const struct wmi_start_scan_arg *arg) -++{ -++ struct wmi_start_scan_cmd *cmd; -++ struct sk_buff *skb; -++ size_t len; -++ int ret; -++ -++ ret = ath10k_wmi_start_scan_verify(arg); -++ if (ret) -++ return ERR_PTR(ret); -+ -+- ath10k_dbg(ATH10K_DBG_WMI, "wmi start scan\n"); -+- return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->start_scan_cmdid); -++ len = sizeof(*cmd) + ath10k_wmi_start_scan_tlvs_len(arg); -++ skb = ath10k_wmi_alloc_skb(ar, len); -++ if (!skb) -++ return ERR_PTR(-ENOMEM); -++ -++ cmd = (struct wmi_start_scan_cmd *)skb->data; -++ -++ ath10k_wmi_put_start_scan_common(&cmd->common, arg); -++ ath10k_wmi_put_start_scan_tlvs(&cmd->tlvs, arg); -++ -++ cmd->burst_duration_ms = __cpu_to_le32(0); -++ -++ ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi start scan\n"); -++ return skb; -++} -++ -++static struct sk_buff * -++ath10k_wmi_10x_op_gen_start_scan(struct ath10k *ar, -++ const struct wmi_start_scan_arg *arg) -++{ -++ struct wmi_10x_start_scan_cmd *cmd; -++ struct sk_buff *skb; -++ size_t len; -++ int ret; -++ -++ ret = ath10k_wmi_start_scan_verify(arg); -++ if (ret) -++ return ERR_PTR(ret); -++ -++ len = sizeof(*cmd) + ath10k_wmi_start_scan_tlvs_len(arg); -++ skb = ath10k_wmi_alloc_skb(ar, len); -++ if (!skb) -++ return ERR_PTR(-ENOMEM); -++ -++ cmd = (struct wmi_10x_start_scan_cmd *)skb->data; -++ -++ ath10k_wmi_put_start_scan_common(&cmd->common, arg); -++ ath10k_wmi_put_start_scan_tlvs(&cmd->tlvs, arg); -++ -++ ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi 10x start scan\n"); -++ return skb; -+ } -+ -+ void ath10k_wmi_start_scan_init(struct ath10k *ar, -+@@ -2938,7 +4226,9 @@ void ath10k_wmi_start_scan_init(struct a -+ arg->bssids[0].bssid = "\xFF\xFF\xFF\xFF\xFF\xFF"; -+ } -+ -+-int ath10k_wmi_stop_scan(struct ath10k *ar, const struct wmi_stop_scan_arg *arg) -++static struct sk_buff * -++ath10k_wmi_op_gen_stop_scan(struct ath10k *ar, -++ const struct wmi_stop_scan_arg *arg) -+ { -+ struct wmi_stop_scan_cmd *cmd; -+ struct sk_buff *skb; -+@@ -2946,13 +4236,13 @@ int ath10k_wmi_stop_scan(struct ath10k * -+ u32 req_id; -+ -+ if (arg->req_id > 0xFFF) -+- return -EINVAL; -++ return ERR_PTR(-EINVAL); -+ if (arg->req_type == WMI_SCAN_STOP_ONE && arg->u.scan_id > 0xFFF) -+- return -EINVAL; -++ return ERR_PTR(-EINVAL); -+ -+- skb = ath10k_wmi_alloc_skb(sizeof(*cmd)); -++ skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd)); -+ if (!skb) -+- return -ENOMEM; -++ return ERR_PTR(-ENOMEM); -+ -+ scan_id = arg->u.scan_id; -+ scan_id |= WMI_HOST_SCAN_REQ_ID_PREFIX; -+@@ -2966,92 +4256,85 @@ int ath10k_wmi_stop_scan(struct ath10k * -+ cmd->scan_id = __cpu_to_le32(scan_id); -+ cmd->scan_req_id = __cpu_to_le32(req_id); -+ -+- ath10k_dbg(ATH10K_DBG_WMI, -++ ath10k_dbg(ar, ATH10K_DBG_WMI, -+ "wmi stop scan reqid %d req_type %d vdev/scan_id %d\n", -+ arg->req_id, arg->req_type, arg->u.scan_id); -+- return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->stop_scan_cmdid); -++ return skb; -+ } -+ -+-int ath10k_wmi_vdev_create(struct ath10k *ar, u32 vdev_id, -+- enum wmi_vdev_type type, -+- enum wmi_vdev_subtype subtype, -+- const u8 macaddr[ETH_ALEN]) -++static struct sk_buff * -++ath10k_wmi_op_gen_vdev_create(struct ath10k *ar, u32 vdev_id, -++ enum wmi_vdev_type type, -++ enum wmi_vdev_subtype subtype, -++ const u8 macaddr[ETH_ALEN]) -+ { -+ struct wmi_vdev_create_cmd *cmd; -+ struct sk_buff *skb; -+ -+- skb = ath10k_wmi_alloc_skb(sizeof(*cmd)); -++ skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd)); -+ if (!skb) -+- return -ENOMEM; -++ return ERR_PTR(-ENOMEM); -+ -+ cmd = (struct wmi_vdev_create_cmd *)skb->data; -+ cmd->vdev_id = __cpu_to_le32(vdev_id); -+ cmd->vdev_type = __cpu_to_le32(type); -+ cmd->vdev_subtype = __cpu_to_le32(subtype); -+- memcpy(cmd->vdev_macaddr.addr, macaddr, ETH_ALEN); -++ ether_addr_copy(cmd->vdev_macaddr.addr, macaddr); -+ -+- ath10k_dbg(ATH10K_DBG_WMI, -++ ath10k_dbg(ar, ATH10K_DBG_WMI, -+ "WMI vdev create: id %d type %d subtype %d macaddr %pM\n", -+ vdev_id, type, subtype, macaddr); -+- -+- return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->vdev_create_cmdid); -++ return skb; -+ } -+ -+-int ath10k_wmi_vdev_delete(struct ath10k *ar, u32 vdev_id) -++static struct sk_buff * -++ath10k_wmi_op_gen_vdev_delete(struct ath10k *ar, u32 vdev_id) -+ { -+ struct wmi_vdev_delete_cmd *cmd; -+ struct sk_buff *skb; -+ -+- skb = ath10k_wmi_alloc_skb(sizeof(*cmd)); -++ skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd)); -+ if (!skb) -+- return -ENOMEM; -++ return ERR_PTR(-ENOMEM); -+ -+ cmd = (struct wmi_vdev_delete_cmd *)skb->data; -+ cmd->vdev_id = __cpu_to_le32(vdev_id); -+ -+- ath10k_dbg(ATH10K_DBG_WMI, -++ ath10k_dbg(ar, ATH10K_DBG_WMI, -+ "WMI vdev delete id %d\n", vdev_id); -+- -+- return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->vdev_delete_cmdid); -++ return skb; -+ } -+ -+-static int ath10k_wmi_vdev_start_restart(struct ath10k *ar, -+- const struct wmi_vdev_start_request_arg *arg, -+- u32 cmd_id) -++static struct sk_buff * -++ath10k_wmi_op_gen_vdev_start(struct ath10k *ar, -++ const struct wmi_vdev_start_request_arg *arg, -++ bool restart) -+ { -+ struct wmi_vdev_start_request_cmd *cmd; -+ struct sk_buff *skb; -+ const char *cmdname; -+ u32 flags = 0; -+- u32 ch_flags = 0; -+ -+- if (cmd_id != ar->wmi.cmd->vdev_start_request_cmdid && -+- cmd_id != ar->wmi.cmd->vdev_restart_request_cmdid) -+- return -EINVAL; -+ if (WARN_ON(arg->ssid && arg->ssid_len == 0)) -+- return -EINVAL; -++ return ERR_PTR(-EINVAL); -+ if (WARN_ON(arg->hidden_ssid && !arg->ssid)) -+- return -EINVAL; -++ return ERR_PTR(-EINVAL); -+ if (WARN_ON(arg->ssid_len > sizeof(cmd->ssid.ssid))) -+- return -EINVAL; -++ return ERR_PTR(-EINVAL); -+ -+- if (cmd_id == ar->wmi.cmd->vdev_start_request_cmdid) -+- cmdname = "start"; -+- else if (cmd_id == ar->wmi.cmd->vdev_restart_request_cmdid) -++ if (restart) -+ cmdname = "restart"; -+ else -+- return -EINVAL; /* should not happen, we already check cmd_id */ -++ cmdname = "start"; -+ -+- skb = ath10k_wmi_alloc_skb(sizeof(*cmd)); -++ skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd)); -+ if (!skb) -+- return -ENOMEM; -++ return ERR_PTR(-ENOMEM); -+ -+ if (arg->hidden_ssid) -+ flags |= WMI_VDEV_START_HIDDEN_SSID; -+ if (arg->pmf_enabled) -+ flags |= WMI_VDEV_START_PMF_ENABLED; -+- if (arg->channel.chan_radar) -+- ch_flags |= WMI_CHAN_FLAG_DFS; -+ -+ cmd = (struct wmi_vdev_start_request_cmd *)skb->data; -+ cmd->vdev_id = __cpu_to_le32(arg->vdev_id); -+@@ -3067,143 +4350,118 @@ static int ath10k_wmi_vdev_start_restart -+ memcpy(cmd->ssid.ssid, arg->ssid, arg->ssid_len); -+ } -+ -+- cmd->chan.mhz = __cpu_to_le32(arg->channel.freq); -++ ath10k_wmi_put_wmi_channel(&cmd->chan, &arg->channel); -+ -+- cmd->chan.band_center_freq1 = -+- __cpu_to_le32(arg->channel.band_center_freq1); -+- -+- cmd->chan.mode = arg->channel.mode; -+- cmd->chan.flags |= __cpu_to_le32(ch_flags); -+- cmd->chan.min_power = arg->channel.min_power; -+- cmd->chan.max_power = arg->channel.max_power; -+- cmd->chan.reg_power = arg->channel.max_reg_power; -+- cmd->chan.reg_classid = arg->channel.reg_class_id; -+- cmd->chan.antenna_max = arg->channel.max_antenna_gain; -+- -+- ath10k_dbg(ATH10K_DBG_WMI, -+- "wmi vdev %s id 0x%x flags: 0x%0X, freq %d, mode %d, " -+- "ch_flags: 0x%0X, max_power: %d\n", cmdname, arg->vdev_id, -++ ath10k_dbg(ar, ATH10K_DBG_WMI, -++ "wmi vdev %s id 0x%x flags: 0x%0X, freq %d, mode %d, ch_flags: 0x%0X, max_power: %d\n", -++ cmdname, arg->vdev_id, -+ flags, arg->channel.freq, arg->channel.mode, -+ cmd->chan.flags, arg->channel.max_power); -+ -+- return ath10k_wmi_cmd_send(ar, skb, cmd_id); -+-} -+- -+-int ath10k_wmi_vdev_start(struct ath10k *ar, -+- const struct wmi_vdev_start_request_arg *arg) -+-{ -+- u32 cmd_id = ar->wmi.cmd->vdev_start_request_cmdid; -+- -+- return ath10k_wmi_vdev_start_restart(ar, arg, cmd_id); -+-} -+- -+-int ath10k_wmi_vdev_restart(struct ath10k *ar, -+- const struct wmi_vdev_start_request_arg *arg) -+-{ -+- u32 cmd_id = ar->wmi.cmd->vdev_restart_request_cmdid; -+- -+- return ath10k_wmi_vdev_start_restart(ar, arg, cmd_id); -++ return skb; -+ } -+ -+-int ath10k_wmi_vdev_stop(struct ath10k *ar, u32 vdev_id) -++static struct sk_buff * -++ath10k_wmi_op_gen_vdev_stop(struct ath10k *ar, u32 vdev_id) -+ { -+ struct wmi_vdev_stop_cmd *cmd; -+ struct sk_buff *skb; -+ -+- skb = ath10k_wmi_alloc_skb(sizeof(*cmd)); -++ skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd)); -+ if (!skb) -+- return -ENOMEM; -++ return ERR_PTR(-ENOMEM); -+ -+ cmd = (struct wmi_vdev_stop_cmd *)skb->data; -+ cmd->vdev_id = __cpu_to_le32(vdev_id); -+ -+- ath10k_dbg(ATH10K_DBG_WMI, "wmi vdev stop id 0x%x\n", vdev_id); -+- -+- return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->vdev_stop_cmdid); -++ ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi vdev stop id 0x%x\n", vdev_id); -++ return skb; -+ } -+ -+-int ath10k_wmi_vdev_up(struct ath10k *ar, u32 vdev_id, u32 aid, const u8 *bssid) -++static struct sk_buff * -++ath10k_wmi_op_gen_vdev_up(struct ath10k *ar, u32 vdev_id, u32 aid, -++ const u8 *bssid) -+ { -+ struct wmi_vdev_up_cmd *cmd; -+ struct sk_buff *skb; -+ -+- skb = ath10k_wmi_alloc_skb(sizeof(*cmd)); -++ skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd)); -+ if (!skb) -+- return -ENOMEM; -++ return ERR_PTR(-ENOMEM); -+ -+ cmd = (struct wmi_vdev_up_cmd *)skb->data; -+ cmd->vdev_id = __cpu_to_le32(vdev_id); -+ cmd->vdev_assoc_id = __cpu_to_le32(aid); -+- memcpy(&cmd->vdev_bssid.addr, bssid, ETH_ALEN); -++ ether_addr_copy(cmd->vdev_bssid.addr, bssid); -+ -+- ath10k_dbg(ATH10K_DBG_WMI, -++ ath10k_dbg(ar, ATH10K_DBG_WMI, -+ "wmi mgmt vdev up id 0x%x assoc id %d bssid %pM\n", -+ vdev_id, aid, bssid); -+- -+- return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->vdev_up_cmdid); -++ return skb; -+ } -+ -+-int ath10k_wmi_vdev_down(struct ath10k *ar, u32 vdev_id) -++static struct sk_buff * -++ath10k_wmi_op_gen_vdev_down(struct ath10k *ar, u32 vdev_id) -+ { -+ struct wmi_vdev_down_cmd *cmd; -+ struct sk_buff *skb; -+ -+- skb = ath10k_wmi_alloc_skb(sizeof(*cmd)); -++ skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd)); -+ if (!skb) -+- return -ENOMEM; -++ return ERR_PTR(-ENOMEM); -+ -+ cmd = (struct wmi_vdev_down_cmd *)skb->data; -+ cmd->vdev_id = __cpu_to_le32(vdev_id); -+ -+- ath10k_dbg(ATH10K_DBG_WMI, -++ ath10k_dbg(ar, ATH10K_DBG_WMI, -+ "wmi mgmt vdev down id 0x%x\n", vdev_id); -+- -+- return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->vdev_down_cmdid); -++ return skb; -+ } -+ -+-int ath10k_wmi_vdev_set_param(struct ath10k *ar, u32 vdev_id, -+- u32 param_id, u32 param_value) -++static struct sk_buff * -++ath10k_wmi_op_gen_vdev_set_param(struct ath10k *ar, u32 vdev_id, -++ u32 param_id, u32 param_value) -+ { -+ struct wmi_vdev_set_param_cmd *cmd; -+ struct sk_buff *skb; -+ -+ if (param_id == WMI_VDEV_PARAM_UNSUPPORTED) { -+- ath10k_dbg(ATH10K_DBG_WMI, -++ ath10k_dbg(ar, ATH10K_DBG_WMI, -+ "vdev param %d not supported by firmware\n", -+ param_id); -+- return -EOPNOTSUPP; -++ return ERR_PTR(-EOPNOTSUPP); -+ } -+ -+- skb = ath10k_wmi_alloc_skb(sizeof(*cmd)); -++ skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd)); -+ if (!skb) -+- return -ENOMEM; -++ return ERR_PTR(-ENOMEM); -+ -+ cmd = (struct wmi_vdev_set_param_cmd *)skb->data; -+ cmd->vdev_id = __cpu_to_le32(vdev_id); -+ cmd->param_id = __cpu_to_le32(param_id); -+ cmd->param_value = __cpu_to_le32(param_value); -+ -+- ath10k_dbg(ATH10K_DBG_WMI, -++ ath10k_dbg(ar, ATH10K_DBG_WMI, -+ "wmi vdev id 0x%x set param %d value %d\n", -+ vdev_id, param_id, param_value); -+- -+- return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->vdev_set_param_cmdid); -++ return skb; -+ } -+ -+-int ath10k_wmi_vdev_install_key(struct ath10k *ar, -+- const struct wmi_vdev_install_key_arg *arg) -++static struct sk_buff * -++ath10k_wmi_op_gen_vdev_install_key(struct ath10k *ar, -++ const struct wmi_vdev_install_key_arg *arg) -+ { -+ struct wmi_vdev_install_key_cmd *cmd; -+ struct sk_buff *skb; -+ -+ if (arg->key_cipher == WMI_CIPHER_NONE && arg->key_data != NULL) -+- return -EINVAL; -++ return ERR_PTR(-EINVAL); -+ if (arg->key_cipher != WMI_CIPHER_NONE && arg->key_data == NULL) -+- return -EINVAL; -++ return ERR_PTR(-EINVAL); -+ -+- skb = ath10k_wmi_alloc_skb(sizeof(*cmd) + arg->key_len); -++ skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd) + arg->key_len); -+ if (!skb) -+- return -ENOMEM; -++ return ERR_PTR(-ENOMEM); -+ -+ cmd = (struct wmi_vdev_install_key_cmd *)skb->data; -+ cmd->vdev_id = __cpu_to_le32(arg->vdev_id); -+@@ -3215,176 +4473,232 @@ int ath10k_wmi_vdev_install_key(struct a -+ cmd->key_rxmic_len = __cpu_to_le32(arg->key_rxmic_len); -+ -+ if (arg->macaddr) -+- memcpy(cmd->peer_macaddr.addr, arg->macaddr, ETH_ALEN); -++ ether_addr_copy(cmd->peer_macaddr.addr, arg->macaddr); -+ if (arg->key_data) -+ memcpy(cmd->key_data, arg->key_data, arg->key_len); -+ -+- ath10k_dbg(ATH10K_DBG_WMI, -++ ath10k_dbg(ar, ATH10K_DBG_WMI, -+ "wmi vdev install key idx %d cipher %d len %d\n", -+ arg->key_idx, arg->key_cipher, arg->key_len); -+- return ath10k_wmi_cmd_send(ar, skb, -+- ar->wmi.cmd->vdev_install_key_cmdid); -++ return skb; -+ } -+ -+-int ath10k_wmi_peer_create(struct ath10k *ar, u32 vdev_id, -+- const u8 peer_addr[ETH_ALEN]) -++static struct sk_buff * -++ath10k_wmi_op_gen_vdev_spectral_conf(struct ath10k *ar, -++ const struct wmi_vdev_spectral_conf_arg *arg) -++{ -++ struct wmi_vdev_spectral_conf_cmd *cmd; -++ struct sk_buff *skb; -++ -++ skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd)); -++ if (!skb) -++ return ERR_PTR(-ENOMEM); -++ -++ cmd = (struct wmi_vdev_spectral_conf_cmd *)skb->data; -++ cmd->vdev_id = __cpu_to_le32(arg->vdev_id); -++ cmd->scan_count = __cpu_to_le32(arg->scan_count); -++ cmd->scan_period = __cpu_to_le32(arg->scan_period); -++ cmd->scan_priority = __cpu_to_le32(arg->scan_priority); -++ cmd->scan_fft_size = __cpu_to_le32(arg->scan_fft_size); -++ cmd->scan_gc_ena = __cpu_to_le32(arg->scan_gc_ena); -++ cmd->scan_restart_ena = __cpu_to_le32(arg->scan_restart_ena); -++ cmd->scan_noise_floor_ref = __cpu_to_le32(arg->scan_noise_floor_ref); -++ cmd->scan_init_delay = __cpu_to_le32(arg->scan_init_delay); -++ cmd->scan_nb_tone_thr = __cpu_to_le32(arg->scan_nb_tone_thr); -++ cmd->scan_str_bin_thr = __cpu_to_le32(arg->scan_str_bin_thr); -++ cmd->scan_wb_rpt_mode = __cpu_to_le32(arg->scan_wb_rpt_mode); -++ cmd->scan_rssi_rpt_mode = __cpu_to_le32(arg->scan_rssi_rpt_mode); -++ cmd->scan_rssi_thr = __cpu_to_le32(arg->scan_rssi_thr); -++ cmd->scan_pwr_format = __cpu_to_le32(arg->scan_pwr_format); -++ cmd->scan_rpt_mode = __cpu_to_le32(arg->scan_rpt_mode); -++ cmd->scan_bin_scale = __cpu_to_le32(arg->scan_bin_scale); -++ cmd->scan_dbm_adj = __cpu_to_le32(arg->scan_dbm_adj); -++ cmd->scan_chn_mask = __cpu_to_le32(arg->scan_chn_mask); -++ -++ return skb; -++} -++ -++static struct sk_buff * -++ath10k_wmi_op_gen_vdev_spectral_enable(struct ath10k *ar, u32 vdev_id, -++ u32 trigger, u32 enable) -++{ -++ struct wmi_vdev_spectral_enable_cmd *cmd; -++ struct sk_buff *skb; -++ -++ skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd)); -++ if (!skb) -++ return ERR_PTR(-ENOMEM); -++ -++ cmd = (struct wmi_vdev_spectral_enable_cmd *)skb->data; -++ cmd->vdev_id = __cpu_to_le32(vdev_id); -++ cmd->trigger_cmd = __cpu_to_le32(trigger); -++ cmd->enable_cmd = __cpu_to_le32(enable); -++ -++ return skb; -++} -++ -++static struct sk_buff * -++ath10k_wmi_op_gen_peer_create(struct ath10k *ar, u32 vdev_id, -++ const u8 peer_addr[ETH_ALEN]) -+ { -+ struct wmi_peer_create_cmd *cmd; -+ struct sk_buff *skb; -+ -+- skb = ath10k_wmi_alloc_skb(sizeof(*cmd)); -++ skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd)); -+ if (!skb) -+- return -ENOMEM; -++ return ERR_PTR(-ENOMEM); -+ -+ cmd = (struct wmi_peer_create_cmd *)skb->data; -+ cmd->vdev_id = __cpu_to_le32(vdev_id); -+- memcpy(cmd->peer_macaddr.addr, peer_addr, ETH_ALEN); -++ ether_addr_copy(cmd->peer_macaddr.addr, peer_addr); -+ -+- ath10k_dbg(ATH10K_DBG_WMI, -++ ath10k_dbg(ar, ATH10K_DBG_WMI, -+ "wmi peer create vdev_id %d peer_addr %pM\n", -+ vdev_id, peer_addr); -+- return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->peer_create_cmdid); -++ return skb; -+ } -+ -+-int ath10k_wmi_peer_delete(struct ath10k *ar, u32 vdev_id, -+- const u8 peer_addr[ETH_ALEN]) -++static struct sk_buff * -++ath10k_wmi_op_gen_peer_delete(struct ath10k *ar, u32 vdev_id, -++ const u8 peer_addr[ETH_ALEN]) -+ { -+ struct wmi_peer_delete_cmd *cmd; -+ struct sk_buff *skb; -+ -+- skb = ath10k_wmi_alloc_skb(sizeof(*cmd)); -++ skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd)); -+ if (!skb) -+- return -ENOMEM; -++ return ERR_PTR(-ENOMEM); -+ -+ cmd = (struct wmi_peer_delete_cmd *)skb->data; -+ cmd->vdev_id = __cpu_to_le32(vdev_id); -+- memcpy(cmd->peer_macaddr.addr, peer_addr, ETH_ALEN); -++ ether_addr_copy(cmd->peer_macaddr.addr, peer_addr); -+ -+- ath10k_dbg(ATH10K_DBG_WMI, -++ ath10k_dbg(ar, ATH10K_DBG_WMI, -+ "wmi peer delete vdev_id %d peer_addr %pM\n", -+ vdev_id, peer_addr); -+- return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->peer_delete_cmdid); -++ return skb; -+ } -+ -+-int ath10k_wmi_peer_flush(struct ath10k *ar, u32 vdev_id, -+- const u8 peer_addr[ETH_ALEN], u32 tid_bitmap) -++static struct sk_buff * -++ath10k_wmi_op_gen_peer_flush(struct ath10k *ar, u32 vdev_id, -++ const u8 peer_addr[ETH_ALEN], u32 tid_bitmap) -+ { -+ struct wmi_peer_flush_tids_cmd *cmd; -+ struct sk_buff *skb; -+ -+- skb = ath10k_wmi_alloc_skb(sizeof(*cmd)); -++ skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd)); -+ if (!skb) -+- return -ENOMEM; -++ return ERR_PTR(-ENOMEM); -+ -+ cmd = (struct wmi_peer_flush_tids_cmd *)skb->data; -+ cmd->vdev_id = __cpu_to_le32(vdev_id); -+ cmd->peer_tid_bitmap = __cpu_to_le32(tid_bitmap); -+- memcpy(cmd->peer_macaddr.addr, peer_addr, ETH_ALEN); -++ ether_addr_copy(cmd->peer_macaddr.addr, peer_addr); -+ -+- ath10k_dbg(ATH10K_DBG_WMI, -++ ath10k_dbg(ar, ATH10K_DBG_WMI, -+ "wmi peer flush vdev_id %d peer_addr %pM tids %08x\n", -+ vdev_id, peer_addr, tid_bitmap); -+- return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->peer_flush_tids_cmdid); -++ return skb; -+ } -+ -+-int ath10k_wmi_peer_set_param(struct ath10k *ar, u32 vdev_id, -+- const u8 *peer_addr, enum wmi_peer_param param_id, -+- u32 param_value) -++static struct sk_buff * -++ath10k_wmi_op_gen_peer_set_param(struct ath10k *ar, u32 vdev_id, -++ const u8 *peer_addr, -++ enum wmi_peer_param param_id, -++ u32 param_value) -+ { -+ struct wmi_peer_set_param_cmd *cmd; -+ struct sk_buff *skb; -+ -+- skb = ath10k_wmi_alloc_skb(sizeof(*cmd)); -++ skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd)); -+ if (!skb) -+- return -ENOMEM; -++ return ERR_PTR(-ENOMEM); -+ -+ cmd = (struct wmi_peer_set_param_cmd *)skb->data; -+ cmd->vdev_id = __cpu_to_le32(vdev_id); -+ cmd->param_id = __cpu_to_le32(param_id); -+ cmd->param_value = __cpu_to_le32(param_value); -+- memcpy(&cmd->peer_macaddr.addr, peer_addr, ETH_ALEN); -++ ether_addr_copy(cmd->peer_macaddr.addr, peer_addr); -+ -+- ath10k_dbg(ATH10K_DBG_WMI, -++ ath10k_dbg(ar, ATH10K_DBG_WMI, -+ "wmi vdev %d peer 0x%pM set param %d value %d\n", -+ vdev_id, peer_addr, param_id, param_value); -+- -+- return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->peer_set_param_cmdid); -++ return skb; -+ } -+ -+-int ath10k_wmi_set_psmode(struct ath10k *ar, u32 vdev_id, -+- enum wmi_sta_ps_mode psmode) -++static struct sk_buff * -++ath10k_wmi_op_gen_set_psmode(struct ath10k *ar, u32 vdev_id, -++ enum wmi_sta_ps_mode psmode) -+ { -+ struct wmi_sta_powersave_mode_cmd *cmd; -+ struct sk_buff *skb; -+ -+- skb = ath10k_wmi_alloc_skb(sizeof(*cmd)); -++ skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd)); -+ if (!skb) -+- return -ENOMEM; -++ return ERR_PTR(-ENOMEM); -+ -+ cmd = (struct wmi_sta_powersave_mode_cmd *)skb->data; -+ cmd->vdev_id = __cpu_to_le32(vdev_id); -+ cmd->sta_ps_mode = __cpu_to_le32(psmode); -+ -+- ath10k_dbg(ATH10K_DBG_WMI, -++ ath10k_dbg(ar, ATH10K_DBG_WMI, -+ "wmi set powersave id 0x%x mode %d\n", -+ vdev_id, psmode); -+- -+- return ath10k_wmi_cmd_send(ar, skb, -+- ar->wmi.cmd->sta_powersave_mode_cmdid); -++ return skb; -+ } -+ -+-int ath10k_wmi_set_sta_ps_param(struct ath10k *ar, u32 vdev_id, -+- enum wmi_sta_powersave_param param_id, -+- u32 value) -++static struct sk_buff * -++ath10k_wmi_op_gen_set_sta_ps(struct ath10k *ar, u32 vdev_id, -++ enum wmi_sta_powersave_param param_id, -++ u32 value) -+ { -+ struct wmi_sta_powersave_param_cmd *cmd; -+ struct sk_buff *skb; -+ -+- skb = ath10k_wmi_alloc_skb(sizeof(*cmd)); -++ skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd)); -+ if (!skb) -+- return -ENOMEM; -++ return ERR_PTR(-ENOMEM); -+ -+ cmd = (struct wmi_sta_powersave_param_cmd *)skb->data; -+ cmd->vdev_id = __cpu_to_le32(vdev_id); -+ cmd->param_id = __cpu_to_le32(param_id); -+ cmd->param_value = __cpu_to_le32(value); -+ -+- ath10k_dbg(ATH10K_DBG_WMI, -++ ath10k_dbg(ar, ATH10K_DBG_WMI, -+ "wmi sta ps param vdev_id 0x%x param %d value %d\n", -+ vdev_id, param_id, value); -+- return ath10k_wmi_cmd_send(ar, skb, -+- ar->wmi.cmd->sta_powersave_param_cmdid); -++ return skb; -+ } -+ -+-int ath10k_wmi_set_ap_ps_param(struct ath10k *ar, u32 vdev_id, const u8 *mac, -+- enum wmi_ap_ps_peer_param param_id, u32 value) -++static struct sk_buff * -++ath10k_wmi_op_gen_set_ap_ps(struct ath10k *ar, u32 vdev_id, const u8 *mac, -++ enum wmi_ap_ps_peer_param param_id, u32 value) -+ { -+ struct wmi_ap_ps_peer_cmd *cmd; -+ struct sk_buff *skb; -+ -+ if (!mac) -+- return -EINVAL; -++ return ERR_PTR(-EINVAL); -+ -+- skb = ath10k_wmi_alloc_skb(sizeof(*cmd)); -++ skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd)); -+ if (!skb) -+- return -ENOMEM; -++ return ERR_PTR(-ENOMEM); -+ -+ cmd = (struct wmi_ap_ps_peer_cmd *)skb->data; -+ cmd->vdev_id = __cpu_to_le32(vdev_id); -+ cmd->param_id = __cpu_to_le32(param_id); -+ cmd->param_value = __cpu_to_le32(value); -+- memcpy(&cmd->peer_macaddr, mac, ETH_ALEN); -++ ether_addr_copy(cmd->peer_macaddr.addr, mac); -+ -+- ath10k_dbg(ATH10K_DBG_WMI, -++ ath10k_dbg(ar, ATH10K_DBG_WMI, -+ "wmi ap ps param vdev_id 0x%X param %d value %d mac_addr %pM\n", -+ vdev_id, param_id, value, mac); -+- -+- return ath10k_wmi_cmd_send(ar, skb, -+- ar->wmi.cmd->ap_ps_peer_param_cmdid); -++ return skb; -+ } -+ -+-int ath10k_wmi_scan_chan_list(struct ath10k *ar, -+- const struct wmi_scan_chan_list_arg *arg) -++static struct sk_buff * -++ath10k_wmi_op_gen_scan_chan_list(struct ath10k *ar, -++ const struct wmi_scan_chan_list_arg *arg) -+ { -+ struct wmi_scan_chan_list_cmd *cmd; -+ struct sk_buff *skb; -+@@ -3395,66 +4709,29 @@ int ath10k_wmi_scan_chan_list(struct ath -+ -+ len = sizeof(*cmd) + arg->n_channels * sizeof(struct wmi_channel); -+ -+- skb = ath10k_wmi_alloc_skb(len); -++ skb = ath10k_wmi_alloc_skb(ar, len); -+ if (!skb) -+- return -EINVAL; -++ return ERR_PTR(-EINVAL); -+ -+ cmd = (struct wmi_scan_chan_list_cmd *)skb->data; -+ cmd->num_scan_chans = __cpu_to_le32(arg->n_channels); -+ -+ for (i = 0; i < arg->n_channels; i++) { -+- u32 flags = 0; -+- -+ ch = &arg->channels[i]; -+ ci = &cmd->chan_info[i]; -+ -+- if (ch->passive) -+- flags |= WMI_CHAN_FLAG_PASSIVE; -+- if (ch->allow_ibss) -+- flags |= WMI_CHAN_FLAG_ADHOC_ALLOWED; -+- if (ch->allow_ht) -+- flags |= WMI_CHAN_FLAG_ALLOW_HT; -+- if (ch->allow_vht) -+- flags |= WMI_CHAN_FLAG_ALLOW_VHT; -+- if (ch->ht40plus) -+- flags |= WMI_CHAN_FLAG_HT40_PLUS; -+- if (ch->chan_radar) -+- flags |= WMI_CHAN_FLAG_DFS; -+- -+- ci->mhz = __cpu_to_le32(ch->freq); -+- ci->band_center_freq1 = __cpu_to_le32(ch->freq); -+- ci->band_center_freq2 = 0; -+- ci->min_power = ch->min_power; -+- ci->max_power = ch->max_power; -+- ci->reg_power = ch->max_reg_power; -+- ci->antenna_max = ch->max_antenna_gain; -+- -+- /* mode & flags share storage */ -+- ci->mode = ch->mode; -+- ci->flags |= __cpu_to_le32(flags); -++ ath10k_wmi_put_wmi_channel(ci, ch); -+ } -+ -+- return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->scan_chan_list_cmdid); -++ return skb; -+ } -+ -+-int ath10k_wmi_peer_assoc(struct ath10k *ar, -+- const struct wmi_peer_assoc_complete_arg *arg) -++static void -++ath10k_wmi_peer_assoc_fill(struct ath10k *ar, void *buf, -++ const struct wmi_peer_assoc_complete_arg *arg) -+ { -+- struct wmi_peer_assoc_complete_cmd *cmd; -+- struct sk_buff *skb; -++ struct wmi_common_peer_assoc_complete_cmd *cmd = buf; -+ -+- if (arg->peer_mpdu_density > 16) -+- return -EINVAL; -+- if (arg->peer_legacy_rates.num_rates > MAX_SUPPORTED_RATES) -+- return -EINVAL; -+- if (arg->peer_ht_rates.num_rates > MAX_SUPPORTED_RATES) -+- return -EINVAL; -+- -+- skb = ath10k_wmi_alloc_skb(sizeof(*cmd)); -+- if (!skb) -+- return -ENOMEM; -+- -+- cmd = (struct wmi_peer_assoc_complete_cmd *)skb->data; -+ cmd->vdev_id = __cpu_to_le32(arg->vdev_id); -+ cmd->peer_new_assoc = __cpu_to_le32(arg->peer_reassoc ? 0 : 1); -+ cmd->peer_associd = __cpu_to_le32(arg->peer_aid); -+@@ -3469,7 +4746,7 @@ int ath10k_wmi_peer_assoc(struct ath10k -+ cmd->peer_vht_caps = __cpu_to_le32(arg->peer_vht_caps); -+ cmd->peer_phymode = __cpu_to_le32(arg->peer_phymode); -+ -+- memcpy(cmd->peer_macaddr.addr, arg->addr, ETH_ALEN); -++ ether_addr_copy(cmd->peer_macaddr.addr, arg->addr); -+ -+ cmd->peer_legacy_rates.num_rates = -+ __cpu_to_le32(arg->peer_legacy_rates.num_rates); -+@@ -3489,57 +4766,183 @@ int ath10k_wmi_peer_assoc(struct ath10k -+ __cpu_to_le32(arg->peer_vht_rates.tx_max_rate); -+ cmd->peer_vht_rates.tx_mcs_set = -+ __cpu_to_le32(arg->peer_vht_rates.tx_mcs_set); -++} -++ -++static void -++ath10k_wmi_peer_assoc_fill_main(struct ath10k *ar, void *buf, -++ const struct wmi_peer_assoc_complete_arg *arg) -++{ -++ struct wmi_main_peer_assoc_complete_cmd *cmd = buf; -+ -+- ath10k_dbg(ATH10K_DBG_WMI, -++ ath10k_wmi_peer_assoc_fill(ar, buf, arg); -++ memset(cmd->peer_ht_info, 0, sizeof(cmd->peer_ht_info)); -++} -++ -++static void -++ath10k_wmi_peer_assoc_fill_10_1(struct ath10k *ar, void *buf, -++ const struct wmi_peer_assoc_complete_arg *arg) -++{ -++ ath10k_wmi_peer_assoc_fill(ar, buf, arg); -++} -++ -++static void -++ath10k_wmi_peer_assoc_fill_10_2(struct ath10k *ar, void *buf, -++ const struct wmi_peer_assoc_complete_arg *arg) -++{ -++ struct wmi_10_2_peer_assoc_complete_cmd *cmd = buf; -++ int max_mcs, max_nss; -++ u32 info0; -++ -++ /* TODO: Is using max values okay with firmware? */ -++ max_mcs = 0xf; -++ max_nss = 0xf; -++ -++ info0 = SM(max_mcs, WMI_PEER_ASSOC_INFO0_MAX_MCS_IDX) | -++ SM(max_nss, WMI_PEER_ASSOC_INFO0_MAX_NSS); -++ -++ ath10k_wmi_peer_assoc_fill(ar, buf, arg); -++ cmd->info0 = __cpu_to_le32(info0); -++} -++ -++static int -++ath10k_wmi_peer_assoc_check_arg(const struct wmi_peer_assoc_complete_arg *arg) -++{ -++ if (arg->peer_mpdu_density > 16) -++ return -EINVAL; -++ if (arg->peer_legacy_rates.num_rates > MAX_SUPPORTED_RATES) -++ return -EINVAL; -++ if (arg->peer_ht_rates.num_rates > MAX_SUPPORTED_RATES) -++ return -EINVAL; -++ -++ return 0; -++} -++ -++static struct sk_buff * -++ath10k_wmi_op_gen_peer_assoc(struct ath10k *ar, -++ const struct wmi_peer_assoc_complete_arg *arg) -++{ -++ size_t len = sizeof(struct wmi_main_peer_assoc_complete_cmd); -++ struct sk_buff *skb; -++ int ret; -++ -++ ret = ath10k_wmi_peer_assoc_check_arg(arg); -++ if (ret) -++ return ERR_PTR(ret); -++ -++ skb = ath10k_wmi_alloc_skb(ar, len); -++ if (!skb) -++ return ERR_PTR(-ENOMEM); -++ -++ ath10k_wmi_peer_assoc_fill_main(ar, skb->data, arg); -++ -++ ath10k_dbg(ar, ATH10K_DBG_WMI, -++ "wmi peer assoc vdev %d addr %pM (%s)\n", -++ arg->vdev_id, arg->addr, -++ arg->peer_reassoc ? "reassociate" : "new"); -++ return skb; -++} -++ -++static struct sk_buff * -++ath10k_wmi_10_1_op_gen_peer_assoc(struct ath10k *ar, -++ const struct wmi_peer_assoc_complete_arg *arg) -++{ -++ size_t len = sizeof(struct wmi_10_1_peer_assoc_complete_cmd); -++ struct sk_buff *skb; -++ int ret; -++ -++ ret = ath10k_wmi_peer_assoc_check_arg(arg); -++ if (ret) -++ return ERR_PTR(ret); -++ -++ skb = ath10k_wmi_alloc_skb(ar, len); -++ if (!skb) -++ return ERR_PTR(-ENOMEM); -++ -++ ath10k_wmi_peer_assoc_fill_10_1(ar, skb->data, arg); -++ -++ ath10k_dbg(ar, ATH10K_DBG_WMI, -++ "wmi peer assoc vdev %d addr %pM (%s)\n", -++ arg->vdev_id, arg->addr, -++ arg->peer_reassoc ? "reassociate" : "new"); -++ return skb; -++} -++ -++static struct sk_buff * -++ath10k_wmi_10_2_op_gen_peer_assoc(struct ath10k *ar, -++ const struct wmi_peer_assoc_complete_arg *arg) -++{ -++ size_t len = sizeof(struct wmi_10_2_peer_assoc_complete_cmd); -++ struct sk_buff *skb; -++ int ret; -++ -++ ret = ath10k_wmi_peer_assoc_check_arg(arg); -++ if (ret) -++ return ERR_PTR(ret); -++ -++ skb = ath10k_wmi_alloc_skb(ar, len); -++ if (!skb) -++ return ERR_PTR(-ENOMEM); -++ -++ ath10k_wmi_peer_assoc_fill_10_2(ar, skb->data, arg); -++ -++ ath10k_dbg(ar, ATH10K_DBG_WMI, -+ "wmi peer assoc vdev %d addr %pM (%s)\n", -+ arg->vdev_id, arg->addr, -+ arg->peer_reassoc ? "reassociate" : "new"); -+- return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->peer_assoc_cmdid); -++ return skb; -++} -++ -++static struct sk_buff * -++ath10k_wmi_10_2_op_gen_pdev_get_temperature(struct ath10k *ar) -++{ -++ struct sk_buff *skb; -++ -++ skb = ath10k_wmi_alloc_skb(ar, 0); -++ if (!skb) -++ return ERR_PTR(-ENOMEM); -++ -++ ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi pdev get temperature\n"); -++ return skb; -+ } -+ -+ /* This function assumes the beacon is already DMA mapped */ -+-int ath10k_wmi_beacon_send_ref_nowait(struct ath10k_vif *arvif) -++static struct sk_buff * -++ath10k_wmi_op_gen_beacon_dma(struct ath10k *ar, u32 vdev_id, const void *bcn, -++ size_t bcn_len, u32 bcn_paddr, bool dtim_zero, -++ bool deliver_cab) -+ { -+ struct wmi_bcn_tx_ref_cmd *cmd; -+ struct sk_buff *skb; -+- struct sk_buff *beacon = arvif->beacon; -+- struct ath10k *ar = arvif->ar; -+ struct ieee80211_hdr *hdr; -+- int ret; -+ u16 fc; -+ -+- skb = ath10k_wmi_alloc_skb(sizeof(*cmd)); -++ skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd)); -+ if (!skb) -+- return -ENOMEM; -++ return ERR_PTR(-ENOMEM); -+ -+- hdr = (struct ieee80211_hdr *)beacon->data; -++ hdr = (struct ieee80211_hdr *)bcn; -+ fc = le16_to_cpu(hdr->frame_control); -+ -+ cmd = (struct wmi_bcn_tx_ref_cmd *)skb->data; -+- cmd->vdev_id = __cpu_to_le32(arvif->vdev_id); -+- cmd->data_len = __cpu_to_le32(beacon->len); -+- cmd->data_ptr = __cpu_to_le32(ATH10K_SKB_CB(beacon)->paddr); -++ cmd->vdev_id = __cpu_to_le32(vdev_id); -++ cmd->data_len = __cpu_to_le32(bcn_len); -++ cmd->data_ptr = __cpu_to_le32(bcn_paddr); -+ cmd->msdu_id = 0; -+ cmd->frame_control = __cpu_to_le32(fc); -+ cmd->flags = 0; -++ cmd->antenna_mask = __cpu_to_le32(WMI_BCN_TX_REF_DEF_ANTENNA); -+ -+- if (ATH10K_SKB_CB(beacon)->bcn.dtim_zero) -++ if (dtim_zero) -+ cmd->flags |= __cpu_to_le32(WMI_BCN_TX_REF_FLAG_DTIM_ZERO); -+ -+- if (ATH10K_SKB_CB(beacon)->bcn.deliver_cab) -++ if (deliver_cab) -+ cmd->flags |= __cpu_to_le32(WMI_BCN_TX_REF_FLAG_DELIVER_CAB); -+ -+- ret = ath10k_wmi_cmd_send_nowait(ar, skb, -+- ar->wmi.cmd->pdev_send_bcn_cmdid); -+- -+- if (ret) -+- dev_kfree_skb(skb); -+- -+- return ret; -++ return skb; -+ } -+ -+-static void ath10k_wmi_pdev_set_wmm_param(struct wmi_wmm_params *params, -+- const struct wmi_wmm_params_arg *arg) -++void ath10k_wmi_set_wmm_param(struct wmi_wmm_params *params, -++ const struct wmi_wmm_params_arg *arg) -+ { -+ params->cwmin = __cpu_to_le32(arg->cwmin); -+ params->cwmax = __cpu_to_le32(arg->cwmax); -+@@ -3549,76 +4952,81 @@ static void ath10k_wmi_pdev_set_wmm_para -+ params->no_ack = __cpu_to_le32(arg->no_ack); -+ } -+ -+-int ath10k_wmi_pdev_set_wmm_params(struct ath10k *ar, -+- const struct wmi_pdev_set_wmm_params_arg *arg) -++static struct sk_buff * -++ath10k_wmi_op_gen_pdev_set_wmm(struct ath10k *ar, -++ const struct wmi_wmm_params_all_arg *arg) -+ { -+ struct wmi_pdev_set_wmm_params *cmd; -+ struct sk_buff *skb; -+ -+- skb = ath10k_wmi_alloc_skb(sizeof(*cmd)); -++ skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd)); -+ if (!skb) -+- return -ENOMEM; -++ return ERR_PTR(-ENOMEM); -+ -+ cmd = (struct wmi_pdev_set_wmm_params *)skb->data; -+- ath10k_wmi_pdev_set_wmm_param(&cmd->ac_be, &arg->ac_be); -+- ath10k_wmi_pdev_set_wmm_param(&cmd->ac_bk, &arg->ac_bk); -+- ath10k_wmi_pdev_set_wmm_param(&cmd->ac_vi, &arg->ac_vi); -+- ath10k_wmi_pdev_set_wmm_param(&cmd->ac_vo, &arg->ac_vo); -++ ath10k_wmi_set_wmm_param(&cmd->ac_be, &arg->ac_be); -++ ath10k_wmi_set_wmm_param(&cmd->ac_bk, &arg->ac_bk); -++ ath10k_wmi_set_wmm_param(&cmd->ac_vi, &arg->ac_vi); -++ ath10k_wmi_set_wmm_param(&cmd->ac_vo, &arg->ac_vo); -+ -+- ath10k_dbg(ATH10K_DBG_WMI, "wmi pdev set wmm params\n"); -+- return ath10k_wmi_cmd_send(ar, skb, -+- ar->wmi.cmd->pdev_set_wmm_params_cmdid); -++ ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi pdev set wmm params\n"); -++ return skb; -+ } -+ -+-int ath10k_wmi_request_stats(struct ath10k *ar, enum wmi_stats_id stats_id) -++static struct sk_buff * -++ath10k_wmi_op_gen_request_stats(struct ath10k *ar, u32 stats_mask) -+ { -+ struct wmi_request_stats_cmd *cmd; -+ struct sk_buff *skb; -+ -+- skb = ath10k_wmi_alloc_skb(sizeof(*cmd)); -++ skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd)); -+ if (!skb) -+- return -ENOMEM; -++ return ERR_PTR(-ENOMEM); -+ -+ cmd = (struct wmi_request_stats_cmd *)skb->data; -+- cmd->stats_id = __cpu_to_le32(stats_id); -++ cmd->stats_id = __cpu_to_le32(stats_mask); -+ -+- ath10k_dbg(ATH10K_DBG_WMI, "wmi request stats %d\n", (int)stats_id); -+- return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->request_stats_cmdid); -++ ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi request stats 0x%08x\n", -++ stats_mask); -++ return skb; -+ } -+ -+-int ath10k_wmi_force_fw_hang(struct ath10k *ar, -+- enum wmi_force_fw_hang_type type, u32 delay_ms) -++static struct sk_buff * -++ath10k_wmi_op_gen_force_fw_hang(struct ath10k *ar, -++ enum wmi_force_fw_hang_type type, u32 delay_ms) -+ { -+ struct wmi_force_fw_hang_cmd *cmd; -+ struct sk_buff *skb; -+ -+- skb = ath10k_wmi_alloc_skb(sizeof(*cmd)); -++ skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd)); -+ if (!skb) -+- return -ENOMEM; -++ return ERR_PTR(-ENOMEM); -+ -+ cmd = (struct wmi_force_fw_hang_cmd *)skb->data; -+ cmd->type = __cpu_to_le32(type); -+ cmd->delay_ms = __cpu_to_le32(delay_ms); -+ -+- ath10k_dbg(ATH10K_DBG_WMI, "wmi force fw hang %d delay %d\n", -++ ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi force fw hang %d delay %d\n", -+ type, delay_ms); -+- return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->force_fw_hang_cmdid); -++ return skb; -+ } -+ -+-int ath10k_wmi_dbglog_cfg(struct ath10k *ar, u32 module_enable) -++static struct sk_buff * -++ath10k_wmi_op_gen_dbglog_cfg(struct ath10k *ar, u32 module_enable, -++ u32 log_level) -+ { -+ struct wmi_dbglog_cfg_cmd *cmd; -+ struct sk_buff *skb; -+ u32 cfg; -+ -+- skb = ath10k_wmi_alloc_skb(sizeof(*cmd)); -++ skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd)); -+ if (!skb) -+- return -ENOMEM; -++ return ERR_PTR(-ENOMEM); -+ -+ cmd = (struct wmi_dbglog_cfg_cmd *)skb->data; -+ -+ if (module_enable) { -+- cfg = SM(ATH10K_DBGLOG_LEVEL_VERBOSE, -++ cfg = SM(log_level, -+ ATH10K_DBGLOG_CFG_LOG_LVL); -+ } else { -+ /* set back defaults, all modules with WARN level */ -+@@ -3632,12 +5040,474 @@ int ath10k_wmi_dbglog_cfg(struct ath10k -+ cmd->config_enable = __cpu_to_le32(cfg); -+ cmd->config_valid = __cpu_to_le32(ATH10K_DBGLOG_CFG_LOG_LVL_MASK); -+ -+- ath10k_dbg(ATH10K_DBG_WMI, -++ ath10k_dbg(ar, ATH10K_DBG_WMI, -+ "wmi dbglog cfg modules %08x %08x config %08x %08x\n", -+ __le32_to_cpu(cmd->module_enable), -+ __le32_to_cpu(cmd->module_valid), -+ __le32_to_cpu(cmd->config_enable), -+ __le32_to_cpu(cmd->config_valid)); -++ return skb; -++} -++ -++static struct sk_buff * -++ath10k_wmi_op_gen_pktlog_enable(struct ath10k *ar, u32 ev_bitmap) -++{ -++ struct wmi_pdev_pktlog_enable_cmd *cmd; -++ struct sk_buff *skb; -++ -++ skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd)); -++ if (!skb) -++ return ERR_PTR(-ENOMEM); -++ -++ ev_bitmap &= ATH10K_PKTLOG_ANY; -++ -++ cmd = (struct wmi_pdev_pktlog_enable_cmd *)skb->data; -++ cmd->ev_bitmap = __cpu_to_le32(ev_bitmap); -++ -++ ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi enable pktlog filter 0x%08x\n", -++ ev_bitmap); -++ return skb; -++} -++ -++static struct sk_buff * -++ath10k_wmi_op_gen_pktlog_disable(struct ath10k *ar) -++{ -++ struct sk_buff *skb; -+ -+- return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->dbglog_cfg_cmdid); -++ skb = ath10k_wmi_alloc_skb(ar, 0); -++ if (!skb) -++ return ERR_PTR(-ENOMEM); -++ -++ ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi disable pktlog\n"); -++ return skb; -++} -++ -++static struct sk_buff * -++ath10k_wmi_op_gen_pdev_set_quiet_mode(struct ath10k *ar, u32 period, -++ u32 duration, u32 next_offset, -++ u32 enabled) -++{ -++ struct wmi_pdev_set_quiet_cmd *cmd; -++ struct sk_buff *skb; -++ -++ skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd)); -++ if (!skb) -++ return ERR_PTR(-ENOMEM); -++ -++ cmd = (struct wmi_pdev_set_quiet_cmd *)skb->data; -++ cmd->period = __cpu_to_le32(period); -++ cmd->duration = __cpu_to_le32(duration); -++ cmd->next_start = __cpu_to_le32(next_offset); -++ cmd->enabled = __cpu_to_le32(enabled); -++ -++ ath10k_dbg(ar, ATH10K_DBG_WMI, -++ "wmi quiet param: period %u duration %u enabled %d\n", -++ period, duration, enabled); -++ return skb; -++} -++ -++static struct sk_buff * -++ath10k_wmi_op_gen_addba_clear_resp(struct ath10k *ar, u32 vdev_id, -++ const u8 *mac) -++{ -++ struct wmi_addba_clear_resp_cmd *cmd; -++ struct sk_buff *skb; -++ -++ if (!mac) -++ return ERR_PTR(-EINVAL); -++ -++ skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd)); -++ if (!skb) -++ return ERR_PTR(-ENOMEM); -++ -++ cmd = (struct wmi_addba_clear_resp_cmd *)skb->data; -++ cmd->vdev_id = __cpu_to_le32(vdev_id); -++ ether_addr_copy(cmd->peer_macaddr.addr, mac); -++ -++ ath10k_dbg(ar, ATH10K_DBG_WMI, -++ "wmi addba clear resp vdev_id 0x%X mac_addr %pM\n", -++ vdev_id, mac); -++ return skb; -++} -++ -++static struct sk_buff * -++ath10k_wmi_op_gen_addba_send(struct ath10k *ar, u32 vdev_id, const u8 *mac, -++ u32 tid, u32 buf_size) -++{ -++ struct wmi_addba_send_cmd *cmd; -++ struct sk_buff *skb; -++ -++ if (!mac) -++ return ERR_PTR(-EINVAL); -++ -++ skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd)); -++ if (!skb) -++ return ERR_PTR(-ENOMEM); -++ -++ cmd = (struct wmi_addba_send_cmd *)skb->data; -++ cmd->vdev_id = __cpu_to_le32(vdev_id); -++ ether_addr_copy(cmd->peer_macaddr.addr, mac); -++ cmd->tid = __cpu_to_le32(tid); -++ cmd->buffersize = __cpu_to_le32(buf_size); -++ -++ ath10k_dbg(ar, ATH10K_DBG_WMI, -++ "wmi addba send vdev_id 0x%X mac_addr %pM tid %u bufsize %u\n", -++ vdev_id, mac, tid, buf_size); -++ return skb; -++} -++ -++static struct sk_buff * -++ath10k_wmi_op_gen_addba_set_resp(struct ath10k *ar, u32 vdev_id, const u8 *mac, -++ u32 tid, u32 status) -++{ -++ struct wmi_addba_setresponse_cmd *cmd; -++ struct sk_buff *skb; -++ -++ if (!mac) -++ return ERR_PTR(-EINVAL); -++ -++ skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd)); -++ if (!skb) -++ return ERR_PTR(-ENOMEM); -++ -++ cmd = (struct wmi_addba_setresponse_cmd *)skb->data; -++ cmd->vdev_id = __cpu_to_le32(vdev_id); -++ ether_addr_copy(cmd->peer_macaddr.addr, mac); -++ cmd->tid = __cpu_to_le32(tid); -++ cmd->statuscode = __cpu_to_le32(status); -++ -++ ath10k_dbg(ar, ATH10K_DBG_WMI, -++ "wmi addba set resp vdev_id 0x%X mac_addr %pM tid %u status %u\n", -++ vdev_id, mac, tid, status); -++ return skb; -++} -++ -++static struct sk_buff * -++ath10k_wmi_op_gen_delba_send(struct ath10k *ar, u32 vdev_id, const u8 *mac, -++ u32 tid, u32 initiator, u32 reason) -++{ -++ struct wmi_delba_send_cmd *cmd; -++ struct sk_buff *skb; -++ -++ if (!mac) -++ return ERR_PTR(-EINVAL); -++ -++ skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd)); -++ if (!skb) -++ return ERR_PTR(-ENOMEM); -++ -++ cmd = (struct wmi_delba_send_cmd *)skb->data; -++ cmd->vdev_id = __cpu_to_le32(vdev_id); -++ ether_addr_copy(cmd->peer_macaddr.addr, mac); -++ cmd->tid = __cpu_to_le32(tid); -++ cmd->initiator = __cpu_to_le32(initiator); -++ cmd->reasoncode = __cpu_to_le32(reason); -++ -++ ath10k_dbg(ar, ATH10K_DBG_WMI, -++ "wmi delba send vdev_id 0x%X mac_addr %pM tid %u initiator %u reason %u\n", -++ vdev_id, mac, tid, initiator, reason); -++ return skb; -++} -++ -++static const struct wmi_ops wmi_ops = { -++ .rx = ath10k_wmi_op_rx, -++ .map_svc = wmi_main_svc_map, -++ -++ .pull_scan = ath10k_wmi_op_pull_scan_ev, -++ .pull_mgmt_rx = ath10k_wmi_op_pull_mgmt_rx_ev, -++ .pull_ch_info = ath10k_wmi_op_pull_ch_info_ev, -++ .pull_vdev_start = ath10k_wmi_op_pull_vdev_start_ev, -++ .pull_peer_kick = ath10k_wmi_op_pull_peer_kick_ev, -++ .pull_swba = ath10k_wmi_op_pull_swba_ev, -++ .pull_phyerr = ath10k_wmi_op_pull_phyerr_ev, -++ .pull_svc_rdy = ath10k_wmi_main_op_pull_svc_rdy_ev, -++ .pull_rdy = ath10k_wmi_op_pull_rdy_ev, -++ .pull_fw_stats = ath10k_wmi_main_op_pull_fw_stats, -++ -++ .gen_pdev_suspend = ath10k_wmi_op_gen_pdev_suspend, -++ .gen_pdev_resume = ath10k_wmi_op_gen_pdev_resume, -++ .gen_pdev_set_rd = ath10k_wmi_op_gen_pdev_set_rd, -++ .gen_pdev_set_param = ath10k_wmi_op_gen_pdev_set_param, -++ .gen_init = ath10k_wmi_op_gen_init, -++ .gen_start_scan = ath10k_wmi_op_gen_start_scan, -++ .gen_stop_scan = ath10k_wmi_op_gen_stop_scan, -++ .gen_vdev_create = ath10k_wmi_op_gen_vdev_create, -++ .gen_vdev_delete = ath10k_wmi_op_gen_vdev_delete, -++ .gen_vdev_start = ath10k_wmi_op_gen_vdev_start, -++ .gen_vdev_stop = ath10k_wmi_op_gen_vdev_stop, -++ .gen_vdev_up = ath10k_wmi_op_gen_vdev_up, -++ .gen_vdev_down = ath10k_wmi_op_gen_vdev_down, -++ .gen_vdev_set_param = ath10k_wmi_op_gen_vdev_set_param, -++ .gen_vdev_install_key = ath10k_wmi_op_gen_vdev_install_key, -++ .gen_vdev_spectral_conf = ath10k_wmi_op_gen_vdev_spectral_conf, -++ .gen_vdev_spectral_enable = ath10k_wmi_op_gen_vdev_spectral_enable, -++ /* .gen_vdev_wmm_conf not implemented */ -++ .gen_peer_create = ath10k_wmi_op_gen_peer_create, -++ .gen_peer_delete = ath10k_wmi_op_gen_peer_delete, -++ .gen_peer_flush = ath10k_wmi_op_gen_peer_flush, -++ .gen_peer_set_param = ath10k_wmi_op_gen_peer_set_param, -++ .gen_peer_assoc = ath10k_wmi_op_gen_peer_assoc, -++ .gen_set_psmode = ath10k_wmi_op_gen_set_psmode, -++ .gen_set_sta_ps = ath10k_wmi_op_gen_set_sta_ps, -++ .gen_set_ap_ps = ath10k_wmi_op_gen_set_ap_ps, -++ .gen_scan_chan_list = ath10k_wmi_op_gen_scan_chan_list, -++ .gen_beacon_dma = ath10k_wmi_op_gen_beacon_dma, -++ .gen_pdev_set_wmm = ath10k_wmi_op_gen_pdev_set_wmm, -++ .gen_request_stats = ath10k_wmi_op_gen_request_stats, -++ .gen_force_fw_hang = ath10k_wmi_op_gen_force_fw_hang, -++ .gen_mgmt_tx = ath10k_wmi_op_gen_mgmt_tx, -++ .gen_dbglog_cfg = ath10k_wmi_op_gen_dbglog_cfg, -++ .gen_pktlog_enable = ath10k_wmi_op_gen_pktlog_enable, -++ .gen_pktlog_disable = ath10k_wmi_op_gen_pktlog_disable, -++ .gen_pdev_set_quiet_mode = ath10k_wmi_op_gen_pdev_set_quiet_mode, -++ /* .gen_pdev_get_temperature not implemented */ -++ .gen_addba_clear_resp = ath10k_wmi_op_gen_addba_clear_resp, -++ .gen_addba_send = ath10k_wmi_op_gen_addba_send, -++ .gen_addba_set_resp = ath10k_wmi_op_gen_addba_set_resp, -++ .gen_delba_send = ath10k_wmi_op_gen_delba_send, -++ /* .gen_bcn_tmpl not implemented */ -++ /* .gen_prb_tmpl not implemented */ -++ /* .gen_p2p_go_bcn_ie not implemented */ -++}; -++ -++static const struct wmi_ops wmi_10_1_ops = { -++ .rx = ath10k_wmi_10_1_op_rx, -++ .map_svc = wmi_10x_svc_map, -++ .pull_svc_rdy = ath10k_wmi_10x_op_pull_svc_rdy_ev, -++ .pull_fw_stats = ath10k_wmi_10x_op_pull_fw_stats, -++ .gen_init = ath10k_wmi_10_1_op_gen_init, -++ .gen_pdev_set_rd = ath10k_wmi_10x_op_gen_pdev_set_rd, -++ .gen_start_scan = ath10k_wmi_10x_op_gen_start_scan, -++ .gen_peer_assoc = ath10k_wmi_10_1_op_gen_peer_assoc, -++ /* .gen_pdev_get_temperature not implemented */ -++ -++ /* shared with main branch */ -++ .pull_scan = ath10k_wmi_op_pull_scan_ev, -++ .pull_mgmt_rx = ath10k_wmi_op_pull_mgmt_rx_ev, -++ .pull_ch_info = ath10k_wmi_op_pull_ch_info_ev, -++ .pull_vdev_start = ath10k_wmi_op_pull_vdev_start_ev, -++ .pull_peer_kick = ath10k_wmi_op_pull_peer_kick_ev, -++ .pull_swba = ath10k_wmi_op_pull_swba_ev, -++ .pull_phyerr = ath10k_wmi_op_pull_phyerr_ev, -++ .pull_rdy = ath10k_wmi_op_pull_rdy_ev, -++ -++ .gen_pdev_suspend = ath10k_wmi_op_gen_pdev_suspend, -++ .gen_pdev_resume = ath10k_wmi_op_gen_pdev_resume, -++ .gen_pdev_set_param = ath10k_wmi_op_gen_pdev_set_param, -++ .gen_stop_scan = ath10k_wmi_op_gen_stop_scan, -++ .gen_vdev_create = ath10k_wmi_op_gen_vdev_create, -++ .gen_vdev_delete = ath10k_wmi_op_gen_vdev_delete, -++ .gen_vdev_start = ath10k_wmi_op_gen_vdev_start, -++ .gen_vdev_stop = ath10k_wmi_op_gen_vdev_stop, -++ .gen_vdev_up = ath10k_wmi_op_gen_vdev_up, -++ .gen_vdev_down = ath10k_wmi_op_gen_vdev_down, -++ .gen_vdev_set_param = ath10k_wmi_op_gen_vdev_set_param, -++ .gen_vdev_install_key = ath10k_wmi_op_gen_vdev_install_key, -++ .gen_vdev_spectral_conf = ath10k_wmi_op_gen_vdev_spectral_conf, -++ .gen_vdev_spectral_enable = ath10k_wmi_op_gen_vdev_spectral_enable, -++ /* .gen_vdev_wmm_conf not implemented */ -++ .gen_peer_create = ath10k_wmi_op_gen_peer_create, -++ .gen_peer_delete = ath10k_wmi_op_gen_peer_delete, -++ .gen_peer_flush = ath10k_wmi_op_gen_peer_flush, -++ .gen_peer_set_param = ath10k_wmi_op_gen_peer_set_param, -++ .gen_set_psmode = ath10k_wmi_op_gen_set_psmode, -++ .gen_set_sta_ps = ath10k_wmi_op_gen_set_sta_ps, -++ .gen_set_ap_ps = ath10k_wmi_op_gen_set_ap_ps, -++ .gen_scan_chan_list = ath10k_wmi_op_gen_scan_chan_list, -++ .gen_beacon_dma = ath10k_wmi_op_gen_beacon_dma, -++ .gen_pdev_set_wmm = ath10k_wmi_op_gen_pdev_set_wmm, -++ .gen_request_stats = ath10k_wmi_op_gen_request_stats, -++ .gen_force_fw_hang = ath10k_wmi_op_gen_force_fw_hang, -++ .gen_mgmt_tx = ath10k_wmi_op_gen_mgmt_tx, -++ .gen_dbglog_cfg = ath10k_wmi_op_gen_dbglog_cfg, -++ .gen_pktlog_enable = ath10k_wmi_op_gen_pktlog_enable, -++ .gen_pktlog_disable = ath10k_wmi_op_gen_pktlog_disable, -++ .gen_pdev_set_quiet_mode = ath10k_wmi_op_gen_pdev_set_quiet_mode, -++ .gen_addba_clear_resp = ath10k_wmi_op_gen_addba_clear_resp, -++ .gen_addba_send = ath10k_wmi_op_gen_addba_send, -++ .gen_addba_set_resp = ath10k_wmi_op_gen_addba_set_resp, -++ .gen_delba_send = ath10k_wmi_op_gen_delba_send, -++ /* .gen_bcn_tmpl not implemented */ -++ /* .gen_prb_tmpl not implemented */ -++ /* .gen_p2p_go_bcn_ie not implemented */ -++}; -++ -++static const struct wmi_ops wmi_10_2_ops = { -++ .rx = ath10k_wmi_10_2_op_rx, -++ .pull_fw_stats = ath10k_wmi_10_2_op_pull_fw_stats, -++ .gen_init = ath10k_wmi_10_2_op_gen_init, -++ .gen_peer_assoc = ath10k_wmi_10_2_op_gen_peer_assoc, -++ /* .gen_pdev_get_temperature not implemented */ -++ -++ /* shared with 10.1 */ -++ .map_svc = wmi_10x_svc_map, -++ .pull_svc_rdy = ath10k_wmi_10x_op_pull_svc_rdy_ev, -++ .gen_pdev_set_rd = ath10k_wmi_10x_op_gen_pdev_set_rd, -++ .gen_start_scan = ath10k_wmi_10x_op_gen_start_scan, -++ -++ .pull_scan = ath10k_wmi_op_pull_scan_ev, -++ .pull_mgmt_rx = ath10k_wmi_op_pull_mgmt_rx_ev, -++ .pull_ch_info = ath10k_wmi_op_pull_ch_info_ev, -++ .pull_vdev_start = ath10k_wmi_op_pull_vdev_start_ev, -++ .pull_peer_kick = ath10k_wmi_op_pull_peer_kick_ev, -++ .pull_swba = ath10k_wmi_op_pull_swba_ev, -++ .pull_phyerr = ath10k_wmi_op_pull_phyerr_ev, -++ .pull_rdy = ath10k_wmi_op_pull_rdy_ev, -++ -++ .gen_pdev_suspend = ath10k_wmi_op_gen_pdev_suspend, -++ .gen_pdev_resume = ath10k_wmi_op_gen_pdev_resume, -++ .gen_pdev_set_param = ath10k_wmi_op_gen_pdev_set_param, -++ .gen_stop_scan = ath10k_wmi_op_gen_stop_scan, -++ .gen_vdev_create = ath10k_wmi_op_gen_vdev_create, -++ .gen_vdev_delete = ath10k_wmi_op_gen_vdev_delete, -++ .gen_vdev_start = ath10k_wmi_op_gen_vdev_start, -++ .gen_vdev_stop = ath10k_wmi_op_gen_vdev_stop, -++ .gen_vdev_up = ath10k_wmi_op_gen_vdev_up, -++ .gen_vdev_down = ath10k_wmi_op_gen_vdev_down, -++ .gen_vdev_set_param = ath10k_wmi_op_gen_vdev_set_param, -++ .gen_vdev_install_key = ath10k_wmi_op_gen_vdev_install_key, -++ .gen_vdev_spectral_conf = ath10k_wmi_op_gen_vdev_spectral_conf, -++ .gen_vdev_spectral_enable = ath10k_wmi_op_gen_vdev_spectral_enable, -++ /* .gen_vdev_wmm_conf not implemented */ -++ .gen_peer_create = ath10k_wmi_op_gen_peer_create, -++ .gen_peer_delete = ath10k_wmi_op_gen_peer_delete, -++ .gen_peer_flush = ath10k_wmi_op_gen_peer_flush, -++ .gen_peer_set_param = ath10k_wmi_op_gen_peer_set_param, -++ .gen_set_psmode = ath10k_wmi_op_gen_set_psmode, -++ .gen_set_sta_ps = ath10k_wmi_op_gen_set_sta_ps, -++ .gen_set_ap_ps = ath10k_wmi_op_gen_set_ap_ps, -++ .gen_scan_chan_list = ath10k_wmi_op_gen_scan_chan_list, -++ .gen_beacon_dma = ath10k_wmi_op_gen_beacon_dma, -++ .gen_pdev_set_wmm = ath10k_wmi_op_gen_pdev_set_wmm, -++ .gen_request_stats = ath10k_wmi_op_gen_request_stats, -++ .gen_force_fw_hang = ath10k_wmi_op_gen_force_fw_hang, -++ .gen_mgmt_tx = ath10k_wmi_op_gen_mgmt_tx, -++ .gen_dbglog_cfg = ath10k_wmi_op_gen_dbglog_cfg, -++ .gen_pktlog_enable = ath10k_wmi_op_gen_pktlog_enable, -++ .gen_pktlog_disable = ath10k_wmi_op_gen_pktlog_disable, -++ .gen_pdev_set_quiet_mode = ath10k_wmi_op_gen_pdev_set_quiet_mode, -++ .gen_addba_clear_resp = ath10k_wmi_op_gen_addba_clear_resp, -++ .gen_addba_send = ath10k_wmi_op_gen_addba_send, -++ .gen_addba_set_resp = ath10k_wmi_op_gen_addba_set_resp, -++ .gen_delba_send = ath10k_wmi_op_gen_delba_send, -++}; -++ -++static const struct wmi_ops wmi_10_2_4_ops = { -++ .rx = ath10k_wmi_10_2_op_rx, -++ .pull_fw_stats = ath10k_wmi_10_2_4_op_pull_fw_stats, -++ .gen_init = ath10k_wmi_10_2_op_gen_init, -++ .gen_peer_assoc = ath10k_wmi_10_2_op_gen_peer_assoc, -++ .gen_pdev_get_temperature = ath10k_wmi_10_2_op_gen_pdev_get_temperature, -++ -++ /* shared with 10.1 */ -++ .map_svc = wmi_10x_svc_map, -++ .pull_svc_rdy = ath10k_wmi_10x_op_pull_svc_rdy_ev, -++ .gen_pdev_set_rd = ath10k_wmi_10x_op_gen_pdev_set_rd, -++ .gen_start_scan = ath10k_wmi_10x_op_gen_start_scan, -++ -++ .pull_scan = ath10k_wmi_op_pull_scan_ev, -++ .pull_mgmt_rx = ath10k_wmi_op_pull_mgmt_rx_ev, -++ .pull_ch_info = ath10k_wmi_op_pull_ch_info_ev, -++ .pull_vdev_start = ath10k_wmi_op_pull_vdev_start_ev, -++ .pull_peer_kick = ath10k_wmi_op_pull_peer_kick_ev, -++ .pull_swba = ath10k_wmi_op_pull_swba_ev, -++ .pull_phyerr = ath10k_wmi_op_pull_phyerr_ev, -++ .pull_rdy = ath10k_wmi_op_pull_rdy_ev, -++ -++ .gen_pdev_suspend = ath10k_wmi_op_gen_pdev_suspend, -++ .gen_pdev_resume = ath10k_wmi_op_gen_pdev_resume, -++ .gen_pdev_set_param = ath10k_wmi_op_gen_pdev_set_param, -++ .gen_stop_scan = ath10k_wmi_op_gen_stop_scan, -++ .gen_vdev_create = ath10k_wmi_op_gen_vdev_create, -++ .gen_vdev_delete = ath10k_wmi_op_gen_vdev_delete, -++ .gen_vdev_start = ath10k_wmi_op_gen_vdev_start, -++ .gen_vdev_stop = ath10k_wmi_op_gen_vdev_stop, -++ .gen_vdev_up = ath10k_wmi_op_gen_vdev_up, -++ .gen_vdev_down = ath10k_wmi_op_gen_vdev_down, -++ .gen_vdev_set_param = ath10k_wmi_op_gen_vdev_set_param, -++ .gen_vdev_install_key = ath10k_wmi_op_gen_vdev_install_key, -++ .gen_vdev_spectral_conf = ath10k_wmi_op_gen_vdev_spectral_conf, -++ .gen_vdev_spectral_enable = ath10k_wmi_op_gen_vdev_spectral_enable, -++ .gen_peer_create = ath10k_wmi_op_gen_peer_create, -++ .gen_peer_delete = ath10k_wmi_op_gen_peer_delete, -++ .gen_peer_flush = ath10k_wmi_op_gen_peer_flush, -++ .gen_peer_set_param = ath10k_wmi_op_gen_peer_set_param, -++ .gen_set_psmode = ath10k_wmi_op_gen_set_psmode, -++ .gen_set_sta_ps = ath10k_wmi_op_gen_set_sta_ps, -++ .gen_set_ap_ps = ath10k_wmi_op_gen_set_ap_ps, -++ .gen_scan_chan_list = ath10k_wmi_op_gen_scan_chan_list, -++ .gen_beacon_dma = ath10k_wmi_op_gen_beacon_dma, -++ .gen_pdev_set_wmm = ath10k_wmi_op_gen_pdev_set_wmm, -++ .gen_request_stats = ath10k_wmi_op_gen_request_stats, -++ .gen_force_fw_hang = ath10k_wmi_op_gen_force_fw_hang, -++ .gen_mgmt_tx = ath10k_wmi_op_gen_mgmt_tx, -++ .gen_dbglog_cfg = ath10k_wmi_op_gen_dbglog_cfg, -++ .gen_pktlog_enable = ath10k_wmi_op_gen_pktlog_enable, -++ .gen_pktlog_disable = ath10k_wmi_op_gen_pktlog_disable, -++ .gen_pdev_set_quiet_mode = ath10k_wmi_op_gen_pdev_set_quiet_mode, -++ .gen_addba_clear_resp = ath10k_wmi_op_gen_addba_clear_resp, -++ .gen_addba_send = ath10k_wmi_op_gen_addba_send, -++ .gen_addba_set_resp = ath10k_wmi_op_gen_addba_set_resp, -++ .gen_delba_send = ath10k_wmi_op_gen_delba_send, -++ /* .gen_bcn_tmpl not implemented */ -++ /* .gen_prb_tmpl not implemented */ -++ /* .gen_p2p_go_bcn_ie not implemented */ -++}; -++ -++int ath10k_wmi_attach(struct ath10k *ar) -++{ -++ switch (ar->wmi.op_version) { -++ case ATH10K_FW_WMI_OP_VERSION_10_2_4: -++ ar->wmi.cmd = &wmi_10_2_4_cmd_map; -++ ar->wmi.ops = &wmi_10_2_4_ops; -++ ar->wmi.vdev_param = &wmi_10_2_4_vdev_param_map; -++ ar->wmi.pdev_param = &wmi_10_2_4_pdev_param_map; -++ break; -++ case ATH10K_FW_WMI_OP_VERSION_10_2: -++ ar->wmi.cmd = &wmi_10_2_cmd_map; -++ ar->wmi.ops = &wmi_10_2_ops; -++ ar->wmi.vdev_param = &wmi_10x_vdev_param_map; -++ ar->wmi.pdev_param = &wmi_10x_pdev_param_map; -++ break; -++ case ATH10K_FW_WMI_OP_VERSION_10_1: -++ ar->wmi.cmd = &wmi_10x_cmd_map; -++ ar->wmi.ops = &wmi_10_1_ops; -++ ar->wmi.vdev_param = &wmi_10x_vdev_param_map; -++ ar->wmi.pdev_param = &wmi_10x_pdev_param_map; -++ break; -++ case ATH10K_FW_WMI_OP_VERSION_MAIN: -++ ar->wmi.cmd = &wmi_cmd_map; -++ ar->wmi.ops = &wmi_ops; -++ ar->wmi.vdev_param = &wmi_vdev_param_map; -++ ar->wmi.pdev_param = &wmi_pdev_param_map; -++ break; -++ case ATH10K_FW_WMI_OP_VERSION_TLV: -++ ath10k_wmi_tlv_attach(ar); -++ break; -++ case ATH10K_FW_WMI_OP_VERSION_UNSET: -++ case ATH10K_FW_WMI_OP_VERSION_MAX: -++ ath10k_err(ar, "unsupported WMI op version: %d\n", -++ ar->wmi.op_version); -++ return -EINVAL; -++ } -++ -++ init_completion(&ar->wmi.service_ready); -++ init_completion(&ar->wmi.unified_ready); -++ -++ return 0; -++} -++ -++void ath10k_wmi_detach(struct ath10k *ar) -++{ -++ int i; -++ -++ /* free the host memory chunks requested by firmware */ -++ for (i = 0; i < ar->wmi.num_mem_chunks; i++) { -++ dma_free_coherent(ar->dev, -++ ar->wmi.mem_chunks[i].len, -++ ar->wmi.mem_chunks[i].vaddr, -++ ar->wmi.mem_chunks[i].paddr); -++ } -++ -++ ar->wmi.num_mem_chunks = 0; -+ } -+--- a/drivers/net/wireless/ath/ath10k/wmi.h -++++ b/drivers/net/wireless/ath/ath10k/wmi.h -+@@ -73,119 +73,361 @@ struct wmi_cmd_hdr { -+ #define HTC_PROTOCOL_VERSION 0x0002 -+ #define WMI_PROTOCOL_VERSION 0x0002 -+ -+-enum wmi_service_id { -+- WMI_SERVICE_BEACON_OFFLOAD = 0, /* beacon offload */ -+- WMI_SERVICE_SCAN_OFFLOAD, /* scan offload */ -+- WMI_SERVICE_ROAM_OFFLOAD, /* roam offload */ -+- WMI_SERVICE_BCN_MISS_OFFLOAD, /* beacon miss offload */ -+- WMI_SERVICE_STA_PWRSAVE, /* fake sleep + basic power save */ -+- WMI_SERVICE_STA_ADVANCED_PWRSAVE, /* uapsd, pspoll, force sleep */ -+- WMI_SERVICE_AP_UAPSD, /* uapsd on AP */ -+- WMI_SERVICE_AP_DFS, /* DFS on AP */ -+- WMI_SERVICE_11AC, /* supports 11ac */ -+- WMI_SERVICE_BLOCKACK, /* Supports triggering ADDBA/DELBA from host*/ -+- WMI_SERVICE_PHYERR, /* PHY error */ -+- WMI_SERVICE_BCN_FILTER, /* Beacon filter support */ -+- WMI_SERVICE_RTT, /* RTT (round trip time) support */ -+- WMI_SERVICE_RATECTRL, /* Rate-control */ -+- WMI_SERVICE_WOW, /* WOW Support */ -+- WMI_SERVICE_RATECTRL_CACHE, /* Rate-control caching */ -+- WMI_SERVICE_IRAM_TIDS, /* TIDs in IRAM */ -+- WMI_SERVICE_ARPNS_OFFLOAD, /* ARP NS Offload support */ -+- WMI_SERVICE_NLO, /* Network list offload service */ -+- WMI_SERVICE_GTK_OFFLOAD, /* GTK offload */ -+- WMI_SERVICE_SCAN_SCH, /* Scan Scheduler Service */ -+- WMI_SERVICE_CSA_OFFLOAD, /* CSA offload service */ -+- WMI_SERVICE_CHATTER, /* Chatter service */ -+- WMI_SERVICE_COEX_FREQAVOID, /* FW report freq range to avoid */ -+- WMI_SERVICE_PACKET_POWER_SAVE, /* packet power save service */ -+- WMI_SERVICE_FORCE_FW_HANG, /* To test fw recovery mechanism */ -+- WMI_SERVICE_GPIO, /* GPIO service */ -+- WMI_SERVICE_STA_DTIM_PS_MODULATED_DTIM, /* Modulated DTIM support */ -+- WMI_STA_UAPSD_BASIC_AUTO_TRIG, /* UAPSD AC Trigger Generation */ -+- WMI_STA_UAPSD_VAR_AUTO_TRIG, /* -do- */ -+- WMI_SERVICE_STA_KEEP_ALIVE, /* STA keep alive mechanism support */ -+- WMI_SERVICE_TX_ENCAP, /* Packet type for TX encapsulation */ -+- -+- WMI_SERVICE_LAST, -+- WMI_MAX_SERVICE = 64 /* max service */ -++enum wmi_service { -++ WMI_SERVICE_BEACON_OFFLOAD = 0, -++ WMI_SERVICE_SCAN_OFFLOAD, -++ WMI_SERVICE_ROAM_OFFLOAD, -++ WMI_SERVICE_BCN_MISS_OFFLOAD, -++ WMI_SERVICE_STA_PWRSAVE, -++ WMI_SERVICE_STA_ADVANCED_PWRSAVE, -++ WMI_SERVICE_AP_UAPSD, -++ WMI_SERVICE_AP_DFS, -++ WMI_SERVICE_11AC, -++ WMI_SERVICE_BLOCKACK, -++ WMI_SERVICE_PHYERR, -++ WMI_SERVICE_BCN_FILTER, -++ WMI_SERVICE_RTT, -++ WMI_SERVICE_RATECTRL, -++ WMI_SERVICE_WOW, -++ WMI_SERVICE_RATECTRL_CACHE, -++ WMI_SERVICE_IRAM_TIDS, -++ WMI_SERVICE_ARPNS_OFFLOAD, -++ WMI_SERVICE_NLO, -++ WMI_SERVICE_GTK_OFFLOAD, -++ WMI_SERVICE_SCAN_SCH, -++ WMI_SERVICE_CSA_OFFLOAD, -++ WMI_SERVICE_CHATTER, -++ WMI_SERVICE_COEX_FREQAVOID, -++ WMI_SERVICE_PACKET_POWER_SAVE, -++ WMI_SERVICE_FORCE_FW_HANG, -++ WMI_SERVICE_GPIO, -++ WMI_SERVICE_STA_DTIM_PS_MODULATED_DTIM, -++ WMI_SERVICE_STA_UAPSD_BASIC_AUTO_TRIG, -++ WMI_SERVICE_STA_UAPSD_VAR_AUTO_TRIG, -++ WMI_SERVICE_STA_KEEP_ALIVE, -++ WMI_SERVICE_TX_ENCAP, -++ WMI_SERVICE_BURST, -++ WMI_SERVICE_SMART_ANTENNA_SW_SUPPORT, -++ WMI_SERVICE_SMART_ANTENNA_HW_SUPPORT, -++ WMI_SERVICE_ROAM_SCAN_OFFLOAD, -++ WMI_SERVICE_AP_PS_DETECT_OUT_OF_SYNC, -++ WMI_SERVICE_EARLY_RX, -++ WMI_SERVICE_STA_SMPS, -++ WMI_SERVICE_FWTEST, -++ WMI_SERVICE_STA_WMMAC, -++ WMI_SERVICE_TDLS, -++ WMI_SERVICE_MCC_BCN_INTERVAL_CHANGE, -++ WMI_SERVICE_ADAPTIVE_OCS, -++ WMI_SERVICE_BA_SSN_SUPPORT, -++ WMI_SERVICE_FILTER_IPSEC_NATKEEPALIVE, -++ WMI_SERVICE_WLAN_HB, -++ WMI_SERVICE_LTE_ANT_SHARE_SUPPORT, -++ WMI_SERVICE_BATCH_SCAN, -++ WMI_SERVICE_QPOWER, -++ WMI_SERVICE_PLMREQ, -++ WMI_SERVICE_THERMAL_MGMT, -++ WMI_SERVICE_RMC, -++ WMI_SERVICE_MHF_OFFLOAD, -++ WMI_SERVICE_COEX_SAR, -++ WMI_SERVICE_BCN_TXRATE_OVERRIDE, -++ WMI_SERVICE_NAN, -++ WMI_SERVICE_L1SS_STAT, -++ WMI_SERVICE_ESTIMATE_LINKSPEED, -++ WMI_SERVICE_OBSS_SCAN, -++ WMI_SERVICE_TDLS_OFFCHAN, -++ WMI_SERVICE_TDLS_UAPSD_BUFFER_STA, -++ WMI_SERVICE_TDLS_UAPSD_SLEEP_STA, -++ WMI_SERVICE_IBSS_PWRSAVE, -++ WMI_SERVICE_LPASS, -++ WMI_SERVICE_EXTSCAN, -++ WMI_SERVICE_D0WOW, -++ WMI_SERVICE_HSOFFLOAD, -++ WMI_SERVICE_ROAM_HO_OFFLOAD, -++ WMI_SERVICE_RX_FULL_REORDER, -++ WMI_SERVICE_DHCP_OFFLOAD, -++ WMI_SERVICE_STA_RX_IPA_OFFLOAD_SUPPORT, -++ WMI_SERVICE_MDNS_OFFLOAD, -++ WMI_SERVICE_SAP_AUTH_OFFLOAD, -++ -++ /* keep last */ -++ WMI_SERVICE_MAX, -++}; -++ -++enum wmi_10x_service { -++ WMI_10X_SERVICE_BEACON_OFFLOAD = 0, -++ WMI_10X_SERVICE_SCAN_OFFLOAD, -++ WMI_10X_SERVICE_ROAM_OFFLOAD, -++ WMI_10X_SERVICE_BCN_MISS_OFFLOAD, -++ WMI_10X_SERVICE_STA_PWRSAVE, -++ WMI_10X_SERVICE_STA_ADVANCED_PWRSAVE, -++ WMI_10X_SERVICE_AP_UAPSD, -++ WMI_10X_SERVICE_AP_DFS, -++ WMI_10X_SERVICE_11AC, -++ WMI_10X_SERVICE_BLOCKACK, -++ WMI_10X_SERVICE_PHYERR, -++ WMI_10X_SERVICE_BCN_FILTER, -++ WMI_10X_SERVICE_RTT, -++ WMI_10X_SERVICE_RATECTRL, -++ WMI_10X_SERVICE_WOW, -++ WMI_10X_SERVICE_RATECTRL_CACHE, -++ WMI_10X_SERVICE_IRAM_TIDS, -++ WMI_10X_SERVICE_BURST, -++ -++ /* introduced in 10.2 */ -++ WMI_10X_SERVICE_SMART_ANTENNA_SW_SUPPORT, -++ WMI_10X_SERVICE_FORCE_FW_HANG, -++ WMI_10X_SERVICE_SMART_ANTENNA_HW_SUPPORT, -++}; -++ -++enum wmi_main_service { -++ WMI_MAIN_SERVICE_BEACON_OFFLOAD = 0, -++ WMI_MAIN_SERVICE_SCAN_OFFLOAD, -++ WMI_MAIN_SERVICE_ROAM_OFFLOAD, -++ WMI_MAIN_SERVICE_BCN_MISS_OFFLOAD, -++ WMI_MAIN_SERVICE_STA_PWRSAVE, -++ WMI_MAIN_SERVICE_STA_ADVANCED_PWRSAVE, -++ WMI_MAIN_SERVICE_AP_UAPSD, -++ WMI_MAIN_SERVICE_AP_DFS, -++ WMI_MAIN_SERVICE_11AC, -++ WMI_MAIN_SERVICE_BLOCKACK, -++ WMI_MAIN_SERVICE_PHYERR, -++ WMI_MAIN_SERVICE_BCN_FILTER, -++ WMI_MAIN_SERVICE_RTT, -++ WMI_MAIN_SERVICE_RATECTRL, -++ WMI_MAIN_SERVICE_WOW, -++ WMI_MAIN_SERVICE_RATECTRL_CACHE, -++ WMI_MAIN_SERVICE_IRAM_TIDS, -++ WMI_MAIN_SERVICE_ARPNS_OFFLOAD, -++ WMI_MAIN_SERVICE_NLO, -++ WMI_MAIN_SERVICE_GTK_OFFLOAD, -++ WMI_MAIN_SERVICE_SCAN_SCH, -++ WMI_MAIN_SERVICE_CSA_OFFLOAD, -++ WMI_MAIN_SERVICE_CHATTER, -++ WMI_MAIN_SERVICE_COEX_FREQAVOID, -++ WMI_MAIN_SERVICE_PACKET_POWER_SAVE, -++ WMI_MAIN_SERVICE_FORCE_FW_HANG, -++ WMI_MAIN_SERVICE_GPIO, -++ WMI_MAIN_SERVICE_STA_DTIM_PS_MODULATED_DTIM, -++ WMI_MAIN_SERVICE_STA_UAPSD_BASIC_AUTO_TRIG, -++ WMI_MAIN_SERVICE_STA_UAPSD_VAR_AUTO_TRIG, -++ WMI_MAIN_SERVICE_STA_KEEP_ALIVE, -++ WMI_MAIN_SERVICE_TX_ENCAP, -+ }; -+ -+ static inline char *wmi_service_name(int service_id) -+ { -++#define SVCSTR(x) case x: return #x -++ -+ switch (service_id) { -+- case WMI_SERVICE_BEACON_OFFLOAD: -+- return "BEACON_OFFLOAD"; -+- case WMI_SERVICE_SCAN_OFFLOAD: -+- return "SCAN_OFFLOAD"; -+- case WMI_SERVICE_ROAM_OFFLOAD: -+- return "ROAM_OFFLOAD"; -+- case WMI_SERVICE_BCN_MISS_OFFLOAD: -+- return "BCN_MISS_OFFLOAD"; -+- case WMI_SERVICE_STA_PWRSAVE: -+- return "STA_PWRSAVE"; -+- case WMI_SERVICE_STA_ADVANCED_PWRSAVE: -+- return "STA_ADVANCED_PWRSAVE"; -+- case WMI_SERVICE_AP_UAPSD: -+- return "AP_UAPSD"; -+- case WMI_SERVICE_AP_DFS: -+- return "AP_DFS"; -+- case WMI_SERVICE_11AC: -+- return "11AC"; -+- case WMI_SERVICE_BLOCKACK: -+- return "BLOCKACK"; -+- case WMI_SERVICE_PHYERR: -+- return "PHYERR"; -+- case WMI_SERVICE_BCN_FILTER: -+- return "BCN_FILTER"; -+- case WMI_SERVICE_RTT: -+- return "RTT"; -+- case WMI_SERVICE_RATECTRL: -+- return "RATECTRL"; -+- case WMI_SERVICE_WOW: -+- return "WOW"; -+- case WMI_SERVICE_RATECTRL_CACHE: -+- return "RATECTRL CACHE"; -+- case WMI_SERVICE_IRAM_TIDS: -+- return "IRAM TIDS"; -+- case WMI_SERVICE_ARPNS_OFFLOAD: -+- return "ARPNS_OFFLOAD"; -+- case WMI_SERVICE_NLO: -+- return "NLO"; -+- case WMI_SERVICE_GTK_OFFLOAD: -+- return "GTK_OFFLOAD"; -+- case WMI_SERVICE_SCAN_SCH: -+- return "SCAN_SCH"; -+- case WMI_SERVICE_CSA_OFFLOAD: -+- return "CSA_OFFLOAD"; -+- case WMI_SERVICE_CHATTER: -+- return "CHATTER"; -+- case WMI_SERVICE_COEX_FREQAVOID: -+- return "COEX_FREQAVOID"; -+- case WMI_SERVICE_PACKET_POWER_SAVE: -+- return "PACKET_POWER_SAVE"; -+- case WMI_SERVICE_FORCE_FW_HANG: -+- return "FORCE FW HANG"; -+- case WMI_SERVICE_GPIO: -+- return "GPIO"; -+- case WMI_SERVICE_STA_DTIM_PS_MODULATED_DTIM: -+- return "MODULATED DTIM"; -+- case WMI_STA_UAPSD_BASIC_AUTO_TRIG: -+- return "BASIC UAPSD"; -+- case WMI_STA_UAPSD_VAR_AUTO_TRIG: -+- return "VAR UAPSD"; -+- case WMI_SERVICE_STA_KEEP_ALIVE: -+- return "STA KEEP ALIVE"; -+- case WMI_SERVICE_TX_ENCAP: -+- return "TX ENCAP"; -++ SVCSTR(WMI_SERVICE_BEACON_OFFLOAD); -++ SVCSTR(WMI_SERVICE_SCAN_OFFLOAD); -++ SVCSTR(WMI_SERVICE_ROAM_OFFLOAD); -++ SVCSTR(WMI_SERVICE_BCN_MISS_OFFLOAD); -++ SVCSTR(WMI_SERVICE_STA_PWRSAVE); -++ SVCSTR(WMI_SERVICE_STA_ADVANCED_PWRSAVE); -++ SVCSTR(WMI_SERVICE_AP_UAPSD); -++ SVCSTR(WMI_SERVICE_AP_DFS); -++ SVCSTR(WMI_SERVICE_11AC); -++ SVCSTR(WMI_SERVICE_BLOCKACK); -++ SVCSTR(WMI_SERVICE_PHYERR); -++ SVCSTR(WMI_SERVICE_BCN_FILTER); -++ SVCSTR(WMI_SERVICE_RTT); -++ SVCSTR(WMI_SERVICE_RATECTRL); -++ SVCSTR(WMI_SERVICE_WOW); -++ SVCSTR(WMI_SERVICE_RATECTRL_CACHE); -++ SVCSTR(WMI_SERVICE_IRAM_TIDS); -++ SVCSTR(WMI_SERVICE_ARPNS_OFFLOAD); -++ SVCSTR(WMI_SERVICE_NLO); -++ SVCSTR(WMI_SERVICE_GTK_OFFLOAD); -++ SVCSTR(WMI_SERVICE_SCAN_SCH); -++ SVCSTR(WMI_SERVICE_CSA_OFFLOAD); -++ SVCSTR(WMI_SERVICE_CHATTER); -++ SVCSTR(WMI_SERVICE_COEX_FREQAVOID); -++ SVCSTR(WMI_SERVICE_PACKET_POWER_SAVE); -++ SVCSTR(WMI_SERVICE_FORCE_FW_HANG); -++ SVCSTR(WMI_SERVICE_GPIO); -++ SVCSTR(WMI_SERVICE_STA_DTIM_PS_MODULATED_DTIM); -++ SVCSTR(WMI_SERVICE_STA_UAPSD_BASIC_AUTO_TRIG); -++ SVCSTR(WMI_SERVICE_STA_UAPSD_VAR_AUTO_TRIG); -++ SVCSTR(WMI_SERVICE_STA_KEEP_ALIVE); -++ SVCSTR(WMI_SERVICE_TX_ENCAP); -++ SVCSTR(WMI_SERVICE_BURST); -++ SVCSTR(WMI_SERVICE_SMART_ANTENNA_SW_SUPPORT); -++ SVCSTR(WMI_SERVICE_SMART_ANTENNA_HW_SUPPORT); -++ SVCSTR(WMI_SERVICE_ROAM_SCAN_OFFLOAD); -++ SVCSTR(WMI_SERVICE_AP_PS_DETECT_OUT_OF_SYNC); -++ SVCSTR(WMI_SERVICE_EARLY_RX); -++ SVCSTR(WMI_SERVICE_STA_SMPS); -++ SVCSTR(WMI_SERVICE_FWTEST); -++ SVCSTR(WMI_SERVICE_STA_WMMAC); -++ SVCSTR(WMI_SERVICE_TDLS); -++ SVCSTR(WMI_SERVICE_MCC_BCN_INTERVAL_CHANGE); -++ SVCSTR(WMI_SERVICE_ADAPTIVE_OCS); -++ SVCSTR(WMI_SERVICE_BA_SSN_SUPPORT); -++ SVCSTR(WMI_SERVICE_FILTER_IPSEC_NATKEEPALIVE); -++ SVCSTR(WMI_SERVICE_WLAN_HB); -++ SVCSTR(WMI_SERVICE_LTE_ANT_SHARE_SUPPORT); -++ SVCSTR(WMI_SERVICE_BATCH_SCAN); -++ SVCSTR(WMI_SERVICE_QPOWER); -++ SVCSTR(WMI_SERVICE_PLMREQ); -++ SVCSTR(WMI_SERVICE_THERMAL_MGMT); -++ SVCSTR(WMI_SERVICE_RMC); -++ SVCSTR(WMI_SERVICE_MHF_OFFLOAD); -++ SVCSTR(WMI_SERVICE_COEX_SAR); -++ SVCSTR(WMI_SERVICE_BCN_TXRATE_OVERRIDE); -++ SVCSTR(WMI_SERVICE_NAN); -++ SVCSTR(WMI_SERVICE_L1SS_STAT); -++ SVCSTR(WMI_SERVICE_ESTIMATE_LINKSPEED); -++ SVCSTR(WMI_SERVICE_OBSS_SCAN); -++ SVCSTR(WMI_SERVICE_TDLS_OFFCHAN); -++ SVCSTR(WMI_SERVICE_TDLS_UAPSD_BUFFER_STA); -++ SVCSTR(WMI_SERVICE_TDLS_UAPSD_SLEEP_STA); -++ SVCSTR(WMI_SERVICE_IBSS_PWRSAVE); -++ SVCSTR(WMI_SERVICE_LPASS); -++ SVCSTR(WMI_SERVICE_EXTSCAN); -++ SVCSTR(WMI_SERVICE_D0WOW); -++ SVCSTR(WMI_SERVICE_HSOFFLOAD); -++ SVCSTR(WMI_SERVICE_ROAM_HO_OFFLOAD); -++ SVCSTR(WMI_SERVICE_RX_FULL_REORDER); -++ SVCSTR(WMI_SERVICE_DHCP_OFFLOAD); -++ SVCSTR(WMI_SERVICE_STA_RX_IPA_OFFLOAD_SUPPORT); -++ SVCSTR(WMI_SERVICE_MDNS_OFFLOAD); -++ SVCSTR(WMI_SERVICE_SAP_AUTH_OFFLOAD); -+ default: -+- return "UNKNOWN SERVICE\n"; -++ return NULL; -+ } -++ -++#undef SVCSTR -+ } -+ -++#define WMI_SERVICE_IS_ENABLED(wmi_svc_bmap, svc_id, len) \ -++ ((svc_id) < (len) && \ -++ __le32_to_cpu((wmi_svc_bmap)[(svc_id)/(sizeof(u32))]) & \ -++ BIT((svc_id)%(sizeof(u32)))) -++ -++#define SVCMAP(x, y, len) \ -++ do { \ -++ if (WMI_SERVICE_IS_ENABLED((in), (x), (len))) \ -++ __set_bit(y, out); \ -++ } while (0) -++ -++static inline void wmi_10x_svc_map(const __le32 *in, unsigned long *out, -++ size_t len) -++{ -++ SVCMAP(WMI_10X_SERVICE_BEACON_OFFLOAD, -++ WMI_SERVICE_BEACON_OFFLOAD, len); -++ SVCMAP(WMI_10X_SERVICE_SCAN_OFFLOAD, -++ WMI_SERVICE_SCAN_OFFLOAD, len); -++ SVCMAP(WMI_10X_SERVICE_ROAM_OFFLOAD, -++ WMI_SERVICE_ROAM_OFFLOAD, len); -++ SVCMAP(WMI_10X_SERVICE_BCN_MISS_OFFLOAD, -++ WMI_SERVICE_BCN_MISS_OFFLOAD, len); -++ SVCMAP(WMI_10X_SERVICE_STA_PWRSAVE, -++ WMI_SERVICE_STA_PWRSAVE, len); -++ SVCMAP(WMI_10X_SERVICE_STA_ADVANCED_PWRSAVE, -++ WMI_SERVICE_STA_ADVANCED_PWRSAVE, len); -++ SVCMAP(WMI_10X_SERVICE_AP_UAPSD, -++ WMI_SERVICE_AP_UAPSD, len); -++ SVCMAP(WMI_10X_SERVICE_AP_DFS, -++ WMI_SERVICE_AP_DFS, len); -++ SVCMAP(WMI_10X_SERVICE_11AC, -++ WMI_SERVICE_11AC, len); -++ SVCMAP(WMI_10X_SERVICE_BLOCKACK, -++ WMI_SERVICE_BLOCKACK, len); -++ SVCMAP(WMI_10X_SERVICE_PHYERR, -++ WMI_SERVICE_PHYERR, len); -++ SVCMAP(WMI_10X_SERVICE_BCN_FILTER, -++ WMI_SERVICE_BCN_FILTER, len); -++ SVCMAP(WMI_10X_SERVICE_RTT, -++ WMI_SERVICE_RTT, len); -++ SVCMAP(WMI_10X_SERVICE_RATECTRL, -++ WMI_SERVICE_RATECTRL, len); -++ SVCMAP(WMI_10X_SERVICE_WOW, -++ WMI_SERVICE_WOW, len); -++ SVCMAP(WMI_10X_SERVICE_RATECTRL_CACHE, -++ WMI_SERVICE_RATECTRL_CACHE, len); -++ SVCMAP(WMI_10X_SERVICE_IRAM_TIDS, -++ WMI_SERVICE_IRAM_TIDS, len); -++ SVCMAP(WMI_10X_SERVICE_BURST, -++ WMI_SERVICE_BURST, len); -++ SVCMAP(WMI_10X_SERVICE_SMART_ANTENNA_SW_SUPPORT, -++ WMI_SERVICE_SMART_ANTENNA_SW_SUPPORT, len); -++ SVCMAP(WMI_10X_SERVICE_FORCE_FW_HANG, -++ WMI_SERVICE_FORCE_FW_HANG, len); -++ SVCMAP(WMI_10X_SERVICE_SMART_ANTENNA_HW_SUPPORT, -++ WMI_SERVICE_SMART_ANTENNA_HW_SUPPORT, len); -++} -++ -++static inline void wmi_main_svc_map(const __le32 *in, unsigned long *out, -++ size_t len) -++{ -++ SVCMAP(WMI_MAIN_SERVICE_BEACON_OFFLOAD, -++ WMI_SERVICE_BEACON_OFFLOAD, len); -++ SVCMAP(WMI_MAIN_SERVICE_SCAN_OFFLOAD, -++ WMI_SERVICE_SCAN_OFFLOAD, len); -++ SVCMAP(WMI_MAIN_SERVICE_ROAM_OFFLOAD, -++ WMI_SERVICE_ROAM_OFFLOAD, len); -++ SVCMAP(WMI_MAIN_SERVICE_BCN_MISS_OFFLOAD, -++ WMI_SERVICE_BCN_MISS_OFFLOAD, len); -++ SVCMAP(WMI_MAIN_SERVICE_STA_PWRSAVE, -++ WMI_SERVICE_STA_PWRSAVE, len); -++ SVCMAP(WMI_MAIN_SERVICE_STA_ADVANCED_PWRSAVE, -++ WMI_SERVICE_STA_ADVANCED_PWRSAVE, len); -++ SVCMAP(WMI_MAIN_SERVICE_AP_UAPSD, -++ WMI_SERVICE_AP_UAPSD, len); -++ SVCMAP(WMI_MAIN_SERVICE_AP_DFS, -++ WMI_SERVICE_AP_DFS, len); -++ SVCMAP(WMI_MAIN_SERVICE_11AC, -++ WMI_SERVICE_11AC, len); -++ SVCMAP(WMI_MAIN_SERVICE_BLOCKACK, -++ WMI_SERVICE_BLOCKACK, len); -++ SVCMAP(WMI_MAIN_SERVICE_PHYERR, -++ WMI_SERVICE_PHYERR, len); -++ SVCMAP(WMI_MAIN_SERVICE_BCN_FILTER, -++ WMI_SERVICE_BCN_FILTER, len); -++ SVCMAP(WMI_MAIN_SERVICE_RTT, -++ WMI_SERVICE_RTT, len); -++ SVCMAP(WMI_MAIN_SERVICE_RATECTRL, -++ WMI_SERVICE_RATECTRL, len); -++ SVCMAP(WMI_MAIN_SERVICE_WOW, -++ WMI_SERVICE_WOW, len); -++ SVCMAP(WMI_MAIN_SERVICE_RATECTRL_CACHE, -++ WMI_SERVICE_RATECTRL_CACHE, len); -++ SVCMAP(WMI_MAIN_SERVICE_IRAM_TIDS, -++ WMI_SERVICE_IRAM_TIDS, len); -++ SVCMAP(WMI_MAIN_SERVICE_ARPNS_OFFLOAD, -++ WMI_SERVICE_ARPNS_OFFLOAD, len); -++ SVCMAP(WMI_MAIN_SERVICE_NLO, -++ WMI_SERVICE_NLO, len); -++ SVCMAP(WMI_MAIN_SERVICE_GTK_OFFLOAD, -++ WMI_SERVICE_GTK_OFFLOAD, len); -++ SVCMAP(WMI_MAIN_SERVICE_SCAN_SCH, -++ WMI_SERVICE_SCAN_SCH, len); -++ SVCMAP(WMI_MAIN_SERVICE_CSA_OFFLOAD, -++ WMI_SERVICE_CSA_OFFLOAD, len); -++ SVCMAP(WMI_MAIN_SERVICE_CHATTER, -++ WMI_SERVICE_CHATTER, len); -++ SVCMAP(WMI_MAIN_SERVICE_COEX_FREQAVOID, -++ WMI_SERVICE_COEX_FREQAVOID, len); -++ SVCMAP(WMI_MAIN_SERVICE_PACKET_POWER_SAVE, -++ WMI_SERVICE_PACKET_POWER_SAVE, len); -++ SVCMAP(WMI_MAIN_SERVICE_FORCE_FW_HANG, -++ WMI_SERVICE_FORCE_FW_HANG, len); -++ SVCMAP(WMI_MAIN_SERVICE_GPIO, -++ WMI_SERVICE_GPIO, len); -++ SVCMAP(WMI_MAIN_SERVICE_STA_DTIM_PS_MODULATED_DTIM, -++ WMI_SERVICE_STA_DTIM_PS_MODULATED_DTIM, len); -++ SVCMAP(WMI_MAIN_SERVICE_STA_UAPSD_BASIC_AUTO_TRIG, -++ WMI_SERVICE_STA_UAPSD_BASIC_AUTO_TRIG, len); -++ SVCMAP(WMI_MAIN_SERVICE_STA_UAPSD_VAR_AUTO_TRIG, -++ WMI_SERVICE_STA_UAPSD_VAR_AUTO_TRIG, len); -++ SVCMAP(WMI_MAIN_SERVICE_STA_KEEP_ALIVE, -++ WMI_SERVICE_STA_KEEP_ALIVE, len); -++ SVCMAP(WMI_MAIN_SERVICE_TX_ENCAP, -++ WMI_SERVICE_TX_ENCAP, len); -++} -+ -+-#define WMI_SERVICE_BM_SIZE \ -+- ((WMI_MAX_SERVICE + sizeof(u32) - 1)/sizeof(u32)) -++#undef SVCMAP -+ -+ /* 2 word representation of MAC addr */ -+ struct wmi_mac_addr { -+@@ -308,6 +550,8 @@ struct wmi_cmd_map { -+ u32 force_fw_hang_cmdid; -+ u32 gpio_config_cmdid; -+ u32 gpio_output_cmdid; -++ u32 pdev_get_temperature_cmdid; -++ u32 vdev_set_wmm_params_cmdid; -+ }; -+ -+ /* -+@@ -803,6 +1047,166 @@ enum wmi_10x_event_id { -+ WMI_10X_PDEV_UTF_EVENTID = WMI_10X_END_EVENTID-1, -+ }; -+ -++enum wmi_10_2_cmd_id { -++ WMI_10_2_START_CMDID = 0x9000, -++ WMI_10_2_END_CMDID = 0x9FFF, -++ WMI_10_2_INIT_CMDID, -++ WMI_10_2_START_SCAN_CMDID = WMI_10_2_START_CMDID, -++ WMI_10_2_STOP_SCAN_CMDID, -++ WMI_10_2_SCAN_CHAN_LIST_CMDID, -++ WMI_10_2_ECHO_CMDID, -++ WMI_10_2_PDEV_SET_REGDOMAIN_CMDID, -++ WMI_10_2_PDEV_SET_CHANNEL_CMDID, -++ WMI_10_2_PDEV_SET_PARAM_CMDID, -++ WMI_10_2_PDEV_PKTLOG_ENABLE_CMDID, -++ WMI_10_2_PDEV_PKTLOG_DISABLE_CMDID, -++ WMI_10_2_PDEV_SET_WMM_PARAMS_CMDID, -++ WMI_10_2_PDEV_SET_HT_CAP_IE_CMDID, -++ WMI_10_2_PDEV_SET_VHT_CAP_IE_CMDID, -++ WMI_10_2_PDEV_SET_BASE_MACADDR_CMDID, -++ WMI_10_2_PDEV_SET_QUIET_MODE_CMDID, -++ WMI_10_2_PDEV_GREEN_AP_PS_ENABLE_CMDID, -++ WMI_10_2_PDEV_GET_TPC_CONFIG_CMDID, -++ WMI_10_2_VDEV_CREATE_CMDID, -++ WMI_10_2_VDEV_DELETE_CMDID, -++ WMI_10_2_VDEV_START_REQUEST_CMDID, -++ WMI_10_2_VDEV_RESTART_REQUEST_CMDID, -++ WMI_10_2_VDEV_UP_CMDID, -++ WMI_10_2_VDEV_STOP_CMDID, -++ WMI_10_2_VDEV_DOWN_CMDID, -++ WMI_10_2_VDEV_STANDBY_RESPONSE_CMDID, -++ WMI_10_2_VDEV_RESUME_RESPONSE_CMDID, -++ WMI_10_2_VDEV_SET_PARAM_CMDID, -++ WMI_10_2_VDEV_INSTALL_KEY_CMDID, -++ WMI_10_2_VDEV_SET_DSCP_TID_MAP_CMDID, -++ WMI_10_2_PEER_CREATE_CMDID, -++ WMI_10_2_PEER_DELETE_CMDID, -++ WMI_10_2_PEER_FLUSH_TIDS_CMDID, -++ WMI_10_2_PEER_SET_PARAM_CMDID, -++ WMI_10_2_PEER_ASSOC_CMDID, -++ WMI_10_2_PEER_ADD_WDS_ENTRY_CMDID, -++ WMI_10_2_PEER_UPDATE_WDS_ENTRY_CMDID, -++ WMI_10_2_PEER_REMOVE_WDS_ENTRY_CMDID, -++ WMI_10_2_PEER_MCAST_GROUP_CMDID, -++ WMI_10_2_BCN_TX_CMDID, -++ WMI_10_2_BCN_PRB_TMPL_CMDID, -++ WMI_10_2_BCN_FILTER_RX_CMDID, -++ WMI_10_2_PRB_REQ_FILTER_RX_CMDID, -++ WMI_10_2_MGMT_TX_CMDID, -++ WMI_10_2_ADDBA_CLEAR_RESP_CMDID, -++ WMI_10_2_ADDBA_SEND_CMDID, -++ WMI_10_2_ADDBA_STATUS_CMDID, -++ WMI_10_2_DELBA_SEND_CMDID, -++ WMI_10_2_ADDBA_SET_RESP_CMDID, -++ WMI_10_2_SEND_SINGLEAMSDU_CMDID, -++ WMI_10_2_STA_POWERSAVE_MODE_CMDID, -++ WMI_10_2_STA_POWERSAVE_PARAM_CMDID, -++ WMI_10_2_STA_MIMO_PS_MODE_CMDID, -++ WMI_10_2_DBGLOG_CFG_CMDID, -++ WMI_10_2_PDEV_DFS_ENABLE_CMDID, -++ WMI_10_2_PDEV_DFS_DISABLE_CMDID, -++ WMI_10_2_PDEV_QVIT_CMDID, -++ WMI_10_2_ROAM_SCAN_MODE, -++ WMI_10_2_ROAM_SCAN_RSSI_THRESHOLD, -++ WMI_10_2_ROAM_SCAN_PERIOD, -++ WMI_10_2_ROAM_SCAN_RSSI_CHANGE_THRESHOLD, -++ WMI_10_2_ROAM_AP_PROFILE, -++ WMI_10_2_OFL_SCAN_ADD_AP_PROFILE, -++ WMI_10_2_OFL_SCAN_REMOVE_AP_PROFILE, -++ WMI_10_2_OFL_SCAN_PERIOD, -++ WMI_10_2_P2P_DEV_SET_DEVICE_INFO, -++ WMI_10_2_P2P_DEV_SET_DISCOVERABILITY, -++ WMI_10_2_P2P_GO_SET_BEACON_IE, -++ WMI_10_2_P2P_GO_SET_PROBE_RESP_IE, -++ WMI_10_2_AP_PS_PEER_PARAM_CMDID, -++ WMI_10_2_AP_PS_PEER_UAPSD_COEX_CMDID, -++ WMI_10_2_PEER_RATE_RETRY_SCHED_CMDID, -++ WMI_10_2_WLAN_PROFILE_TRIGGER_CMDID, -++ WMI_10_2_WLAN_PROFILE_SET_HIST_INTVL_CMDID, -++ WMI_10_2_WLAN_PROFILE_GET_PROFILE_DATA_CMDID, -++ WMI_10_2_WLAN_PROFILE_ENABLE_PROFILE_ID_CMDID, -++ WMI_10_2_WLAN_PROFILE_LIST_PROFILE_ID_CMDID, -++ WMI_10_2_PDEV_SUSPEND_CMDID, -++ WMI_10_2_PDEV_RESUME_CMDID, -++ WMI_10_2_ADD_BCN_FILTER_CMDID, -++ WMI_10_2_RMV_BCN_FILTER_CMDID, -++ WMI_10_2_WOW_ADD_WAKE_PATTERN_CMDID, -++ WMI_10_2_WOW_DEL_WAKE_PATTERN_CMDID, -++ WMI_10_2_WOW_ENABLE_DISABLE_WAKE_EVENT_CMDID, -++ WMI_10_2_WOW_ENABLE_CMDID, -++ WMI_10_2_WOW_HOSTWAKEUP_FROM_SLEEP_CMDID, -++ WMI_10_2_RTT_MEASREQ_CMDID, -++ WMI_10_2_RTT_TSF_CMDID, -++ WMI_10_2_RTT_KEEPALIVE_CMDID, -++ WMI_10_2_PDEV_SEND_BCN_CMDID, -++ WMI_10_2_VDEV_SPECTRAL_SCAN_CONFIGURE_CMDID, -++ WMI_10_2_VDEV_SPECTRAL_SCAN_ENABLE_CMDID, -++ WMI_10_2_REQUEST_STATS_CMDID, -++ WMI_10_2_GPIO_CONFIG_CMDID, -++ WMI_10_2_GPIO_OUTPUT_CMDID, -++ WMI_10_2_VDEV_RATEMASK_CMDID, -++ WMI_10_2_PDEV_SMART_ANT_ENABLE_CMDID, -++ WMI_10_2_PDEV_SMART_ANT_SET_RX_ANTENNA_CMDID, -++ WMI_10_2_PEER_SMART_ANT_SET_TX_ANTENNA_CMDID, -++ WMI_10_2_PEER_SMART_ANT_SET_TRAIN_INFO_CMDID, -++ WMI_10_2_PEER_SMART_ANT_SET_NODE_CONFIG_OPS_CMDID, -++ WMI_10_2_FORCE_FW_HANG_CMDID, -++ WMI_10_2_PDEV_SET_ANTENNA_SWITCH_TABLE_CMDID, -++ WMI_10_2_PDEV_SET_CTL_TABLE_CMDID, -++ WMI_10_2_PDEV_SET_MIMOGAIN_TABLE_CMDID, -++ WMI_10_2_PDEV_RATEPWR_TABLE_CMDID, -++ WMI_10_2_PDEV_RATEPWR_CHAINMSK_TABLE_CMDID, -++ WMI_10_2_PDEV_GET_INFO, -++ WMI_10_2_VDEV_GET_INFO, -++ WMI_10_2_VDEV_ATF_REQUEST_CMDID, -++ WMI_10_2_PEER_ATF_REQUEST_CMDID, -++ WMI_10_2_PDEV_GET_TEMPERATURE_CMDID, -++ WMI_10_2_PDEV_UTF_CMDID = WMI_10_2_END_CMDID - 1, -++}; -++ -++enum wmi_10_2_event_id { -++ WMI_10_2_SERVICE_READY_EVENTID = 0x8000, -++ WMI_10_2_READY_EVENTID, -++ WMI_10_2_DEBUG_MESG_EVENTID, -++ WMI_10_2_START_EVENTID = 0x9000, -++ WMI_10_2_END_EVENTID = 0x9FFF, -++ WMI_10_2_SCAN_EVENTID = WMI_10_2_START_EVENTID, -++ WMI_10_2_ECHO_EVENTID, -++ WMI_10_2_UPDATE_STATS_EVENTID, -++ WMI_10_2_INST_RSSI_STATS_EVENTID, -++ WMI_10_2_VDEV_START_RESP_EVENTID, -++ WMI_10_2_VDEV_STANDBY_REQ_EVENTID, -++ WMI_10_2_VDEV_RESUME_REQ_EVENTID, -++ WMI_10_2_VDEV_STOPPED_EVENTID, -++ WMI_10_2_PEER_STA_KICKOUT_EVENTID, -++ WMI_10_2_HOST_SWBA_EVENTID, -++ WMI_10_2_TBTTOFFSET_UPDATE_EVENTID, -++ WMI_10_2_MGMT_RX_EVENTID, -++ WMI_10_2_CHAN_INFO_EVENTID, -++ WMI_10_2_PHYERR_EVENTID, -++ WMI_10_2_ROAM_EVENTID, -++ WMI_10_2_PROFILE_MATCH, -++ WMI_10_2_DEBUG_PRINT_EVENTID, -++ WMI_10_2_PDEV_QVIT_EVENTID, -++ WMI_10_2_WLAN_PROFILE_DATA_EVENTID, -++ WMI_10_2_RTT_MEASUREMENT_REPORT_EVENTID, -++ WMI_10_2_TSF_MEASUREMENT_REPORT_EVENTID, -++ WMI_10_2_RTT_ERROR_REPORT_EVENTID, -++ WMI_10_2_RTT_KEEPALIVE_EVENTID, -++ WMI_10_2_WOW_WAKEUP_HOST_EVENTID, -++ WMI_10_2_DCS_INTERFERENCE_EVENTID, -++ WMI_10_2_PDEV_TPC_CONFIG_EVENTID, -++ WMI_10_2_GPIO_INPUT_EVENTID, -++ WMI_10_2_PEER_RATECODE_LIST_EVENTID, -++ WMI_10_2_GENERIC_BUFFER_EVENTID, -++ WMI_10_2_MCAST_BUF_RELEASE_EVENTID, -++ WMI_10_2_MCAST_LIST_AGEOUT_EVENTID, -++ WMI_10_2_WDS_PEER_EVENTID, -++ WMI_10_2_PEER_STA_PS_STATECHG_EVENTID, -++ WMI_10_2_PDEV_TEMPERATURE_EVENTID, -++ WMI_10_2_PDEV_UTF_EVENTID = WMI_10_2_END_EVENTID - 1, -++}; -++ -+ enum wmi_phy_mode { -+ MODE_11A = 0, /* 11a Mode */ -+ MODE_11G = 1, /* 11b/g Mode */ -+@@ -955,7 +1359,6 @@ enum wmi_channel_change_cause { -+ WMI_HT_CAP_RX_STBC | \ -+ WMI_HT_CAP_LDPC) -+ -+- -+ /* -+ * WMI_VHT_CAP_* these maps to ieee 802.11ac vht capability information -+ * field. The fields not defined here are not supported, or reserved. -+@@ -1076,10 +1479,6 @@ struct wlan_host_mem_req { -+ __le32 num_units; -+ } __packed; -+ -+-#define WMI_SERVICE_IS_ENABLED(wmi_svc_bmap, svc_id) \ -+- ((((wmi_svc_bmap)[(svc_id)/(sizeof(u32))]) & \ -+- (1 << ((svc_id)%(sizeof(u32))))) != 0) -+- -+ /* -+ * The following struct holds optional payload for -+ * wmi_service_ready_event,e.g., 11ac pass some of the -+@@ -1093,7 +1492,7 @@ struct wmi_service_ready_event { -+ __le32 phy_capability; -+ /* Maximum number of frag table entries that SW will populate less 1 */ -+ __le32 max_frag_entry; -+- __le32 wmi_service_bitmap[WMI_SERVICE_BM_SIZE]; -++ __le32 wmi_service_bitmap[16]; -+ __le32 num_rf_chains; -+ /* -+ * The following field is only valid for service type -+@@ -1119,11 +1518,11 @@ struct wmi_service_ready_event { -+ * where FW can access this memory directly (or) by DMA. -+ */ -+ __le32 num_mem_reqs; -+- struct wlan_host_mem_req mem_reqs[1]; -++ struct wlan_host_mem_req mem_reqs[0]; -+ } __packed; -+ -+ /* This is the definition from 10.X firmware branch */ -+-struct wmi_service_ready_event_10x { -++struct wmi_10x_service_ready_event { -+ __le32 sw_version; -+ __le32 abi_version; -+ -+@@ -1132,7 +1531,7 @@ struct wmi_service_ready_event_10x { -+ -+ /* Maximum number of frag table entries that SW will populate less 1 */ -+ __le32 max_frag_entry; -+- __le32 wmi_service_bitmap[WMI_SERVICE_BM_SIZE]; -++ __le32 wmi_service_bitmap[16]; -+ __le32 num_rf_chains; -+ -+ /* -+@@ -1158,10 +1557,9 @@ struct wmi_service_ready_event_10x { -+ */ -+ __le32 num_mem_reqs; -+ -+- struct wlan_host_mem_req mem_reqs[1]; -++ struct wlan_host_mem_req mem_reqs[0]; -+ } __packed; -+ -+- -+ #define WMI_SERVICE_READY_TIMEOUT_HZ (5*HZ) -+ #define WMI_UNIFIED_READY_TIMEOUT_HZ (5*HZ) -+ -+@@ -1255,7 +1653,7 @@ struct wmi_resource_config { -+ */ -+ __le32 rx_decap_mode; -+ -+- /* what is the maximum scan requests than can be queued */ -++ /* what is the maximum number of scan requests that can be queued */ -+ __le32 scan_max_pending_reqs; -+ -+ /* maximum VDEV that could use BMISS offload */ -+@@ -1440,7 +1838,7 @@ struct wmi_resource_config_10x { -+ */ -+ __le32 rx_decap_mode; -+ -+- /* what is the maximum scan requests than can be queued */ -++ /* what is the maximum number of scan requests that can be queued */ -+ __le32 scan_max_pending_reqs; -+ -+ /* maximum VDEV that could use BMISS offload */ -+@@ -1551,6 +1949,21 @@ struct wmi_resource_config_10x { -+ __le32 max_frag_entries; -+ } __packed; -+ -++enum wmi_10_2_feature_mask { -++ WMI_10_2_RX_BATCH_MODE = BIT(0), -++ WMI_10_2_ATF_CONFIG = BIT(1), -++}; -++ -++struct wmi_resource_config_10_2 { -++ struct wmi_resource_config_10x common; -++ __le32 max_peer_ext_stats; -++ __le32 smart_ant_cap; /* 0-disable, 1-enable */ -++ __le32 bk_min_free; -++ __le32 be_min_free; -++ __le32 vi_min_free; -++ __le32 vo_min_free; -++ __le32 feature_mask; -++} __packed; -+ -+ #define NUM_UNITS_IS_NUM_VDEVS 0x1 -+ #define NUM_UNITS_IS_NUM_PEERS 0x2 -+@@ -1565,34 +1978,39 @@ struct host_memory_chunk { -+ __le32 size; -+ } __packed; -+ -++struct wmi_host_mem_chunks { -++ __le32 count; -++ /* some fw revisions require at least 1 chunk regardless of count */ -++ struct host_memory_chunk items[1]; -++} __packed; -++ -+ struct wmi_init_cmd { -+ struct wmi_resource_config resource_config; -+- __le32 num_host_mem_chunks; -+- -+- /* -+- * variable number of host memory chunks. -+- * This should be the last element in the structure -+- */ -+- struct host_memory_chunk host_mem_chunks[1]; -++ struct wmi_host_mem_chunks mem_chunks; -+ } __packed; -+ -+ /* _10x stucture is from 10.X FW API */ -+ struct wmi_init_cmd_10x { -+ struct wmi_resource_config_10x resource_config; -+- __le32 num_host_mem_chunks; -++ struct wmi_host_mem_chunks mem_chunks; -++} __packed; -+ -+- /* -+- * variable number of host memory chunks. -+- * This should be the last element in the structure -+- */ -+- struct host_memory_chunk host_mem_chunks[1]; -++struct wmi_init_cmd_10_2 { -++ struct wmi_resource_config_10_2 resource_config; -++ struct wmi_host_mem_chunks mem_chunks; -++} __packed; -++ -++struct wmi_chan_list_entry { -++ __le16 freq; -++ u8 phy_mode; /* valid for 10.2 only */ -++ u8 reserved; -+ } __packed; -+ -+ /* TLV for channel list */ -+ struct wmi_chan_list { -+ __le32 tag; /* WMI_CHAN_LIST_TAG */ -+ __le32 num_chan; -+- __le32 channel_list[0]; -++ struct wmi_chan_list_entry channel_list[0]; -+ } __packed; -+ -+ struct wmi_bssid_list { -+@@ -1629,6 +2047,11 @@ struct wmi_ssid_list { -+ #define WLAN_SCAN_PARAMS_MAX_BSSID 4 -+ #define WLAN_SCAN_PARAMS_MAX_IE_LEN 256 -+ -++/* Values lower than this may be refused by some firmware revisions with a scan -++ * completion with a timedout reason. -++ */ -++#define WMI_SCAN_CHAN_MIN_TIME_MSEC 40 -++ -+ /* Scan priority numbers must be sequential, starting with 0 */ -+ enum wmi_scan_priority { -+ WMI_SCAN_PRIORITY_VERY_LOW = 0, -+@@ -1639,7 +2062,7 @@ enum wmi_scan_priority { -+ WMI_SCAN_PRIORITY_COUNT /* number of priorities supported */ -+ }; -+ -+-struct wmi_start_scan_cmd { -++struct wmi_start_scan_common { -+ /* Scan ID */ -+ __le32 scan_id; -+ /* Scan requestor ID */ -+@@ -1697,97 +2120,26 @@ struct wmi_start_scan_cmd { -+ __le32 probe_delay; -+ /* Scan control flags */ -+ __le32 scan_ctrl_flags; -+- -+- /* Burst duration time in msecs */ -+- __le32 burst_duration; -+- /* -+- * TLV (tag length value ) paramerters follow the scan_cmd structure. -+- * TLV can contain channel list, bssid list, ssid list and -+- * ie. the TLV tags are defined above; -+- */ -+ } __packed; -+ -+-/* This is the definition from 10.X firmware branch */ -+-struct wmi_start_scan_cmd_10x { -+- /* Scan ID */ -+- __le32 scan_id; -+- -+- /* Scan requestor ID */ -+- __le32 scan_req_id; -+- -+- /* VDEV id(interface) that is requesting scan */ -+- __le32 vdev_id; -+- -+- /* Scan Priority, input to scan scheduler */ -+- __le32 scan_priority; -+- -+- /* Scan events subscription */ -+- __le32 notify_scan_events; -+- -+- /* dwell time in msec on active channels */ -+- __le32 dwell_time_active; -+- -+- /* dwell time in msec on passive channels */ -+- __le32 dwell_time_passive; -+- -+- /* -+- * min time in msec on the BSS channel,only valid if atleast one -+- * VDEV is active -+- */ -+- __le32 min_rest_time; -+- -+- /* -+- * max rest time in msec on the BSS channel,only valid if at least -+- * one VDEV is active -+- */ -+- /* -+- * the scanner will rest on the bss channel at least min_rest_time -+- * after min_rest_time the scanner will start checking for tx/rx -+- * activity on all VDEVs. if there is no activity the scanner will -+- * switch to off channel. if there is activity the scanner will let -+- * the radio on the bss channel until max_rest_time expires.at -+- * max_rest_time scanner will switch to off channel irrespective of -+- * activity. activity is determined by the idle_time parameter. -+- */ -+- __le32 max_rest_time; -+- -+- /* -+- * time before sending next set of probe requests. -+- * The scanner keeps repeating probe requests transmission with -+- * period specified by repeat_probe_time. -+- * The number of probe requests specified depends on the ssid_list -+- * and bssid_list -+- */ -+- __le32 repeat_probe_time; -+- -+- /* time in msec between 2 consequetive probe requests with in a set. */ -+- __le32 probe_spacing_time; -+- -+- /* -+- * data inactivity time in msec on bss channel that will be used by -+- * scanner for measuring the inactivity. -++struct wmi_start_scan_tlvs { -++ /* TLV parameters. These includes channel list, ssid list, bssid list, -++ * extra ies. -+ */ -+- __le32 idle_time; -+- -+- /* maximum time in msec allowed for scan */ -+- __le32 max_scan_time; -+- -+- /* -+- * delay in msec before sending first probe request after switching -+- * to a channel -+- */ -+- __le32 probe_delay; -+- -+- /* Scan control flags */ -+- __le32 scan_ctrl_flags; -++ u8 tlvs[0]; -++} __packed; -+ -+- /* -+- * TLV (tag length value ) paramerters follow the scan_cmd structure. -+- * TLV can contain channel list, bssid list, ssid list and -+- * ie. the TLV tags are defined above; -+- */ -++struct wmi_start_scan_cmd { -++ struct wmi_start_scan_common common; -++ __le32 burst_duration_ms; -++ struct wmi_start_scan_tlvs tlvs; -+ } __packed; -+ -++/* This is the definition from 10.X firmware branch */ -++struct wmi_10x_start_scan_cmd { -++ struct wmi_start_scan_common common; -++ struct wmi_start_scan_tlvs tlvs; -++} __packed; -+ -+ struct wmi_ssid_arg { -+ int len; -+@@ -1821,7 +2173,7 @@ struct wmi_start_scan_arg { -+ u32 n_bssids; -+ -+ u8 ie[WLAN_SCAN_PARAMS_MAX_IE_LEN]; -+- u32 channels[64]; -++ u16 channels[64]; -+ struct wmi_ssid_arg ssids[WLAN_SCAN_PARAMS_MAX_SSID]; -+ struct wmi_bssid_arg bssids[WLAN_SCAN_PARAMS_MAX_BSSID]; -+ }; -+@@ -1849,7 +2201,6 @@ struct wmi_start_scan_arg { -+ /* WMI_SCAN_CLASS_MASK must be the same value as IEEE80211_SCAN_CLASS_MASK */ -+ #define WMI_SCAN_CLASS_MASK 0xFF000000 -+ -+- -+ enum wmi_stop_scan_type { -+ WMI_SCAN_STOP_ONE = 0x00000000, /* stop by scan_id */ -+ WMI_SCAN_STOP_VDEV_ALL = 0x01000000, /* stop by vdev_id */ -+@@ -1973,100 +2324,31 @@ struct wmi_mgmt_rx_event_v2 { -+ #define PHY_ERROR_FALSE_RADAR_EXT 0x24 -+ #define PHY_ERROR_RADAR 0x05 -+ -+-struct wmi_single_phyerr_rx_hdr { -+- /* TSF timestamp */ -++struct wmi_phyerr { -+ __le32 tsf_timestamp; -+- -+- /* -+- * Current freq1, freq2 -+- * -+- * [7:0]: freq1[lo] -+- * [15:8] : freq1[hi] -+- * [23:16]: freq2[lo] -+- * [31:24]: freq2[hi] -+- */ -+ __le16 freq1; -+ __le16 freq2; -+- -+- /* -+- * Combined RSSI over all chains and channel width for this PHY error -+- * -+- * [7:0]: RSSI combined -+- * [15:8]: Channel width (MHz) -+- * [23:16]: PHY error code -+- * [24:16]: reserved (future use) -+- */ -+ u8 rssi_combined; -+ u8 chan_width_mhz; -+ u8 phy_err_code; -+ u8 rsvd0; -+- -+- /* -+- * RSSI on chain 0 through 3 -+- * -+- * This is formatted the same as the PPDU_START RX descriptor -+- * field: -+- * -+- * [7:0]: pri20 -+- * [15:8]: sec20 -+- * [23:16]: sec40 -+- * [31:24]: sec80 -+- */ -+- -+- __le32 rssi_chain0; -+- __le32 rssi_chain1; -+- __le32 rssi_chain2; -+- __le32 rssi_chain3; -+- -+- /* -+- * Last calibrated NF value for chain 0 through 3 -+- * -+- * nf_list_1: -+- * -+- * + [15:0] - chain 0 -+- * + [31:16] - chain 1 -+- * -+- * nf_list_2: -+- * -+- * + [15:0] - chain 2 -+- * + [31:16] - chain 3 -+- */ -+- __le32 nf_list_1; -+- __le32 nf_list_2; -+- -+- -+- /* Length of the frame */ -++ __le32 rssi_chains[4]; -++ __le16 nf_chains[4]; -+ __le32 buf_len; -++ u8 buf[0]; -+ } __packed; -+ -+-struct wmi_single_phyerr_rx_event { -+- /* Phy error event header */ -+- struct wmi_single_phyerr_rx_hdr hdr; -+- /* frame buffer */ -+- u8 bufp[0]; -+-} __packed; -+- -+-struct wmi_comb_phyerr_rx_hdr { -+- /* Phy error phy error count */ -+- __le32 num_phyerr_events; -++struct wmi_phyerr_event { -++ __le32 num_phyerrs; -+ __le32 tsf_l32; -+ __le32 tsf_u32; -+-} __packed; -+- -+-struct wmi_comb_phyerr_rx_event { -+- /* Phy error phy error count */ -+- struct wmi_comb_phyerr_rx_hdr hdr; -+- /* -+- * frame buffer - contains multiple payloads in the order: -+- * header - payload, header - payload... -+- * (The header is of type: wmi_single_phyerr_rx_hdr) -+- */ -+- u8 bufp[0]; -++ struct wmi_phyerr phyerrs[0]; -+ } __packed; -+ -+ #define PHYERR_TLV_SIG 0xBB -+ #define PHYERR_TLV_TAG_SEARCH_FFT_REPORT 0xFB -+ #define PHYERR_TLV_TAG_RADAR_PULSE_SUMMARY 0xF8 -++#define PHYERR_TLV_TAG_SPECTRAL_SUMMARY_REPORT 0xF9 -+ -+ struct phyerr_radar_report { -+ __le32 reg0; /* RADAR_REPORT_REG0_* */ -+@@ -2135,7 +2417,6 @@ struct phyerr_fft_report { -+ #define SEARCH_FFT_REPORT_REG1_NUM_STR_BINS_IB_MASK 0x000000FF -+ #define SEARCH_FFT_REPORT_REG1_NUM_STR_BINS_IB_LSB 0 -+ -+- -+ struct phyerr_tlv { -+ __le16 len; -+ u8 tag; -+@@ -2166,7 +2447,6 @@ struct wmi_echo_cmd { -+ __le32 value; -+ } __packed; -+ -+- -+ struct wmi_pdev_set_regdomain_cmd { -+ __le32 reg_domain; -+ __le32 reg_domain_2G; -+@@ -2215,7 +2495,6 @@ struct wmi_pdev_set_quiet_cmd { -+ __le32 enabled; -+ } __packed; -+ -+- -+ /* -+ * 802.11g protection mode. -+ */ -+@@ -2318,14 +2597,15 @@ struct wmi_pdev_param_map { -+ u32 fast_channel_reset; -+ u32 burst_dur; -+ u32 burst_enable; -++ u32 cal_period; -+ }; -+ -+ #define WMI_PDEV_PARAM_UNSUPPORTED 0 -+ -+ enum wmi_pdev_param { -+- /* TX chian mask */ -++ /* TX chain mask */ -+ WMI_PDEV_PARAM_TX_CHAIN_MASK = 0x1, -+- /* RX chian mask */ -++ /* RX chain mask */ -+ WMI_PDEV_PARAM_RX_CHAIN_MASK, -+ /* TX power limit for 2G Radio */ -+ WMI_PDEV_PARAM_TXPOWER_LIMIT2G, -+@@ -2515,6 +2795,22 @@ enum wmi_10x_pdev_param { -+ WMI_10X_PDEV_PARAM_BURST_DUR, -+ /* Set Bursting Enable*/ -+ WMI_10X_PDEV_PARAM_BURST_ENABLE, -++ -++ /* following are available as of firmware 10.2 */ -++ WMI_10X_PDEV_PARAM_SMART_ANTENNA_DEFAULT_ANTENNA, -++ WMI_10X_PDEV_PARAM_IGMPMLD_OVERRIDE, -++ WMI_10X_PDEV_PARAM_IGMPMLD_TID, -++ WMI_10X_PDEV_PARAM_ANTENNA_GAIN, -++ WMI_10X_PDEV_PARAM_RX_DECAP_MODE, -++ WMI_10X_PDEV_PARAM_RX_FILTER, -++ WMI_10X_PDEV_PARAM_SET_MCAST_TO_UCAST_TID, -++ WMI_10X_PDEV_PARAM_PROXY_STA_MODE, -++ WMI_10X_PDEV_PARAM_SET_MCAST2UCAST_MODE, -++ WMI_10X_PDEV_PARAM_SET_MCAST2UCAST_BUFFER, -++ WMI_10X_PDEV_PARAM_REMOVE_MCAST2UCAST_BUFFER, -++ WMI_10X_PDEV_PARAM_PEER_STA_PS_STATECHG_ENABLE, -++ WMI_10X_PDEV_PARAM_RTS_FIXED_RATE, -++ WMI_10X_PDEV_PARAM_CAL_PERIOD -+ }; -+ -+ struct wmi_pdev_set_param_cmd { -+@@ -2522,6 +2818,9 @@ struct wmi_pdev_set_param_cmd { -+ __le32 param_value; -+ } __packed; -+ -++/* valid period is 1 ~ 60000ms, unit in millisecond */ -++#define WMI_PDEV_PARAM_CAL_PERIOD_MAX 60000 -++ -+ struct wmi_pdev_get_tpc_config_cmd { -+ /* parameter */ -+ __le32 param; -+@@ -2565,11 +2864,6 @@ enum wmi_tp_scale { -+ WMI_TP_SCALE_SIZE = 5, /* max num of enum */ -+ }; -+ -+-struct wmi_set_channel_cmd { -+- /* channel (only frequency and mode info are used) */ -+- struct wmi_channel chan; -+-} __packed; -+- -+ struct wmi_pdev_chanlist_update_event { -+ /* number of channels */ -+ __le32 num_chan; -+@@ -2600,6 +2894,10 @@ struct wmi_pdev_set_channel_cmd { -+ struct wmi_channel chan; -+ } __packed; -+ -++struct wmi_pdev_pktlog_enable_cmd { -++ __le32 ev_bitmap; -++} __packed; -++ -+ /* Customize the DSCP (bit) to TID (0-7) mapping for QOS */ -+ #define WMI_DSCP_MAP_MAX (64) -+ struct wmi_pdev_set_dscp_tid_map_cmd { -+@@ -2642,14 +2940,14 @@ struct wmi_wmm_params_arg { -+ u32 no_ack; -+ }; -+ -+-struct wmi_pdev_set_wmm_params_arg { -++struct wmi_wmm_params_all_arg { -+ struct wmi_wmm_params_arg ac_be; -+ struct wmi_wmm_params_arg ac_bk; -+ struct wmi_wmm_params_arg ac_vi; -+ struct wmi_wmm_params_arg ac_vo; -+ }; -+ -+-struct wal_dbg_tx_stats { -++struct wmi_pdev_stats_tx { -+ /* Num HTT cookies queued to dispatch list */ -+ __le32 comp_queued; -+ -+@@ -2719,7 +3017,7 @@ struct wal_dbg_tx_stats { -+ __le32 txop_ovf; -+ } __packed; -+ -+-struct wal_dbg_rx_stats { -++struct wmi_pdev_stats_rx { -+ /* Cnts any change in ring routing mid-ppdu */ -+ __le32 mid_ppdu_route_change; -+ -+@@ -2753,20 +3051,18 @@ struct wal_dbg_rx_stats { -+ __le32 mpdu_errs; -+ } __packed; -+ -+-struct wal_dbg_peer_stats { -++struct wmi_pdev_stats_peer { -+ /* REMOVE THIS ONCE REAL PEER STAT COUNTERS ARE ADDED */ -+ __le32 dummy; -+ } __packed; -+ -+-struct wal_dbg_stats { -+- struct wal_dbg_tx_stats tx; -+- struct wal_dbg_rx_stats rx; -+- struct wal_dbg_peer_stats peer; -+-} __packed; -+- -+ enum wmi_stats_id { -+- WMI_REQUEST_PEER_STAT = 0x01, -+- WMI_REQUEST_AP_STAT = 0x02 -++ WMI_STAT_PEER = BIT(0), -++ WMI_STAT_AP = BIT(1), -++ WMI_STAT_PDEV = BIT(2), -++ WMI_STAT_VDEV = BIT(3), -++ WMI_STAT_BCNFLT = BIT(4), -++ WMI_STAT_VDEV_RATE = BIT(5), -+ }; -+ -+ struct wlan_inst_rssi_args { -+@@ -2801,7 +3097,7 @@ struct wmi_pdev_suspend_cmd { -+ } __packed; -+ -+ struct wmi_stats_event { -+- __le32 stats_id; /* %WMI_REQUEST_ */ -++ __le32 stats_id; /* WMI_STAT_ */ -+ /* -+ * number of pdev stats event structures -+ * (wmi_pdev_stats) 0 or 1 -+@@ -2830,30 +3126,38 @@ struct wmi_stats_event { -+ u8 data[0]; -+ } __packed; -+ -++struct wmi_10_2_stats_event { -++ __le32 stats_id; /* %WMI_REQUEST_ */ -++ __le32 num_pdev_stats; -++ __le32 num_pdev_ext_stats; -++ __le32 num_vdev_stats; -++ __le32 num_peer_stats; -++ __le32 num_bcnflt_stats; -++ u8 data[0]; -++} __packed; -++ -+ /* -+ * PDEV statistics -+ * TODO: add all PDEV stats here -+ */ -+-struct wmi_pdev_stats_old { -+- __le32 chan_nf; /* Channel noise floor */ -+- __le32 tx_frame_count; /* TX frame count */ -+- __le32 rx_frame_count; /* RX frame count */ -+- __le32 rx_clear_count; /* rx clear count */ -+- __le32 cycle_count; /* cycle count */ -+- __le32 phy_err_count; /* Phy error count */ -+- __le32 chan_tx_pwr; /* channel tx power */ -+- struct wal_dbg_stats wal; /* WAL dbg stats */ -+-} __packed; -+- -+-struct wmi_pdev_stats_10x { -+- __le32 chan_nf; /* Channel noise floor */ -+- __le32 tx_frame_count; /* TX frame count */ -+- __le32 rx_frame_count; /* RX frame count */ -+- __le32 rx_clear_count; /* rx clear count */ -+- __le32 cycle_count; /* cycle count */ -+- __le32 phy_err_count; /* Phy error count */ -+- __le32 chan_tx_pwr; /* channel tx power */ -+- struct wal_dbg_stats wal; /* WAL dbg stats */ -++struct wmi_pdev_stats_base { -++ __le32 chan_nf; -++ __le32 tx_frame_count; -++ __le32 rx_frame_count; -++ __le32 rx_clear_count; -++ __le32 cycle_count; -++ __le32 phy_err_count; -++ __le32 chan_tx_pwr; -++} __packed; -++ -++struct wmi_pdev_stats { -++ struct wmi_pdev_stats_base base; -++ struct wmi_pdev_stats_tx tx; -++ struct wmi_pdev_stats_rx rx; -++ struct wmi_pdev_stats_peer peer; -++} __packed; -++ -++struct wmi_pdev_stats_extra { -+ __le32 ack_rx_bad; -+ __le32 rts_bad; -+ __le32 rts_good; -+@@ -2862,6 +3166,30 @@ struct wmi_pdev_stats_10x { -+ __le32 mib_int_count; -+ } __packed; -+ -++struct wmi_10x_pdev_stats { -++ struct wmi_pdev_stats_base base; -++ struct wmi_pdev_stats_tx tx; -++ struct wmi_pdev_stats_rx rx; -++ struct wmi_pdev_stats_peer peer; -++ struct wmi_pdev_stats_extra extra; -++} __packed; -++ -++struct wmi_pdev_stats_mem { -++ __le32 dram_free; -++ __le32 iram_free; -++} __packed; -++ -++struct wmi_10_2_pdev_stats { -++ struct wmi_pdev_stats_base base; -++ struct wmi_pdev_stats_tx tx; -++ __le32 mc_drop; -++ struct wmi_pdev_stats_rx rx; -++ __le32 pdev_rx_timeout; -++ struct wmi_pdev_stats_mem mem; -++ struct wmi_pdev_stats_peer peer; -++ struct wmi_pdev_stats_extra extra; -++} __packed; -++ -+ /* -+ * VDEV statistics -+ * TODO: add all VDEV stats here -+@@ -2874,19 +3202,43 @@ struct wmi_vdev_stats { -+ * peer statistics. -+ * TODO: add more stats -+ */ -+-struct wmi_peer_stats_old { -++struct wmi_peer_stats { -+ struct wmi_mac_addr peer_macaddr; -+ __le32 peer_rssi; -+ __le32 peer_tx_rate; -+ } __packed; -+ -+-struct wmi_peer_stats_10x { -+- struct wmi_mac_addr peer_macaddr; -+- __le32 peer_rssi; -+- __le32 peer_tx_rate; -++struct wmi_10x_peer_stats { -++ struct wmi_peer_stats old; -+ __le32 peer_rx_rate; -+ } __packed; -+ -++struct wmi_10_2_peer_stats { -++ struct wmi_peer_stats old; -++ __le32 peer_rx_rate; -++ __le32 current_per; -++ __le32 retries; -++ __le32 tx_rate_count; -++ __le32 max_4ms_frame_len; -++ __le32 total_sub_frames; -++ __le32 tx_bytes; -++ __le32 num_pkt_loss_overflow[4]; -++ __le32 num_pkt_loss_excess_retry[4]; -++} __packed; -++ -++struct wmi_10_2_4_peer_stats { -++ struct wmi_10_2_peer_stats common; -++ __le32 unknown_value; /* FIXME: what is this word? */ -++} __packed; -++ -++struct wmi_10_2_pdev_ext_stats { -++ __le32 rx_rssi_comb; -++ __le32 rx_rssi[4]; -++ __le32 rx_mcs[10]; -++ __le32 tx_mcs[10]; -++ __le32 ack_rssi; -++} __packed; -++ -+ struct wmi_vdev_create_cmd { -+ __le32 vdev_id; -+ __le32 vdev_type; -+@@ -3387,8 +3739,21 @@ enum wmi_10x_vdev_param { -+ WMI_10X_VDEV_PARAM_ENABLE_RTSCTS, -+ -+ WMI_10X_VDEV_PARAM_AP_DETECT_OUT_OF_SYNC_SLEEPING_STA_TIME_SECS, -++ -++ /* following are available as of firmware 10.2 */ -++ WMI_10X_VDEV_PARAM_TX_ENCAP_TYPE, -++ WMI_10X_VDEV_PARAM_CABQ_MAXDUR, -++ WMI_10X_VDEV_PARAM_MFPTEST_SET, -++ WMI_10X_VDEV_PARAM_RTS_FIXED_RATE, -++ WMI_10X_VDEV_PARAM_VHT_SGIMASK, -++ WMI_10X_VDEV_PARAM_VHT80_RATEMASK, -+ }; -+ -++#define WMI_VDEV_PARAM_TXBF_SU_TX_BFEE BIT(0) -++#define WMI_VDEV_PARAM_TXBF_MU_TX_BFEE BIT(1) -++#define WMI_VDEV_PARAM_TXBF_SU_TX_BFER BIT(2) -++#define WMI_VDEV_PARAM_TXBF_MU_TX_BFER BIT(3) -++ -+ /* slot time long */ -+ #define WMI_VDEV_SLOT_TIME_LONG 0x1 -+ /* slot time short */ -+@@ -3444,6 +3809,98 @@ struct wmi_vdev_simple_event { -+ /* unsupported VDEV combination */ -+ #define WMI_INIFIED_VDEV_START_RESPONSE_NOT_SUPPORTED 0x2 -+ -++/* TODO: please add more comments if you have in-depth information */ -++struct wmi_vdev_spectral_conf_cmd { -++ __le32 vdev_id; -++ -++ /* number of fft samples to send (0 for infinite) */ -++ __le32 scan_count; -++ __le32 scan_period; -++ __le32 scan_priority; -++ -++ /* number of bins in the FFT: 2^(fft_size - bin_scale) */ -++ __le32 scan_fft_size; -++ __le32 scan_gc_ena; -++ __le32 scan_restart_ena; -++ __le32 scan_noise_floor_ref; -++ __le32 scan_init_delay; -++ __le32 scan_nb_tone_thr; -++ __le32 scan_str_bin_thr; -++ __le32 scan_wb_rpt_mode; -++ __le32 scan_rssi_rpt_mode; -++ __le32 scan_rssi_thr; -++ __le32 scan_pwr_format; -++ -++ /* rpt_mode: Format of FFT report to software for spectral scan -++ * triggered FFTs: -++ * 0: No FFT report (only spectral scan summary report) -++ * 1: 2-dword summary of metrics for each completed FFT + spectral -++ * scan summary report -++ * 2: 2-dword summary of metrics for each completed FFT + -++ * 1x- oversampled bins(in-band) per FFT + spectral scan summary -++ * report -++ * 3: 2-dword summary of metrics for each completed FFT + -++ * 2x- oversampled bins (all) per FFT + spectral scan summary -++ */ -++ __le32 scan_rpt_mode; -++ __le32 scan_bin_scale; -++ __le32 scan_dbm_adj; -++ __le32 scan_chn_mask; -++} __packed; -++ -++struct wmi_vdev_spectral_conf_arg { -++ u32 vdev_id; -++ u32 scan_count; -++ u32 scan_period; -++ u32 scan_priority; -++ u32 scan_fft_size; -++ u32 scan_gc_ena; -++ u32 scan_restart_ena; -++ u32 scan_noise_floor_ref; -++ u32 scan_init_delay; -++ u32 scan_nb_tone_thr; -++ u32 scan_str_bin_thr; -++ u32 scan_wb_rpt_mode; -++ u32 scan_rssi_rpt_mode; -++ u32 scan_rssi_thr; -++ u32 scan_pwr_format; -++ u32 scan_rpt_mode; -++ u32 scan_bin_scale; -++ u32 scan_dbm_adj; -++ u32 scan_chn_mask; -++}; -++ -++#define WMI_SPECTRAL_ENABLE_DEFAULT 0 -++#define WMI_SPECTRAL_COUNT_DEFAULT 0 -++#define WMI_SPECTRAL_PERIOD_DEFAULT 35 -++#define WMI_SPECTRAL_PRIORITY_DEFAULT 1 -++#define WMI_SPECTRAL_FFT_SIZE_DEFAULT 7 -++#define WMI_SPECTRAL_GC_ENA_DEFAULT 1 -++#define WMI_SPECTRAL_RESTART_ENA_DEFAULT 0 -++#define WMI_SPECTRAL_NOISE_FLOOR_REF_DEFAULT -96 -++#define WMI_SPECTRAL_INIT_DELAY_DEFAULT 80 -++#define WMI_SPECTRAL_NB_TONE_THR_DEFAULT 12 -++#define WMI_SPECTRAL_STR_BIN_THR_DEFAULT 8 -++#define WMI_SPECTRAL_WB_RPT_MODE_DEFAULT 0 -++#define WMI_SPECTRAL_RSSI_RPT_MODE_DEFAULT 0 -++#define WMI_SPECTRAL_RSSI_THR_DEFAULT 0xf0 -++#define WMI_SPECTRAL_PWR_FORMAT_DEFAULT 0 -++#define WMI_SPECTRAL_RPT_MODE_DEFAULT 2 -++#define WMI_SPECTRAL_BIN_SCALE_DEFAULT 1 -++#define WMI_SPECTRAL_DBM_ADJ_DEFAULT 1 -++#define WMI_SPECTRAL_CHN_MASK_DEFAULT 1 -++ -++struct wmi_vdev_spectral_enable_cmd { -++ __le32 vdev_id; -++ __le32 trigger_cmd; -++ __le32 enable_cmd; -++} __packed; -++ -++#define WMI_SPECTRAL_TRIGGER_CMD_TRIGGER 1 -++#define WMI_SPECTRAL_TRIGGER_CMD_CLEAR 2 -++#define WMI_SPECTRAL_ENABLE_CMD_ENABLE 1 -++#define WMI_SPECTRAL_ENABLE_CMD_DISABLE 2 -++ -+ /* Beacon processing related command and event structures */ -+ struct wmi_bcn_tx_hdr { -+ __le32 vdev_id; -+@@ -3470,6 +3927,11 @@ enum wmi_bcn_tx_ref_flags { -+ WMI_BCN_TX_REF_FLAG_DELIVER_CAB = 0x2, -+ }; -+ -++/* TODO: It is unclear why "no antenna" works while any other seemingly valid -++ * chainmask yields no beacons on the air at all. -++ */ -++#define WMI_BCN_TX_REF_DEF_ANTENNA 0 -++ -+ struct wmi_bcn_tx_ref_cmd { -+ __le32 vdev_id; -+ __le32 data_len; -+@@ -3481,6 +3943,8 @@ struct wmi_bcn_tx_ref_cmd { -+ __le32 frame_control; -+ /* to control CABQ traffic: WMI_BCN_TX_REF_FLAG_ */ -+ __le32 flags; -++ /* introduced in 10.2 */ -++ __le32 antenna_mask; -+ } __packed; -+ -+ /* Beacon filter */ -+@@ -3633,6 +4097,13 @@ enum wmi_sta_ps_param_pspoll_count { -+ * Values greater than 0 indicate the maximum numer of PS-Poll frames -+ * FW will send before waking up. -+ */ -++ -++ /* When u-APSD is enabled the firmware will be very reluctant to exit -++ * STA PS. This could result in very poor Rx performance with STA doing -++ * PS-Poll for each and every buffered frame. This value is a bit -++ * arbitrary. -++ */ -++ WMI_STA_PS_PSPOLL_COUNT_UAPSD = 3, -+ }; -+ -+ /* -+@@ -3658,6 +4129,30 @@ enum wmi_sta_ps_param_uapsd { -+ WMI_STA_PS_UAPSD_AC3_TRIGGER_EN = (1 << 7), -+ }; -+ -++#define WMI_STA_UAPSD_MAX_INTERVAL_MSEC UINT_MAX -++ -++struct wmi_sta_uapsd_auto_trig_param { -++ __le32 wmm_ac; -++ __le32 user_priority; -++ __le32 service_interval; -++ __le32 suspend_interval; -++ __le32 delay_interval; -++}; -++ -++struct wmi_sta_uapsd_auto_trig_cmd_fixed_param { -++ __le32 vdev_id; -++ struct wmi_mac_addr peer_macaddr; -++ __le32 num_ac; -++}; -++ -++struct wmi_sta_uapsd_auto_trig_arg { -++ u32 wmm_ac; -++ u32 user_priority; -++ u32 service_interval; -++ u32 suspend_interval; -++ u32 delay_interval; -++}; -++ -+ enum wmi_sta_powersave_param { -+ /* -+ * Controls how frames are retrievd from AP while STA is sleeping -+@@ -3823,7 +4318,7 @@ struct wmi_bcn_info { -+ -+ struct wmi_host_swba_event { -+ __le32 vdev_map; -+- struct wmi_bcn_info bcn_info[1]; -++ struct wmi_bcn_info bcn_info[0]; -+ } __packed; -+ -+ #define WMI_MAX_AP_VDEV 16 -+@@ -3833,7 +4328,6 @@ struct wmi_tbtt_offset_event { -+ __le32 tbttoffset_list[WMI_MAX_AP_VDEV]; -+ } __packed; -+ -+- -+ struct wmi_peer_create_cmd { -+ __le32 vdev_id; -+ struct wmi_mac_addr peer_macaddr; -+@@ -3951,7 +4445,8 @@ enum wmi_peer_param { -+ WMI_PEER_AUTHORIZE = 0x3, -+ WMI_PEER_CHAN_WIDTH = 0x4, -+ WMI_PEER_NSS = 0x5, -+- WMI_PEER_USE_4ADDR = 0x6 -++ WMI_PEER_USE_4ADDR = 0x6, -++ WMI_PEER_DUMMY_VAR = 0xff, /* dummy parameter for STA PS workaround */ -+ }; -+ -+ struct wmi_peer_set_param_cmd { -+@@ -4029,7 +4524,7 @@ struct wmi_peer_set_q_empty_callback_cmd -+ #define WMI_PEER_SPATIAL_MUX 0x00200000 -+ #define WMI_PEER_VHT 0x02000000 -+ #define WMI_PEER_80MHZ 0x04000000 -+-#define WMI_PEER_PMF 0x08000000 -++#define WMI_PEER_VHT_2G 0x08000000 -+ -+ /* -+ * Peer rate capabilities. -+@@ -4053,7 +4548,7 @@ struct wmi_peer_set_q_empty_callback_cmd -+ /* Maximum listen interval supported by hw in units of beacon interval */ -+ #define ATH10K_MAX_HW_LISTEN_INTERVAL 5 -+ -+-struct wmi_peer_assoc_complete_cmd { -++struct wmi_common_peer_assoc_complete_cmd { -+ struct wmi_mac_addr peer_macaddr; -+ __le32 vdev_id; -+ __le32 peer_new_assoc; /* 1=assoc, 0=reassoc */ -+@@ -4071,11 +4566,30 @@ struct wmi_peer_assoc_complete_cmd { -+ __le32 peer_vht_caps; -+ __le32 peer_phymode; -+ struct wmi_vht_rate_set peer_vht_rates; -++}; -++ -++struct wmi_main_peer_assoc_complete_cmd { -++ struct wmi_common_peer_assoc_complete_cmd cmd; -++ -+ /* HT Operation Element of the peer. Five bytes packed in 2 -+ * INT32 array and filled from lsb to msb. */ -+ __le32 peer_ht_info[2]; -+ } __packed; -+ -++struct wmi_10_1_peer_assoc_complete_cmd { -++ struct wmi_common_peer_assoc_complete_cmd cmd; -++} __packed; -++ -++#define WMI_PEER_ASSOC_INFO0_MAX_MCS_IDX_LSB 0 -++#define WMI_PEER_ASSOC_INFO0_MAX_MCS_IDX_MASK 0x0f -++#define WMI_PEER_ASSOC_INFO0_MAX_NSS_LSB 4 -++#define WMI_PEER_ASSOC_INFO0_MAX_NSS_MASK 0xf0 -++ -++struct wmi_10_2_peer_assoc_complete_cmd { -++ struct wmi_common_peer_assoc_complete_cmd cmd; -++ __le32 info0; /* WMI_PEER_ASSOC_INFO0_ */ -++} __packed; -++ -+ struct wmi_peer_assoc_complete_arg { -+ u8 addr[ETH_ALEN]; -+ u32 vdev_id; -+@@ -4161,6 +4675,11 @@ enum wmi_sta_keepalive_method { -+ WMI_STA_KEEPALIVE_METHOD_UNSOLICITATED_ARP_RESPONSE = 2, -+ }; -+ -++#define WMI_STA_KEEPALIVE_INTERVAL_DISABLE 0 -++ -++/* Firmware crashes if keepalive interval exceeds this limit */ -++#define WMI_STA_KEEPALIVE_INTERVAL_MAX_SECONDS 0xffff -++ -+ /* note: ip4 addresses are in network byte order, i.e. big endian */ -+ struct wmi_sta_keepalive_arp_resp { -+ __be32 src_ip4_addr; -+@@ -4176,6 +4695,16 @@ struct wmi_sta_keepalive_cmd { -+ struct wmi_sta_keepalive_arp_resp arp_resp; -+ } __packed; -+ -++struct wmi_sta_keepalive_arg { -++ u32 vdev_id; -++ u32 enabled; -++ u32 method; -++ u32 interval; -++ __be32 src_ip4_addr; -++ __be32 dest_ip4_addr; -++ const u8 dest_mac_addr[ETH_ALEN]; -++}; -++ -+ enum wmi_force_fw_hang_type { -+ WMI_FORCE_FW_HANG_ASSERT = 1, -+ WMI_FORCE_FW_HANG_NO_DETECT, -+@@ -4240,7 +4769,6 @@ struct wmi_dbglog_cfg_cmd { -+ __le32 config_valid; -+ } __packed; -+ -+-#define ATH10K_RTS_MAX 2347 -+ #define ATH10K_FRAGMT_THRESHOLD_MIN 540 -+ #define ATH10K_FRAGMT_THRESHOLD_MAX 2346 -+ -+@@ -4251,72 +4779,170 @@ struct wmi_dbglog_cfg_cmd { -+ /* By default disable power save for IBSS */ -+ #define ATH10K_DEFAULT_ATIM 0 -+ -++#define WMI_MAX_MEM_REQS 16 -++ -++struct wmi_scan_ev_arg { -++ __le32 event_type; /* %WMI_SCAN_EVENT_ */ -++ __le32 reason; /* %WMI_SCAN_REASON_ */ -++ __le32 channel_freq; /* only valid for WMI_SCAN_EVENT_FOREIGN_CHANNEL */ -++ __le32 scan_req_id; -++ __le32 scan_id; -++ __le32 vdev_id; -++}; -++ -++struct wmi_mgmt_rx_ev_arg { -++ __le32 channel; -++ __le32 snr; -++ __le32 rate; -++ __le32 phy_mode; -++ __le32 buf_len; -++ __le32 status; /* %WMI_RX_STATUS_ */ -++}; -++ -++struct wmi_ch_info_ev_arg { -++ __le32 err_code; -++ __le32 freq; -++ __le32 cmd_flags; -++ __le32 noise_floor; -++ __le32 rx_clear_count; -++ __le32 cycle_count; -++}; -++ -++struct wmi_vdev_start_ev_arg { -++ __le32 vdev_id; -++ __le32 req_id; -++ __le32 resp_type; /* %WMI_VDEV_RESP_ */ -++ __le32 status; -++}; -++ -++struct wmi_peer_kick_ev_arg { -++ const u8 *mac_addr; -++}; -++ -++struct wmi_swba_ev_arg { -++ __le32 vdev_map; -++ const struct wmi_tim_info *tim_info[WMI_MAX_AP_VDEV]; -++ const struct wmi_p2p_noa_info *noa_info[WMI_MAX_AP_VDEV]; -++}; -++ -++struct wmi_phyerr_ev_arg { -++ __le32 num_phyerrs; -++ __le32 tsf_l32; -++ __le32 tsf_u32; -++ __le32 buf_len; -++ const struct wmi_phyerr *phyerrs; -++}; -++ -++struct wmi_svc_rdy_ev_arg { -++ __le32 min_tx_power; -++ __le32 max_tx_power; -++ __le32 ht_cap; -++ __le32 vht_cap; -++ __le32 sw_ver0; -++ __le32 sw_ver1; -++ __le32 fw_build; -++ __le32 phy_capab; -++ __le32 num_rf_chains; -++ __le32 eeprom_rd; -++ __le32 num_mem_reqs; -++ const __le32 *service_map; -++ size_t service_map_len; -++ const struct wlan_host_mem_req *mem_reqs[WMI_MAX_MEM_REQS]; -++}; -++ -++struct wmi_rdy_ev_arg { -++ __le32 sw_version; -++ __le32 abi_version; -++ __le32 status; -++ const u8 *mac_addr; -++}; -++ -++struct wmi_pdev_temperature_event { -++ /* temperature value in Celcius degree */ -++ __le32 temperature; -++} __packed; -++ -+ struct ath10k; -+ struct ath10k_vif; -++struct ath10k_fw_stats_pdev; -++struct ath10k_fw_stats_peer; -+ -+ int ath10k_wmi_attach(struct ath10k *ar); -+ void ath10k_wmi_detach(struct ath10k *ar); -+ int ath10k_wmi_wait_for_service_ready(struct ath10k *ar); -+ int ath10k_wmi_wait_for_unified_ready(struct ath10k *ar); -+ -+-int ath10k_wmi_connect_htc_service(struct ath10k *ar); -+-int ath10k_wmi_pdev_set_channel(struct ath10k *ar, -+- const struct wmi_channel_arg *); -+-int ath10k_wmi_pdev_suspend_target(struct ath10k *ar, u32 suspend_opt); -+-int ath10k_wmi_pdev_resume_target(struct ath10k *ar); -+-int ath10k_wmi_pdev_set_regdomain(struct ath10k *ar, u16 rd, u16 rd2g, -+- u16 rd5g, u16 ctl2g, u16 ctl5g, -+- enum wmi_dfs_region dfs_reg); -+-int ath10k_wmi_pdev_set_param(struct ath10k *ar, u32 id, u32 value); -+-int ath10k_wmi_cmd_init(struct ath10k *ar); -+-int ath10k_wmi_start_scan(struct ath10k *ar, const struct wmi_start_scan_arg *); -++struct sk_buff *ath10k_wmi_alloc_skb(struct ath10k *ar, u32 len); -++int ath10k_wmi_connect(struct ath10k *ar); -++ -++struct sk_buff *ath10k_wmi_alloc_skb(struct ath10k *ar, u32 len); -++int ath10k_wmi_cmd_send(struct ath10k *ar, struct sk_buff *skb, u32 cmd_id); -++int ath10k_wmi_cmd_send_nowait(struct ath10k *ar, struct sk_buff *skb, -++ u32 cmd_id); -+ void ath10k_wmi_start_scan_init(struct ath10k *ar, struct wmi_start_scan_arg *); -+-int ath10k_wmi_stop_scan(struct ath10k *ar, -+- const struct wmi_stop_scan_arg *arg); -+-int ath10k_wmi_vdev_create(struct ath10k *ar, u32 vdev_id, -+- enum wmi_vdev_type type, -+- enum wmi_vdev_subtype subtype, -+- const u8 macaddr[ETH_ALEN]); -+-int ath10k_wmi_vdev_delete(struct ath10k *ar, u32 vdev_id); -+-int ath10k_wmi_vdev_start(struct ath10k *ar, -+- const struct wmi_vdev_start_request_arg *); -+-int ath10k_wmi_vdev_restart(struct ath10k *ar, -+- const struct wmi_vdev_start_request_arg *); -+-int ath10k_wmi_vdev_stop(struct ath10k *ar, u32 vdev_id); -+-int ath10k_wmi_vdev_up(struct ath10k *ar, u32 vdev_id, u32 aid, -+- const u8 *bssid); -+-int ath10k_wmi_vdev_down(struct ath10k *ar, u32 vdev_id); -+-int ath10k_wmi_vdev_set_param(struct ath10k *ar, u32 vdev_id, -+- u32 param_id, u32 param_value); -+-int ath10k_wmi_vdev_install_key(struct ath10k *ar, -+- const struct wmi_vdev_install_key_arg *arg); -+-int ath10k_wmi_peer_create(struct ath10k *ar, u32 vdev_id, -+- const u8 peer_addr[ETH_ALEN]); -+-int ath10k_wmi_peer_delete(struct ath10k *ar, u32 vdev_id, -+- const u8 peer_addr[ETH_ALEN]); -+-int ath10k_wmi_peer_flush(struct ath10k *ar, u32 vdev_id, -+- const u8 peer_addr[ETH_ALEN], u32 tid_bitmap); -+-int ath10k_wmi_peer_set_param(struct ath10k *ar, u32 vdev_id, -+- const u8 *peer_addr, -+- enum wmi_peer_param param_id, u32 param_value); -+-int ath10k_wmi_peer_assoc(struct ath10k *ar, -+- const struct wmi_peer_assoc_complete_arg *arg); -+-int ath10k_wmi_set_psmode(struct ath10k *ar, u32 vdev_id, -+- enum wmi_sta_ps_mode psmode); -+-int ath10k_wmi_set_sta_ps_param(struct ath10k *ar, u32 vdev_id, -+- enum wmi_sta_powersave_param param_id, -+- u32 value); -+-int ath10k_wmi_set_ap_ps_param(struct ath10k *ar, u32 vdev_id, const u8 *mac, -+- enum wmi_ap_ps_peer_param param_id, u32 value); -+-int ath10k_wmi_scan_chan_list(struct ath10k *ar, -+- const struct wmi_scan_chan_list_arg *arg); -+-int ath10k_wmi_beacon_send_ref_nowait(struct ath10k_vif *arvif); -+-int ath10k_wmi_pdev_set_wmm_params(struct ath10k *ar, -+- const struct wmi_pdev_set_wmm_params_arg *arg); -+-int ath10k_wmi_request_stats(struct ath10k *ar, enum wmi_stats_id stats_id); -+-int ath10k_wmi_force_fw_hang(struct ath10k *ar, -+- enum wmi_force_fw_hang_type type, u32 delay_ms); -+-int ath10k_wmi_mgmt_tx(struct ath10k *ar, struct sk_buff *skb); -+-int ath10k_wmi_dbglog_cfg(struct ath10k *ar, u32 module_enable); -++ -++void ath10k_wmi_pull_pdev_stats_base(const struct wmi_pdev_stats_base *src, -++ struct ath10k_fw_stats_pdev *dst); -++void ath10k_wmi_pull_pdev_stats_tx(const struct wmi_pdev_stats_tx *src, -++ struct ath10k_fw_stats_pdev *dst); -++void ath10k_wmi_pull_pdev_stats_rx(const struct wmi_pdev_stats_rx *src, -++ struct ath10k_fw_stats_pdev *dst); -++void ath10k_wmi_pull_pdev_stats_extra(const struct wmi_pdev_stats_extra *src, -++ struct ath10k_fw_stats_pdev *dst); -++void ath10k_wmi_pull_peer_stats(const struct wmi_peer_stats *src, -++ struct ath10k_fw_stats_peer *dst); -++void ath10k_wmi_put_host_mem_chunks(struct ath10k *ar, -++ struct wmi_host_mem_chunks *chunks); -++void ath10k_wmi_put_start_scan_common(struct wmi_start_scan_common *cmn, -++ const struct wmi_start_scan_arg *arg); -++void ath10k_wmi_set_wmm_param(struct wmi_wmm_params *params, -++ const struct wmi_wmm_params_arg *arg); -++void ath10k_wmi_put_wmi_channel(struct wmi_channel *ch, -++ const struct wmi_channel_arg *arg); -++int ath10k_wmi_start_scan_verify(const struct wmi_start_scan_arg *arg); -++ -++int ath10k_wmi_event_scan(struct ath10k *ar, struct sk_buff *skb); -++int ath10k_wmi_event_mgmt_rx(struct ath10k *ar, struct sk_buff *skb); -++void ath10k_wmi_event_chan_info(struct ath10k *ar, struct sk_buff *skb); -++void ath10k_wmi_event_echo(struct ath10k *ar, struct sk_buff *skb); -++int ath10k_wmi_event_debug_mesg(struct ath10k *ar, struct sk_buff *skb); -++void ath10k_wmi_event_update_stats(struct ath10k *ar, struct sk_buff *skb); -++void ath10k_wmi_event_vdev_start_resp(struct ath10k *ar, struct sk_buff *skb); -++void ath10k_wmi_event_vdev_stopped(struct ath10k *ar, struct sk_buff *skb); -++void ath10k_wmi_event_peer_sta_kickout(struct ath10k *ar, struct sk_buff *skb); -++void ath10k_wmi_event_host_swba(struct ath10k *ar, struct sk_buff *skb); -++void ath10k_wmi_event_tbttoffset_update(struct ath10k *ar, struct sk_buff *skb); -++void ath10k_wmi_event_dfs(struct ath10k *ar, -++ const struct wmi_phyerr *phyerr, u64 tsf); -++void ath10k_wmi_event_spectral_scan(struct ath10k *ar, -++ const struct wmi_phyerr *phyerr, -++ u64 tsf); -++void ath10k_wmi_event_phyerr(struct ath10k *ar, struct sk_buff *skb); -++void ath10k_wmi_event_roam(struct ath10k *ar, struct sk_buff *skb); -++void ath10k_wmi_event_profile_match(struct ath10k *ar, struct sk_buff *skb); -++void ath10k_wmi_event_debug_print(struct ath10k *ar, struct sk_buff *skb); -++void ath10k_wmi_event_pdev_qvit(struct ath10k *ar, struct sk_buff *skb); -++void ath10k_wmi_event_wlan_profile_data(struct ath10k *ar, struct sk_buff *skb); -++void ath10k_wmi_event_rtt_measurement_report(struct ath10k *ar, -++ struct sk_buff *skb); -++void ath10k_wmi_event_tsf_measurement_report(struct ath10k *ar, -++ struct sk_buff *skb); -++void ath10k_wmi_event_rtt_error_report(struct ath10k *ar, struct sk_buff *skb); -++void ath10k_wmi_event_wow_wakeup_host(struct ath10k *ar, struct sk_buff *skb); -++void ath10k_wmi_event_dcs_interference(struct ath10k *ar, struct sk_buff *skb); -++void ath10k_wmi_event_pdev_tpc_config(struct ath10k *ar, struct sk_buff *skb); -++void ath10k_wmi_event_pdev_ftm_intg(struct ath10k *ar, struct sk_buff *skb); -++void ath10k_wmi_event_gtk_offload_status(struct ath10k *ar, -++ struct sk_buff *skb); -++void ath10k_wmi_event_gtk_rekey_fail(struct ath10k *ar, struct sk_buff *skb); -++void ath10k_wmi_event_delba_complete(struct ath10k *ar, struct sk_buff *skb); -++void ath10k_wmi_event_addba_complete(struct ath10k *ar, struct sk_buff *skb); -++void ath10k_wmi_event_vdev_install_key_complete(struct ath10k *ar, -++ struct sk_buff *skb); -++void ath10k_wmi_event_inst_rssi_stats(struct ath10k *ar, struct sk_buff *skb); -++void ath10k_wmi_event_vdev_standby_req(struct ath10k *ar, struct sk_buff *skb); -++void ath10k_wmi_event_vdev_resume_req(struct ath10k *ar, struct sk_buff *skb); -++void ath10k_wmi_event_service_ready(struct ath10k *ar, struct sk_buff *skb); -++int ath10k_wmi_event_ready(struct ath10k *ar, struct sk_buff *skb); -+ -+ #endif /* _WMI_H_ */ -+--- /dev/null -++++ b/drivers/net/wireless/ath/ath10k/spectral.c -+@@ -0,0 +1,552 @@ -++/* -++ * Copyright (c) 2013 Qualcomm Atheros, Inc. -++ * -++ * Permission to use, copy, modify, and/or distribute this software for any -++ * purpose with or without fee is hereby granted, provided that the above -++ * copyright notice and this permission notice appear in all copies. -++ * -++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -++ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -++ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -++ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -++ */ -++ -++#include -++#include "core.h" -++#include "debug.h" -++#include "wmi-ops.h" -++ -++static void send_fft_sample(struct ath10k *ar, -++ const struct fft_sample_tlv *fft_sample_tlv) -++{ -++ int length; -++ -++ if (!ar->spectral.rfs_chan_spec_scan) -++ return; -++ -++ length = __be16_to_cpu(fft_sample_tlv->length) + -++ sizeof(*fft_sample_tlv); -++ relay_write(ar->spectral.rfs_chan_spec_scan, fft_sample_tlv, length); -++} -++ -++static uint8_t get_max_exp(s8 max_index, u16 max_magnitude, size_t bin_len, -++ u8 *data) -++{ -++ int dc_pos; -++ u8 max_exp; -++ -++ dc_pos = bin_len / 2; -++ -++ /* peak index outside of bins */ -++ if (dc_pos < max_index || -dc_pos >= max_index) -++ return 0; -++ -++ for (max_exp = 0; max_exp < 8; max_exp++) { -++ if (data[dc_pos + max_index] == (max_magnitude >> max_exp)) -++ break; -++ } -++ -++ /* max_exp not found */ -++ if (data[dc_pos + max_index] != (max_magnitude >> max_exp)) -++ return 0; -++ -++ return max_exp; -++} -++ -++int ath10k_spectral_process_fft(struct ath10k *ar, -++ const struct wmi_phyerr *phyerr, -++ const struct phyerr_fft_report *fftr, -++ size_t bin_len, u64 tsf) -++{ -++ struct fft_sample_ath10k *fft_sample; -++ u8 buf[sizeof(*fft_sample) + SPECTRAL_ATH10K_MAX_NUM_BINS]; -++ u16 freq1, freq2, total_gain_db, base_pwr_db, length, peak_mag; -++ u32 reg0, reg1; -++ u8 chain_idx, *bins; -++ int dc_pos; -++ -++ fft_sample = (struct fft_sample_ath10k *)&buf; -++ -++ if (bin_len < 64 || bin_len > SPECTRAL_ATH10K_MAX_NUM_BINS) -++ return -EINVAL; -++ -++ reg0 = __le32_to_cpu(fftr->reg0); -++ reg1 = __le32_to_cpu(fftr->reg1); -++ -++ length = sizeof(*fft_sample) - sizeof(struct fft_sample_tlv) + bin_len; -++ fft_sample->tlv.type = ATH_FFT_SAMPLE_ATH10K; -++ fft_sample->tlv.length = __cpu_to_be16(length); -++ -++ /* TODO: there might be a reason why the hardware reports 20/40/80 MHz, -++ * but the results/plots suggest that its actually 22/44/88 MHz. -++ */ -++ switch (phyerr->chan_width_mhz) { -++ case 20: -++ fft_sample->chan_width_mhz = 22; -++ break; -++ case 40: -++ fft_sample->chan_width_mhz = 44; -++ break; -++ case 80: -++ /* TODO: As experiments with an analogue sender and various -++ * configuaritions (fft-sizes of 64/128/256 and 20/40/80 Mhz) -++ * show, the particular configuration of 80 MHz/64 bins does -++ * not match with the other smaples at all. Until the reason -++ * for that is found, don't report these samples. -++ */ -++ if (bin_len == 64) -++ return -EINVAL; -++ fft_sample->chan_width_mhz = 88; -++ break; -++ default: -++ fft_sample->chan_width_mhz = phyerr->chan_width_mhz; -++ } -++ -++ fft_sample->relpwr_db = MS(reg1, SEARCH_FFT_REPORT_REG1_RELPWR_DB); -++ fft_sample->avgpwr_db = MS(reg1, SEARCH_FFT_REPORT_REG1_AVGPWR_DB); -++ -++ peak_mag = MS(reg1, SEARCH_FFT_REPORT_REG1_PEAK_MAG); -++ fft_sample->max_magnitude = __cpu_to_be16(peak_mag); -++ fft_sample->max_index = MS(reg0, SEARCH_FFT_REPORT_REG0_PEAK_SIDX); -++ fft_sample->rssi = phyerr->rssi_combined; -++ -++ total_gain_db = MS(reg0, SEARCH_FFT_REPORT_REG0_TOTAL_GAIN_DB); -++ base_pwr_db = MS(reg0, SEARCH_FFT_REPORT_REG0_BASE_PWR_DB); -++ fft_sample->total_gain_db = __cpu_to_be16(total_gain_db); -++ fft_sample->base_pwr_db = __cpu_to_be16(base_pwr_db); -++ -++ freq1 = __le16_to_cpu(phyerr->freq1); -++ freq2 = __le16_to_cpu(phyerr->freq2); -++ fft_sample->freq1 = __cpu_to_be16(freq1); -++ fft_sample->freq2 = __cpu_to_be16(freq2); -++ -++ chain_idx = MS(reg0, SEARCH_FFT_REPORT_REG0_FFT_CHN_IDX); -++ -++ fft_sample->noise = __cpu_to_be16( -++ __le16_to_cpu(phyerr->nf_chains[chain_idx])); -++ -++ bins = (u8 *)fftr; -++ bins += sizeof(*fftr); -++ -++ fft_sample->tsf = __cpu_to_be64(tsf); -++ -++ /* max_exp has been directly reported by previous hardware (ath9k), -++ * maybe its possible to get it by other means? -++ */ -++ fft_sample->max_exp = get_max_exp(fft_sample->max_index, peak_mag, -++ bin_len, bins); -++ -++ memcpy(fft_sample->data, bins, bin_len); -++ -++ /* DC value (value in the middle) is the blind spot of the spectral -++ * sample and invalid, interpolate it. -++ */ -++ dc_pos = bin_len / 2; -++ fft_sample->data[dc_pos] = (fft_sample->data[dc_pos + 1] + -++ fft_sample->data[dc_pos - 1]) / 2; -++ -++ send_fft_sample(ar, &fft_sample->tlv); -++ -++ return 0; -++} -++ -++static struct ath10k_vif *ath10k_get_spectral_vdev(struct ath10k *ar) -++{ -++ struct ath10k_vif *arvif; -++ -++ lockdep_assert_held(&ar->conf_mutex); -++ -++ if (list_empty(&ar->arvifs)) -++ return NULL; -++ -++ /* if there already is a vif doing spectral, return that. */ -++ list_for_each_entry(arvif, &ar->arvifs, list) -++ if (arvif->spectral_enabled) -++ return arvif; -++ -++ /* otherwise, return the first vif. */ -++ return list_first_entry(&ar->arvifs, typeof(*arvif), list); -++} -++ -++static int ath10k_spectral_scan_trigger(struct ath10k *ar) -++{ -++ struct ath10k_vif *arvif; -++ int res; -++ int vdev_id; -++ -++ lockdep_assert_held(&ar->conf_mutex); -++ -++ arvif = ath10k_get_spectral_vdev(ar); -++ if (!arvif) -++ return -ENODEV; -++ vdev_id = arvif->vdev_id; -++ -++ if (ar->spectral.mode == SPECTRAL_DISABLED) -++ return 0; -++ -++ res = ath10k_wmi_vdev_spectral_enable(ar, vdev_id, -++ WMI_SPECTRAL_TRIGGER_CMD_CLEAR, -++ WMI_SPECTRAL_ENABLE_CMD_ENABLE); -++ if (res < 0) -++ return res; -++ -++ res = ath10k_wmi_vdev_spectral_enable(ar, vdev_id, -++ WMI_SPECTRAL_TRIGGER_CMD_TRIGGER, -++ WMI_SPECTRAL_ENABLE_CMD_ENABLE); -++ if (res < 0) -++ return res; -++ -++ return 0; -++} -++ -++static int ath10k_spectral_scan_config(struct ath10k *ar, -++ enum ath10k_spectral_mode mode) -++{ -++ struct wmi_vdev_spectral_conf_arg arg; -++ struct ath10k_vif *arvif; -++ int vdev_id, count, res = 0; -++ -++ lockdep_assert_held(&ar->conf_mutex); -++ -++ arvif = ath10k_get_spectral_vdev(ar); -++ if (!arvif) -++ return -ENODEV; -++ -++ vdev_id = arvif->vdev_id; -++ -++ arvif->spectral_enabled = (mode != SPECTRAL_DISABLED); -++ ar->spectral.mode = mode; -++ -++ res = ath10k_wmi_vdev_spectral_enable(ar, vdev_id, -++ WMI_SPECTRAL_TRIGGER_CMD_CLEAR, -++ WMI_SPECTRAL_ENABLE_CMD_DISABLE); -++ if (res < 0) { -++ ath10k_warn(ar, "failed to enable spectral scan: %d\n", res); -++ return res; -++ } -++ -++ if (mode == SPECTRAL_DISABLED) -++ return 0; -++ -++ if (mode == SPECTRAL_BACKGROUND) -++ count = WMI_SPECTRAL_COUNT_DEFAULT; -++ else -++ count = max_t(u8, 1, ar->spectral.config.count); -++ -++ arg.vdev_id = vdev_id; -++ arg.scan_count = count; -++ arg.scan_period = WMI_SPECTRAL_PERIOD_DEFAULT; -++ arg.scan_priority = WMI_SPECTRAL_PRIORITY_DEFAULT; -++ arg.scan_fft_size = ar->spectral.config.fft_size; -++ arg.scan_gc_ena = WMI_SPECTRAL_GC_ENA_DEFAULT; -++ arg.scan_restart_ena = WMI_SPECTRAL_RESTART_ENA_DEFAULT; -++ arg.scan_noise_floor_ref = WMI_SPECTRAL_NOISE_FLOOR_REF_DEFAULT; -++ arg.scan_init_delay = WMI_SPECTRAL_INIT_DELAY_DEFAULT; -++ arg.scan_nb_tone_thr = WMI_SPECTRAL_NB_TONE_THR_DEFAULT; -++ arg.scan_str_bin_thr = WMI_SPECTRAL_STR_BIN_THR_DEFAULT; -++ arg.scan_wb_rpt_mode = WMI_SPECTRAL_WB_RPT_MODE_DEFAULT; -++ arg.scan_rssi_rpt_mode = WMI_SPECTRAL_RSSI_RPT_MODE_DEFAULT; -++ arg.scan_rssi_thr = WMI_SPECTRAL_RSSI_THR_DEFAULT; -++ arg.scan_pwr_format = WMI_SPECTRAL_PWR_FORMAT_DEFAULT; -++ arg.scan_rpt_mode = WMI_SPECTRAL_RPT_MODE_DEFAULT; -++ arg.scan_bin_scale = WMI_SPECTRAL_BIN_SCALE_DEFAULT; -++ arg.scan_dbm_adj = WMI_SPECTRAL_DBM_ADJ_DEFAULT; -++ arg.scan_chn_mask = WMI_SPECTRAL_CHN_MASK_DEFAULT; -++ -++ res = ath10k_wmi_vdev_spectral_conf(ar, &arg); -++ if (res < 0) { -++ ath10k_warn(ar, "failed to configure spectral scan: %d\n", res); -++ return res; -++ } -++ -++ return 0; -++} -++ -++static ssize_t read_file_spec_scan_ctl(struct file *file, char __user *user_buf, -++ size_t count, loff_t *ppos) -++{ -++ struct ath10k *ar = file->private_data; -++ char *mode = ""; -++ unsigned int len; -++ enum ath10k_spectral_mode spectral_mode; -++ -++ mutex_lock(&ar->conf_mutex); -++ spectral_mode = ar->spectral.mode; -++ mutex_unlock(&ar->conf_mutex); -++ -++ switch (spectral_mode) { -++ case SPECTRAL_DISABLED: -++ mode = "disable"; -++ break; -++ case SPECTRAL_BACKGROUND: -++ mode = "background"; -++ break; -++ case SPECTRAL_MANUAL: -++ mode = "manual"; -++ break; -++ } -++ -++ len = strlen(mode); -++ return simple_read_from_buffer(user_buf, count, ppos, mode, len); -++} -++ -++static ssize_t write_file_spec_scan_ctl(struct file *file, -++ const char __user *user_buf, -++ size_t count, loff_t *ppos) -++{ -++ struct ath10k *ar = file->private_data; -++ char buf[32]; -++ ssize_t len; -++ int res; -++ -++ len = min(count, sizeof(buf) - 1); -++ if (copy_from_user(buf, user_buf, len)) -++ return -EFAULT; -++ -++ buf[len] = '\0'; -++ -++ mutex_lock(&ar->conf_mutex); -++ -++ if (strncmp("trigger", buf, 7) == 0) { -++ if (ar->spectral.mode == SPECTRAL_MANUAL || -++ ar->spectral.mode == SPECTRAL_BACKGROUND) { -++ /* reset the configuration to adopt possibly changed -++ * debugfs parameters -++ */ -++ res = ath10k_spectral_scan_config(ar, -++ ar->spectral.mode); -++ if (res < 0) { -++ ath10k_warn(ar, "failed to reconfigure spectral scan: %d\n", -++ res); -++ } -++ res = ath10k_spectral_scan_trigger(ar); -++ if (res < 0) { -++ ath10k_warn(ar, "failed to trigger spectral scan: %d\n", -++ res); -++ } -++ } else { -++ res = -EINVAL; -++ } -++ } else if (strncmp("background", buf, 9) == 0) { -++ res = ath10k_spectral_scan_config(ar, SPECTRAL_BACKGROUND); -++ } else if (strncmp("manual", buf, 6) == 0) { -++ res = ath10k_spectral_scan_config(ar, SPECTRAL_MANUAL); -++ } else if (strncmp("disable", buf, 7) == 0) { -++ res = ath10k_spectral_scan_config(ar, SPECTRAL_DISABLED); -++ } else { -++ res = -EINVAL; -++ } -++ -++ mutex_unlock(&ar->conf_mutex); -++ -++ if (res < 0) -++ return res; -++ -++ return count; -++} -++ -++static const struct file_operations fops_spec_scan_ctl = { -++ .read = read_file_spec_scan_ctl, -++ .write = write_file_spec_scan_ctl, -++ .open = simple_open, -++ .owner = THIS_MODULE, -++ .llseek = default_llseek, -++}; -++ -++static ssize_t read_file_spectral_count(struct file *file, -++ char __user *user_buf, -++ size_t count, loff_t *ppos) -++{ -++ struct ath10k *ar = file->private_data; -++ char buf[32]; -++ unsigned int len; -++ u8 spectral_count; -++ -++ mutex_lock(&ar->conf_mutex); -++ spectral_count = ar->spectral.config.count; -++ mutex_unlock(&ar->conf_mutex); -++ -++ len = sprintf(buf, "%d\n", spectral_count); -++ return simple_read_from_buffer(user_buf, count, ppos, buf, len); -++} -++ -++static ssize_t write_file_spectral_count(struct file *file, -++ const char __user *user_buf, -++ size_t count, loff_t *ppos) -++{ -++ struct ath10k *ar = file->private_data; -++ unsigned long val; -++ char buf[32]; -++ ssize_t len; -++ -++ len = min(count, sizeof(buf) - 1); -++ if (copy_from_user(buf, user_buf, len)) -++ return -EFAULT; -++ -++ buf[len] = '\0'; -++ if (kstrtoul(buf, 0, &val)) -++ return -EINVAL; -++ -++ if (val < 0 || val > 255) -++ return -EINVAL; -++ -++ mutex_lock(&ar->conf_mutex); -++ ar->spectral.config.count = val; -++ mutex_unlock(&ar->conf_mutex); -++ -++ return count; -++} -++ -++static const struct file_operations fops_spectral_count = { -++ .read = read_file_spectral_count, -++ .write = write_file_spectral_count, -++ .open = simple_open, -++ .owner = THIS_MODULE, -++ .llseek = default_llseek, -++}; -++ -++static ssize_t read_file_spectral_bins(struct file *file, -++ char __user *user_buf, -++ size_t count, loff_t *ppos) -++{ -++ struct ath10k *ar = file->private_data; -++ char buf[32]; -++ unsigned int len, bins, fft_size, bin_scale; -++ -++ mutex_lock(&ar->conf_mutex); -++ -++ fft_size = ar->spectral.config.fft_size; -++ bin_scale = WMI_SPECTRAL_BIN_SCALE_DEFAULT; -++ bins = 1 << (fft_size - bin_scale); -++ -++ mutex_unlock(&ar->conf_mutex); -++ -++ len = sprintf(buf, "%d\n", bins); -++ return simple_read_from_buffer(user_buf, count, ppos, buf, len); -++} -++ -++static ssize_t write_file_spectral_bins(struct file *file, -++ const char __user *user_buf, -++ size_t count, loff_t *ppos) -++{ -++ struct ath10k *ar = file->private_data; -++ unsigned long val; -++ char buf[32]; -++ ssize_t len; -++ -++ len = min(count, sizeof(buf) - 1); -++ if (copy_from_user(buf, user_buf, len)) -++ return -EFAULT; -++ -++ buf[len] = '\0'; -++ if (kstrtoul(buf, 0, &val)) -++ return -EINVAL; -++ -++ if (val < 64 || val > SPECTRAL_ATH10K_MAX_NUM_BINS) -++ return -EINVAL; -++ -++ if (!is_power_of_2(val)) -++ return -EINVAL; -++ -++ mutex_lock(&ar->conf_mutex); -++ ar->spectral.config.fft_size = ilog2(val); -++ ar->spectral.config.fft_size += WMI_SPECTRAL_BIN_SCALE_DEFAULT; -++ mutex_unlock(&ar->conf_mutex); -++ -++ return count; -++} -++ -++static const struct file_operations fops_spectral_bins = { -++ .read = read_file_spectral_bins, -++ .write = write_file_spectral_bins, -++ .open = simple_open, -++ .owner = THIS_MODULE, -++ .llseek = default_llseek, -++}; -++ -++static struct dentry *create_buf_file_handler(const char *filename, -++ struct dentry *parent, -++#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,3,0)) -++ umode_t mode, -++#else -++ int mode, -++#endif -++ struct rchan_buf *buf, -++ int *is_global) -++{ -++ struct dentry *buf_file; -++ -++ buf_file = debugfs_create_file(filename, mode, parent, buf, -++ &relay_file_operations); -++ *is_global = 1; -++ return buf_file; -++} -++ -++static int remove_buf_file_handler(struct dentry *dentry) -++{ -++ debugfs_remove(dentry); -++ -++ return 0; -++} -++ -++static struct rchan_callbacks rfs_spec_scan_cb = { -++ .create_buf_file = create_buf_file_handler, -++ .remove_buf_file = remove_buf_file_handler, -++}; -++ -++int ath10k_spectral_start(struct ath10k *ar) -++{ -++ struct ath10k_vif *arvif; -++ -++ lockdep_assert_held(&ar->conf_mutex); -++ -++ list_for_each_entry(arvif, &ar->arvifs, list) -++ arvif->spectral_enabled = 0; -++ -++ ar->spectral.mode = SPECTRAL_DISABLED; -++ ar->spectral.config.count = WMI_SPECTRAL_COUNT_DEFAULT; -++ ar->spectral.config.fft_size = WMI_SPECTRAL_FFT_SIZE_DEFAULT; -++ -++ return 0; -++} -++ -++int ath10k_spectral_vif_stop(struct ath10k_vif *arvif) -++{ -++ if (!arvif->spectral_enabled) -++ return 0; -++ -++ return ath10k_spectral_scan_config(arvif->ar, SPECTRAL_DISABLED); -++} -++ -++int ath10k_spectral_create(struct ath10k *ar) -++{ -++ ar->spectral.rfs_chan_spec_scan = relay_open("spectral_scan", -++ ar->debug.debugfs_phy, -++ 1024, 256, -++ &rfs_spec_scan_cb, NULL); -++ debugfs_create_file("spectral_scan_ctl", -++ S_IRUSR | S_IWUSR, -++ ar->debug.debugfs_phy, ar, -++ &fops_spec_scan_ctl); -++ debugfs_create_file("spectral_count", -++ S_IRUSR | S_IWUSR, -++ ar->debug.debugfs_phy, ar, -++ &fops_spectral_count); -++ debugfs_create_file("spectral_bins", -++ S_IRUSR | S_IWUSR, -++ ar->debug.debugfs_phy, ar, -++ &fops_spectral_bins); -++ -++ return 0; -++} -++ -++void ath10k_spectral_destroy(struct ath10k *ar) -++{ -++ if (ar->spectral.rfs_chan_spec_scan) { -++ relay_close(ar->spectral.rfs_chan_spec_scan); -++ ar->spectral.rfs_chan_spec_scan = NULL; -++ } -++} -+--- /dev/null -++++ b/drivers/net/wireless/ath/ath10k/spectral.h -+@@ -0,0 +1,90 @@ -++/* -++ * Copyright (c) 2013 Qualcomm Atheros, Inc. -++ * -++ * Permission to use, copy, modify, and/or distribute this software for any -++ * purpose with or without fee is hereby granted, provided that the above -++ * copyright notice and this permission notice appear in all copies. -++ * -++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -++ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -++ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -++ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -++ */ -++ -++#ifndef SPECTRAL_H -++#define SPECTRAL_H -++ -++#include "../spectral_common.h" -++ -++/** -++ * struct ath10k_spec_scan - parameters for Atheros spectral scan -++ * -++ * @count: number of scan results requested for manual mode -++ * @fft_size: number of bins to be requested = 2^(fft_size - bin_scale) -++ */ -++struct ath10k_spec_scan { -++ u8 count; -++ u8 fft_size; -++}; -++ -++/* enum ath10k_spectral_mode: -++ * -++ * @SPECTRAL_DISABLED: spectral mode is disabled -++ * @SPECTRAL_BACKGROUND: hardware sends samples when it is not busy with -++ * something else. -++ * @SPECTRAL_MANUAL: spectral scan is enabled, triggering for samples -++ * is performed manually. -++ */ -++enum ath10k_spectral_mode { -++ SPECTRAL_DISABLED = 0, -++ SPECTRAL_BACKGROUND, -++ SPECTRAL_MANUAL, -++}; -++ -++#ifdef CPTCFG_ATH10K_DEBUGFS -++ -++int ath10k_spectral_process_fft(struct ath10k *ar, -++ const struct wmi_phyerr *phyerr, -++ const struct phyerr_fft_report *fftr, -++ size_t bin_len, u64 tsf); -++int ath10k_spectral_start(struct ath10k *ar); -++int ath10k_spectral_vif_stop(struct ath10k_vif *arvif); -++int ath10k_spectral_create(struct ath10k *ar); -++void ath10k_spectral_destroy(struct ath10k *ar); -++ -++#else -++ -++static inline int -++ath10k_spectral_process_fft(struct ath10k *ar, -++ const struct wmi_phyerr *phyerr, -++ const struct phyerr_fft_report *fftr, -++ size_t bin_len, u64 tsf) -++{ -++ return 0; -++} -++ -++static inline int ath10k_spectral_start(struct ath10k *ar) -++{ -++ return 0; -++} -++ -++static inline int ath10k_spectral_vif_stop(struct ath10k_vif *arvif) -++{ -++ return 0; -++} -++ -++static inline int ath10k_spectral_create(struct ath10k *ar) -++{ -++ return 0; -++} -++ -++static inline void ath10k_spectral_destroy(struct ath10k *ar) -++{ -++} -++ -++#endif /* CPTCFG_ATH10K_DEBUGFS */ -++ -++#endif /* SPECTRAL_H */ -+--- /dev/null -++++ b/drivers/net/wireless/ath/ath10k/testmode.c -+@@ -0,0 +1,385 @@ -++/* -++ * Copyright (c) 2014 Qualcomm Atheros, Inc. -++ * -++ * Permission to use, copy, modify, and/or distribute this software for any -++ * purpose with or without fee is hereby granted, provided that the above -++ * copyright notice and this permission notice appear in all copies. -++ * -++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -++ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -++ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -++ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -++ */ -++ -++#include "testmode.h" -++ -++#include -++#include -++ -++#include "debug.h" -++#include "wmi.h" -++#include "hif.h" -++#include "hw.h" -++ -++#include "testmode_i.h" -++ -++static const struct nla_policy ath10k_tm_policy[ATH10K_TM_ATTR_MAX + 1] = { -++ [ATH10K_TM_ATTR_CMD] = { .type = NLA_U32 }, -++ [ATH10K_TM_ATTR_DATA] = { .type = NLA_BINARY, -++ .len = ATH10K_TM_DATA_MAX_LEN }, -++ [ATH10K_TM_ATTR_WMI_CMDID] = { .type = NLA_U32 }, -++ [ATH10K_TM_ATTR_VERSION_MAJOR] = { .type = NLA_U32 }, -++ [ATH10K_TM_ATTR_VERSION_MINOR] = { .type = NLA_U32 }, -++}; -++ -++/* Returns true if callee consumes the skb and the skb should be discarded. -++ * Returns false if skb is not used. Does not sleep. -++ */ -++bool ath10k_tm_event_wmi(struct ath10k *ar, u32 cmd_id, struct sk_buff *skb) -++{ -++ struct sk_buff *nl_skb; -++ bool consumed; -++ int ret; -++ -++ ath10k_dbg(ar, ATH10K_DBG_TESTMODE, -++ "testmode event wmi cmd_id %d skb %p skb->len %d\n", -++ cmd_id, skb, skb->len); -++ -++ ath10k_dbg_dump(ar, ATH10K_DBG_TESTMODE, NULL, "", skb->data, skb->len); -++ -++ spin_lock_bh(&ar->data_lock); -++ -++ if (!ar->testmode.utf_monitor) { -++ consumed = false; -++ goto out; -++ } -++ -++ /* Only testmode.c should be handling events from utf firmware, -++ * otherwise all sort of problems will arise as mac80211 operations -++ * are not initialised. -++ */ -++ consumed = true; -++ -++ nl_skb = cfg80211_testmode_alloc_event_skb(ar->hw->wiphy, -++ 2 * sizeof(u32) + skb->len, -++ GFP_ATOMIC); -++ if (!nl_skb) { -++ ath10k_warn(ar, -++ "failed to allocate skb for testmode wmi event\n"); -++ goto out; -++ } -++ -++ ret = nla_put_u32(nl_skb, ATH10K_TM_ATTR_CMD, ATH10K_TM_CMD_WMI); -++ if (ret) { -++ ath10k_warn(ar, -++ "failed to to put testmode wmi event cmd attribute: %d\n", -++ ret); -++ kfree_skb(nl_skb); -++ goto out; -++ } -++ -++ ret = nla_put_u32(nl_skb, ATH10K_TM_ATTR_WMI_CMDID, cmd_id); -++ if (ret) { -++ ath10k_warn(ar, -++ "failed to to put testmode wmi even cmd_id: %d\n", -++ ret); -++ kfree_skb(nl_skb); -++ goto out; -++ } -++ -++ ret = nla_put(nl_skb, ATH10K_TM_ATTR_DATA, skb->len, skb->data); -++ if (ret) { -++ ath10k_warn(ar, -++ "failed to copy skb to testmode wmi event: %d\n", -++ ret); -++ kfree_skb(nl_skb); -++ goto out; -++ } -++ -++ cfg80211_testmode_event(nl_skb, GFP_ATOMIC); -++ -++out: -++ spin_unlock_bh(&ar->data_lock); -++ -++ return consumed; -++} -++ -++static int ath10k_tm_cmd_get_version(struct ath10k *ar, struct nlattr *tb[]) -++{ -++ struct sk_buff *skb; -++ int ret; -++ -++ ath10k_dbg(ar, ATH10K_DBG_TESTMODE, -++ "testmode cmd get version_major %d version_minor %d\n", -++ ATH10K_TESTMODE_VERSION_MAJOR, -++ ATH10K_TESTMODE_VERSION_MINOR); -++ -++ skb = cfg80211_testmode_alloc_reply_skb(ar->hw->wiphy, -++ nla_total_size(sizeof(u32))); -++ if (!skb) -++ return -ENOMEM; -++ -++ ret = nla_put_u32(skb, ATH10K_TM_ATTR_VERSION_MAJOR, -++ ATH10K_TESTMODE_VERSION_MAJOR); -++ if (ret) { -++ kfree_skb(skb); -++ return ret; -++ } -++ -++ ret = nla_put_u32(skb, ATH10K_TM_ATTR_VERSION_MINOR, -++ ATH10K_TESTMODE_VERSION_MINOR); -++ if (ret) { -++ kfree_skb(skb); -++ return ret; -++ } -++ -++ return cfg80211_testmode_reply(skb); -++} -++ -++static int ath10k_tm_cmd_utf_start(struct ath10k *ar, struct nlattr *tb[]) -++{ -++ char filename[100]; -++ int ret; -++ -++ ath10k_dbg(ar, ATH10K_DBG_TESTMODE, "testmode cmd utf start\n"); -++ -++ mutex_lock(&ar->conf_mutex); -++ -++ if (ar->state == ATH10K_STATE_UTF) { -++ ret = -EALREADY; -++ goto err; -++ } -++ -++ /* start utf only when the driver is not in use */ -++ if (ar->state != ATH10K_STATE_OFF) { -++ ret = -EBUSY; -++ goto err; -++ } -++ -++ if (WARN_ON(ar->testmode.utf != NULL)) { -++ /* utf image is already downloaded, it shouldn't be */ -++ ret = -EEXIST; -++ goto err; -++ } -++ -++ snprintf(filename, sizeof(filename), "%s/%s", -++ ar->hw_params.fw.dir, ATH10K_FW_UTF_FILE); -++ -++ /* load utf firmware image */ -++ ret = request_firmware(&ar->testmode.utf, filename, ar->dev); -++ if (ret) { -++ ath10k_warn(ar, "failed to retrieve utf firmware '%s': %d\n", -++ filename, ret); -++ goto err; -++ } -++ -++ spin_lock_bh(&ar->data_lock); -++ -++ ar->testmode.utf_monitor = true; -++ -++ spin_unlock_bh(&ar->data_lock); -++ -++ BUILD_BUG_ON(sizeof(ar->fw_features) != -++ sizeof(ar->testmode.orig_fw_features)); -++ -++ memcpy(ar->testmode.orig_fw_features, ar->fw_features, -++ sizeof(ar->fw_features)); -++ ar->testmode.orig_wmi_op_version = ar->wmi.op_version; -++ -++ /* utf.bin firmware image does not advertise firmware features. Do -++ * an ugly hack where we force the firmware features so that wmi.c -++ * will use the correct WMI interface. -++ */ -++ memset(ar->fw_features, 0, sizeof(ar->fw_features)); -++ ar->wmi.op_version = ATH10K_FW_WMI_OP_VERSION_10_1; -++ -++ ret = ath10k_hif_power_up(ar); -++ if (ret) { -++ ath10k_err(ar, "failed to power up hif (testmode): %d\n", ret); -++ ar->state = ATH10K_STATE_OFF; -++ goto err_fw_features; -++ } -++ -++ ret = ath10k_core_start(ar, ATH10K_FIRMWARE_MODE_UTF); -++ if (ret) { -++ ath10k_err(ar, "failed to start core (testmode): %d\n", ret); -++ ar->state = ATH10K_STATE_OFF; -++ goto err_power_down; -++ } -++ -++ ar->state = ATH10K_STATE_UTF; -++ -++ ath10k_info(ar, "UTF firmware started\n"); -++ -++ mutex_unlock(&ar->conf_mutex); -++ -++ return 0; -++ -++err_power_down: -++ ath10k_hif_power_down(ar); -++ -++err_fw_features: -++ /* return the original firmware features */ -++ memcpy(ar->fw_features, ar->testmode.orig_fw_features, -++ sizeof(ar->fw_features)); -++ ar->wmi.op_version = ar->testmode.orig_wmi_op_version; -++ -++ release_firmware(ar->testmode.utf); -++ ar->testmode.utf = NULL; -++ -++err: -++ mutex_unlock(&ar->conf_mutex); -++ -++ return ret; -++} -++ -++static void __ath10k_tm_cmd_utf_stop(struct ath10k *ar) -++{ -++ lockdep_assert_held(&ar->conf_mutex); -++ -++ ath10k_core_stop(ar); -++ ath10k_hif_power_down(ar); -++ -++ spin_lock_bh(&ar->data_lock); -++ -++ ar->testmode.utf_monitor = false; -++ -++ spin_unlock_bh(&ar->data_lock); -++ -++ /* return the original firmware features */ -++ memcpy(ar->fw_features, ar->testmode.orig_fw_features, -++ sizeof(ar->fw_features)); -++ ar->wmi.op_version = ar->testmode.orig_wmi_op_version; -++ -++ release_firmware(ar->testmode.utf); -++ ar->testmode.utf = NULL; -++ -++ ar->state = ATH10K_STATE_OFF; -++} -++ -++static int ath10k_tm_cmd_utf_stop(struct ath10k *ar, struct nlattr *tb[]) -++{ -++ int ret; -++ -++ ath10k_dbg(ar, ATH10K_DBG_TESTMODE, "testmode cmd utf stop\n"); -++ -++ mutex_lock(&ar->conf_mutex); -++ -++ if (ar->state != ATH10K_STATE_UTF) { -++ ret = -ENETDOWN; -++ goto out; -++ } -++ -++ __ath10k_tm_cmd_utf_stop(ar); -++ -++ ret = 0; -++ -++ ath10k_info(ar, "UTF firmware stopped\n"); -++ -++out: -++ mutex_unlock(&ar->conf_mutex); -++ return ret; -++} -++ -++static int ath10k_tm_cmd_wmi(struct ath10k *ar, struct nlattr *tb[]) -++{ -++ struct sk_buff *skb; -++ int ret, buf_len; -++ u32 cmd_id; -++ void *buf; -++ -++ mutex_lock(&ar->conf_mutex); -++ -++ if (ar->state != ATH10K_STATE_UTF) { -++ ret = -ENETDOWN; -++ goto out; -++ } -++ -++ if (!tb[ATH10K_TM_ATTR_DATA]) { -++ ret = -EINVAL; -++ goto out; -++ } -++ -++ if (!tb[ATH10K_TM_ATTR_WMI_CMDID]) { -++ ret = -EINVAL; -++ goto out; -++ } -++ -++ buf = nla_data(tb[ATH10K_TM_ATTR_DATA]); -++ buf_len = nla_len(tb[ATH10K_TM_ATTR_DATA]); -++ cmd_id = nla_get_u32(tb[ATH10K_TM_ATTR_WMI_CMDID]); -++ -++ ath10k_dbg(ar, ATH10K_DBG_TESTMODE, -++ "testmode cmd wmi cmd_id %d buf %p buf_len %d\n", -++ cmd_id, buf, buf_len); -++ -++ ath10k_dbg_dump(ar, ATH10K_DBG_TESTMODE, NULL, "", buf, buf_len); -++ -++ skb = ath10k_wmi_alloc_skb(ar, buf_len); -++ if (!skb) { -++ ret = -ENOMEM; -++ goto out; -++ } -++ -++ memcpy(skb->data, buf, buf_len); -++ -++ ret = ath10k_wmi_cmd_send(ar, skb, cmd_id); -++ if (ret) { -++ ath10k_warn(ar, "failed to transmit wmi command (testmode): %d\n", -++ ret); -++ goto out; -++ } -++ -++ ret = 0; -++ -++out: -++ mutex_unlock(&ar->conf_mutex); -++ return ret; -++} -++ -++int ath10k_tm_cmd(struct ieee80211_hw *hw, struct ieee80211_vif *vif, -++ void *data, int len) -++{ -++ struct ath10k *ar = hw->priv; -++ struct nlattr *tb[ATH10K_TM_ATTR_MAX + 1]; -++ int ret; -++ -++ ret = nla_parse(tb, ATH10K_TM_ATTR_MAX, data, len, -++ ath10k_tm_policy); -++ if (ret) -++ return ret; -++ -++ if (!tb[ATH10K_TM_ATTR_CMD]) -++ return -EINVAL; -++ -++ switch (nla_get_u32(tb[ATH10K_TM_ATTR_CMD])) { -++ case ATH10K_TM_CMD_GET_VERSION: -++ return ath10k_tm_cmd_get_version(ar, tb); -++ case ATH10K_TM_CMD_UTF_START: -++ return ath10k_tm_cmd_utf_start(ar, tb); -++ case ATH10K_TM_CMD_UTF_STOP: -++ return ath10k_tm_cmd_utf_stop(ar, tb); -++ case ATH10K_TM_CMD_WMI: -++ return ath10k_tm_cmd_wmi(ar, tb); -++ default: -++ return -EOPNOTSUPP; -++ } -++} -++ -++void ath10k_testmode_destroy(struct ath10k *ar) -++{ -++ mutex_lock(&ar->conf_mutex); -++ -++ if (ar->state != ATH10K_STATE_UTF) { -++ /* utf firmware is not running, nothing to do */ -++ goto out; -++ } -++ -++ __ath10k_tm_cmd_utf_stop(ar); -++ -++out: -++ mutex_unlock(&ar->conf_mutex); -++} -+--- /dev/null -++++ b/drivers/net/wireless/ath/ath10k/testmode.h -+@@ -0,0 +1,46 @@ -++/* -++ * Copyright (c) 2014 Qualcomm Atheros, Inc. -++ * -++ * Permission to use, copy, modify, and/or distribute this software for any -++ * purpose with or without fee is hereby granted, provided that the above -++ * copyright notice and this permission notice appear in all copies. -++ * -++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -++ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -++ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -++ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -++ */ -++ -++#include "core.h" -++ -++#ifdef CPTCFG_NL80211_TESTMODE -++ -++void ath10k_testmode_destroy(struct ath10k *ar); -++ -++bool ath10k_tm_event_wmi(struct ath10k *ar, u32 cmd_id, struct sk_buff *skb); -++int ath10k_tm_cmd(struct ieee80211_hw *hw, struct ieee80211_vif *vif, -++ void *data, int len); -++ -++#else -++ -++static inline void ath10k_testmode_destroy(struct ath10k *ar) -++{ -++} -++ -++static inline bool ath10k_tm_event_wmi(struct ath10k *ar, u32 cmd_id, -++ struct sk_buff *skb) -++{ -++ return false; -++} -++ -++static inline int ath10k_tm_cmd(struct ieee80211_hw *hw, -++ struct ieee80211_vif *vif, -++ void *data, int len) -++{ -++ return 0; -++} -++ -++#endif -+--- /dev/null -++++ b/drivers/net/wireless/ath/ath10k/testmode_i.h -+@@ -0,0 +1,70 @@ -++/* -++ * Copyright (c) 2014 Qualcomm Atheros, Inc. -++ * -++ * Permission to use, copy, modify, and/or distribute this software for any -++ * purpose with or without fee is hereby granted, provided that the above -++ * copyright notice and this permission notice appear in all copies. -++ * -++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -++ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -++ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -++ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -++ */ -++ -++/* "API" level of the ath10k testmode interface. Bump it after every -++ * incompatible interface change. -++ */ -++#define ATH10K_TESTMODE_VERSION_MAJOR 1 -++ -++/* Bump this after every _compatible_ interface change, for example -++ * addition of a new command or an attribute. -++ */ -++#define ATH10K_TESTMODE_VERSION_MINOR 0 -++ -++#define ATH10K_TM_DATA_MAX_LEN 5000 -++ -++enum ath10k_tm_attr { -++ __ATH10K_TM_ATTR_INVALID = 0, -++ ATH10K_TM_ATTR_CMD = 1, -++ ATH10K_TM_ATTR_DATA = 2, -++ ATH10K_TM_ATTR_WMI_CMDID = 3, -++ ATH10K_TM_ATTR_VERSION_MAJOR = 4, -++ ATH10K_TM_ATTR_VERSION_MINOR = 5, -++ -++ /* keep last */ -++ __ATH10K_TM_ATTR_AFTER_LAST, -++ ATH10K_TM_ATTR_MAX = __ATH10K_TM_ATTR_AFTER_LAST - 1, -++}; -++ -++/* All ath10k testmode interface commands specified in -++ * ATH10K_TM_ATTR_CMD -++ */ -++enum ath10k_tm_cmd { -++ /* Returns the supported ath10k testmode interface version in -++ * ATH10K_TM_ATTR_VERSION. Always guaranteed to work. User space -++ * uses this to verify it's using the correct version of the -++ * testmode interface -++ */ -++ ATH10K_TM_CMD_GET_VERSION = 0, -++ -++ /* Boots the UTF firmware, the netdev interface must be down at the -++ * time. -++ */ -++ ATH10K_TM_CMD_UTF_START = 1, -++ -++ /* Shuts down the UTF firmware and puts the driver back into OFF -++ * state. -++ */ -++ ATH10K_TM_CMD_UTF_STOP = 2, -++ -++ /* The command used to transmit a WMI command to the firmware and -++ * the event to receive WMI events from the firmware. Without -++ * struct wmi_cmd_hdr header, only the WMI payload. Command id is -++ * provided with ATH10K_TM_ATTR_WMI_CMDID and payload in -++ * ATH10K_TM_ATTR_DATA. -++ */ -++ ATH10K_TM_CMD_WMI = 3, -++}; -+--- /dev/null -++++ b/drivers/net/wireless/ath/ath10k/debugfs_sta.c -+@@ -0,0 +1,243 @@ -++/* -++ * Copyright (c) 2014 Qualcomm Atheros, Inc. -++ * -++ * Permission to use, copy, modify, and/or distribute this software for any -++ * purpose with or without fee is hereby granted, provided that the above -++ * copyright notice and this permission notice appear in all copies. -++ * -++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -++ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -++ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -++ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -++ */ -++ -++#include "core.h" -++#include "wmi-ops.h" -++#include "debug.h" -++ -++static ssize_t ath10k_dbg_sta_read_aggr_mode(struct file *file, -++ char __user *user_buf, -++ size_t count, loff_t *ppos) -++{ -++ struct ieee80211_sta *sta = file->private_data; -++ struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv; -++ struct ath10k *ar = arsta->arvif->ar; -++ char buf[32]; -++ int len = 0; -++ -++ mutex_lock(&ar->conf_mutex); -++ len = scnprintf(buf, sizeof(buf) - len, "aggregation mode: %s\n", -++ (arsta->aggr_mode == ATH10K_DBG_AGGR_MODE_AUTO) ? -++ "auto" : "manual"); -++ mutex_unlock(&ar->conf_mutex); -++ -++ return simple_read_from_buffer(user_buf, count, ppos, buf, len); -++} -++ -++static ssize_t ath10k_dbg_sta_write_aggr_mode(struct file *file, -++ const char __user *user_buf, -++ size_t count, loff_t *ppos) -++{ -++ struct ieee80211_sta *sta = file->private_data; -++ struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv; -++ struct ath10k *ar = arsta->arvif->ar; -++ u32 aggr_mode; -++ int ret; -++ -++ if (kstrtouint_from_user(user_buf, count, 0, &aggr_mode)) -++ return -EINVAL; -++ -++ if (aggr_mode >= ATH10K_DBG_AGGR_MODE_MAX) -++ return -EINVAL; -++ -++ mutex_lock(&ar->conf_mutex); -++ if ((ar->state != ATH10K_STATE_ON) || -++ (aggr_mode == arsta->aggr_mode)) { -++ ret = count; -++ goto out; -++ } -++ -++ ret = ath10k_wmi_addba_clear_resp(ar, arsta->arvif->vdev_id, sta->addr); -++ if (ret) { -++ ath10k_warn(ar, "failed to clear addba session ret: %d\n", ret); -++ goto out; -++ } -++ -++ arsta->aggr_mode = aggr_mode; -++out: -++ mutex_unlock(&ar->conf_mutex); -++ return ret; -++} -++ -++static const struct file_operations fops_aggr_mode = { -++ .read = ath10k_dbg_sta_read_aggr_mode, -++ .write = ath10k_dbg_sta_write_aggr_mode, -++ .open = simple_open, -++ .owner = THIS_MODULE, -++ .llseek = default_llseek, -++}; -++ -++static ssize_t ath10k_dbg_sta_write_addba(struct file *file, -++ const char __user *user_buf, -++ size_t count, loff_t *ppos) -++{ -++ struct ieee80211_sta *sta = file->private_data; -++ struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv; -++ struct ath10k *ar = arsta->arvif->ar; -++ u32 tid, buf_size; -++ int ret; -++ char buf[64]; -++ -++ simple_write_to_buffer(buf, sizeof(buf) - 1, ppos, user_buf, count); -++ -++ /* make sure that buf is null terminated */ -++ buf[sizeof(buf) - 1] = '\0'; -++ -++ ret = sscanf(buf, "%u %u", &tid, &buf_size); -++ if (ret != 2) -++ return -EINVAL; -++ -++ /* Valid TID values are 0 through 15 */ -++ if (tid > HTT_DATA_TX_EXT_TID_MGMT - 2) -++ return -EINVAL; -++ -++ mutex_lock(&ar->conf_mutex); -++ if ((ar->state != ATH10K_STATE_ON) || -++ (arsta->aggr_mode != ATH10K_DBG_AGGR_MODE_MANUAL)) { -++ ret = count; -++ goto out; -++ } -++ -++ ret = ath10k_wmi_addba_send(ar, arsta->arvif->vdev_id, sta->addr, -++ tid, buf_size); -++ if (ret) { -++ ath10k_warn(ar, "failed to send addba request: vdev_id %u peer %pM tid %u buf_size %u\n", -++ arsta->arvif->vdev_id, sta->addr, tid, buf_size); -++ } -++ -++ ret = count; -++out: -++ mutex_unlock(&ar->conf_mutex); -++ return ret; -++} -++ -++static const struct file_operations fops_addba = { -++ .write = ath10k_dbg_sta_write_addba, -++ .open = simple_open, -++ .owner = THIS_MODULE, -++ .llseek = default_llseek, -++}; -++ -++static ssize_t ath10k_dbg_sta_write_addba_resp(struct file *file, -++ const char __user *user_buf, -++ size_t count, loff_t *ppos) -++{ -++ struct ieee80211_sta *sta = file->private_data; -++ struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv; -++ struct ath10k *ar = arsta->arvif->ar; -++ u32 tid, status; -++ int ret; -++ char buf[64]; -++ -++ simple_write_to_buffer(buf, sizeof(buf) - 1, ppos, user_buf, count); -++ -++ /* make sure that buf is null terminated */ -++ buf[sizeof(buf) - 1] = '\0'; -++ -++ ret = sscanf(buf, "%u %u", &tid, &status); -++ if (ret != 2) -++ return -EINVAL; -++ -++ /* Valid TID values are 0 through 15 */ -++ if (tid > HTT_DATA_TX_EXT_TID_MGMT - 2) -++ return -EINVAL; -++ -++ mutex_lock(&ar->conf_mutex); -++ if ((ar->state != ATH10K_STATE_ON) || -++ (arsta->aggr_mode != ATH10K_DBG_AGGR_MODE_MANUAL)) { -++ ret = count; -++ goto out; -++ } -++ -++ ret = ath10k_wmi_addba_set_resp(ar, arsta->arvif->vdev_id, sta->addr, -++ tid, status); -++ if (ret) { -++ ath10k_warn(ar, "failed to send addba response: vdev_id %u peer %pM tid %u status%u\n", -++ arsta->arvif->vdev_id, sta->addr, tid, status); -++ } -++ ret = count; -++out: -++ mutex_unlock(&ar->conf_mutex); -++ return ret; -++} -++ -++static const struct file_operations fops_addba_resp = { -++ .write = ath10k_dbg_sta_write_addba_resp, -++ .open = simple_open, -++ .owner = THIS_MODULE, -++ .llseek = default_llseek, -++}; -++ -++static ssize_t ath10k_dbg_sta_write_delba(struct file *file, -++ const char __user *user_buf, -++ size_t count, loff_t *ppos) -++{ -++ struct ieee80211_sta *sta = file->private_data; -++ struct ath10k_sta *arsta = (struct ath10k_sta *)sta->drv_priv; -++ struct ath10k *ar = arsta->arvif->ar; -++ u32 tid, initiator, reason; -++ int ret; -++ char buf[64]; -++ -++ simple_write_to_buffer(buf, sizeof(buf) - 1, ppos, user_buf, count); -++ -++ /* make sure that buf is null terminated */ -++ buf[sizeof(buf) - 1] = '\0'; -++ -++ ret = sscanf(buf, "%u %u %u", &tid, &initiator, &reason); -++ if (ret != 3) -++ return -EINVAL; -++ -++ /* Valid TID values are 0 through 15 */ -++ if (tid > HTT_DATA_TX_EXT_TID_MGMT - 2) -++ return -EINVAL; -++ -++ mutex_lock(&ar->conf_mutex); -++ if ((ar->state != ATH10K_STATE_ON) || -++ (arsta->aggr_mode != ATH10K_DBG_AGGR_MODE_MANUAL)) { -++ ret = count; -++ goto out; -++ } -++ -++ ret = ath10k_wmi_delba_send(ar, arsta->arvif->vdev_id, sta->addr, -++ tid, initiator, reason); -++ if (ret) { -++ ath10k_warn(ar, "failed to send delba: vdev_id %u peer %pM tid %u initiator %u reason %u\n", -++ arsta->arvif->vdev_id, sta->addr, tid, initiator, -++ reason); -++ } -++ ret = count; -++out: -++ mutex_unlock(&ar->conf_mutex); -++ return ret; -++} -++ -++static const struct file_operations fops_delba = { -++ .write = ath10k_dbg_sta_write_delba, -++ .open = simple_open, -++ .owner = THIS_MODULE, -++ .llseek = default_llseek, -++}; -++ -++void ath10k_sta_add_debugfs(struct ieee80211_hw *hw, struct ieee80211_vif *vif, -++ struct ieee80211_sta *sta, struct dentry *dir) -++{ -++ debugfs_create_file("aggr_mode", S_IRUGO | S_IWUSR, dir, sta, -++ &fops_aggr_mode); -++ debugfs_create_file("addba", S_IWUSR, dir, sta, &fops_addba); -++ debugfs_create_file("addba_resp", S_IWUSR, dir, sta, &fops_addba_resp); -++ debugfs_create_file("delba", S_IWUSR, dir, sta, &fops_delba); -++} -+--- /dev/null -++++ b/drivers/net/wireless/ath/ath10k/hw.c -+@@ -0,0 +1,58 @@ -++/* -++ * Copyright (c) 2014-2015 Qualcomm Atheros, Inc. -++ * -++ * Permission to use, copy, modify, and/or distribute this software for any -++ * purpose with or without fee is hereby granted, provided that the above -++ * copyright notice and this permission notice appear in all copies. -++ * -++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -++ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -++ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -++ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -++ */ -++ -++#include -++#include "hw.h" -++ -++const struct ath10k_hw_regs qca988x_regs = { -++ .rtc_state_cold_reset_mask = 0x00000400, -++ .rtc_soc_base_address = 0x00004000, -++ .rtc_wmac_base_address = 0x00005000, -++ .soc_core_base_address = 0x00009000, -++ .ce_wrapper_base_address = 0x00057000, -++ .ce0_base_address = 0x00057400, -++ .ce1_base_address = 0x00057800, -++ .ce2_base_address = 0x00057c00, -++ .ce3_base_address = 0x00058000, -++ .ce4_base_address = 0x00058400, -++ .ce5_base_address = 0x00058800, -++ .ce6_base_address = 0x00058c00, -++ .ce7_base_address = 0x00059000, -++ .soc_reset_control_si0_rst_mask = 0x00000001, -++ .soc_reset_control_ce_rst_mask = 0x00040000, -++ .soc_chip_id_address = 0x00ec, -++ .scratch_3_address = 0x0030, -++}; -++ -++const struct ath10k_hw_regs qca6174_regs = { -++ .rtc_state_cold_reset_mask = 0x00002000, -++ .rtc_soc_base_address = 0x00000800, -++ .rtc_wmac_base_address = 0x00001000, -++ .soc_core_base_address = 0x0003a000, -++ .ce_wrapper_base_address = 0x00034000, -++ .ce0_base_address = 0x00034400, -++ .ce1_base_address = 0x00034800, -++ .ce2_base_address = 0x00034c00, -++ .ce3_base_address = 0x00035000, -++ .ce4_base_address = 0x00035400, -++ .ce5_base_address = 0x00035800, -++ .ce6_base_address = 0x00035c00, -++ .ce7_base_address = 0x00036000, -++ .soc_reset_control_si0_rst_mask = 0x00000000, -++ .soc_reset_control_ce_rst_mask = 0x00000001, -++ .soc_chip_id_address = 0x000f0, -++ .scratch_3_address = 0x0028, -++}; -+--- /dev/null -++++ b/drivers/net/wireless/ath/ath10k/thermal.c -+@@ -0,0 +1,244 @@ -++/* -++ * Copyright (c) 2014 Qualcomm Atheros, Inc. -++ * -++ * Permission to use, copy, modify, and/or distribute this software for any -++ * purpose with or without fee is hereby granted, provided that the above -++ * copyright notice and this permission notice appear in all copies. -++ * -++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -++ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -++ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -++ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -++ */ -++ -++#include -++#include -++#include -++#include -++#include -++#include "core.h" -++#include "debug.h" -++#include "wmi-ops.h" -++ -++static int ath10k_thermal_get_active_vifs(struct ath10k *ar, -++ enum wmi_vdev_type type) -++{ -++ struct ath10k_vif *arvif; -++ int count = 0; -++ -++ lockdep_assert_held(&ar->conf_mutex); -++ -++ list_for_each_entry(arvif, &ar->arvifs, list) { -++ if (!arvif->is_started) -++ continue; -++ -++ if (!arvif->is_up) -++ continue; -++ -++ if (arvif->vdev_type != type) -++ continue; -++ -++ count++; -++ } -++ return count; -++} -++ -++static int ath10k_thermal_get_max_dutycycle(struct thermal_cooling_device *cdev, -++ unsigned long *state) -++{ -++ *state = ATH10K_QUIET_DUTY_CYCLE_MAX; -++ -++ return 0; -++} -++ -++static int ath10k_thermal_get_cur_dutycycle(struct thermal_cooling_device *cdev, -++ unsigned long *state) -++{ -++ struct ath10k *ar = cdev->devdata; -++ -++ mutex_lock(&ar->conf_mutex); -++ *state = ar->thermal.duty_cycle; -++ mutex_unlock(&ar->conf_mutex); -++ -++ return 0; -++} -++ -++static int ath10k_thermal_set_cur_dutycycle(struct thermal_cooling_device *cdev, -++ unsigned long duty_cycle) -++{ -++ struct ath10k *ar = cdev->devdata; -++ u32 period, duration, enabled; -++ int num_bss, ret = 0; -++ -++ mutex_lock(&ar->conf_mutex); -++ if (ar->state != ATH10K_STATE_ON) { -++ ret = -ENETDOWN; -++ goto out; -++ } -++ -++ if (duty_cycle > ATH10K_QUIET_DUTY_CYCLE_MAX) { -++ ath10k_warn(ar, "duty cycle %ld is exceeding the limit %d\n", -++ duty_cycle, ATH10K_QUIET_DUTY_CYCLE_MAX); -++ ret = -EINVAL; -++ goto out; -++ } -++ /* TODO: Right now, thermal mitigation is handled only for single/multi -++ * vif AP mode. Since quiet param is not validated in STA mode, it needs -++ * to be investigated further to handle multi STA and multi-vif (AP+STA) -++ * mode properly. -++ */ -++ num_bss = ath10k_thermal_get_active_vifs(ar, WMI_VDEV_TYPE_AP); -++ if (!num_bss) { -++ ath10k_warn(ar, "no active AP interfaces\n"); -++ ret = -ENETDOWN; -++ goto out; -++ } -++ period = max(ATH10K_QUIET_PERIOD_MIN, -++ (ATH10K_QUIET_PERIOD_DEFAULT / num_bss)); -++ duration = (period * duty_cycle) / 100; -++ enabled = duration ? 1 : 0; -++ -++ ret = ath10k_wmi_pdev_set_quiet_mode(ar, period, duration, -++ ATH10K_QUIET_START_OFFSET, -++ enabled); -++ if (ret) { -++ ath10k_warn(ar, "failed to set quiet mode period %u duarion %u enabled %u ret %d\n", -++ period, duration, enabled, ret); -++ goto out; -++ } -++ ar->thermal.duty_cycle = duty_cycle; -++out: -++ mutex_unlock(&ar->conf_mutex); -++ return ret; -++} -++ -++static struct thermal_cooling_device_ops ath10k_thermal_ops = { -++ .get_max_state = ath10k_thermal_get_max_dutycycle, -++ .get_cur_state = ath10k_thermal_get_cur_dutycycle, -++ .set_cur_state = ath10k_thermal_set_cur_dutycycle, -++}; -++ -++static ssize_t ath10k_thermal_show_temp(struct device *dev, -++ struct device_attribute *attr, -++ char *buf) -++{ -++ struct ath10k *ar = dev_get_drvdata(dev); -++ int ret, temperature; -++ -++ mutex_lock(&ar->conf_mutex); -++ -++ /* Can't get temperature when the card is off */ -++ if (ar->state != ATH10K_STATE_ON) { -++ ret = -ENETDOWN; -++ goto out; -++ } -++ -++ reinit_completion(&ar->thermal.wmi_sync); -++ ret = ath10k_wmi_pdev_get_temperature(ar); -++ if (ret) { -++ ath10k_warn(ar, "failed to read temperature %d\n", ret); -++ goto out; -++ } -++ -++ if (test_bit(ATH10K_FLAG_CRASH_FLUSH, &ar->dev_flags)) { -++ ret = -ESHUTDOWN; -++ goto out; -++ } -++ -++ ret = wait_for_completion_timeout(&ar->thermal.wmi_sync, -++ ATH10K_THERMAL_SYNC_TIMEOUT_HZ); -++ if (ret == 0) { -++ ath10k_warn(ar, "failed to synchronize thermal read\n"); -++ ret = -ETIMEDOUT; -++ goto out; -++ } -++ -++ spin_lock_bh(&ar->data_lock); -++ temperature = ar->thermal.temperature; -++ spin_unlock_bh(&ar->data_lock); -++ -++ /* display in millidegree celcius */ -++ ret = snprintf(buf, PAGE_SIZE, "%d\n", temperature * 1000); -++out: -++ mutex_unlock(&ar->conf_mutex); -++ return ret; -++} -++ -++void ath10k_thermal_event_temperature(struct ath10k *ar, int temperature) -++{ -++ spin_lock_bh(&ar->data_lock); -++ ar->thermal.temperature = temperature; -++ spin_unlock_bh(&ar->data_lock); -++ complete(&ar->thermal.wmi_sync); -++} -++ -++static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, ath10k_thermal_show_temp, -++ NULL, 0); -++ -++static struct attribute *ath10k_hwmon_attrs[] = { -++ &sensor_dev_attr_temp1_input.dev_attr.attr, -++ NULL, -++}; -++ATTRIBUTE_GROUPS(ath10k_hwmon); -++ -++int ath10k_thermal_register(struct ath10k *ar) -++{ -++ struct thermal_cooling_device *cdev; -++ struct device *hwmon_dev; -++ int ret; -++ -++ cdev = thermal_cooling_device_register("ath10k_thermal", ar, -++ &ath10k_thermal_ops); -++ -++ if (IS_ERR(cdev)) { -++ ath10k_err(ar, "failed to setup thermal device result: %ld\n", -++ PTR_ERR(cdev)); -++ return -EINVAL; -++ } -++ -++ ret = sysfs_create_link(&ar->dev->kobj, &cdev->device.kobj, -++ "cooling_device"); -++ if (ret) { -++ ath10k_err(ar, "failed to create thermal symlink\n"); -++ goto err_cooling_destroy; -++ } -++ -++ ar->thermal.cdev = cdev; -++ -++ /* Do not register hwmon device when temperature reading is not -++ * supported by firmware -++ */ -++ if (ar->wmi.op_version != ATH10K_FW_WMI_OP_VERSION_10_2_4) -++ return 0; -++ -++ /* Avoid linking error on devm_hwmon_device_register_with_groups, I -++ * guess linux/hwmon.h is missing proper stubs. */ -++ if (!config_enabled(CPTCFG_HWMON)) -++ return 0; -++ -++ hwmon_dev = devm_hwmon_device_register_with_groups(ar->dev, -++ "ath10k_hwmon", ar, -++ ath10k_hwmon_groups); -++ if (IS_ERR(hwmon_dev)) { -++ ath10k_err(ar, "failed to register hwmon device: %ld\n", -++ PTR_ERR(hwmon_dev)); -++ ret = -EINVAL; -++ goto err_remove_link; -++ } -++ return 0; -++ -++err_remove_link: -++ sysfs_remove_link(&ar->dev->kobj, "thermal_sensor"); -++err_cooling_destroy: -++ thermal_cooling_device_unregister(cdev); -++ return ret; -++} -++ -++void ath10k_thermal_unregister(struct ath10k *ar) -++{ -++ thermal_cooling_device_unregister(ar->thermal.cdev); -++ sysfs_remove_link(&ar->dev->kobj, "cooling_device"); -++} -+--- /dev/null -++++ b/drivers/net/wireless/ath/ath10k/thermal.h -+@@ -0,0 +1,58 @@ -++/* -++ * Copyright (c) 2014 Qualcomm Atheros, Inc. -++ * -++ * Permission to use, copy, modify, and/or distribute this software for any -++ * purpose with or without fee is hereby granted, provided that the above -++ * copyright notice and this permission notice appear in all copies. -++ * -++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -++ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -++ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -++ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -++ */ -++#ifndef _THERMAL_ -++#define _THERMAL_ -++ -++#define ATH10K_QUIET_PERIOD_DEFAULT 100 -++#define ATH10K_QUIET_PERIOD_MIN 25 -++#define ATH10K_QUIET_START_OFFSET 10 -++#define ATH10K_QUIET_DUTY_CYCLE_MAX 70 -++#define ATH10K_HWMON_NAME_LEN 15 -++#define ATH10K_THERMAL_SYNC_TIMEOUT_HZ (5*HZ) -++ -++struct ath10k_thermal { -++ struct thermal_cooling_device *cdev; -++ struct completion wmi_sync; -++ -++ /* protected by conf_mutex */ -++ u32 duty_cycle; -++ /* temperature value in Celcius degree -++ * protected by data_lock -++ */ -++ int temperature; -++}; -++ -++#ifdef CONFIG_THERMAL -++int ath10k_thermal_register(struct ath10k *ar); -++void ath10k_thermal_unregister(struct ath10k *ar); -++void ath10k_thermal_event_temperature(struct ath10k *ar, int temperature); -++#else -++static inline int ath10k_thermal_register(struct ath10k *ar) -++{ -++ return 0; -++} -++ -++static inline void ath10k_thermal_unregister(struct ath10k *ar) -++{ -++} -++ -++static inline void ath10k_thermal_event_temperature(struct ath10k *ar, -++ int temperature) -++{ -++} -++ -++#endif -++#endif /* _THERMAL_ */ -+--- /dev/null -++++ b/drivers/net/wireless/ath/ath10k/wmi-ops.h -+@@ -0,0 +1,1063 @@ -++/* -++ * Copyright (c) 2005-2011 Atheros Communications Inc. -++ * Copyright (c) 2011-2014 Qualcomm Atheros, Inc. -++ * -++ * Permission to use, copy, modify, and/or distribute this software for any -++ * purpose with or without fee is hereby granted, provided that the above -++ * copyright notice and this permission notice appear in all copies. -++ * -++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -++ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -++ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -++ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -++ */ -++ -++#ifndef _WMI_OPS_H_ -++#define _WMI_OPS_H_ -++ -++struct ath10k; -++struct sk_buff; -++ -++struct wmi_ops { -++ void (*rx)(struct ath10k *ar, struct sk_buff *skb); -++ void (*map_svc)(const __le32 *in, unsigned long *out, size_t len); -++ -++ int (*pull_scan)(struct ath10k *ar, struct sk_buff *skb, -++ struct wmi_scan_ev_arg *arg); -++ int (*pull_mgmt_rx)(struct ath10k *ar, struct sk_buff *skb, -++ struct wmi_mgmt_rx_ev_arg *arg); -++ int (*pull_ch_info)(struct ath10k *ar, struct sk_buff *skb, -++ struct wmi_ch_info_ev_arg *arg); -++ int (*pull_vdev_start)(struct ath10k *ar, struct sk_buff *skb, -++ struct wmi_vdev_start_ev_arg *arg); -++ int (*pull_peer_kick)(struct ath10k *ar, struct sk_buff *skb, -++ struct wmi_peer_kick_ev_arg *arg); -++ int (*pull_swba)(struct ath10k *ar, struct sk_buff *skb, -++ struct wmi_swba_ev_arg *arg); -++ int (*pull_phyerr)(struct ath10k *ar, struct sk_buff *skb, -++ struct wmi_phyerr_ev_arg *arg); -++ int (*pull_svc_rdy)(struct ath10k *ar, struct sk_buff *skb, -++ struct wmi_svc_rdy_ev_arg *arg); -++ int (*pull_rdy)(struct ath10k *ar, struct sk_buff *skb, -++ struct wmi_rdy_ev_arg *arg); -++ int (*pull_fw_stats)(struct ath10k *ar, struct sk_buff *skb, -++ struct ath10k_fw_stats *stats); -++ -++ struct sk_buff *(*gen_pdev_suspend)(struct ath10k *ar, u32 suspend_opt); -++ struct sk_buff *(*gen_pdev_resume)(struct ath10k *ar); -++ struct sk_buff *(*gen_pdev_set_rd)(struct ath10k *ar, u16 rd, u16 rd2g, -++ u16 rd5g, u16 ctl2g, u16 ctl5g, -++ enum wmi_dfs_region dfs_reg); -++ struct sk_buff *(*gen_pdev_set_param)(struct ath10k *ar, u32 id, -++ u32 value); -++ struct sk_buff *(*gen_init)(struct ath10k *ar); -++ struct sk_buff *(*gen_start_scan)(struct ath10k *ar, -++ const struct wmi_start_scan_arg *arg); -++ struct sk_buff *(*gen_stop_scan)(struct ath10k *ar, -++ const struct wmi_stop_scan_arg *arg); -++ struct sk_buff *(*gen_vdev_create)(struct ath10k *ar, u32 vdev_id, -++ enum wmi_vdev_type type, -++ enum wmi_vdev_subtype subtype, -++ const u8 macaddr[ETH_ALEN]); -++ struct sk_buff *(*gen_vdev_delete)(struct ath10k *ar, u32 vdev_id); -++ struct sk_buff *(*gen_vdev_start)(struct ath10k *ar, -++ const struct wmi_vdev_start_request_arg *arg, -++ bool restart); -++ struct sk_buff *(*gen_vdev_stop)(struct ath10k *ar, u32 vdev_id); -++ struct sk_buff *(*gen_vdev_up)(struct ath10k *ar, u32 vdev_id, u32 aid, -++ const u8 *bssid); -++ struct sk_buff *(*gen_vdev_down)(struct ath10k *ar, u32 vdev_id); -++ struct sk_buff *(*gen_vdev_set_param)(struct ath10k *ar, u32 vdev_id, -++ u32 param_id, u32 param_value); -++ struct sk_buff *(*gen_vdev_install_key)(struct ath10k *ar, -++ const struct wmi_vdev_install_key_arg *arg); -++ struct sk_buff *(*gen_vdev_spectral_conf)(struct ath10k *ar, -++ const struct wmi_vdev_spectral_conf_arg *arg); -++ struct sk_buff *(*gen_vdev_spectral_enable)(struct ath10k *ar, u32 vdev_id, -++ u32 trigger, u32 enable); -++ struct sk_buff *(*gen_vdev_wmm_conf)(struct ath10k *ar, u32 vdev_id, -++ const struct wmi_wmm_params_all_arg *arg); -++ struct sk_buff *(*gen_peer_create)(struct ath10k *ar, u32 vdev_id, -++ const u8 peer_addr[ETH_ALEN]); -++ struct sk_buff *(*gen_peer_delete)(struct ath10k *ar, u32 vdev_id, -++ const u8 peer_addr[ETH_ALEN]); -++ struct sk_buff *(*gen_peer_flush)(struct ath10k *ar, u32 vdev_id, -++ const u8 peer_addr[ETH_ALEN], -++ u32 tid_bitmap); -++ struct sk_buff *(*gen_peer_set_param)(struct ath10k *ar, u32 vdev_id, -++ const u8 *peer_addr, -++ enum wmi_peer_param param_id, -++ u32 param_value); -++ struct sk_buff *(*gen_peer_assoc)(struct ath10k *ar, -++ const struct wmi_peer_assoc_complete_arg *arg); -++ struct sk_buff *(*gen_set_psmode)(struct ath10k *ar, u32 vdev_id, -++ enum wmi_sta_ps_mode psmode); -++ struct sk_buff *(*gen_set_sta_ps)(struct ath10k *ar, u32 vdev_id, -++ enum wmi_sta_powersave_param param_id, -++ u32 value); -++ struct sk_buff *(*gen_set_ap_ps)(struct ath10k *ar, u32 vdev_id, -++ const u8 *mac, -++ enum wmi_ap_ps_peer_param param_id, -++ u32 value); -++ struct sk_buff *(*gen_scan_chan_list)(struct ath10k *ar, -++ const struct wmi_scan_chan_list_arg *arg); -++ struct sk_buff *(*gen_beacon_dma)(struct ath10k *ar, u32 vdev_id, -++ const void *bcn, size_t bcn_len, -++ u32 bcn_paddr, bool dtim_zero, -++ bool deliver_cab); -++ struct sk_buff *(*gen_pdev_set_wmm)(struct ath10k *ar, -++ const struct wmi_wmm_params_all_arg *arg); -++ struct sk_buff *(*gen_request_stats)(struct ath10k *ar, u32 stats_mask); -++ struct sk_buff *(*gen_force_fw_hang)(struct ath10k *ar, -++ enum wmi_force_fw_hang_type type, -++ u32 delay_ms); -++ struct sk_buff *(*gen_mgmt_tx)(struct ath10k *ar, struct sk_buff *skb); -++ struct sk_buff *(*gen_dbglog_cfg)(struct ath10k *ar, u32 module_enable, -++ u32 log_level); -++ struct sk_buff *(*gen_pktlog_enable)(struct ath10k *ar, u32 filter); -++ struct sk_buff *(*gen_pktlog_disable)(struct ath10k *ar); -++ struct sk_buff *(*gen_pdev_set_quiet_mode)(struct ath10k *ar, -++ u32 period, u32 duration, -++ u32 next_offset, -++ u32 enabled); -++ struct sk_buff *(*gen_pdev_get_temperature)(struct ath10k *ar); -++ struct sk_buff *(*gen_addba_clear_resp)(struct ath10k *ar, u32 vdev_id, -++ const u8 *mac); -++ struct sk_buff *(*gen_addba_send)(struct ath10k *ar, u32 vdev_id, -++ const u8 *mac, u32 tid, u32 buf_size); -++ struct sk_buff *(*gen_addba_set_resp)(struct ath10k *ar, u32 vdev_id, -++ const u8 *mac, u32 tid, -++ u32 status); -++ struct sk_buff *(*gen_delba_send)(struct ath10k *ar, u32 vdev_id, -++ const u8 *mac, u32 tid, u32 initiator, -++ u32 reason); -++ struct sk_buff *(*gen_bcn_tmpl)(struct ath10k *ar, u32 vdev_id, -++ u32 tim_ie_offset, struct sk_buff *bcn, -++ u32 prb_caps, u32 prb_erp, -++ void *prb_ies, size_t prb_ies_len); -++ struct sk_buff *(*gen_prb_tmpl)(struct ath10k *ar, u32 vdev_id, -++ struct sk_buff *bcn); -++ struct sk_buff *(*gen_p2p_go_bcn_ie)(struct ath10k *ar, u32 vdev_id, -++ const u8 *p2p_ie); -++ struct sk_buff *(*gen_vdev_sta_uapsd)(struct ath10k *ar, u32 vdev_id, -++ const u8 peer_addr[ETH_ALEN], -++ const struct wmi_sta_uapsd_auto_trig_arg *args, -++ u32 num_ac); -++ struct sk_buff *(*gen_sta_keepalive)(struct ath10k *ar, -++ const struct wmi_sta_keepalive_arg *arg); -++}; -++ -++int ath10k_wmi_cmd_send(struct ath10k *ar, struct sk_buff *skb, u32 cmd_id); -++ -++static inline int -++ath10k_wmi_rx(struct ath10k *ar, struct sk_buff *skb) -++{ -++ if (WARN_ON_ONCE(!ar->wmi.ops->rx)) -++ return -EOPNOTSUPP; -++ -++ ar->wmi.ops->rx(ar, skb); -++ return 0; -++} -++ -++static inline int -++ath10k_wmi_map_svc(struct ath10k *ar, const __le32 *in, unsigned long *out, -++ size_t len) -++{ -++ if (!ar->wmi.ops->map_svc) -++ return -EOPNOTSUPP; -++ -++ ar->wmi.ops->map_svc(in, out, len); -++ return 0; -++} -++ -++static inline int -++ath10k_wmi_pull_scan(struct ath10k *ar, struct sk_buff *skb, -++ struct wmi_scan_ev_arg *arg) -++{ -++ if (!ar->wmi.ops->pull_scan) -++ return -EOPNOTSUPP; -++ -++ return ar->wmi.ops->pull_scan(ar, skb, arg); -++} -++ -++static inline int -++ath10k_wmi_pull_mgmt_rx(struct ath10k *ar, struct sk_buff *skb, -++ struct wmi_mgmt_rx_ev_arg *arg) -++{ -++ if (!ar->wmi.ops->pull_mgmt_rx) -++ return -EOPNOTSUPP; -++ -++ return ar->wmi.ops->pull_mgmt_rx(ar, skb, arg); -++} -++ -++static inline int -++ath10k_wmi_pull_ch_info(struct ath10k *ar, struct sk_buff *skb, -++ struct wmi_ch_info_ev_arg *arg) -++{ -++ if (!ar->wmi.ops->pull_ch_info) -++ return -EOPNOTSUPP; -++ -++ return ar->wmi.ops->pull_ch_info(ar, skb, arg); -++} -++ -++static inline int -++ath10k_wmi_pull_vdev_start(struct ath10k *ar, struct sk_buff *skb, -++ struct wmi_vdev_start_ev_arg *arg) -++{ -++ if (!ar->wmi.ops->pull_vdev_start) -++ return -EOPNOTSUPP; -++ -++ return ar->wmi.ops->pull_vdev_start(ar, skb, arg); -++} -++ -++static inline int -++ath10k_wmi_pull_peer_kick(struct ath10k *ar, struct sk_buff *skb, -++ struct wmi_peer_kick_ev_arg *arg) -++{ -++ if (!ar->wmi.ops->pull_peer_kick) -++ return -EOPNOTSUPP; -++ -++ return ar->wmi.ops->pull_peer_kick(ar, skb, arg); -++} -++ -++static inline int -++ath10k_wmi_pull_swba(struct ath10k *ar, struct sk_buff *skb, -++ struct wmi_swba_ev_arg *arg) -++{ -++ if (!ar->wmi.ops->pull_swba) -++ return -EOPNOTSUPP; -++ -++ return ar->wmi.ops->pull_swba(ar, skb, arg); -++} -++ -++static inline int -++ath10k_wmi_pull_phyerr(struct ath10k *ar, struct sk_buff *skb, -++ struct wmi_phyerr_ev_arg *arg) -++{ -++ if (!ar->wmi.ops->pull_phyerr) -++ return -EOPNOTSUPP; -++ -++ return ar->wmi.ops->pull_phyerr(ar, skb, arg); -++} -++ -++static inline int -++ath10k_wmi_pull_svc_rdy(struct ath10k *ar, struct sk_buff *skb, -++ struct wmi_svc_rdy_ev_arg *arg) -++{ -++ if (!ar->wmi.ops->pull_svc_rdy) -++ return -EOPNOTSUPP; -++ -++ return ar->wmi.ops->pull_svc_rdy(ar, skb, arg); -++} -++ -++static inline int -++ath10k_wmi_pull_rdy(struct ath10k *ar, struct sk_buff *skb, -++ struct wmi_rdy_ev_arg *arg) -++{ -++ if (!ar->wmi.ops->pull_rdy) -++ return -EOPNOTSUPP; -++ -++ return ar->wmi.ops->pull_rdy(ar, skb, arg); -++} -++ -++static inline int -++ath10k_wmi_pull_fw_stats(struct ath10k *ar, struct sk_buff *skb, -++ struct ath10k_fw_stats *stats) -++{ -++ if (!ar->wmi.ops->pull_fw_stats) -++ return -EOPNOTSUPP; -++ -++ return ar->wmi.ops->pull_fw_stats(ar, skb, stats); -++} -++ -++static inline int -++ath10k_wmi_mgmt_tx(struct ath10k *ar, struct sk_buff *msdu) -++{ -++ struct ieee80211_tx_info *info = IEEE80211_SKB_CB(msdu); -++ struct sk_buff *skb; -++ int ret; -++ -++ if (!ar->wmi.ops->gen_mgmt_tx) -++ return -EOPNOTSUPP; -++ -++ skb = ar->wmi.ops->gen_mgmt_tx(ar, msdu); -++ if (IS_ERR(skb)) -++ return PTR_ERR(skb); -++ -++ ret = ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->mgmt_tx_cmdid); -++ if (ret) -++ return ret; -++ -++ /* FIXME There's no ACK event for Management Tx. This probably -++ * shouldn't be called here either. */ -++ info->flags |= IEEE80211_TX_STAT_ACK; -++ ieee80211_tx_status_irqsafe(ar->hw, msdu); -++ -++ return 0; -++} -++ -++static inline int -++ath10k_wmi_pdev_set_regdomain(struct ath10k *ar, u16 rd, u16 rd2g, u16 rd5g, -++ u16 ctl2g, u16 ctl5g, -++ enum wmi_dfs_region dfs_reg) -++{ -++ struct sk_buff *skb; -++ -++ if (!ar->wmi.ops->gen_pdev_set_rd) -++ return -EOPNOTSUPP; -++ -++ skb = ar->wmi.ops->gen_pdev_set_rd(ar, rd, rd2g, rd5g, ctl2g, ctl5g, -++ dfs_reg); -++ if (IS_ERR(skb)) -++ return PTR_ERR(skb); -++ -++ return ath10k_wmi_cmd_send(ar, skb, -++ ar->wmi.cmd->pdev_set_regdomain_cmdid); -++} -++ -++static inline int -++ath10k_wmi_pdev_suspend_target(struct ath10k *ar, u32 suspend_opt) -++{ -++ struct sk_buff *skb; -++ -++ if (!ar->wmi.ops->gen_pdev_suspend) -++ return -EOPNOTSUPP; -++ -++ skb = ar->wmi.ops->gen_pdev_suspend(ar, suspend_opt); -++ if (IS_ERR(skb)) -++ return PTR_ERR(skb); -++ -++ return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->pdev_suspend_cmdid); -++} -++ -++static inline int -++ath10k_wmi_pdev_resume_target(struct ath10k *ar) -++{ -++ struct sk_buff *skb; -++ -++ if (!ar->wmi.ops->gen_pdev_resume) -++ return -EOPNOTSUPP; -++ -++ skb = ar->wmi.ops->gen_pdev_resume(ar); -++ if (IS_ERR(skb)) -++ return PTR_ERR(skb); -++ -++ return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->pdev_resume_cmdid); -++} -++ -++static inline int -++ath10k_wmi_pdev_set_param(struct ath10k *ar, u32 id, u32 value) -++{ -++ struct sk_buff *skb; -++ -++ if (!ar->wmi.ops->gen_pdev_set_param) -++ return -EOPNOTSUPP; -++ -++ skb = ar->wmi.ops->gen_pdev_set_param(ar, id, value); -++ if (IS_ERR(skb)) -++ return PTR_ERR(skb); -++ -++ return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->pdev_set_param_cmdid); -++} -++ -++static inline int -++ath10k_wmi_cmd_init(struct ath10k *ar) -++{ -++ struct sk_buff *skb; -++ -++ if (!ar->wmi.ops->gen_init) -++ return -EOPNOTSUPP; -++ -++ skb = ar->wmi.ops->gen_init(ar); -++ if (IS_ERR(skb)) -++ return PTR_ERR(skb); -++ -++ return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->init_cmdid); -++} -++ -++static inline int -++ath10k_wmi_start_scan(struct ath10k *ar, -++ const struct wmi_start_scan_arg *arg) -++{ -++ struct sk_buff *skb; -++ -++ if (!ar->wmi.ops->gen_start_scan) -++ return -EOPNOTSUPP; -++ -++ skb = ar->wmi.ops->gen_start_scan(ar, arg); -++ if (IS_ERR(skb)) -++ return PTR_ERR(skb); -++ -++ return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->start_scan_cmdid); -++} -++ -++static inline int -++ath10k_wmi_stop_scan(struct ath10k *ar, const struct wmi_stop_scan_arg *arg) -++{ -++ struct sk_buff *skb; -++ -++ if (!ar->wmi.ops->gen_stop_scan) -++ return -EOPNOTSUPP; -++ -++ skb = ar->wmi.ops->gen_stop_scan(ar, arg); -++ if (IS_ERR(skb)) -++ return PTR_ERR(skb); -++ -++ return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->stop_scan_cmdid); -++} -++ -++static inline int -++ath10k_wmi_vdev_create(struct ath10k *ar, u32 vdev_id, -++ enum wmi_vdev_type type, -++ enum wmi_vdev_subtype subtype, -++ const u8 macaddr[ETH_ALEN]) -++{ -++ struct sk_buff *skb; -++ -++ if (!ar->wmi.ops->gen_vdev_create) -++ return -EOPNOTSUPP; -++ -++ skb = ar->wmi.ops->gen_vdev_create(ar, vdev_id, type, subtype, macaddr); -++ if (IS_ERR(skb)) -++ return PTR_ERR(skb); -++ -++ return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->vdev_create_cmdid); -++} -++ -++static inline int -++ath10k_wmi_vdev_delete(struct ath10k *ar, u32 vdev_id) -++{ -++ struct sk_buff *skb; -++ -++ if (!ar->wmi.ops->gen_vdev_delete) -++ return -EOPNOTSUPP; -++ -++ skb = ar->wmi.ops->gen_vdev_delete(ar, vdev_id); -++ if (IS_ERR(skb)) -++ return PTR_ERR(skb); -++ -++ return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->vdev_delete_cmdid); -++} -++ -++static inline int -++ath10k_wmi_vdev_start(struct ath10k *ar, -++ const struct wmi_vdev_start_request_arg *arg) -++{ -++ struct sk_buff *skb; -++ -++ if (!ar->wmi.ops->gen_vdev_start) -++ return -EOPNOTSUPP; -++ -++ skb = ar->wmi.ops->gen_vdev_start(ar, arg, false); -++ if (IS_ERR(skb)) -++ return PTR_ERR(skb); -++ -++ return ath10k_wmi_cmd_send(ar, skb, -++ ar->wmi.cmd->vdev_start_request_cmdid); -++} -++ -++static inline int -++ath10k_wmi_vdev_restart(struct ath10k *ar, -++ const struct wmi_vdev_start_request_arg *arg) -++{ -++ struct sk_buff *skb; -++ -++ if (!ar->wmi.ops->gen_vdev_start) -++ return -EOPNOTSUPP; -++ -++ skb = ar->wmi.ops->gen_vdev_start(ar, arg, true); -++ if (IS_ERR(skb)) -++ return PTR_ERR(skb); -++ -++ return ath10k_wmi_cmd_send(ar, skb, -++ ar->wmi.cmd->vdev_restart_request_cmdid); -++} -++ -++static inline int -++ath10k_wmi_vdev_stop(struct ath10k *ar, u32 vdev_id) -++{ -++ struct sk_buff *skb; -++ -++ if (!ar->wmi.ops->gen_vdev_stop) -++ return -EOPNOTSUPP; -++ -++ skb = ar->wmi.ops->gen_vdev_stop(ar, vdev_id); -++ if (IS_ERR(skb)) -++ return PTR_ERR(skb); -++ -++ return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->vdev_stop_cmdid); -++} -++ -++static inline int -++ath10k_wmi_vdev_up(struct ath10k *ar, u32 vdev_id, u32 aid, const u8 *bssid) -++{ -++ struct sk_buff *skb; -++ -++ if (!ar->wmi.ops->gen_vdev_up) -++ return -EOPNOTSUPP; -++ -++ skb = ar->wmi.ops->gen_vdev_up(ar, vdev_id, aid, bssid); -++ if (IS_ERR(skb)) -++ return PTR_ERR(skb); -++ -++ return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->vdev_up_cmdid); -++} -++ -++static inline int -++ath10k_wmi_vdev_down(struct ath10k *ar, u32 vdev_id) -++{ -++ struct sk_buff *skb; -++ -++ if (!ar->wmi.ops->gen_vdev_down) -++ return -EOPNOTSUPP; -++ -++ skb = ar->wmi.ops->gen_vdev_down(ar, vdev_id); -++ if (IS_ERR(skb)) -++ return PTR_ERR(skb); -++ -++ return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->vdev_down_cmdid); -++} -++ -++static inline int -++ath10k_wmi_vdev_set_param(struct ath10k *ar, u32 vdev_id, u32 param_id, -++ u32 param_value) -++{ -++ struct sk_buff *skb; -++ -++ if (!ar->wmi.ops->gen_vdev_set_param) -++ return -EOPNOTSUPP; -++ -++ skb = ar->wmi.ops->gen_vdev_set_param(ar, vdev_id, param_id, -++ param_value); -++ if (IS_ERR(skb)) -++ return PTR_ERR(skb); -++ -++ return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->vdev_set_param_cmdid); -++} -++ -++static inline int -++ath10k_wmi_vdev_install_key(struct ath10k *ar, -++ const struct wmi_vdev_install_key_arg *arg) -++{ -++ struct sk_buff *skb; -++ -++ if (!ar->wmi.ops->gen_vdev_install_key) -++ return -EOPNOTSUPP; -++ -++ skb = ar->wmi.ops->gen_vdev_install_key(ar, arg); -++ if (IS_ERR(skb)) -++ return PTR_ERR(skb); -++ -++ return ath10k_wmi_cmd_send(ar, skb, -++ ar->wmi.cmd->vdev_install_key_cmdid); -++} -++ -++static inline int -++ath10k_wmi_vdev_spectral_conf(struct ath10k *ar, -++ const struct wmi_vdev_spectral_conf_arg *arg) -++{ -++ struct sk_buff *skb; -++ u32 cmd_id; -++ -++ skb = ar->wmi.ops->gen_vdev_spectral_conf(ar, arg); -++ if (IS_ERR(skb)) -++ return PTR_ERR(skb); -++ -++ cmd_id = ar->wmi.cmd->vdev_spectral_scan_configure_cmdid; -++ return ath10k_wmi_cmd_send(ar, skb, cmd_id); -++} -++ -++static inline int -++ath10k_wmi_vdev_spectral_enable(struct ath10k *ar, u32 vdev_id, u32 trigger, -++ u32 enable) -++{ -++ struct sk_buff *skb; -++ u32 cmd_id; -++ -++ skb = ar->wmi.ops->gen_vdev_spectral_enable(ar, vdev_id, trigger, -++ enable); -++ if (IS_ERR(skb)) -++ return PTR_ERR(skb); -++ -++ cmd_id = ar->wmi.cmd->vdev_spectral_scan_enable_cmdid; -++ return ath10k_wmi_cmd_send(ar, skb, cmd_id); -++} -++ -++static inline int -++ath10k_wmi_vdev_sta_uapsd(struct ath10k *ar, u32 vdev_id, -++ const u8 peer_addr[ETH_ALEN], -++ const struct wmi_sta_uapsd_auto_trig_arg *args, -++ u32 num_ac) -++{ -++ struct sk_buff *skb; -++ u32 cmd_id; -++ -++ if (!ar->wmi.ops->gen_vdev_sta_uapsd) -++ return -EOPNOTSUPP; -++ -++ skb = ar->wmi.ops->gen_vdev_sta_uapsd(ar, vdev_id, peer_addr, args, -++ num_ac); -++ if (IS_ERR(skb)) -++ return PTR_ERR(skb); -++ -++ cmd_id = ar->wmi.cmd->sta_uapsd_auto_trig_cmdid; -++ return ath10k_wmi_cmd_send(ar, skb, cmd_id); -++} -++ -++static inline int -++ath10k_wmi_vdev_wmm_conf(struct ath10k *ar, u32 vdev_id, -++ const struct wmi_wmm_params_all_arg *arg) -++{ -++ struct sk_buff *skb; -++ u32 cmd_id; -++ -++ skb = ar->wmi.ops->gen_vdev_wmm_conf(ar, vdev_id, arg); -++ if (IS_ERR(skb)) -++ return PTR_ERR(skb); -++ -++ cmd_id = ar->wmi.cmd->vdev_set_wmm_params_cmdid; -++ return ath10k_wmi_cmd_send(ar, skb, cmd_id); -++} -++ -++static inline int -++ath10k_wmi_peer_create(struct ath10k *ar, u32 vdev_id, -++ const u8 peer_addr[ETH_ALEN]) -++{ -++ struct sk_buff *skb; -++ -++ if (!ar->wmi.ops->gen_peer_create) -++ return -EOPNOTSUPP; -++ -++ skb = ar->wmi.ops->gen_peer_create(ar, vdev_id, peer_addr); -++ if (IS_ERR(skb)) -++ return PTR_ERR(skb); -++ -++ return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->peer_create_cmdid); -++} -++ -++static inline int -++ath10k_wmi_peer_delete(struct ath10k *ar, u32 vdev_id, -++ const u8 peer_addr[ETH_ALEN]) -++{ -++ struct sk_buff *skb; -++ -++ if (!ar->wmi.ops->gen_peer_delete) -++ return -EOPNOTSUPP; -++ -++ skb = ar->wmi.ops->gen_peer_delete(ar, vdev_id, peer_addr); -++ if (IS_ERR(skb)) -++ return PTR_ERR(skb); -++ -++ return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->peer_delete_cmdid); -++} -++ -++static inline int -++ath10k_wmi_peer_flush(struct ath10k *ar, u32 vdev_id, -++ const u8 peer_addr[ETH_ALEN], u32 tid_bitmap) -++{ -++ struct sk_buff *skb; -++ -++ if (!ar->wmi.ops->gen_peer_flush) -++ return -EOPNOTSUPP; -++ -++ skb = ar->wmi.ops->gen_peer_flush(ar, vdev_id, peer_addr, tid_bitmap); -++ if (IS_ERR(skb)) -++ return PTR_ERR(skb); -++ -++ return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->peer_flush_tids_cmdid); -++} -++ -++static inline int -++ath10k_wmi_peer_set_param(struct ath10k *ar, u32 vdev_id, const u8 *peer_addr, -++ enum wmi_peer_param param_id, u32 param_value) -++{ -++ struct sk_buff *skb; -++ -++ if (!ar->wmi.ops->gen_peer_set_param) -++ return -EOPNOTSUPP; -++ -++ skb = ar->wmi.ops->gen_peer_set_param(ar, vdev_id, peer_addr, param_id, -++ param_value); -++ if (IS_ERR(skb)) -++ return PTR_ERR(skb); -++ -++ return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->peer_set_param_cmdid); -++} -++ -++static inline int -++ath10k_wmi_set_psmode(struct ath10k *ar, u32 vdev_id, -++ enum wmi_sta_ps_mode psmode) -++{ -++ struct sk_buff *skb; -++ -++ if (!ar->wmi.ops->gen_set_psmode) -++ return -EOPNOTSUPP; -++ -++ skb = ar->wmi.ops->gen_set_psmode(ar, vdev_id, psmode); -++ if (IS_ERR(skb)) -++ return PTR_ERR(skb); -++ -++ return ath10k_wmi_cmd_send(ar, skb, -++ ar->wmi.cmd->sta_powersave_mode_cmdid); -++} -++ -++static inline int -++ath10k_wmi_set_sta_ps_param(struct ath10k *ar, u32 vdev_id, -++ enum wmi_sta_powersave_param param_id, u32 value) -++{ -++ struct sk_buff *skb; -++ -++ if (!ar->wmi.ops->gen_set_sta_ps) -++ return -EOPNOTSUPP; -++ -++ skb = ar->wmi.ops->gen_set_sta_ps(ar, vdev_id, param_id, value); -++ if (IS_ERR(skb)) -++ return PTR_ERR(skb); -++ -++ return ath10k_wmi_cmd_send(ar, skb, -++ ar->wmi.cmd->sta_powersave_param_cmdid); -++} -++ -++static inline int -++ath10k_wmi_set_ap_ps_param(struct ath10k *ar, u32 vdev_id, const u8 *mac, -++ enum wmi_ap_ps_peer_param param_id, u32 value) -++{ -++ struct sk_buff *skb; -++ -++ if (!ar->wmi.ops->gen_set_ap_ps) -++ return -EOPNOTSUPP; -++ -++ skb = ar->wmi.ops->gen_set_ap_ps(ar, vdev_id, mac, param_id, value); -++ if (IS_ERR(skb)) -++ return PTR_ERR(skb); -++ -++ return ath10k_wmi_cmd_send(ar, skb, -++ ar->wmi.cmd->ap_ps_peer_param_cmdid); -++} -++ -++static inline int -++ath10k_wmi_scan_chan_list(struct ath10k *ar, -++ const struct wmi_scan_chan_list_arg *arg) -++{ -++ struct sk_buff *skb; -++ -++ if (!ar->wmi.ops->gen_scan_chan_list) -++ return -EOPNOTSUPP; -++ -++ skb = ar->wmi.ops->gen_scan_chan_list(ar, arg); -++ if (IS_ERR(skb)) -++ return PTR_ERR(skb); -++ -++ return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->scan_chan_list_cmdid); -++} -++ -++static inline int -++ath10k_wmi_peer_assoc(struct ath10k *ar, -++ const struct wmi_peer_assoc_complete_arg *arg) -++{ -++ struct sk_buff *skb; -++ -++ if (!ar->wmi.ops->gen_peer_assoc) -++ return -EOPNOTSUPP; -++ -++ skb = ar->wmi.ops->gen_peer_assoc(ar, arg); -++ if (IS_ERR(skb)) -++ return PTR_ERR(skb); -++ -++ return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->peer_assoc_cmdid); -++} -++ -++static inline int -++ath10k_wmi_beacon_send_ref_nowait(struct ath10k *ar, u32 vdev_id, -++ const void *bcn, size_t bcn_len, -++ u32 bcn_paddr, bool dtim_zero, -++ bool deliver_cab) -++{ -++ struct sk_buff *skb; -++ int ret; -++ -++ if (!ar->wmi.ops->gen_beacon_dma) -++ return -EOPNOTSUPP; -++ -++ skb = ar->wmi.ops->gen_beacon_dma(ar, vdev_id, bcn, bcn_len, bcn_paddr, -++ dtim_zero, deliver_cab); -++ if (IS_ERR(skb)) -++ return PTR_ERR(skb); -++ -++ ret = ath10k_wmi_cmd_send_nowait(ar, skb, -++ ar->wmi.cmd->pdev_send_bcn_cmdid); -++ if (ret) { -++ dev_kfree_skb(skb); -++ return ret; -++ } -++ -++ return 0; -++} -++ -++static inline int -++ath10k_wmi_pdev_set_wmm_params(struct ath10k *ar, -++ const struct wmi_wmm_params_all_arg *arg) -++{ -++ struct sk_buff *skb; -++ -++ if (!ar->wmi.ops->gen_pdev_set_wmm) -++ return -EOPNOTSUPP; -++ -++ skb = ar->wmi.ops->gen_pdev_set_wmm(ar, arg); -++ if (IS_ERR(skb)) -++ return PTR_ERR(skb); -++ -++ return ath10k_wmi_cmd_send(ar, skb, -++ ar->wmi.cmd->pdev_set_wmm_params_cmdid); -++} -++ -++static inline int -++ath10k_wmi_request_stats(struct ath10k *ar, u32 stats_mask) -++{ -++ struct sk_buff *skb; -++ -++ if (!ar->wmi.ops->gen_request_stats) -++ return -EOPNOTSUPP; -++ -++ skb = ar->wmi.ops->gen_request_stats(ar, stats_mask); -++ if (IS_ERR(skb)) -++ return PTR_ERR(skb); -++ -++ return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->request_stats_cmdid); -++} -++ -++static inline int -++ath10k_wmi_force_fw_hang(struct ath10k *ar, -++ enum wmi_force_fw_hang_type type, u32 delay_ms) -++{ -++ struct sk_buff *skb; -++ -++ if (!ar->wmi.ops->gen_force_fw_hang) -++ return -EOPNOTSUPP; -++ -++ skb = ar->wmi.ops->gen_force_fw_hang(ar, type, delay_ms); -++ if (IS_ERR(skb)) -++ return PTR_ERR(skb); -++ -++ return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->force_fw_hang_cmdid); -++} -++ -++static inline int -++ath10k_wmi_dbglog_cfg(struct ath10k *ar, u32 module_enable, u32 log_level) -++{ -++ struct sk_buff *skb; -++ -++ if (!ar->wmi.ops->gen_dbglog_cfg) -++ return -EOPNOTSUPP; -++ -++ skb = ar->wmi.ops->gen_dbglog_cfg(ar, module_enable, log_level); -++ if (IS_ERR(skb)) -++ return PTR_ERR(skb); -++ -++ return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->dbglog_cfg_cmdid); -++} -++ -++static inline int -++ath10k_wmi_pdev_pktlog_enable(struct ath10k *ar, u32 filter) -++{ -++ struct sk_buff *skb; -++ -++ if (!ar->wmi.ops->gen_pktlog_enable) -++ return -EOPNOTSUPP; -++ -++ skb = ar->wmi.ops->gen_pktlog_enable(ar, filter); -++ if (IS_ERR(skb)) -++ return PTR_ERR(skb); -++ -++ return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->pdev_pktlog_enable_cmdid); -++} -++ -++static inline int -++ath10k_wmi_pdev_pktlog_disable(struct ath10k *ar) -++{ -++ struct sk_buff *skb; -++ -++ if (!ar->wmi.ops->gen_pktlog_disable) -++ return -EOPNOTSUPP; -++ -++ skb = ar->wmi.ops->gen_pktlog_disable(ar); -++ if (IS_ERR(skb)) -++ return PTR_ERR(skb); -++ -++ return ath10k_wmi_cmd_send(ar, skb, -++ ar->wmi.cmd->pdev_pktlog_disable_cmdid); -++} -++ -++static inline int -++ath10k_wmi_pdev_set_quiet_mode(struct ath10k *ar, u32 period, u32 duration, -++ u32 next_offset, u32 enabled) -++{ -++ struct sk_buff *skb; -++ -++ if (!ar->wmi.ops->gen_pdev_set_quiet_mode) -++ return -EOPNOTSUPP; -++ -++ skb = ar->wmi.ops->gen_pdev_set_quiet_mode(ar, period, duration, -++ next_offset, enabled); -++ if (IS_ERR(skb)) -++ return PTR_ERR(skb); -++ -++ return ath10k_wmi_cmd_send(ar, skb, -++ ar->wmi.cmd->pdev_set_quiet_mode_cmdid); -++} -++ -++static inline int -++ath10k_wmi_pdev_get_temperature(struct ath10k *ar) -++{ -++ struct sk_buff *skb; -++ -++ if (!ar->wmi.ops->gen_pdev_get_temperature) -++ return -EOPNOTSUPP; -++ -++ skb = ar->wmi.ops->gen_pdev_get_temperature(ar); -++ if (IS_ERR(skb)) -++ return PTR_ERR(skb); -++ -++ return ath10k_wmi_cmd_send(ar, skb, -++ ar->wmi.cmd->pdev_get_temperature_cmdid); -++} -++ -++static inline int -++ath10k_wmi_addba_clear_resp(struct ath10k *ar, u32 vdev_id, const u8 *mac) -++{ -++ struct sk_buff *skb; -++ -++ if (!ar->wmi.ops->gen_addba_clear_resp) -++ return -EOPNOTSUPP; -++ -++ skb = ar->wmi.ops->gen_addba_clear_resp(ar, vdev_id, mac); -++ if (IS_ERR(skb)) -++ return PTR_ERR(skb); -++ -++ return ath10k_wmi_cmd_send(ar, skb, -++ ar->wmi.cmd->addba_clear_resp_cmdid); -++} -++ -++static inline int -++ath10k_wmi_addba_send(struct ath10k *ar, u32 vdev_id, const u8 *mac, -++ u32 tid, u32 buf_size) -++{ -++ struct sk_buff *skb; -++ -++ if (!ar->wmi.ops->gen_addba_send) -++ return -EOPNOTSUPP; -++ -++ skb = ar->wmi.ops->gen_addba_send(ar, vdev_id, mac, tid, buf_size); -++ if (IS_ERR(skb)) -++ return PTR_ERR(skb); -++ -++ return ath10k_wmi_cmd_send(ar, skb, -++ ar->wmi.cmd->addba_send_cmdid); -++} -++ -++static inline int -++ath10k_wmi_addba_set_resp(struct ath10k *ar, u32 vdev_id, const u8 *mac, -++ u32 tid, u32 status) -++{ -++ struct sk_buff *skb; -++ -++ if (!ar->wmi.ops->gen_addba_set_resp) -++ return -EOPNOTSUPP; -++ -++ skb = ar->wmi.ops->gen_addba_set_resp(ar, vdev_id, mac, tid, status); -++ if (IS_ERR(skb)) -++ return PTR_ERR(skb); -++ -++ return ath10k_wmi_cmd_send(ar, skb, -++ ar->wmi.cmd->addba_set_resp_cmdid); -++} -++ -++static inline int -++ath10k_wmi_delba_send(struct ath10k *ar, u32 vdev_id, const u8 *mac, -++ u32 tid, u32 initiator, u32 reason) -++{ -++ struct sk_buff *skb; -++ -++ if (!ar->wmi.ops->gen_delba_send) -++ return -EOPNOTSUPP; -++ -++ skb = ar->wmi.ops->gen_delba_send(ar, vdev_id, mac, tid, initiator, -++ reason); -++ if (IS_ERR(skb)) -++ return PTR_ERR(skb); -++ -++ return ath10k_wmi_cmd_send(ar, skb, -++ ar->wmi.cmd->delba_send_cmdid); -++} -++ -++static inline int -++ath10k_wmi_bcn_tmpl(struct ath10k *ar, u32 vdev_id, u32 tim_ie_offset, -++ struct sk_buff *bcn, u32 prb_caps, u32 prb_erp, -++ void *prb_ies, size_t prb_ies_len) -++{ -++ struct sk_buff *skb; -++ -++ if (!ar->wmi.ops->gen_bcn_tmpl) -++ return -EOPNOTSUPP; -++ -++ skb = ar->wmi.ops->gen_bcn_tmpl(ar, vdev_id, tim_ie_offset, bcn, -++ prb_caps, prb_erp, prb_ies, -++ prb_ies_len); -++ if (IS_ERR(skb)) -++ return PTR_ERR(skb); -++ -++ return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->bcn_tmpl_cmdid); -++} -++ -++static inline int -++ath10k_wmi_prb_tmpl(struct ath10k *ar, u32 vdev_id, struct sk_buff *prb) -++{ -++ struct sk_buff *skb; -++ -++ if (!ar->wmi.ops->gen_prb_tmpl) -++ return -EOPNOTSUPP; -++ -++ skb = ar->wmi.ops->gen_prb_tmpl(ar, vdev_id, prb); -++ if (IS_ERR(skb)) -++ return PTR_ERR(skb); -++ -++ return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->prb_tmpl_cmdid); -++} -++ -++static inline int -++ath10k_wmi_p2p_go_bcn_ie(struct ath10k *ar, u32 vdev_id, const u8 *p2p_ie) -++{ -++ struct sk_buff *skb; -++ -++ if (!ar->wmi.ops->gen_p2p_go_bcn_ie) -++ return -EOPNOTSUPP; -++ -++ skb = ar->wmi.ops->gen_p2p_go_bcn_ie(ar, vdev_id, p2p_ie); -++ if (IS_ERR(skb)) -++ return PTR_ERR(skb); -++ -++ return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->p2p_go_set_beacon_ie); -++} -++ -++static inline int -++ath10k_wmi_sta_keepalive(struct ath10k *ar, -++ const struct wmi_sta_keepalive_arg *arg) -++{ -++ struct sk_buff *skb; -++ u32 cmd_id; -++ -++ if (!ar->wmi.ops->gen_sta_keepalive) -++ return -EOPNOTSUPP; -++ -++ skb = ar->wmi.ops->gen_sta_keepalive(ar, arg); -++ if (IS_ERR(skb)) -++ return PTR_ERR(skb); -++ -++ cmd_id = ar->wmi.cmd->sta_keepalive_cmd; -++ return ath10k_wmi_cmd_send(ar, skb, cmd_id); -++} -++ -++#endif -+--- /dev/null -++++ b/drivers/net/wireless/ath/ath10k/wmi-tlv.c -+@@ -0,0 +1,2796 @@ -++/* -++ * Copyright (c) 2005-2011 Atheros Communications Inc. -++ * Copyright (c) 2011-2014 Qualcomm Atheros, Inc. -++ * -++ * Permission to use, copy, modify, and/or distribute this software for any -++ * purpose with or without fee is hereby granted, provided that the above -++ * copyright notice and this permission notice appear in all copies. -++ * -++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -++ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -++ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -++ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -++ */ -++#include "core.h" -++#include "debug.h" -++#include "hw.h" -++#include "wmi.h" -++#include "wmi-ops.h" -++#include "wmi-tlv.h" -++ -++/***************/ -++/* TLV helpers */ -++/**************/ -++ -++struct wmi_tlv_policy { -++ size_t min_len; -++}; -++ -++static const struct wmi_tlv_policy wmi_tlv_policies[] = { -++ [WMI_TLV_TAG_ARRAY_BYTE] -++ = { .min_len = sizeof(u8) }, -++ [WMI_TLV_TAG_ARRAY_UINT32] -++ = { .min_len = sizeof(u32) }, -++ [WMI_TLV_TAG_STRUCT_SCAN_EVENT] -++ = { .min_len = sizeof(struct wmi_scan_event) }, -++ [WMI_TLV_TAG_STRUCT_MGMT_RX_HDR] -++ = { .min_len = sizeof(struct wmi_tlv_mgmt_rx_ev) }, -++ [WMI_TLV_TAG_STRUCT_CHAN_INFO_EVENT] -++ = { .min_len = sizeof(struct wmi_chan_info_event) }, -++ [WMI_TLV_TAG_STRUCT_VDEV_START_RESPONSE_EVENT] -++ = { .min_len = sizeof(struct wmi_vdev_start_response_event) }, -++ [WMI_TLV_TAG_STRUCT_PEER_STA_KICKOUT_EVENT] -++ = { .min_len = sizeof(struct wmi_peer_sta_kickout_event) }, -++ [WMI_TLV_TAG_STRUCT_HOST_SWBA_EVENT] -++ = { .min_len = sizeof(struct wmi_host_swba_event) }, -++ [WMI_TLV_TAG_STRUCT_TIM_INFO] -++ = { .min_len = sizeof(struct wmi_tim_info) }, -++ [WMI_TLV_TAG_STRUCT_P2P_NOA_INFO] -++ = { .min_len = sizeof(struct wmi_p2p_noa_info) }, -++ [WMI_TLV_TAG_STRUCT_SERVICE_READY_EVENT] -++ = { .min_len = sizeof(struct wmi_tlv_svc_rdy_ev) }, -++ [WMI_TLV_TAG_STRUCT_HAL_REG_CAPABILITIES] -++ = { .min_len = sizeof(struct hal_reg_capabilities) }, -++ [WMI_TLV_TAG_STRUCT_WLAN_HOST_MEM_REQ] -++ = { .min_len = sizeof(struct wlan_host_mem_req) }, -++ [WMI_TLV_TAG_STRUCT_READY_EVENT] -++ = { .min_len = sizeof(struct wmi_tlv_rdy_ev) }, -++ [WMI_TLV_TAG_STRUCT_OFFLOAD_BCN_TX_STATUS_EVENT] -++ = { .min_len = sizeof(struct wmi_tlv_bcn_tx_status_ev) }, -++ [WMI_TLV_TAG_STRUCT_DIAG_DATA_CONTAINER_EVENT] -++ = { .min_len = sizeof(struct wmi_tlv_diag_data_ev) }, -++}; -++ -++static int -++ath10k_wmi_tlv_iter(struct ath10k *ar, const void *ptr, size_t len, -++ int (*iter)(struct ath10k *ar, u16 tag, u16 len, -++ const void *ptr, void *data), -++ void *data) -++{ -++ const void *begin = ptr; -++ const struct wmi_tlv *tlv; -++ u16 tlv_tag, tlv_len; -++ int ret; -++ -++ while (len > 0) { -++ if (len < sizeof(*tlv)) { -++ ath10k_dbg(ar, ATH10K_DBG_WMI, -++ "wmi tlv parse failure at byte %zd (%zu bytes left, %zu expected)\n", -++ ptr - begin, len, sizeof(*tlv)); -++ return -EINVAL; -++ } -++ -++ tlv = ptr; -++ tlv_tag = __le16_to_cpu(tlv->tag); -++ tlv_len = __le16_to_cpu(tlv->len); -++ ptr += sizeof(*tlv); -++ len -= sizeof(*tlv); -++ -++ if (tlv_len > len) { -++ ath10k_dbg(ar, ATH10K_DBG_WMI, -++ "wmi tlv parse failure of tag %hhu at byte %zd (%zu bytes left, %hhu expected)\n", -++ tlv_tag, ptr - begin, len, tlv_len); -++ return -EINVAL; -++ } -++ -++ if (tlv_tag < ARRAY_SIZE(wmi_tlv_policies) && -++ wmi_tlv_policies[tlv_tag].min_len && -++ wmi_tlv_policies[tlv_tag].min_len > tlv_len) { -++ ath10k_dbg(ar, ATH10K_DBG_WMI, -++ "wmi tlv parse failure of tag %hhu at byte %zd (%hhu bytes is less than min length %zu)\n", -++ tlv_tag, ptr - begin, tlv_len, -++ wmi_tlv_policies[tlv_tag].min_len); -++ return -EINVAL; -++ } -++ -++ ret = iter(ar, tlv_tag, tlv_len, ptr, data); -++ if (ret) -++ return ret; -++ -++ ptr += tlv_len; -++ len -= tlv_len; -++ } -++ -++ return 0; -++} -++ -++static int ath10k_wmi_tlv_iter_parse(struct ath10k *ar, u16 tag, u16 len, -++ const void *ptr, void *data) -++{ -++ const void **tb = data; -++ -++ if (tag < WMI_TLV_TAG_MAX) -++ tb[tag] = ptr; -++ -++ return 0; -++} -++ -++static int ath10k_wmi_tlv_parse(struct ath10k *ar, const void **tb, -++ const void *ptr, size_t len) -++{ -++ return ath10k_wmi_tlv_iter(ar, ptr, len, ath10k_wmi_tlv_iter_parse, -++ (void *)tb); -++} -++ -++static const void ** -++ath10k_wmi_tlv_parse_alloc(struct ath10k *ar, const void *ptr, -++ size_t len, gfp_t gfp) -++{ -++ const void **tb; -++ int ret; -++ -++ tb = kzalloc(sizeof(*tb) * WMI_TLV_TAG_MAX, gfp); -++ if (!tb) -++ return ERR_PTR(-ENOMEM); -++ -++ ret = ath10k_wmi_tlv_parse(ar, tb, ptr, len); -++ if (ret) { -++ kfree(tb); -++ return ERR_PTR(ret); -++ } -++ -++ return tb; -++} -++ -++static u16 ath10k_wmi_tlv_len(const void *ptr) -++{ -++ return __le16_to_cpu((((const struct wmi_tlv *)ptr) - 1)->len); -++} -++ -++/**************/ -++/* TLV events */ -++/**************/ -++static int ath10k_wmi_tlv_event_bcn_tx_status(struct ath10k *ar, -++ struct sk_buff *skb) -++{ -++ const void **tb; -++ const struct wmi_tlv_bcn_tx_status_ev *ev; -++ u32 vdev_id, tx_status; -++ int ret; -++ -++ tb = ath10k_wmi_tlv_parse_alloc(ar, skb->data, skb->len, GFP_ATOMIC); -++ if (IS_ERR(tb)) { -++ ret = PTR_ERR(tb); -++ ath10k_warn(ar, "failed to parse tlv: %d\n", ret); -++ return ret; -++ } -++ -++ ev = tb[WMI_TLV_TAG_STRUCT_OFFLOAD_BCN_TX_STATUS_EVENT]; -++ if (!ev) { -++ kfree(tb); -++ return -EPROTO; -++ } -++ -++ tx_status = __le32_to_cpu(ev->tx_status); -++ vdev_id = __le32_to_cpu(ev->vdev_id); -++ -++ switch (tx_status) { -++ case WMI_TLV_BCN_TX_STATUS_OK: -++ break; -++ case WMI_TLV_BCN_TX_STATUS_XRETRY: -++ case WMI_TLV_BCN_TX_STATUS_DROP: -++ case WMI_TLV_BCN_TX_STATUS_FILTERED: -++ /* FIXME: It's probably worth telling mac80211 to stop the -++ * interface as it is crippled. -++ */ -++ ath10k_warn(ar, "received bcn tmpl tx status on vdev %i: %d", -++ vdev_id, tx_status); -++ break; -++ } -++ -++ kfree(tb); -++ return 0; -++} -++ -++static int ath10k_wmi_tlv_event_diag_data(struct ath10k *ar, -++ struct sk_buff *skb) -++{ -++ const void **tb; -++ const struct wmi_tlv_diag_data_ev *ev; -++ const struct wmi_tlv_diag_item *item; -++ const void *data; -++ int ret, num_items, len; -++ -++ tb = ath10k_wmi_tlv_parse_alloc(ar, skb->data, skb->len, GFP_ATOMIC); -++ if (IS_ERR(tb)) { -++ ret = PTR_ERR(tb); -++ ath10k_warn(ar, "failed to parse tlv: %d\n", ret); -++ return ret; -++ } -++ -++ ev = tb[WMI_TLV_TAG_STRUCT_DIAG_DATA_CONTAINER_EVENT]; -++ data = tb[WMI_TLV_TAG_ARRAY_BYTE]; -++ if (!ev || !data) { -++ kfree(tb); -++ return -EPROTO; -++ } -++ -++ num_items = __le32_to_cpu(ev->num_items); -++ len = ath10k_wmi_tlv_len(data); -++ -++ while (num_items--) { -++ if (len == 0) -++ break; -++ if (len < sizeof(*item)) { -++ ath10k_warn(ar, "failed to parse diag data: can't fit item header\n"); -++ break; -++ } -++ -++ item = data; -++ -++ if (len < sizeof(*item) + __le16_to_cpu(item->len)) { -++ ath10k_warn(ar, "failed to parse diag data: item is too long\n"); -++ break; -++ } -++ -++ trace_ath10k_wmi_diag_container(ar, -++ item->type, -++ __le32_to_cpu(item->timestamp), -++ __le32_to_cpu(item->code), -++ __le16_to_cpu(item->len), -++ item->payload); -++ -++ len -= sizeof(*item); -++ len -= roundup(__le16_to_cpu(item->len), 4); -++ -++ data += sizeof(*item); -++ data += roundup(__le16_to_cpu(item->len), 4); -++ } -++ -++ if (num_items != -1 || len != 0) -++ ath10k_warn(ar, "failed to parse diag data event: num_items %d len %d\n", -++ num_items, len); -++ -++ kfree(tb); -++ return 0; -++} -++ -++static int ath10k_wmi_tlv_event_diag(struct ath10k *ar, -++ struct sk_buff *skb) -++{ -++ const void **tb; -++ const void *data; -++ int ret, len; -++ -++ tb = ath10k_wmi_tlv_parse_alloc(ar, skb->data, skb->len, GFP_ATOMIC); -++ if (IS_ERR(tb)) { -++ ret = PTR_ERR(tb); -++ ath10k_warn(ar, "failed to parse tlv: %d\n", ret); -++ return ret; -++ } -++ -++ data = tb[WMI_TLV_TAG_ARRAY_BYTE]; -++ if (!data) { -++ kfree(tb); -++ return -EPROTO; -++ } -++ len = ath10k_wmi_tlv_len(data); -++ -++ ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv diag event len %d\n", len); -++ trace_ath10k_wmi_diag(ar, data, len); -++ -++ kfree(tb); -++ return 0; -++} -++ -++/***********/ -++/* TLV ops */ -++/***********/ -++ -++static void ath10k_wmi_tlv_op_rx(struct ath10k *ar, struct sk_buff *skb) -++{ -++ struct wmi_cmd_hdr *cmd_hdr; -++ enum wmi_tlv_event_id id; -++ -++ cmd_hdr = (struct wmi_cmd_hdr *)skb->data; -++ id = MS(__le32_to_cpu(cmd_hdr->cmd_id), WMI_CMD_HDR_CMD_ID); -++ -++ if (skb_pull(skb, sizeof(struct wmi_cmd_hdr)) == NULL) -++ return; -++ -++ trace_ath10k_wmi_event(ar, id, skb->data, skb->len); -++ -++ switch (id) { -++ case WMI_TLV_MGMT_RX_EVENTID: -++ ath10k_wmi_event_mgmt_rx(ar, skb); -++ /* mgmt_rx() owns the skb now! */ -++ return; -++ case WMI_TLV_SCAN_EVENTID: -++ ath10k_wmi_event_scan(ar, skb); -++ break; -++ case WMI_TLV_CHAN_INFO_EVENTID: -++ ath10k_wmi_event_chan_info(ar, skb); -++ break; -++ case WMI_TLV_ECHO_EVENTID: -++ ath10k_wmi_event_echo(ar, skb); -++ break; -++ case WMI_TLV_DEBUG_MESG_EVENTID: -++ ath10k_wmi_event_debug_mesg(ar, skb); -++ break; -++ case WMI_TLV_UPDATE_STATS_EVENTID: -++ ath10k_wmi_event_update_stats(ar, skb); -++ break; -++ case WMI_TLV_VDEV_START_RESP_EVENTID: -++ ath10k_wmi_event_vdev_start_resp(ar, skb); -++ break; -++ case WMI_TLV_VDEV_STOPPED_EVENTID: -++ ath10k_wmi_event_vdev_stopped(ar, skb); -++ break; -++ case WMI_TLV_PEER_STA_KICKOUT_EVENTID: -++ ath10k_wmi_event_peer_sta_kickout(ar, skb); -++ break; -++ case WMI_TLV_HOST_SWBA_EVENTID: -++ ath10k_wmi_event_host_swba(ar, skb); -++ break; -++ case WMI_TLV_TBTTOFFSET_UPDATE_EVENTID: -++ ath10k_wmi_event_tbttoffset_update(ar, skb); -++ break; -++ case WMI_TLV_PHYERR_EVENTID: -++ ath10k_wmi_event_phyerr(ar, skb); -++ break; -++ case WMI_TLV_ROAM_EVENTID: -++ ath10k_wmi_event_roam(ar, skb); -++ break; -++ case WMI_TLV_PROFILE_MATCH: -++ ath10k_wmi_event_profile_match(ar, skb); -++ break; -++ case WMI_TLV_DEBUG_PRINT_EVENTID: -++ ath10k_wmi_event_debug_print(ar, skb); -++ break; -++ case WMI_TLV_PDEV_QVIT_EVENTID: -++ ath10k_wmi_event_pdev_qvit(ar, skb); -++ break; -++ case WMI_TLV_WLAN_PROFILE_DATA_EVENTID: -++ ath10k_wmi_event_wlan_profile_data(ar, skb); -++ break; -++ case WMI_TLV_RTT_MEASUREMENT_REPORT_EVENTID: -++ ath10k_wmi_event_rtt_measurement_report(ar, skb); -++ break; -++ case WMI_TLV_TSF_MEASUREMENT_REPORT_EVENTID: -++ ath10k_wmi_event_tsf_measurement_report(ar, skb); -++ break; -++ case WMI_TLV_RTT_ERROR_REPORT_EVENTID: -++ ath10k_wmi_event_rtt_error_report(ar, skb); -++ break; -++ case WMI_TLV_WOW_WAKEUP_HOST_EVENTID: -++ ath10k_wmi_event_wow_wakeup_host(ar, skb); -++ break; -++ case WMI_TLV_DCS_INTERFERENCE_EVENTID: -++ ath10k_wmi_event_dcs_interference(ar, skb); -++ break; -++ case WMI_TLV_PDEV_TPC_CONFIG_EVENTID: -++ ath10k_wmi_event_pdev_tpc_config(ar, skb); -++ break; -++ case WMI_TLV_PDEV_FTM_INTG_EVENTID: -++ ath10k_wmi_event_pdev_ftm_intg(ar, skb); -++ break; -++ case WMI_TLV_GTK_OFFLOAD_STATUS_EVENTID: -++ ath10k_wmi_event_gtk_offload_status(ar, skb); -++ break; -++ case WMI_TLV_GTK_REKEY_FAIL_EVENTID: -++ ath10k_wmi_event_gtk_rekey_fail(ar, skb); -++ break; -++ case WMI_TLV_TX_DELBA_COMPLETE_EVENTID: -++ ath10k_wmi_event_delba_complete(ar, skb); -++ break; -++ case WMI_TLV_TX_ADDBA_COMPLETE_EVENTID: -++ ath10k_wmi_event_addba_complete(ar, skb); -++ break; -++ case WMI_TLV_VDEV_INSTALL_KEY_COMPLETE_EVENTID: -++ ath10k_wmi_event_vdev_install_key_complete(ar, skb); -++ break; -++ case WMI_TLV_SERVICE_READY_EVENTID: -++ ath10k_wmi_event_service_ready(ar, skb); -++ break; -++ case WMI_TLV_READY_EVENTID: -++ ath10k_wmi_event_ready(ar, skb); -++ break; -++ case WMI_TLV_OFFLOAD_BCN_TX_STATUS_EVENTID: -++ ath10k_wmi_tlv_event_bcn_tx_status(ar, skb); -++ break; -++ case WMI_TLV_DIAG_DATA_CONTAINER_EVENTID: -++ ath10k_wmi_tlv_event_diag_data(ar, skb); -++ break; -++ case WMI_TLV_DIAG_EVENTID: -++ ath10k_wmi_tlv_event_diag(ar, skb); -++ break; -++ default: -++ ath10k_warn(ar, "Unknown eventid: %d\n", id); -++ break; -++ } -++ -++ dev_kfree_skb(skb); -++} -++ -++static int ath10k_wmi_tlv_op_pull_scan_ev(struct ath10k *ar, -++ struct sk_buff *skb, -++ struct wmi_scan_ev_arg *arg) -++{ -++ const void **tb; -++ const struct wmi_scan_event *ev; -++ int ret; -++ -++ tb = ath10k_wmi_tlv_parse_alloc(ar, skb->data, skb->len, GFP_ATOMIC); -++ if (IS_ERR(tb)) { -++ ret = PTR_ERR(tb); -++ ath10k_warn(ar, "failed to parse tlv: %d\n", ret); -++ return ret; -++ } -++ -++ ev = tb[WMI_TLV_TAG_STRUCT_SCAN_EVENT]; -++ if (!ev) { -++ kfree(tb); -++ return -EPROTO; -++ } -++ -++ arg->event_type = ev->event_type; -++ arg->reason = ev->reason; -++ arg->channel_freq = ev->channel_freq; -++ arg->scan_req_id = ev->scan_req_id; -++ arg->scan_id = ev->scan_id; -++ arg->vdev_id = ev->vdev_id; -++ -++ kfree(tb); -++ return 0; -++} -++ -++static int ath10k_wmi_tlv_op_pull_mgmt_rx_ev(struct ath10k *ar, -++ struct sk_buff *skb, -++ struct wmi_mgmt_rx_ev_arg *arg) -++{ -++ const void **tb; -++ const struct wmi_tlv_mgmt_rx_ev *ev; -++ const u8 *frame; -++ u32 msdu_len; -++ int ret; -++ -++ tb = ath10k_wmi_tlv_parse_alloc(ar, skb->data, skb->len, GFP_ATOMIC); -++ if (IS_ERR(tb)) { -++ ret = PTR_ERR(tb); -++ ath10k_warn(ar, "failed to parse tlv: %d\n", ret); -++ return ret; -++ } -++ -++ ev = tb[WMI_TLV_TAG_STRUCT_MGMT_RX_HDR]; -++ frame = tb[WMI_TLV_TAG_ARRAY_BYTE]; -++ -++ if (!ev || !frame) { -++ kfree(tb); -++ return -EPROTO; -++ } -++ -++ arg->channel = ev->channel; -++ arg->buf_len = ev->buf_len; -++ arg->status = ev->status; -++ arg->snr = ev->snr; -++ arg->phy_mode = ev->phy_mode; -++ arg->rate = ev->rate; -++ -++ msdu_len = __le32_to_cpu(arg->buf_len); -++ -++ if (skb->len < (frame - skb->data) + msdu_len) { -++ kfree(tb); -++ return -EPROTO; -++ } -++ -++ /* shift the sk_buff to point to `frame` */ -++ skb_trim(skb, 0); -++ skb_put(skb, frame - skb->data); -++ skb_pull(skb, frame - skb->data); -++ skb_put(skb, msdu_len); -++ -++ kfree(tb); -++ return 0; -++} -++ -++static int ath10k_wmi_tlv_op_pull_ch_info_ev(struct ath10k *ar, -++ struct sk_buff *skb, -++ struct wmi_ch_info_ev_arg *arg) -++{ -++ const void **tb; -++ const struct wmi_chan_info_event *ev; -++ int ret; -++ -++ tb = ath10k_wmi_tlv_parse_alloc(ar, skb->data, skb->len, GFP_ATOMIC); -++ if (IS_ERR(tb)) { -++ ret = PTR_ERR(tb); -++ ath10k_warn(ar, "failed to parse tlv: %d\n", ret); -++ return ret; -++ } -++ -++ ev = tb[WMI_TLV_TAG_STRUCT_CHAN_INFO_EVENT]; -++ if (!ev) { -++ kfree(tb); -++ return -EPROTO; -++ } -++ -++ arg->err_code = ev->err_code; -++ arg->freq = ev->freq; -++ arg->cmd_flags = ev->cmd_flags; -++ arg->noise_floor = ev->noise_floor; -++ arg->rx_clear_count = ev->rx_clear_count; -++ arg->cycle_count = ev->cycle_count; -++ -++ kfree(tb); -++ return 0; -++} -++ -++static int -++ath10k_wmi_tlv_op_pull_vdev_start_ev(struct ath10k *ar, struct sk_buff *skb, -++ struct wmi_vdev_start_ev_arg *arg) -++{ -++ const void **tb; -++ const struct wmi_vdev_start_response_event *ev; -++ int ret; -++ -++ tb = ath10k_wmi_tlv_parse_alloc(ar, skb->data, skb->len, GFP_ATOMIC); -++ if (IS_ERR(tb)) { -++ ret = PTR_ERR(tb); -++ ath10k_warn(ar, "failed to parse tlv: %d\n", ret); -++ return ret; -++ } -++ -++ ev = tb[WMI_TLV_TAG_STRUCT_VDEV_START_RESPONSE_EVENT]; -++ if (!ev) { -++ kfree(tb); -++ return -EPROTO; -++ } -++ -++ skb_pull(skb, sizeof(*ev)); -++ arg->vdev_id = ev->vdev_id; -++ arg->req_id = ev->req_id; -++ arg->resp_type = ev->resp_type; -++ arg->status = ev->status; -++ -++ kfree(tb); -++ return 0; -++} -++ -++static int ath10k_wmi_tlv_op_pull_peer_kick_ev(struct ath10k *ar, -++ struct sk_buff *skb, -++ struct wmi_peer_kick_ev_arg *arg) -++{ -++ const void **tb; -++ const struct wmi_peer_sta_kickout_event *ev; -++ int ret; -++ -++ tb = ath10k_wmi_tlv_parse_alloc(ar, skb->data, skb->len, GFP_ATOMIC); -++ if (IS_ERR(tb)) { -++ ret = PTR_ERR(tb); -++ ath10k_warn(ar, "failed to parse tlv: %d\n", ret); -++ return ret; -++ } -++ -++ ev = tb[WMI_TLV_TAG_STRUCT_PEER_STA_KICKOUT_EVENT]; -++ if (!ev) { -++ kfree(tb); -++ return -EPROTO; -++ } -++ -++ arg->mac_addr = ev->peer_macaddr.addr; -++ -++ kfree(tb); -++ return 0; -++} -++ -++struct wmi_tlv_swba_parse { -++ const struct wmi_host_swba_event *ev; -++ bool tim_done; -++ bool noa_done; -++ size_t n_tim; -++ size_t n_noa; -++ struct wmi_swba_ev_arg *arg; -++}; -++ -++static int ath10k_wmi_tlv_swba_tim_parse(struct ath10k *ar, u16 tag, u16 len, -++ const void *ptr, void *data) -++{ -++ struct wmi_tlv_swba_parse *swba = data; -++ -++ if (tag != WMI_TLV_TAG_STRUCT_TIM_INFO) -++ return -EPROTO; -++ -++ if (swba->n_tim >= ARRAY_SIZE(swba->arg->tim_info)) -++ return -ENOBUFS; -++ -++ swba->arg->tim_info[swba->n_tim++] = ptr; -++ return 0; -++} -++ -++static int ath10k_wmi_tlv_swba_noa_parse(struct ath10k *ar, u16 tag, u16 len, -++ const void *ptr, void *data) -++{ -++ struct wmi_tlv_swba_parse *swba = data; -++ -++ if (tag != WMI_TLV_TAG_STRUCT_P2P_NOA_INFO) -++ return -EPROTO; -++ -++ if (swba->n_noa >= ARRAY_SIZE(swba->arg->noa_info)) -++ return -ENOBUFS; -++ -++ swba->arg->noa_info[swba->n_noa++] = ptr; -++ return 0; -++} -++ -++static int ath10k_wmi_tlv_swba_parse(struct ath10k *ar, u16 tag, u16 len, -++ const void *ptr, void *data) -++{ -++ struct wmi_tlv_swba_parse *swba = data; -++ int ret; -++ -++ switch (tag) { -++ case WMI_TLV_TAG_STRUCT_HOST_SWBA_EVENT: -++ swba->ev = ptr; -++ break; -++ case WMI_TLV_TAG_ARRAY_STRUCT: -++ if (!swba->tim_done) { -++ swba->tim_done = true; -++ ret = ath10k_wmi_tlv_iter(ar, ptr, len, -++ ath10k_wmi_tlv_swba_tim_parse, -++ swba); -++ if (ret) -++ return ret; -++ } else if (!swba->noa_done) { -++ swba->noa_done = true; -++ ret = ath10k_wmi_tlv_iter(ar, ptr, len, -++ ath10k_wmi_tlv_swba_noa_parse, -++ swba); -++ if (ret) -++ return ret; -++ } -++ break; -++ default: -++ break; -++ } -++ return 0; -++} -++ -++static int ath10k_wmi_tlv_op_pull_swba_ev(struct ath10k *ar, -++ struct sk_buff *skb, -++ struct wmi_swba_ev_arg *arg) -++{ -++ struct wmi_tlv_swba_parse swba = { .arg = arg }; -++ u32 map; -++ size_t n_vdevs; -++ int ret; -++ -++ ret = ath10k_wmi_tlv_iter(ar, skb->data, skb->len, -++ ath10k_wmi_tlv_swba_parse, &swba); -++ if (ret) { -++ ath10k_warn(ar, "failed to parse tlv: %d\n", ret); -++ return ret; -++ } -++ -++ if (!swba.ev) -++ return -EPROTO; -++ -++ arg->vdev_map = swba.ev->vdev_map; -++ -++ for (map = __le32_to_cpu(arg->vdev_map), n_vdevs = 0; map; map >>= 1) -++ if (map & BIT(0)) -++ n_vdevs++; -++ -++ if (n_vdevs != swba.n_tim || -++ n_vdevs != swba.n_noa) -++ return -EPROTO; -++ -++ return 0; -++} -++ -++static int ath10k_wmi_tlv_op_pull_phyerr_ev(struct ath10k *ar, -++ struct sk_buff *skb, -++ struct wmi_phyerr_ev_arg *arg) -++{ -++ const void **tb; -++ const struct wmi_tlv_phyerr_ev *ev; -++ const void *phyerrs; -++ int ret; -++ -++ tb = ath10k_wmi_tlv_parse_alloc(ar, skb->data, skb->len, GFP_ATOMIC); -++ if (IS_ERR(tb)) { -++ ret = PTR_ERR(tb); -++ ath10k_warn(ar, "failed to parse tlv: %d\n", ret); -++ return ret; -++ } -++ -++ ev = tb[WMI_TLV_TAG_STRUCT_COMB_PHYERR_RX_HDR]; -++ phyerrs = tb[WMI_TLV_TAG_ARRAY_BYTE]; -++ -++ if (!ev || !phyerrs) { -++ kfree(tb); -++ return -EPROTO; -++ } -++ -++ arg->num_phyerrs = ev->num_phyerrs; -++ arg->tsf_l32 = ev->tsf_l32; -++ arg->tsf_u32 = ev->tsf_u32; -++ arg->buf_len = ev->buf_len; -++ arg->phyerrs = phyerrs; -++ -++ kfree(tb); -++ return 0; -++} -++ -++#define WMI_TLV_ABI_VER_NS0 0x5F414351 -++#define WMI_TLV_ABI_VER_NS1 0x00004C4D -++#define WMI_TLV_ABI_VER_NS2 0x00000000 -++#define WMI_TLV_ABI_VER_NS3 0x00000000 -++ -++#define WMI_TLV_ABI_VER0_MAJOR 1 -++#define WMI_TLV_ABI_VER0_MINOR 0 -++#define WMI_TLV_ABI_VER0 ((((WMI_TLV_ABI_VER0_MAJOR) << 24) & 0xFF000000) | \ -++ (((WMI_TLV_ABI_VER0_MINOR) << 0) & 0x00FFFFFF)) -++#define WMI_TLV_ABI_VER1 53 -++ -++static int -++ath10k_wmi_tlv_parse_mem_reqs(struct ath10k *ar, u16 tag, u16 len, -++ const void *ptr, void *data) -++{ -++ struct wmi_svc_rdy_ev_arg *arg = data; -++ int i; -++ -++ if (tag != WMI_TLV_TAG_STRUCT_WLAN_HOST_MEM_REQ) -++ return -EPROTO; -++ -++ for (i = 0; i < ARRAY_SIZE(arg->mem_reqs); i++) { -++ if (!arg->mem_reqs[i]) { -++ arg->mem_reqs[i] = ptr; -++ return 0; -++ } -++ } -++ -++ return -ENOMEM; -++} -++ -++static int ath10k_wmi_tlv_op_pull_svc_rdy_ev(struct ath10k *ar, -++ struct sk_buff *skb, -++ struct wmi_svc_rdy_ev_arg *arg) -++{ -++ const void **tb; -++ const struct hal_reg_capabilities *reg; -++ const struct wmi_tlv_svc_rdy_ev *ev; -++ const __le32 *svc_bmap; -++ const struct wlan_host_mem_req *mem_reqs; -++ int ret; -++ -++ tb = ath10k_wmi_tlv_parse_alloc(ar, skb->data, skb->len, GFP_ATOMIC); -++ if (IS_ERR(tb)) { -++ ret = PTR_ERR(tb); -++ ath10k_warn(ar, "failed to parse tlv: %d\n", ret); -++ return ret; -++ } -++ -++ ev = tb[WMI_TLV_TAG_STRUCT_SERVICE_READY_EVENT]; -++ reg = tb[WMI_TLV_TAG_STRUCT_HAL_REG_CAPABILITIES]; -++ svc_bmap = tb[WMI_TLV_TAG_ARRAY_UINT32]; -++ mem_reqs = tb[WMI_TLV_TAG_ARRAY_STRUCT]; -++ -++ if (!ev || !reg || !svc_bmap || !mem_reqs) { -++ kfree(tb); -++ return -EPROTO; -++ } -++ -++ /* This is an internal ABI compatibility check for WMI TLV so check it -++ * here instead of the generic WMI code. -++ */ -++ ath10k_dbg(ar, ATH10K_DBG_WMI, -++ "wmi tlv abi 0x%08x ?= 0x%08x, 0x%08x ?= 0x%08x, 0x%08x ?= 0x%08x, 0x%08x ?= 0x%08x, 0x%08x ?= 0x%08x\n", -++ __le32_to_cpu(ev->abi.abi_ver0), WMI_TLV_ABI_VER0, -++ __le32_to_cpu(ev->abi.abi_ver_ns0), WMI_TLV_ABI_VER_NS0, -++ __le32_to_cpu(ev->abi.abi_ver_ns1), WMI_TLV_ABI_VER_NS1, -++ __le32_to_cpu(ev->abi.abi_ver_ns2), WMI_TLV_ABI_VER_NS2, -++ __le32_to_cpu(ev->abi.abi_ver_ns3), WMI_TLV_ABI_VER_NS3); -++ -++ if (__le32_to_cpu(ev->abi.abi_ver0) != WMI_TLV_ABI_VER0 || -++ __le32_to_cpu(ev->abi.abi_ver_ns0) != WMI_TLV_ABI_VER_NS0 || -++ __le32_to_cpu(ev->abi.abi_ver_ns1) != WMI_TLV_ABI_VER_NS1 || -++ __le32_to_cpu(ev->abi.abi_ver_ns2) != WMI_TLV_ABI_VER_NS2 || -++ __le32_to_cpu(ev->abi.abi_ver_ns3) != WMI_TLV_ABI_VER_NS3) { -++ kfree(tb); -++ return -ENOTSUPP; -++ } -++ -++ arg->min_tx_power = ev->hw_min_tx_power; -++ arg->max_tx_power = ev->hw_max_tx_power; -++ arg->ht_cap = ev->ht_cap_info; -++ arg->vht_cap = ev->vht_cap_info; -++ arg->sw_ver0 = ev->abi.abi_ver0; -++ arg->sw_ver1 = ev->abi.abi_ver1; -++ arg->fw_build = ev->fw_build_vers; -++ arg->phy_capab = ev->phy_capability; -++ arg->num_rf_chains = ev->num_rf_chains; -++ arg->eeprom_rd = reg->eeprom_rd; -++ arg->num_mem_reqs = ev->num_mem_reqs; -++ arg->service_map = svc_bmap; -++ arg->service_map_len = ath10k_wmi_tlv_len(svc_bmap); -++ -++ ret = ath10k_wmi_tlv_iter(ar, mem_reqs, ath10k_wmi_tlv_len(mem_reqs), -++ ath10k_wmi_tlv_parse_mem_reqs, arg); -++ if (ret) { -++ kfree(tb); -++ ath10k_warn(ar, "failed to parse mem_reqs tlv: %d\n", ret); -++ return ret; -++ } -++ -++ kfree(tb); -++ return 0; -++} -++ -++static int ath10k_wmi_tlv_op_pull_rdy_ev(struct ath10k *ar, -++ struct sk_buff *skb, -++ struct wmi_rdy_ev_arg *arg) -++{ -++ const void **tb; -++ const struct wmi_tlv_rdy_ev *ev; -++ int ret; -++ -++ tb = ath10k_wmi_tlv_parse_alloc(ar, skb->data, skb->len, GFP_ATOMIC); -++ if (IS_ERR(tb)) { -++ ret = PTR_ERR(tb); -++ ath10k_warn(ar, "failed to parse tlv: %d\n", ret); -++ return ret; -++ } -++ -++ ev = tb[WMI_TLV_TAG_STRUCT_READY_EVENT]; -++ if (!ev) { -++ kfree(tb); -++ return -EPROTO; -++ } -++ -++ arg->sw_version = ev->abi.abi_ver0; -++ arg->abi_version = ev->abi.abi_ver1; -++ arg->status = ev->status; -++ arg->mac_addr = ev->mac_addr.addr; -++ -++ kfree(tb); -++ return 0; -++} -++ -++static void ath10k_wmi_tlv_pull_vdev_stats(const struct wmi_tlv_vdev_stats *src, -++ struct ath10k_fw_stats_vdev *dst) -++{ -++ int i; -++ -++ dst->vdev_id = __le32_to_cpu(src->vdev_id); -++ dst->beacon_snr = __le32_to_cpu(src->beacon_snr); -++ dst->data_snr = __le32_to_cpu(src->data_snr); -++ dst->num_rx_frames = __le32_to_cpu(src->num_rx_frames); -++ dst->num_rts_fail = __le32_to_cpu(src->num_rts_fail); -++ dst->num_rts_success = __le32_to_cpu(src->num_rts_success); -++ dst->num_rx_err = __le32_to_cpu(src->num_rx_err); -++ dst->num_rx_discard = __le32_to_cpu(src->num_rx_discard); -++ dst->num_tx_not_acked = __le32_to_cpu(src->num_tx_not_acked); -++ -++ for (i = 0; i < ARRAY_SIZE(src->num_tx_frames); i++) -++ dst->num_tx_frames[i] = -++ __le32_to_cpu(src->num_tx_frames[i]); -++ -++ for (i = 0; i < ARRAY_SIZE(src->num_tx_frames_retries); i++) -++ dst->num_tx_frames_retries[i] = -++ __le32_to_cpu(src->num_tx_frames_retries[i]); -++ -++ for (i = 0; i < ARRAY_SIZE(src->num_tx_frames_failures); i++) -++ dst->num_tx_frames_failures[i] = -++ __le32_to_cpu(src->num_tx_frames_failures[i]); -++ -++ for (i = 0; i < ARRAY_SIZE(src->tx_rate_history); i++) -++ dst->tx_rate_history[i] = -++ __le32_to_cpu(src->tx_rate_history[i]); -++ -++ for (i = 0; i < ARRAY_SIZE(src->beacon_rssi_history); i++) -++ dst->beacon_rssi_history[i] = -++ __le32_to_cpu(src->beacon_rssi_history[i]); -++} -++ -++static int ath10k_wmi_tlv_op_pull_fw_stats(struct ath10k *ar, -++ struct sk_buff *skb, -++ struct ath10k_fw_stats *stats) -++{ -++ const void **tb; -++ const struct wmi_tlv_stats_ev *ev; -++ const void *data; -++ u32 num_pdev_stats; -++ u32 num_vdev_stats; -++ u32 num_peer_stats; -++ u32 num_bcnflt_stats; -++ u32 num_chan_stats; -++ size_t data_len; -++ int ret; -++ int i; -++ -++ tb = ath10k_wmi_tlv_parse_alloc(ar, skb->data, skb->len, GFP_ATOMIC); -++ if (IS_ERR(tb)) { -++ ret = PTR_ERR(tb); -++ ath10k_warn(ar, "failed to parse tlv: %d\n", ret); -++ return ret; -++ } -++ -++ ev = tb[WMI_TLV_TAG_STRUCT_STATS_EVENT]; -++ data = tb[WMI_TLV_TAG_ARRAY_BYTE]; -++ -++ if (!ev || !data) { -++ kfree(tb); -++ return -EPROTO; -++ } -++ -++ data_len = ath10k_wmi_tlv_len(data); -++ num_pdev_stats = __le32_to_cpu(ev->num_pdev_stats); -++ num_vdev_stats = __le32_to_cpu(ev->num_vdev_stats); -++ num_peer_stats = __le32_to_cpu(ev->num_peer_stats); -++ num_bcnflt_stats = __le32_to_cpu(ev->num_bcnflt_stats); -++ num_chan_stats = __le32_to_cpu(ev->num_chan_stats); -++ -++ ath10k_dbg(ar, ATH10K_DBG_WMI, -++ "wmi tlv stats update pdev %i vdev %i peer %i bcnflt %i chan %i\n", -++ num_pdev_stats, num_vdev_stats, num_peer_stats, -++ num_bcnflt_stats, num_chan_stats); -++ -++ for (i = 0; i < num_pdev_stats; i++) { -++ const struct wmi_pdev_stats *src; -++ struct ath10k_fw_stats_pdev *dst; -++ -++ src = data; -++ if (data_len < sizeof(*src)) -++ return -EPROTO; -++ -++ data += sizeof(*src); -++ data_len -= sizeof(*src); -++ -++ dst = kzalloc(sizeof(*dst), GFP_ATOMIC); -++ if (!dst) -++ continue; -++ -++ ath10k_wmi_pull_pdev_stats_base(&src->base, dst); -++ ath10k_wmi_pull_pdev_stats_tx(&src->tx, dst); -++ ath10k_wmi_pull_pdev_stats_rx(&src->rx, dst); -++ list_add_tail(&dst->list, &stats->pdevs); -++ } -++ -++ for (i = 0; i < num_vdev_stats; i++) { -++ const struct wmi_tlv_vdev_stats *src; -++ struct ath10k_fw_stats_vdev *dst; -++ -++ src = data; -++ if (data_len < sizeof(*src)) -++ return -EPROTO; -++ -++ data += sizeof(*src); -++ data_len -= sizeof(*src); -++ -++ dst = kzalloc(sizeof(*dst), GFP_ATOMIC); -++ if (!dst) -++ continue; -++ -++ ath10k_wmi_tlv_pull_vdev_stats(src, dst); -++ list_add_tail(&dst->list, &stats->vdevs); -++ } -++ -++ for (i = 0; i < num_peer_stats; i++) { -++ const struct wmi_10x_peer_stats *src; -++ struct ath10k_fw_stats_peer *dst; -++ -++ src = data; -++ if (data_len < sizeof(*src)) -++ return -EPROTO; -++ -++ data += sizeof(*src); -++ data_len -= sizeof(*src); -++ -++ dst = kzalloc(sizeof(*dst), GFP_ATOMIC); -++ if (!dst) -++ continue; -++ -++ ath10k_wmi_pull_peer_stats(&src->old, dst); -++ dst->peer_rx_rate = __le32_to_cpu(src->peer_rx_rate); -++ list_add_tail(&dst->list, &stats->peers); -++ } -++ -++ kfree(tb); -++ return 0; -++} -++ -++static struct sk_buff * -++ath10k_wmi_tlv_op_gen_pdev_suspend(struct ath10k *ar, u32 opt) -++{ -++ struct wmi_tlv_pdev_suspend *cmd; -++ struct wmi_tlv *tlv; -++ struct sk_buff *skb; -++ -++ skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd)); -++ if (!skb) -++ return ERR_PTR(-ENOMEM); -++ -++ tlv = (void *)skb->data; -++ tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_PDEV_SUSPEND_CMD); -++ tlv->len = __cpu_to_le16(sizeof(*cmd)); -++ cmd = (void *)tlv->value; -++ cmd->opt = __cpu_to_le32(opt); -++ -++ ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv pdev suspend\n"); -++ return skb; -++} -++ -++static struct sk_buff * -++ath10k_wmi_tlv_op_gen_pdev_resume(struct ath10k *ar) -++{ -++ struct wmi_tlv_resume_cmd *cmd; -++ struct wmi_tlv *tlv; -++ struct sk_buff *skb; -++ -++ skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd)); -++ if (!skb) -++ return ERR_PTR(-ENOMEM); -++ -++ tlv = (void *)skb->data; -++ tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_PDEV_RESUME_CMD); -++ tlv->len = __cpu_to_le16(sizeof(*cmd)); -++ cmd = (void *)tlv->value; -++ cmd->reserved = __cpu_to_le32(0); -++ -++ ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv pdev resume\n"); -++ return skb; -++} -++ -++static struct sk_buff * -++ath10k_wmi_tlv_op_gen_pdev_set_rd(struct ath10k *ar, -++ u16 rd, u16 rd2g, u16 rd5g, -++ u16 ctl2g, u16 ctl5g, -++ enum wmi_dfs_region dfs_reg) -++{ -++ struct wmi_tlv_pdev_set_rd_cmd *cmd; -++ struct wmi_tlv *tlv; -++ struct sk_buff *skb; -++ -++ skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd)); -++ if (!skb) -++ return ERR_PTR(-ENOMEM); -++ -++ tlv = (void *)skb->data; -++ tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_PDEV_SET_REGDOMAIN_CMD); -++ tlv->len = __cpu_to_le16(sizeof(*cmd)); -++ cmd = (void *)tlv->value; -++ cmd->regd = __cpu_to_le32(rd); -++ cmd->regd_2ghz = __cpu_to_le32(rd2g); -++ cmd->regd_5ghz = __cpu_to_le32(rd5g); -++ cmd->conform_limit_2ghz = __cpu_to_le32(rd2g); -++ cmd->conform_limit_5ghz = __cpu_to_le32(rd5g); -++ -++ ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv pdev set rd\n"); -++ return skb; -++} -++ -++static struct sk_buff * -++ath10k_wmi_tlv_op_gen_pdev_set_param(struct ath10k *ar, u32 param_id, -++ u32 param_value) -++{ -++ struct wmi_tlv_pdev_set_param_cmd *cmd; -++ struct wmi_tlv *tlv; -++ struct sk_buff *skb; -++ -++ skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd)); -++ if (!skb) -++ return ERR_PTR(-ENOMEM); -++ -++ tlv = (void *)skb->data; -++ tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_PDEV_SET_PARAM_CMD); -++ tlv->len = __cpu_to_le16(sizeof(*cmd)); -++ cmd = (void *)tlv->value; -++ cmd->param_id = __cpu_to_le32(param_id); -++ cmd->param_value = __cpu_to_le32(param_value); -++ -++ ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv pdev set param\n"); -++ return skb; -++} -++ -++static struct sk_buff *ath10k_wmi_tlv_op_gen_init(struct ath10k *ar) -++{ -++ struct sk_buff *skb; -++ struct wmi_tlv *tlv; -++ struct wmi_tlv_init_cmd *cmd; -++ struct wmi_tlv_resource_config *cfg; -++ struct wmi_host_mem_chunks *chunks; -++ size_t len, chunks_len; -++ void *ptr; -++ -++ chunks_len = ar->wmi.num_mem_chunks * sizeof(struct host_memory_chunk); -++ len = (sizeof(*tlv) + sizeof(*cmd)) + -++ (sizeof(*tlv) + sizeof(*cfg)) + -++ (sizeof(*tlv) + chunks_len); -++ -++ skb = ath10k_wmi_alloc_skb(ar, len); -++ if (!skb) -++ return ERR_PTR(-ENOMEM); -++ -++ ptr = skb->data; -++ -++ tlv = ptr; -++ tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_INIT_CMD); -++ tlv->len = __cpu_to_le16(sizeof(*cmd)); -++ cmd = (void *)tlv->value; -++ ptr += sizeof(*tlv); -++ ptr += sizeof(*cmd); -++ -++ tlv = ptr; -++ tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_RESOURCE_CONFIG); -++ tlv->len = __cpu_to_le16(sizeof(*cfg)); -++ cfg = (void *)tlv->value; -++ ptr += sizeof(*tlv); -++ ptr += sizeof(*cfg); -++ -++ tlv = ptr; -++ tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_STRUCT); -++ tlv->len = __cpu_to_le16(chunks_len); -++ chunks = (void *)tlv->value; -++ -++ ptr += sizeof(*tlv); -++ ptr += chunks_len; -++ -++ cmd->abi.abi_ver0 = __cpu_to_le32(WMI_TLV_ABI_VER0); -++ cmd->abi.abi_ver1 = __cpu_to_le32(WMI_TLV_ABI_VER1); -++ cmd->abi.abi_ver_ns0 = __cpu_to_le32(WMI_TLV_ABI_VER_NS0); -++ cmd->abi.abi_ver_ns1 = __cpu_to_le32(WMI_TLV_ABI_VER_NS1); -++ cmd->abi.abi_ver_ns2 = __cpu_to_le32(WMI_TLV_ABI_VER_NS2); -++ cmd->abi.abi_ver_ns3 = __cpu_to_le32(WMI_TLV_ABI_VER_NS3); -++ cmd->num_host_mem_chunks = __cpu_to_le32(ar->wmi.num_mem_chunks); -++ -++ cfg->num_vdevs = __cpu_to_le32(TARGET_TLV_NUM_VDEVS); -++ cfg->num_peers = __cpu_to_le32(TARGET_TLV_NUM_PEERS); -++ -++ if (test_bit(WMI_SERVICE_RX_FULL_REORDER, ar->wmi.svc_map)) { -++ cfg->num_offload_peers = __cpu_to_le32(3); -++ cfg->num_offload_reorder_bufs = __cpu_to_le32(3); -++ } else { -++ cfg->num_offload_peers = __cpu_to_le32(0); -++ cfg->num_offload_reorder_bufs = __cpu_to_le32(0); -++ } -++ -++ cfg->num_peer_keys = __cpu_to_le32(2); -++ cfg->num_tids = __cpu_to_le32(TARGET_TLV_NUM_TIDS); -++ cfg->ast_skid_limit = __cpu_to_le32(0x10); -++ cfg->tx_chain_mask = __cpu_to_le32(0x7); -++ cfg->rx_chain_mask = __cpu_to_le32(0x7); -++ cfg->rx_timeout_pri[0] = __cpu_to_le32(0x64); -++ cfg->rx_timeout_pri[1] = __cpu_to_le32(0x64); -++ cfg->rx_timeout_pri[2] = __cpu_to_le32(0x64); -++ cfg->rx_timeout_pri[3] = __cpu_to_le32(0x28); -++ cfg->rx_decap_mode = __cpu_to_le32(1); -++ cfg->scan_max_pending_reqs = __cpu_to_le32(4); -++ cfg->bmiss_offload_max_vdev = __cpu_to_le32(3); -++ cfg->roam_offload_max_vdev = __cpu_to_le32(3); -++ cfg->roam_offload_max_ap_profiles = __cpu_to_le32(8); -++ cfg->num_mcast_groups = __cpu_to_le32(0); -++ cfg->num_mcast_table_elems = __cpu_to_le32(0); -++ cfg->mcast2ucast_mode = __cpu_to_le32(0); -++ cfg->tx_dbg_log_size = __cpu_to_le32(0x400); -++ cfg->num_wds_entries = __cpu_to_le32(0x20); -++ cfg->dma_burst_size = __cpu_to_le32(0); -++ cfg->mac_aggr_delim = __cpu_to_le32(0); -++ cfg->rx_skip_defrag_timeout_dup_detection_check = __cpu_to_le32(0); -++ cfg->vow_config = __cpu_to_le32(0); -++ cfg->gtk_offload_max_vdev = __cpu_to_le32(2); -++ cfg->num_msdu_desc = __cpu_to_le32(TARGET_TLV_NUM_MSDU_DESC); -++ cfg->max_frag_entries = __cpu_to_le32(2); -++ cfg->num_tdls_vdevs = __cpu_to_le32(1); -++ cfg->num_tdls_conn_table_entries = __cpu_to_le32(0x20); -++ cfg->beacon_tx_offload_max_vdev = __cpu_to_le32(2); -++ cfg->num_multicast_filter_entries = __cpu_to_le32(5); -++ cfg->num_wow_filters = __cpu_to_le32(0x16); -++ cfg->num_keep_alive_pattern = __cpu_to_le32(6); -++ cfg->keep_alive_pattern_size = __cpu_to_le32(0); -++ cfg->max_tdls_concurrent_sleep_sta = __cpu_to_le32(1); -++ cfg->max_tdls_concurrent_buffer_sta = __cpu_to_le32(1); -++ -++ ath10k_wmi_put_host_mem_chunks(ar, chunks); -++ -++ ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv init\n"); -++ return skb; -++} -++ -++static struct sk_buff * -++ath10k_wmi_tlv_op_gen_start_scan(struct ath10k *ar, -++ const struct wmi_start_scan_arg *arg) -++{ -++ struct wmi_tlv_start_scan_cmd *cmd; -++ struct wmi_tlv *tlv; -++ struct sk_buff *skb; -++ size_t len, chan_len, ssid_len, bssid_len, ie_len; -++ __le32 *chans; -++ struct wmi_ssid *ssids; -++ struct wmi_mac_addr *addrs; -++ void *ptr; -++ int i, ret; -++ -++ ret = ath10k_wmi_start_scan_verify(arg); -++ if (ret) -++ return ERR_PTR(ret); -++ -++ chan_len = arg->n_channels * sizeof(__le32); -++ ssid_len = arg->n_ssids * sizeof(struct wmi_ssid); -++ bssid_len = arg->n_bssids * sizeof(struct wmi_mac_addr); -++ ie_len = roundup(arg->ie_len, 4); -++ len = (sizeof(*tlv) + sizeof(*cmd)) + -++ (arg->n_channels ? sizeof(*tlv) + chan_len : 0) + -++ (arg->n_ssids ? sizeof(*tlv) + ssid_len : 0) + -++ (arg->n_bssids ? sizeof(*tlv) + bssid_len : 0) + -++ (arg->ie_len ? sizeof(*tlv) + ie_len : 0); -++ -++ skb = ath10k_wmi_alloc_skb(ar, len); -++ if (!skb) -++ return ERR_PTR(-ENOMEM); -++ -++ ptr = (void *)skb->data; -++ tlv = ptr; -++ tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_START_SCAN_CMD); -++ tlv->len = __cpu_to_le16(sizeof(*cmd)); -++ cmd = (void *)tlv->value; -++ -++ ath10k_wmi_put_start_scan_common(&cmd->common, arg); -++ cmd->burst_duration_ms = __cpu_to_le32(0); -++ cmd->num_channels = __cpu_to_le32(arg->n_channels); -++ cmd->num_ssids = __cpu_to_le32(arg->n_ssids); -++ cmd->num_bssids = __cpu_to_le32(arg->n_bssids); -++ cmd->ie_len = __cpu_to_le32(arg->ie_len); -++ cmd->num_probes = __cpu_to_le32(3); -++ -++ /* FIXME: There are some scan flag inconsistencies across firmwares, -++ * e.g. WMI-TLV inverts the logic behind the following flag. -++ */ -++ cmd->common.scan_ctrl_flags ^= __cpu_to_le32(WMI_SCAN_FILTER_PROBE_REQ); -++ -++ ptr += sizeof(*tlv); -++ ptr += sizeof(*cmd); -++ -++ tlv = ptr; -++ tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_UINT32); -++ tlv->len = __cpu_to_le16(chan_len); -++ chans = (void *)tlv->value; -++ for (i = 0; i < arg->n_channels; i++) -++ chans[i] = __cpu_to_le32(arg->channels[i]); -++ -++ ptr += sizeof(*tlv); -++ ptr += chan_len; -++ -++ tlv = ptr; -++ tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_FIXED_STRUCT); -++ tlv->len = __cpu_to_le16(ssid_len); -++ ssids = (void *)tlv->value; -++ for (i = 0; i < arg->n_ssids; i++) { -++ ssids[i].ssid_len = __cpu_to_le32(arg->ssids[i].len); -++ memcpy(ssids[i].ssid, arg->ssids[i].ssid, arg->ssids[i].len); -++ } -++ -++ ptr += sizeof(*tlv); -++ ptr += ssid_len; -++ -++ tlv = ptr; -++ tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_FIXED_STRUCT); -++ tlv->len = __cpu_to_le16(bssid_len); -++ addrs = (void *)tlv->value; -++ for (i = 0; i < arg->n_bssids; i++) -++ ether_addr_copy(addrs[i].addr, arg->bssids[i].bssid); -++ -++ ptr += sizeof(*tlv); -++ ptr += bssid_len; -++ -++ tlv = ptr; -++ tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_BYTE); -++ tlv->len = __cpu_to_le16(ie_len); -++ memcpy(tlv->value, arg->ie, arg->ie_len); -++ -++ ptr += sizeof(*tlv); -++ ptr += ie_len; -++ -++ ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv start scan\n"); -++ return skb; -++} -++ -++static struct sk_buff * -++ath10k_wmi_tlv_op_gen_stop_scan(struct ath10k *ar, -++ const struct wmi_stop_scan_arg *arg) -++{ -++ struct wmi_stop_scan_cmd *cmd; -++ struct wmi_tlv *tlv; -++ struct sk_buff *skb; -++ u32 scan_id; -++ u32 req_id; -++ -++ if (arg->req_id > 0xFFF) -++ return ERR_PTR(-EINVAL); -++ if (arg->req_type == WMI_SCAN_STOP_ONE && arg->u.scan_id > 0xFFF) -++ return ERR_PTR(-EINVAL); -++ -++ skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd)); -++ if (!skb) -++ return ERR_PTR(-ENOMEM); -++ -++ scan_id = arg->u.scan_id; -++ scan_id |= WMI_HOST_SCAN_REQ_ID_PREFIX; -++ -++ req_id = arg->req_id; -++ req_id |= WMI_HOST_SCAN_REQUESTOR_ID_PREFIX; -++ -++ tlv = (void *)skb->data; -++ tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_STOP_SCAN_CMD); -++ tlv->len = __cpu_to_le16(sizeof(*cmd)); -++ cmd = (void *)tlv->value; -++ cmd->req_type = __cpu_to_le32(arg->req_type); -++ cmd->vdev_id = __cpu_to_le32(arg->u.vdev_id); -++ cmd->scan_id = __cpu_to_le32(scan_id); -++ cmd->scan_req_id = __cpu_to_le32(req_id); -++ -++ ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv stop scan\n"); -++ return skb; -++} -++ -++static struct sk_buff * -++ath10k_wmi_tlv_op_gen_vdev_create(struct ath10k *ar, -++ u32 vdev_id, -++ enum wmi_vdev_type vdev_type, -++ enum wmi_vdev_subtype vdev_subtype, -++ const u8 mac_addr[ETH_ALEN]) -++{ -++ struct wmi_vdev_create_cmd *cmd; -++ struct wmi_tlv *tlv; -++ struct sk_buff *skb; -++ -++ skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd)); -++ if (!skb) -++ return ERR_PTR(-ENOMEM); -++ -++ tlv = (void *)skb->data; -++ tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_VDEV_CREATE_CMD); -++ tlv->len = __cpu_to_le16(sizeof(*cmd)); -++ cmd = (void *)tlv->value; -++ cmd->vdev_id = __cpu_to_le32(vdev_id); -++ cmd->vdev_type = __cpu_to_le32(vdev_type); -++ cmd->vdev_subtype = __cpu_to_le32(vdev_subtype); -++ ether_addr_copy(cmd->vdev_macaddr.addr, mac_addr); -++ -++ ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv vdev create\n"); -++ return skb; -++} -++ -++static struct sk_buff * -++ath10k_wmi_tlv_op_gen_vdev_delete(struct ath10k *ar, u32 vdev_id) -++{ -++ struct wmi_vdev_delete_cmd *cmd; -++ struct wmi_tlv *tlv; -++ struct sk_buff *skb; -++ -++ skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd)); -++ if (!skb) -++ return ERR_PTR(-ENOMEM); -++ -++ tlv = (void *)skb->data; -++ tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_VDEV_DELETE_CMD); -++ tlv->len = __cpu_to_le16(sizeof(*cmd)); -++ cmd = (void *)tlv->value; -++ cmd->vdev_id = __cpu_to_le32(vdev_id); -++ -++ ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv vdev delete\n"); -++ return skb; -++} -++ -++static struct sk_buff * -++ath10k_wmi_tlv_op_gen_vdev_start(struct ath10k *ar, -++ const struct wmi_vdev_start_request_arg *arg, -++ bool restart) -++{ -++ struct wmi_tlv_vdev_start_cmd *cmd; -++ struct wmi_channel *ch; -++ struct wmi_p2p_noa_descriptor *noa; -++ struct wmi_tlv *tlv; -++ struct sk_buff *skb; -++ size_t len; -++ void *ptr; -++ u32 flags = 0; -++ -++ if (WARN_ON(arg->ssid && arg->ssid_len == 0)) -++ return ERR_PTR(-EINVAL); -++ if (WARN_ON(arg->hidden_ssid && !arg->ssid)) -++ return ERR_PTR(-EINVAL); -++ if (WARN_ON(arg->ssid_len > sizeof(cmd->ssid.ssid))) -++ return ERR_PTR(-EINVAL); -++ -++ len = (sizeof(*tlv) + sizeof(*cmd)) + -++ (sizeof(*tlv) + sizeof(*ch)) + -++ (sizeof(*tlv) + 0); -++ skb = ath10k_wmi_alloc_skb(ar, len); -++ if (!skb) -++ return ERR_PTR(-ENOMEM); -++ -++ if (arg->hidden_ssid) -++ flags |= WMI_VDEV_START_HIDDEN_SSID; -++ if (arg->pmf_enabled) -++ flags |= WMI_VDEV_START_PMF_ENABLED; -++ -++ ptr = (void *)skb->data; -++ -++ tlv = ptr; -++ tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_VDEV_START_REQUEST_CMD); -++ tlv->len = __cpu_to_le16(sizeof(*cmd)); -++ cmd = (void *)tlv->value; -++ cmd->vdev_id = __cpu_to_le32(arg->vdev_id); -++ cmd->bcn_intval = __cpu_to_le32(arg->bcn_intval); -++ cmd->dtim_period = __cpu_to_le32(arg->dtim_period); -++ cmd->flags = __cpu_to_le32(flags); -++ cmd->bcn_tx_rate = __cpu_to_le32(arg->bcn_tx_rate); -++ cmd->bcn_tx_power = __cpu_to_le32(arg->bcn_tx_power); -++ cmd->disable_hw_ack = __cpu_to_le32(arg->disable_hw_ack); -++ -++ if (arg->ssid) { -++ cmd->ssid.ssid_len = __cpu_to_le32(arg->ssid_len); -++ memcpy(cmd->ssid.ssid, arg->ssid, arg->ssid_len); -++ } -++ -++ ptr += sizeof(*tlv); -++ ptr += sizeof(*cmd); -++ -++ tlv = ptr; -++ tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_CHANNEL); -++ tlv->len = __cpu_to_le16(sizeof(*ch)); -++ ch = (void *)tlv->value; -++ ath10k_wmi_put_wmi_channel(ch, &arg->channel); -++ -++ ptr += sizeof(*tlv); -++ ptr += sizeof(*ch); -++ -++ tlv = ptr; -++ tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_STRUCT); -++ tlv->len = 0; -++ noa = (void *)tlv->value; -++ -++ /* Note: This is a nested TLV containing: -++ * [wmi_tlv][wmi_p2p_noa_descriptor][wmi_tlv].. -++ */ -++ -++ ptr += sizeof(*tlv); -++ ptr += 0; -++ -++ ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv vdev start\n"); -++ return skb; -++} -++ -++static struct sk_buff * -++ath10k_wmi_tlv_op_gen_vdev_stop(struct ath10k *ar, u32 vdev_id) -++{ -++ struct wmi_vdev_stop_cmd *cmd; -++ struct wmi_tlv *tlv; -++ struct sk_buff *skb; -++ -++ skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd)); -++ if (!skb) -++ return ERR_PTR(-ENOMEM); -++ -++ tlv = (void *)skb->data; -++ tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_VDEV_STOP_CMD); -++ tlv->len = __cpu_to_le16(sizeof(*cmd)); -++ cmd = (void *)tlv->value; -++ cmd->vdev_id = __cpu_to_le32(vdev_id); -++ -++ ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv vdev stop\n"); -++ return skb; -++} -++ -++static struct sk_buff * -++ath10k_wmi_tlv_op_gen_vdev_up(struct ath10k *ar, u32 vdev_id, u32 aid, -++ const u8 *bssid) -++ -++{ -++ struct wmi_vdev_up_cmd *cmd; -++ struct wmi_tlv *tlv; -++ struct sk_buff *skb; -++ -++ skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd)); -++ if (!skb) -++ return ERR_PTR(-ENOMEM); -++ -++ tlv = (void *)skb->data; -++ tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_VDEV_UP_CMD); -++ tlv->len = __cpu_to_le16(sizeof(*cmd)); -++ cmd = (void *)tlv->value; -++ cmd->vdev_id = __cpu_to_le32(vdev_id); -++ cmd->vdev_assoc_id = __cpu_to_le32(aid); -++ ether_addr_copy(cmd->vdev_bssid.addr, bssid); -++ -++ ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv vdev up\n"); -++ return skb; -++} -++ -++static struct sk_buff * -++ath10k_wmi_tlv_op_gen_vdev_down(struct ath10k *ar, u32 vdev_id) -++{ -++ struct wmi_vdev_down_cmd *cmd; -++ struct wmi_tlv *tlv; -++ struct sk_buff *skb; -++ -++ skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd)); -++ if (!skb) -++ return ERR_PTR(-ENOMEM); -++ -++ tlv = (void *)skb->data; -++ tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_VDEV_DOWN_CMD); -++ tlv->len = __cpu_to_le16(sizeof(*cmd)); -++ cmd = (void *)tlv->value; -++ cmd->vdev_id = __cpu_to_le32(vdev_id); -++ -++ ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv vdev down\n"); -++ return skb; -++} -++ -++static struct sk_buff * -++ath10k_wmi_tlv_op_gen_vdev_set_param(struct ath10k *ar, u32 vdev_id, -++ u32 param_id, u32 param_value) -++{ -++ struct wmi_vdev_set_param_cmd *cmd; -++ struct wmi_tlv *tlv; -++ struct sk_buff *skb; -++ -++ skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd)); -++ if (!skb) -++ return ERR_PTR(-ENOMEM); -++ -++ tlv = (void *)skb->data; -++ tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_VDEV_SET_PARAM_CMD); -++ tlv->len = __cpu_to_le16(sizeof(*cmd)); -++ cmd = (void *)tlv->value; -++ cmd->vdev_id = __cpu_to_le32(vdev_id); -++ cmd->param_id = __cpu_to_le32(param_id); -++ cmd->param_value = __cpu_to_le32(param_value); -++ -++ ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv vdev set param\n"); -++ return skb; -++} -++ -++static struct sk_buff * -++ath10k_wmi_tlv_op_gen_vdev_install_key(struct ath10k *ar, -++ const struct wmi_vdev_install_key_arg *arg) -++{ -++ struct wmi_vdev_install_key_cmd *cmd; -++ struct wmi_tlv *tlv; -++ struct sk_buff *skb; -++ size_t len; -++ void *ptr; -++ -++ if (arg->key_cipher == WMI_CIPHER_NONE && arg->key_data != NULL) -++ return ERR_PTR(-EINVAL); -++ if (arg->key_cipher != WMI_CIPHER_NONE && arg->key_data == NULL) -++ return ERR_PTR(-EINVAL); -++ -++ len = sizeof(*tlv) + sizeof(*cmd) + -++ sizeof(*tlv) + roundup(arg->key_len, sizeof(__le32)); -++ skb = ath10k_wmi_alloc_skb(ar, len); -++ if (!skb) -++ return ERR_PTR(-ENOMEM); -++ -++ ptr = (void *)skb->data; -++ tlv = ptr; -++ tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_VDEV_INSTALL_KEY_CMD); -++ tlv->len = __cpu_to_le16(sizeof(*cmd)); -++ cmd = (void *)tlv->value; -++ cmd->vdev_id = __cpu_to_le32(arg->vdev_id); -++ cmd->key_idx = __cpu_to_le32(arg->key_idx); -++ cmd->key_flags = __cpu_to_le32(arg->key_flags); -++ cmd->key_cipher = __cpu_to_le32(arg->key_cipher); -++ cmd->key_len = __cpu_to_le32(arg->key_len); -++ cmd->key_txmic_len = __cpu_to_le32(arg->key_txmic_len); -++ cmd->key_rxmic_len = __cpu_to_le32(arg->key_rxmic_len); -++ -++ if (arg->macaddr) -++ ether_addr_copy(cmd->peer_macaddr.addr, arg->macaddr); -++ -++ ptr += sizeof(*tlv); -++ ptr += sizeof(*cmd); -++ -++ tlv = ptr; -++ tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_BYTE); -++ tlv->len = __cpu_to_le16(roundup(arg->key_len, sizeof(__le32))); -++ if (arg->key_data) -++ memcpy(tlv->value, arg->key_data, arg->key_len); -++ -++ ptr += sizeof(*tlv); -++ ptr += roundup(arg->key_len, sizeof(__le32)); -++ -++ ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv vdev install key\n"); -++ return skb; -++} -++ -++static void *ath10k_wmi_tlv_put_uapsd_ac(struct ath10k *ar, void *ptr, -++ const struct wmi_sta_uapsd_auto_trig_arg *arg) -++{ -++ struct wmi_sta_uapsd_auto_trig_param *ac; -++ struct wmi_tlv *tlv; -++ -++ tlv = ptr; -++ tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_STA_UAPSD_AUTO_TRIG_PARAM); -++ tlv->len = __cpu_to_le16(sizeof(*ac)); -++ ac = (void *)tlv->value; -++ -++ ac->wmm_ac = __cpu_to_le32(arg->wmm_ac); -++ ac->user_priority = __cpu_to_le32(arg->user_priority); -++ ac->service_interval = __cpu_to_le32(arg->service_interval); -++ ac->suspend_interval = __cpu_to_le32(arg->suspend_interval); -++ ac->delay_interval = __cpu_to_le32(arg->delay_interval); -++ -++ ath10k_dbg(ar, ATH10K_DBG_WMI, -++ "wmi tlv vdev sta uapsd auto trigger ac %d prio %d svc int %d susp int %d delay int %d\n", -++ ac->wmm_ac, ac->user_priority, ac->service_interval, -++ ac->suspend_interval, ac->delay_interval); -++ -++ return ptr + sizeof(*tlv) + sizeof(*ac); -++} -++ -++static struct sk_buff * -++ath10k_wmi_tlv_op_gen_vdev_sta_uapsd(struct ath10k *ar, u32 vdev_id, -++ const u8 peer_addr[ETH_ALEN], -++ const struct wmi_sta_uapsd_auto_trig_arg *args, -++ u32 num_ac) -++{ -++ struct wmi_sta_uapsd_auto_trig_cmd_fixed_param *cmd; -++ struct wmi_sta_uapsd_auto_trig_param *ac; -++ struct wmi_tlv *tlv; -++ struct sk_buff *skb; -++ size_t len; -++ size_t ac_tlv_len; -++ void *ptr; -++ int i; -++ -++ ac_tlv_len = num_ac * (sizeof(*tlv) + sizeof(*ac)); -++ len = sizeof(*tlv) + sizeof(*cmd) + -++ sizeof(*tlv) + ac_tlv_len; -++ skb = ath10k_wmi_alloc_skb(ar, len); -++ if (!skb) -++ return ERR_PTR(-ENOMEM); -++ -++ ptr = (void *)skb->data; -++ tlv = ptr; -++ tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_STA_UAPSD_AUTO_TRIG_CMD); -++ tlv->len = __cpu_to_le16(sizeof(*cmd)); -++ cmd = (void *)tlv->value; -++ cmd->vdev_id = __cpu_to_le32(vdev_id); -++ cmd->num_ac = __cpu_to_le32(num_ac); -++ ether_addr_copy(cmd->peer_macaddr.addr, peer_addr); -++ -++ ptr += sizeof(*tlv); -++ ptr += sizeof(*cmd); -++ -++ tlv = ptr; -++ tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_STRUCT); -++ tlv->len = __cpu_to_le16(ac_tlv_len); -++ ac = (void *)tlv->value; -++ -++ ptr += sizeof(*tlv); -++ for (i = 0; i < num_ac; i++) -++ ptr = ath10k_wmi_tlv_put_uapsd_ac(ar, ptr, &args[i]); -++ -++ ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv vdev sta uapsd auto trigger\n"); -++ return skb; -++} -++ -++static void *ath10k_wmi_tlv_put_wmm(void *ptr, -++ const struct wmi_wmm_params_arg *arg) -++{ -++ struct wmi_wmm_params *wmm; -++ struct wmi_tlv *tlv; -++ -++ tlv = ptr; -++ tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_WMM_PARAMS); -++ tlv->len = __cpu_to_le16(sizeof(*wmm)); -++ wmm = (void *)tlv->value; -++ ath10k_wmi_set_wmm_param(wmm, arg); -++ -++ return ptr + sizeof(*tlv) + sizeof(*wmm); -++} -++ -++static struct sk_buff * -++ath10k_wmi_tlv_op_gen_vdev_wmm_conf(struct ath10k *ar, u32 vdev_id, -++ const struct wmi_wmm_params_all_arg *arg) -++{ -++ struct wmi_tlv_vdev_set_wmm_cmd *cmd; -++ struct wmi_tlv *tlv; -++ struct sk_buff *skb; -++ size_t len; -++ void *ptr; -++ -++ len = sizeof(*tlv) + sizeof(*cmd); -++ skb = ath10k_wmi_alloc_skb(ar, len); -++ if (!skb) -++ return ERR_PTR(-ENOMEM); -++ -++ ptr = (void *)skb->data; -++ tlv = ptr; -++ tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_VDEV_SET_WMM_PARAMS_CMD); -++ tlv->len = __cpu_to_le16(sizeof(*cmd)); -++ cmd = (void *)tlv->value; -++ cmd->vdev_id = __cpu_to_le32(vdev_id); -++ -++ ath10k_wmi_set_wmm_param(&cmd->vdev_wmm_params[0].params, &arg->ac_be); -++ ath10k_wmi_set_wmm_param(&cmd->vdev_wmm_params[1].params, &arg->ac_bk); -++ ath10k_wmi_set_wmm_param(&cmd->vdev_wmm_params[2].params, &arg->ac_vi); -++ ath10k_wmi_set_wmm_param(&cmd->vdev_wmm_params[3].params, &arg->ac_vo); -++ -++ ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv vdev wmm conf\n"); -++ return skb; -++} -++ -++static struct sk_buff * -++ath10k_wmi_tlv_op_gen_sta_keepalive(struct ath10k *ar, -++ const struct wmi_sta_keepalive_arg *arg) -++{ -++ struct wmi_tlv_sta_keepalive_cmd *cmd; -++ struct wmi_sta_keepalive_arp_resp *arp; -++ struct sk_buff *skb; -++ struct wmi_tlv *tlv; -++ void *ptr; -++ size_t len; -++ -++ len = sizeof(*tlv) + sizeof(*cmd) + -++ sizeof(*tlv) + sizeof(*arp); -++ skb = ath10k_wmi_alloc_skb(ar, len); -++ if (!skb) -++ return ERR_PTR(-ENOMEM); -++ -++ ptr = (void *)skb->data; -++ tlv = ptr; -++ tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_STA_KEEPALIVE_CMD); -++ tlv->len = __cpu_to_le16(sizeof(*cmd)); -++ cmd = (void *)tlv->value; -++ cmd->vdev_id = __cpu_to_le32(arg->vdev_id); -++ cmd->enabled = __cpu_to_le32(arg->enabled); -++ cmd->method = __cpu_to_le32(arg->method); -++ cmd->interval = __cpu_to_le32(arg->interval); -++ -++ ptr += sizeof(*tlv); -++ ptr += sizeof(*cmd); -++ -++ tlv = ptr; -++ tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_STA_KEEPALVE_ARP_RESPONSE); -++ tlv->len = __cpu_to_le16(sizeof(*arp)); -++ arp = (void *)tlv->value; -++ -++ arp->src_ip4_addr = arg->src_ip4_addr; -++ arp->dest_ip4_addr = arg->dest_ip4_addr; -++ ether_addr_copy(arp->dest_mac_addr.addr, arg->dest_mac_addr); -++ -++ ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv sta keepalive vdev %d enabled %d method %d inverval %d\n", -++ arg->vdev_id, arg->enabled, arg->method, arg->interval); -++ return skb; -++} -++ -++static struct sk_buff * -++ath10k_wmi_tlv_op_gen_peer_create(struct ath10k *ar, u32 vdev_id, -++ const u8 peer_addr[ETH_ALEN]) -++{ -++ struct wmi_tlv_peer_create_cmd *cmd; -++ struct wmi_tlv *tlv; -++ struct sk_buff *skb; -++ -++ skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd)); -++ if (!skb) -++ return ERR_PTR(-ENOMEM); -++ -++ tlv = (void *)skb->data; -++ tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_PEER_CREATE_CMD); -++ tlv->len = __cpu_to_le16(sizeof(*cmd)); -++ cmd = (void *)tlv->value; -++ cmd->vdev_id = __cpu_to_le32(vdev_id); -++ cmd->peer_type = __cpu_to_le32(WMI_TLV_PEER_TYPE_DEFAULT); /* FIXME */ -++ ether_addr_copy(cmd->peer_addr.addr, peer_addr); -++ -++ ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv peer create\n"); -++ return skb; -++} -++ -++static struct sk_buff * -++ath10k_wmi_tlv_op_gen_peer_delete(struct ath10k *ar, u32 vdev_id, -++ const u8 peer_addr[ETH_ALEN]) -++{ -++ struct wmi_peer_delete_cmd *cmd; -++ struct wmi_tlv *tlv; -++ struct sk_buff *skb; -++ -++ skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd)); -++ if (!skb) -++ return ERR_PTR(-ENOMEM); -++ -++ tlv = (void *)skb->data; -++ tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_PEER_DELETE_CMD); -++ tlv->len = __cpu_to_le16(sizeof(*cmd)); -++ cmd = (void *)tlv->value; -++ cmd->vdev_id = __cpu_to_le32(vdev_id); -++ ether_addr_copy(cmd->peer_macaddr.addr, peer_addr); -++ -++ ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv peer delete\n"); -++ return skb; -++} -++ -++static struct sk_buff * -++ath10k_wmi_tlv_op_gen_peer_flush(struct ath10k *ar, u32 vdev_id, -++ const u8 peer_addr[ETH_ALEN], u32 tid_bitmap) -++{ -++ struct wmi_peer_flush_tids_cmd *cmd; -++ struct wmi_tlv *tlv; -++ struct sk_buff *skb; -++ -++ skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd)); -++ if (!skb) -++ return ERR_PTR(-ENOMEM); -++ -++ tlv = (void *)skb->data; -++ tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_PEER_FLUSH_TIDS_CMD); -++ tlv->len = __cpu_to_le16(sizeof(*cmd)); -++ cmd = (void *)tlv->value; -++ cmd->vdev_id = __cpu_to_le32(vdev_id); -++ cmd->peer_tid_bitmap = __cpu_to_le32(tid_bitmap); -++ ether_addr_copy(cmd->peer_macaddr.addr, peer_addr); -++ -++ ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv peer flush\n"); -++ return skb; -++} -++ -++static struct sk_buff * -++ath10k_wmi_tlv_op_gen_peer_set_param(struct ath10k *ar, u32 vdev_id, -++ const u8 *peer_addr, -++ enum wmi_peer_param param_id, -++ u32 param_value) -++{ -++ struct wmi_peer_set_param_cmd *cmd; -++ struct wmi_tlv *tlv; -++ struct sk_buff *skb; -++ -++ skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd)); -++ if (!skb) -++ return ERR_PTR(-ENOMEM); -++ -++ tlv = (void *)skb->data; -++ tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_PEER_SET_PARAM_CMD); -++ tlv->len = __cpu_to_le16(sizeof(*cmd)); -++ cmd = (void *)tlv->value; -++ cmd->vdev_id = __cpu_to_le32(vdev_id); -++ cmd->param_id = __cpu_to_le32(param_id); -++ cmd->param_value = __cpu_to_le32(param_value); -++ ether_addr_copy(cmd->peer_macaddr.addr, peer_addr); -++ -++ ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv peer set param\n"); -++ return skb; -++} -++ -++static struct sk_buff * -++ath10k_wmi_tlv_op_gen_peer_assoc(struct ath10k *ar, -++ const struct wmi_peer_assoc_complete_arg *arg) -++{ -++ struct wmi_tlv_peer_assoc_cmd *cmd; -++ struct wmi_vht_rate_set *vht_rate; -++ struct wmi_tlv *tlv; -++ struct sk_buff *skb; -++ size_t len, legacy_rate_len, ht_rate_len; -++ void *ptr; -++ -++ if (arg->peer_mpdu_density > 16) -++ return ERR_PTR(-EINVAL); -++ if (arg->peer_legacy_rates.num_rates > MAX_SUPPORTED_RATES) -++ return ERR_PTR(-EINVAL); -++ if (arg->peer_ht_rates.num_rates > MAX_SUPPORTED_RATES) -++ return ERR_PTR(-EINVAL); -++ -++ legacy_rate_len = roundup(arg->peer_legacy_rates.num_rates, -++ sizeof(__le32)); -++ ht_rate_len = roundup(arg->peer_ht_rates.num_rates, sizeof(__le32)); -++ len = (sizeof(*tlv) + sizeof(*cmd)) + -++ (sizeof(*tlv) + legacy_rate_len) + -++ (sizeof(*tlv) + ht_rate_len) + -++ (sizeof(*tlv) + sizeof(*vht_rate)); -++ skb = ath10k_wmi_alloc_skb(ar, len); -++ if (!skb) -++ return ERR_PTR(-ENOMEM); -++ -++ ptr = (void *)skb->data; -++ tlv = ptr; -++ tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_PEER_ASSOC_COMPLETE_CMD); -++ tlv->len = __cpu_to_le16(sizeof(*cmd)); -++ cmd = (void *)tlv->value; -++ -++ cmd->vdev_id = __cpu_to_le32(arg->vdev_id); -++ cmd->new_assoc = __cpu_to_le32(arg->peer_reassoc ? 0 : 1); -++ cmd->assoc_id = __cpu_to_le32(arg->peer_aid); -++ cmd->flags = __cpu_to_le32(arg->peer_flags); -++ cmd->caps = __cpu_to_le32(arg->peer_caps); -++ cmd->listen_intval = __cpu_to_le32(arg->peer_listen_intval); -++ cmd->ht_caps = __cpu_to_le32(arg->peer_ht_caps); -++ cmd->max_mpdu = __cpu_to_le32(arg->peer_max_mpdu); -++ cmd->mpdu_density = __cpu_to_le32(arg->peer_mpdu_density); -++ cmd->rate_caps = __cpu_to_le32(arg->peer_rate_caps); -++ cmd->nss = __cpu_to_le32(arg->peer_num_spatial_streams); -++ cmd->vht_caps = __cpu_to_le32(arg->peer_vht_caps); -++ cmd->phy_mode = __cpu_to_le32(arg->peer_phymode); -++ cmd->num_legacy_rates = __cpu_to_le32(arg->peer_legacy_rates.num_rates); -++ cmd->num_ht_rates = __cpu_to_le32(arg->peer_ht_rates.num_rates); -++ ether_addr_copy(cmd->mac_addr.addr, arg->addr); -++ -++ ptr += sizeof(*tlv); -++ ptr += sizeof(*cmd); -++ -++ tlv = ptr; -++ tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_BYTE); -++ tlv->len = __cpu_to_le16(legacy_rate_len); -++ memcpy(tlv->value, arg->peer_legacy_rates.rates, -++ arg->peer_legacy_rates.num_rates); -++ -++ ptr += sizeof(*tlv); -++ ptr += legacy_rate_len; -++ -++ tlv = ptr; -++ tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_BYTE); -++ tlv->len = __cpu_to_le16(ht_rate_len); -++ memcpy(tlv->value, arg->peer_ht_rates.rates, -++ arg->peer_ht_rates.num_rates); -++ -++ ptr += sizeof(*tlv); -++ ptr += ht_rate_len; -++ -++ tlv = ptr; -++ tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_VHT_RATE_SET); -++ tlv->len = __cpu_to_le16(sizeof(*vht_rate)); -++ vht_rate = (void *)tlv->value; -++ -++ vht_rate->rx_max_rate = __cpu_to_le32(arg->peer_vht_rates.rx_max_rate); -++ vht_rate->rx_mcs_set = __cpu_to_le32(arg->peer_vht_rates.rx_mcs_set); -++ vht_rate->tx_max_rate = __cpu_to_le32(arg->peer_vht_rates.tx_max_rate); -++ vht_rate->tx_mcs_set = __cpu_to_le32(arg->peer_vht_rates.tx_mcs_set); -++ -++ ptr += sizeof(*tlv); -++ ptr += sizeof(*vht_rate); -++ -++ ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv peer assoc\n"); -++ return skb; -++} -++ -++static struct sk_buff * -++ath10k_wmi_tlv_op_gen_set_psmode(struct ath10k *ar, u32 vdev_id, -++ enum wmi_sta_ps_mode psmode) -++{ -++ struct wmi_sta_powersave_mode_cmd *cmd; -++ struct wmi_tlv *tlv; -++ struct sk_buff *skb; -++ -++ skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd)); -++ if (!skb) -++ return ERR_PTR(-ENOMEM); -++ -++ tlv = (void *)skb->data; -++ tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_STA_POWERSAVE_MODE_CMD); -++ tlv->len = __cpu_to_le16(sizeof(*cmd)); -++ cmd = (void *)tlv->value; -++ cmd->vdev_id = __cpu_to_le32(vdev_id); -++ cmd->sta_ps_mode = __cpu_to_le32(psmode); -++ -++ ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv set psmode\n"); -++ return skb; -++} -++ -++static struct sk_buff * -++ath10k_wmi_tlv_op_gen_set_sta_ps(struct ath10k *ar, u32 vdev_id, -++ enum wmi_sta_powersave_param param_id, -++ u32 param_value) -++{ -++ struct wmi_sta_powersave_param_cmd *cmd; -++ struct wmi_tlv *tlv; -++ struct sk_buff *skb; -++ -++ skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd)); -++ if (!skb) -++ return ERR_PTR(-ENOMEM); -++ -++ tlv = (void *)skb->data; -++ tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_STA_POWERSAVE_PARAM_CMD); -++ tlv->len = __cpu_to_le16(sizeof(*cmd)); -++ cmd = (void *)tlv->value; -++ cmd->vdev_id = __cpu_to_le32(vdev_id); -++ cmd->param_id = __cpu_to_le32(param_id); -++ cmd->param_value = __cpu_to_le32(param_value); -++ -++ ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv set sta ps\n"); -++ return skb; -++} -++ -++static struct sk_buff * -++ath10k_wmi_tlv_op_gen_set_ap_ps(struct ath10k *ar, u32 vdev_id, const u8 *mac, -++ enum wmi_ap_ps_peer_param param_id, u32 value) -++{ -++ struct wmi_ap_ps_peer_cmd *cmd; -++ struct wmi_tlv *tlv; -++ struct sk_buff *skb; -++ -++ if (!mac) -++ return ERR_PTR(-EINVAL); -++ -++ skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd)); -++ if (!skb) -++ return ERR_PTR(-ENOMEM); -++ -++ tlv = (void *)skb->data; -++ tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_AP_PS_PEER_CMD); -++ tlv->len = __cpu_to_le16(sizeof(*cmd)); -++ cmd = (void *)tlv->value; -++ cmd->vdev_id = __cpu_to_le32(vdev_id); -++ cmd->param_id = __cpu_to_le32(param_id); -++ cmd->param_value = __cpu_to_le32(value); -++ ether_addr_copy(cmd->peer_macaddr.addr, mac); -++ -++ ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv ap ps param\n"); -++ return skb; -++} -++ -++static struct sk_buff * -++ath10k_wmi_tlv_op_gen_scan_chan_list(struct ath10k *ar, -++ const struct wmi_scan_chan_list_arg *arg) -++{ -++ struct wmi_tlv_scan_chan_list_cmd *cmd; -++ struct wmi_channel *ci; -++ struct wmi_channel_arg *ch; -++ struct wmi_tlv *tlv; -++ struct sk_buff *skb; -++ size_t chans_len, len; -++ int i; -++ void *ptr, *chans; -++ -++ chans_len = arg->n_channels * (sizeof(*tlv) + sizeof(*ci)); -++ len = (sizeof(*tlv) + sizeof(*cmd)) + -++ (sizeof(*tlv) + chans_len); -++ -++ skb = ath10k_wmi_alloc_skb(ar, len); -++ if (!skb) -++ return ERR_PTR(-ENOMEM); -++ -++ ptr = (void *)skb->data; -++ tlv = ptr; -++ tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_SCAN_CHAN_LIST_CMD); -++ tlv->len = __cpu_to_le16(sizeof(*cmd)); -++ cmd = (void *)tlv->value; -++ cmd->num_scan_chans = __cpu_to_le32(arg->n_channels); -++ -++ ptr += sizeof(*tlv); -++ ptr += sizeof(*cmd); -++ -++ tlv = ptr; -++ tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_STRUCT); -++ tlv->len = __cpu_to_le16(chans_len); -++ chans = (void *)tlv->value; -++ -++ for (i = 0; i < arg->n_channels; i++) { -++ ch = &arg->channels[i]; -++ -++ tlv = chans; -++ tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_CHANNEL); -++ tlv->len = __cpu_to_le16(sizeof(*ci)); -++ ci = (void *)tlv->value; -++ -++ ath10k_wmi_put_wmi_channel(ci, ch); -++ -++ chans += sizeof(*tlv); -++ chans += sizeof(*ci); -++ } -++ -++ ptr += sizeof(*tlv); -++ ptr += chans_len; -++ -++ ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv scan chan list\n"); -++ return skb; -++} -++ -++static struct sk_buff * -++ath10k_wmi_tlv_op_gen_beacon_dma(struct ath10k *ar, u32 vdev_id, -++ const void *bcn, size_t bcn_len, -++ u32 bcn_paddr, bool dtim_zero, -++ bool deliver_cab) -++ -++{ -++ struct wmi_bcn_tx_ref_cmd *cmd; -++ struct wmi_tlv *tlv; -++ struct sk_buff *skb; -++ struct ieee80211_hdr *hdr; -++ u16 fc; -++ -++ skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd)); -++ if (!skb) -++ return ERR_PTR(-ENOMEM); -++ -++ hdr = (struct ieee80211_hdr *)bcn; -++ fc = le16_to_cpu(hdr->frame_control); -++ -++ tlv = (void *)skb->data; -++ tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_BCN_SEND_FROM_HOST_CMD); -++ tlv->len = __cpu_to_le16(sizeof(*cmd)); -++ cmd = (void *)tlv->value; -++ cmd->vdev_id = __cpu_to_le32(vdev_id); -++ cmd->data_len = __cpu_to_le32(bcn_len); -++ cmd->data_ptr = __cpu_to_le32(bcn_paddr); -++ cmd->msdu_id = 0; -++ cmd->frame_control = __cpu_to_le32(fc); -++ cmd->flags = 0; -++ -++ if (dtim_zero) -++ cmd->flags |= __cpu_to_le32(WMI_BCN_TX_REF_FLAG_DTIM_ZERO); -++ -++ if (deliver_cab) -++ cmd->flags |= __cpu_to_le32(WMI_BCN_TX_REF_FLAG_DELIVER_CAB); -++ -++ ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv beacon dma\n"); -++ return skb; -++} -++ -++static struct sk_buff * -++ath10k_wmi_tlv_op_gen_pdev_set_wmm(struct ath10k *ar, -++ const struct wmi_wmm_params_all_arg *arg) -++{ -++ struct wmi_tlv_pdev_set_wmm_cmd *cmd; -++ struct wmi_wmm_params *wmm; -++ struct wmi_tlv *tlv; -++ struct sk_buff *skb; -++ size_t len; -++ void *ptr; -++ -++ len = (sizeof(*tlv) + sizeof(*cmd)) + -++ (4 * (sizeof(*tlv) + sizeof(*wmm))); -++ skb = ath10k_wmi_alloc_skb(ar, len); -++ if (!skb) -++ return ERR_PTR(-ENOMEM); -++ -++ ptr = (void *)skb->data; -++ -++ tlv = ptr; -++ tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_PDEV_SET_WMM_PARAMS_CMD); -++ tlv->len = __cpu_to_le16(sizeof(*cmd)); -++ cmd = (void *)tlv->value; -++ -++ /* nothing to set here */ -++ -++ ptr += sizeof(*tlv); -++ ptr += sizeof(*cmd); -++ -++ ptr = ath10k_wmi_tlv_put_wmm(ptr, &arg->ac_be); -++ ptr = ath10k_wmi_tlv_put_wmm(ptr, &arg->ac_bk); -++ ptr = ath10k_wmi_tlv_put_wmm(ptr, &arg->ac_vi); -++ ptr = ath10k_wmi_tlv_put_wmm(ptr, &arg->ac_vo); -++ -++ ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv pdev set wmm\n"); -++ return skb; -++} -++ -++static struct sk_buff * -++ath10k_wmi_tlv_op_gen_request_stats(struct ath10k *ar, u32 stats_mask) -++{ -++ struct wmi_request_stats_cmd *cmd; -++ struct wmi_tlv *tlv; -++ struct sk_buff *skb; -++ -++ skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd)); -++ if (!skb) -++ return ERR_PTR(-ENOMEM); -++ -++ tlv = (void *)skb->data; -++ tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_REQUEST_STATS_CMD); -++ tlv->len = __cpu_to_le16(sizeof(*cmd)); -++ cmd = (void *)tlv->value; -++ cmd->stats_id = __cpu_to_le32(stats_mask); -++ -++ ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv request stats\n"); -++ return skb; -++} -++ -++static struct sk_buff * -++ath10k_wmi_tlv_op_gen_force_fw_hang(struct ath10k *ar, -++ enum wmi_force_fw_hang_type type, -++ u32 delay_ms) -++{ -++ struct wmi_force_fw_hang_cmd *cmd; -++ struct wmi_tlv *tlv; -++ struct sk_buff *skb; -++ -++ skb = ath10k_wmi_alloc_skb(ar, sizeof(*tlv) + sizeof(*cmd)); -++ if (!skb) -++ return ERR_PTR(-ENOMEM); -++ -++ tlv = (void *)skb->data; -++ tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_FORCE_FW_HANG_CMD); -++ tlv->len = __cpu_to_le16(sizeof(*cmd)); -++ cmd = (void *)tlv->value; -++ cmd->type = __cpu_to_le32(type); -++ cmd->delay_ms = __cpu_to_le32(delay_ms); -++ -++ ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv force fw hang\n"); -++ return skb; -++} -++ -++static struct sk_buff * -++ath10k_wmi_tlv_op_gen_dbglog_cfg(struct ath10k *ar, u32 module_enable, -++ u32 log_level) { -++ struct wmi_tlv_dbglog_cmd *cmd; -++ struct wmi_tlv *tlv; -++ struct sk_buff *skb; -++ size_t len, bmap_len; -++ u32 value; -++ void *ptr; -++ -++ if (module_enable) { -++ value = WMI_TLV_DBGLOG_LOG_LEVEL_VALUE( -++ module_enable, -++ WMI_TLV_DBGLOG_LOG_LEVEL_VERBOSE); -++ } else { -++ value = WMI_TLV_DBGLOG_LOG_LEVEL_VALUE( -++ WMI_TLV_DBGLOG_ALL_MODULES, -++ WMI_TLV_DBGLOG_LOG_LEVEL_WARN); -++ } -++ -++ bmap_len = 0; -++ len = sizeof(*tlv) + sizeof(*cmd) + sizeof(*tlv) + bmap_len; -++ skb = ath10k_wmi_alloc_skb(ar, len); -++ if (!skb) -++ return ERR_PTR(-ENOMEM); -++ -++ ptr = (void *)skb->data; -++ -++ tlv = ptr; -++ tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_DEBUG_LOG_CONFIG_CMD); -++ tlv->len = __cpu_to_le16(sizeof(*cmd)); -++ cmd = (void *)tlv->value; -++ cmd->param = __cpu_to_le32(WMI_TLV_DBGLOG_PARAM_LOG_LEVEL); -++ cmd->value = __cpu_to_le32(value); -++ -++ ptr += sizeof(*tlv); -++ ptr += sizeof(*cmd); -++ -++ tlv = ptr; -++ tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_UINT32); -++ tlv->len = __cpu_to_le16(bmap_len); -++ -++ /* nothing to do here */ -++ -++ ptr += sizeof(*tlv); -++ ptr += sizeof(bmap_len); -++ -++ ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv dbglog value 0x%08x\n", value); -++ return skb; -++} -++ -++static struct sk_buff * -++ath10k_wmi_tlv_op_gen_pktlog_enable(struct ath10k *ar, u32 filter) -++{ -++ struct wmi_tlv_pktlog_enable *cmd; -++ struct wmi_tlv *tlv; -++ struct sk_buff *skb; -++ void *ptr; -++ size_t len; -++ -++ len = sizeof(*tlv) + sizeof(*cmd); -++ skb = ath10k_wmi_alloc_skb(ar, len); -++ if (!skb) -++ return ERR_PTR(-ENOMEM); -++ -++ ptr = (void *)skb->data; -++ tlv = ptr; -++ tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_PDEV_PKTLOG_ENABLE_CMD); -++ tlv->len = __cpu_to_le16(sizeof(*cmd)); -++ cmd = (void *)tlv->value; -++ cmd->filter = __cpu_to_le32(filter); -++ -++ ptr += sizeof(*tlv); -++ ptr += sizeof(*cmd); -++ -++ ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv pktlog enable filter 0x%08x\n", -++ filter); -++ return skb; -++} -++ -++static struct sk_buff * -++ath10k_wmi_tlv_op_gen_pktlog_disable(struct ath10k *ar) -++{ -++ struct wmi_tlv_pktlog_disable *cmd; -++ struct wmi_tlv *tlv; -++ struct sk_buff *skb; -++ void *ptr; -++ size_t len; -++ -++ len = sizeof(*tlv) + sizeof(*cmd); -++ skb = ath10k_wmi_alloc_skb(ar, len); -++ if (!skb) -++ return ERR_PTR(-ENOMEM); -++ -++ ptr = (void *)skb->data; -++ tlv = ptr; -++ tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_PDEV_PKTLOG_DISABLE_CMD); -++ tlv->len = __cpu_to_le16(sizeof(*cmd)); -++ cmd = (void *)tlv->value; -++ -++ ptr += sizeof(*tlv); -++ ptr += sizeof(*cmd); -++ -++ ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv pktlog disable\n"); -++ return skb; -++} -++ -++static struct sk_buff * -++ath10k_wmi_tlv_op_gen_bcn_tmpl(struct ath10k *ar, u32 vdev_id, -++ u32 tim_ie_offset, struct sk_buff *bcn, -++ u32 prb_caps, u32 prb_erp, void *prb_ies, -++ size_t prb_ies_len) -++{ -++ struct wmi_tlv_bcn_tmpl_cmd *cmd; -++ struct wmi_tlv_bcn_prb_info *info; -++ struct wmi_tlv *tlv; -++ struct sk_buff *skb; -++ void *ptr; -++ size_t len; -++ -++ if (WARN_ON(prb_ies_len > 0 && !prb_ies)) -++ return ERR_PTR(-EINVAL); -++ -++ len = sizeof(*tlv) + sizeof(*cmd) + -++ sizeof(*tlv) + sizeof(*info) + prb_ies_len + -++ sizeof(*tlv) + roundup(bcn->len, 4); -++ skb = ath10k_wmi_alloc_skb(ar, len); -++ if (!skb) -++ return ERR_PTR(-ENOMEM); -++ -++ ptr = (void *)skb->data; -++ tlv = ptr; -++ tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_BCN_TMPL_CMD); -++ tlv->len = __cpu_to_le16(sizeof(*cmd)); -++ cmd = (void *)tlv->value; -++ cmd->vdev_id = __cpu_to_le32(vdev_id); -++ cmd->tim_ie_offset = __cpu_to_le32(tim_ie_offset); -++ cmd->buf_len = __cpu_to_le32(bcn->len); -++ -++ ptr += sizeof(*tlv); -++ ptr += sizeof(*cmd); -++ -++ /* FIXME: prb_ies_len should be probably aligned to 4byte boundary but -++ * then it is then impossible to pass original ie len. -++ * This chunk is not used yet so if setting probe resp template yields -++ * problems with beaconing or crashes firmware look here. -++ */ -++ tlv = ptr; -++ tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_BCN_PRB_INFO); -++ tlv->len = __cpu_to_le16(sizeof(*info) + prb_ies_len); -++ info = (void *)tlv->value; -++ info->caps = __cpu_to_le32(prb_caps); -++ info->erp = __cpu_to_le32(prb_erp); -++ memcpy(info->ies, prb_ies, prb_ies_len); -++ -++ ptr += sizeof(*tlv); -++ ptr += sizeof(*info); -++ ptr += prb_ies_len; -++ -++ tlv = ptr; -++ tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_BYTE); -++ tlv->len = __cpu_to_le16(roundup(bcn->len, 4)); -++ memcpy(tlv->value, bcn->data, bcn->len); -++ -++ /* FIXME: Adjust TSF? */ -++ -++ ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv bcn tmpl vdev_id %i\n", -++ vdev_id); -++ return skb; -++} -++ -++static struct sk_buff * -++ath10k_wmi_tlv_op_gen_prb_tmpl(struct ath10k *ar, u32 vdev_id, -++ struct sk_buff *prb) -++{ -++ struct wmi_tlv_prb_tmpl_cmd *cmd; -++ struct wmi_tlv_bcn_prb_info *info; -++ struct wmi_tlv *tlv; -++ struct sk_buff *skb; -++ void *ptr; -++ size_t len; -++ -++ len = sizeof(*tlv) + sizeof(*cmd) + -++ sizeof(*tlv) + sizeof(*info) + -++ sizeof(*tlv) + roundup(prb->len, 4); -++ skb = ath10k_wmi_alloc_skb(ar, len); -++ if (!skb) -++ return ERR_PTR(-ENOMEM); -++ -++ ptr = (void *)skb->data; -++ tlv = ptr; -++ tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_PRB_TMPL_CMD); -++ tlv->len = __cpu_to_le16(sizeof(*cmd)); -++ cmd = (void *)tlv->value; -++ cmd->vdev_id = __cpu_to_le32(vdev_id); -++ cmd->buf_len = __cpu_to_le32(prb->len); -++ -++ ptr += sizeof(*tlv); -++ ptr += sizeof(*cmd); -++ -++ tlv = ptr; -++ tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_BCN_PRB_INFO); -++ tlv->len = __cpu_to_le16(sizeof(*info)); -++ info = (void *)tlv->value; -++ info->caps = 0; -++ info->erp = 0; -++ -++ ptr += sizeof(*tlv); -++ ptr += sizeof(*info); -++ -++ tlv = ptr; -++ tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_BYTE); -++ tlv->len = __cpu_to_le16(roundup(prb->len, 4)); -++ memcpy(tlv->value, prb->data, prb->len); -++ -++ ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv prb tmpl vdev_id %i\n", -++ vdev_id); -++ return skb; -++} -++ -++static struct sk_buff * -++ath10k_wmi_tlv_op_gen_p2p_go_bcn_ie(struct ath10k *ar, u32 vdev_id, -++ const u8 *p2p_ie) -++{ -++ struct wmi_tlv_p2p_go_bcn_ie *cmd; -++ struct wmi_tlv *tlv; -++ struct sk_buff *skb; -++ void *ptr; -++ size_t len; -++ -++ len = sizeof(*tlv) + sizeof(*cmd) + -++ sizeof(*tlv) + roundup(p2p_ie[1] + 2, 4); -++ skb = ath10k_wmi_alloc_skb(ar, len); -++ if (!skb) -++ return ERR_PTR(-ENOMEM); -++ -++ ptr = (void *)skb->data; -++ tlv = ptr; -++ tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_P2P_GO_SET_BEACON_IE); -++ tlv->len = __cpu_to_le16(sizeof(*cmd)); -++ cmd = (void *)tlv->value; -++ cmd->vdev_id = __cpu_to_le32(vdev_id); -++ cmd->ie_len = __cpu_to_le32(p2p_ie[1] + 2); -++ -++ ptr += sizeof(*tlv); -++ ptr += sizeof(*cmd); -++ -++ tlv = ptr; -++ tlv->tag = __cpu_to_le16(WMI_TLV_TAG_ARRAY_BYTE); -++ tlv->len = __cpu_to_le16(roundup(p2p_ie[1] + 2, 4)); -++ memcpy(tlv->value, p2p_ie, p2p_ie[1] + 2); -++ -++ ptr += sizeof(*tlv); -++ ptr += roundup(p2p_ie[1] + 2, 4); -++ -++ ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv p2p go bcn ie for vdev %i\n", -++ vdev_id); -++ return skb; -++} -++ -++/****************/ -++/* TLV mappings */ -++/****************/ -++ -++static struct wmi_cmd_map wmi_tlv_cmd_map = { -++ .init_cmdid = WMI_TLV_INIT_CMDID, -++ .start_scan_cmdid = WMI_TLV_START_SCAN_CMDID, -++ .stop_scan_cmdid = WMI_TLV_STOP_SCAN_CMDID, -++ .scan_chan_list_cmdid = WMI_TLV_SCAN_CHAN_LIST_CMDID, -++ .scan_sch_prio_tbl_cmdid = WMI_TLV_SCAN_SCH_PRIO_TBL_CMDID, -++ .pdev_set_regdomain_cmdid = WMI_TLV_PDEV_SET_REGDOMAIN_CMDID, -++ .pdev_set_channel_cmdid = WMI_TLV_PDEV_SET_CHANNEL_CMDID, -++ .pdev_set_param_cmdid = WMI_TLV_PDEV_SET_PARAM_CMDID, -++ .pdev_pktlog_enable_cmdid = WMI_TLV_PDEV_PKTLOG_ENABLE_CMDID, -++ .pdev_pktlog_disable_cmdid = WMI_TLV_PDEV_PKTLOG_DISABLE_CMDID, -++ .pdev_set_wmm_params_cmdid = WMI_TLV_PDEV_SET_WMM_PARAMS_CMDID, -++ .pdev_set_ht_cap_ie_cmdid = WMI_TLV_PDEV_SET_HT_CAP_IE_CMDID, -++ .pdev_set_vht_cap_ie_cmdid = WMI_TLV_PDEV_SET_VHT_CAP_IE_CMDID, -++ .pdev_set_dscp_tid_map_cmdid = WMI_TLV_PDEV_SET_DSCP_TID_MAP_CMDID, -++ .pdev_set_quiet_mode_cmdid = WMI_TLV_PDEV_SET_QUIET_MODE_CMDID, -++ .pdev_green_ap_ps_enable_cmdid = WMI_TLV_PDEV_GREEN_AP_PS_ENABLE_CMDID, -++ .pdev_get_tpc_config_cmdid = WMI_TLV_PDEV_GET_TPC_CONFIG_CMDID, -++ .pdev_set_base_macaddr_cmdid = WMI_TLV_PDEV_SET_BASE_MACADDR_CMDID, -++ .vdev_create_cmdid = WMI_TLV_VDEV_CREATE_CMDID, -++ .vdev_delete_cmdid = WMI_TLV_VDEV_DELETE_CMDID, -++ .vdev_start_request_cmdid = WMI_TLV_VDEV_START_REQUEST_CMDID, -++ .vdev_restart_request_cmdid = WMI_TLV_VDEV_RESTART_REQUEST_CMDID, -++ .vdev_up_cmdid = WMI_TLV_VDEV_UP_CMDID, -++ .vdev_stop_cmdid = WMI_TLV_VDEV_STOP_CMDID, -++ .vdev_down_cmdid = WMI_TLV_VDEV_DOWN_CMDID, -++ .vdev_set_param_cmdid = WMI_TLV_VDEV_SET_PARAM_CMDID, -++ .vdev_install_key_cmdid = WMI_TLV_VDEV_INSTALL_KEY_CMDID, -++ .peer_create_cmdid = WMI_TLV_PEER_CREATE_CMDID, -++ .peer_delete_cmdid = WMI_TLV_PEER_DELETE_CMDID, -++ .peer_flush_tids_cmdid = WMI_TLV_PEER_FLUSH_TIDS_CMDID, -++ .peer_set_param_cmdid = WMI_TLV_PEER_SET_PARAM_CMDID, -++ .peer_assoc_cmdid = WMI_TLV_PEER_ASSOC_CMDID, -++ .peer_add_wds_entry_cmdid = WMI_TLV_PEER_ADD_WDS_ENTRY_CMDID, -++ .peer_remove_wds_entry_cmdid = WMI_TLV_PEER_REMOVE_WDS_ENTRY_CMDID, -++ .peer_mcast_group_cmdid = WMI_TLV_PEER_MCAST_GROUP_CMDID, -++ .bcn_tx_cmdid = WMI_TLV_BCN_TX_CMDID, -++ .pdev_send_bcn_cmdid = WMI_TLV_PDEV_SEND_BCN_CMDID, -++ .bcn_tmpl_cmdid = WMI_TLV_BCN_TMPL_CMDID, -++ .bcn_filter_rx_cmdid = WMI_TLV_BCN_FILTER_RX_CMDID, -++ .prb_req_filter_rx_cmdid = WMI_TLV_PRB_REQ_FILTER_RX_CMDID, -++ .mgmt_tx_cmdid = WMI_TLV_MGMT_TX_CMDID, -++ .prb_tmpl_cmdid = WMI_TLV_PRB_TMPL_CMDID, -++ .addba_clear_resp_cmdid = WMI_TLV_ADDBA_CLEAR_RESP_CMDID, -++ .addba_send_cmdid = WMI_TLV_ADDBA_SEND_CMDID, -++ .addba_status_cmdid = WMI_TLV_ADDBA_STATUS_CMDID, -++ .delba_send_cmdid = WMI_TLV_DELBA_SEND_CMDID, -++ .addba_set_resp_cmdid = WMI_TLV_ADDBA_SET_RESP_CMDID, -++ .send_singleamsdu_cmdid = WMI_TLV_SEND_SINGLEAMSDU_CMDID, -++ .sta_powersave_mode_cmdid = WMI_TLV_STA_POWERSAVE_MODE_CMDID, -++ .sta_powersave_param_cmdid = WMI_TLV_STA_POWERSAVE_PARAM_CMDID, -++ .sta_mimo_ps_mode_cmdid = WMI_TLV_STA_MIMO_PS_MODE_CMDID, -++ .pdev_dfs_enable_cmdid = WMI_TLV_PDEV_DFS_ENABLE_CMDID, -++ .pdev_dfs_disable_cmdid = WMI_TLV_PDEV_DFS_DISABLE_CMDID, -++ .roam_scan_mode = WMI_TLV_ROAM_SCAN_MODE, -++ .roam_scan_rssi_threshold = WMI_TLV_ROAM_SCAN_RSSI_THRESHOLD, -++ .roam_scan_period = WMI_TLV_ROAM_SCAN_PERIOD, -++ .roam_scan_rssi_change_threshold = -++ WMI_TLV_ROAM_SCAN_RSSI_CHANGE_THRESHOLD, -++ .roam_ap_profile = WMI_TLV_ROAM_AP_PROFILE, -++ .ofl_scan_add_ap_profile = WMI_TLV_ROAM_AP_PROFILE, -++ .ofl_scan_remove_ap_profile = WMI_TLV_OFL_SCAN_REMOVE_AP_PROFILE, -++ .ofl_scan_period = WMI_TLV_OFL_SCAN_PERIOD, -++ .p2p_dev_set_device_info = WMI_TLV_P2P_DEV_SET_DEVICE_INFO, -++ .p2p_dev_set_discoverability = WMI_TLV_P2P_DEV_SET_DISCOVERABILITY, -++ .p2p_go_set_beacon_ie = WMI_TLV_P2P_GO_SET_BEACON_IE, -++ .p2p_go_set_probe_resp_ie = WMI_TLV_P2P_GO_SET_PROBE_RESP_IE, -++ .p2p_set_vendor_ie_data_cmdid = WMI_TLV_P2P_SET_VENDOR_IE_DATA_CMDID, -++ .ap_ps_peer_param_cmdid = WMI_TLV_AP_PS_PEER_PARAM_CMDID, -++ .ap_ps_peer_uapsd_coex_cmdid = WMI_TLV_AP_PS_PEER_UAPSD_COEX_CMDID, -++ .peer_rate_retry_sched_cmdid = WMI_TLV_PEER_RATE_RETRY_SCHED_CMDID, -++ .wlan_profile_trigger_cmdid = WMI_TLV_WLAN_PROFILE_TRIGGER_CMDID, -++ .wlan_profile_set_hist_intvl_cmdid = -++ WMI_TLV_WLAN_PROFILE_SET_HIST_INTVL_CMDID, -++ .wlan_profile_get_profile_data_cmdid = -++ WMI_TLV_WLAN_PROFILE_GET_PROFILE_DATA_CMDID, -++ .wlan_profile_enable_profile_id_cmdid = -++ WMI_TLV_WLAN_PROFILE_ENABLE_PROFILE_ID_CMDID, -++ .wlan_profile_list_profile_id_cmdid = -++ WMI_TLV_WLAN_PROFILE_LIST_PROFILE_ID_CMDID, -++ .pdev_suspend_cmdid = WMI_TLV_PDEV_SUSPEND_CMDID, -++ .pdev_resume_cmdid = WMI_TLV_PDEV_RESUME_CMDID, -++ .add_bcn_filter_cmdid = WMI_TLV_ADD_BCN_FILTER_CMDID, -++ .rmv_bcn_filter_cmdid = WMI_TLV_RMV_BCN_FILTER_CMDID, -++ .wow_add_wake_pattern_cmdid = WMI_TLV_WOW_ADD_WAKE_PATTERN_CMDID, -++ .wow_del_wake_pattern_cmdid = WMI_TLV_WOW_DEL_WAKE_PATTERN_CMDID, -++ .wow_enable_disable_wake_event_cmdid = -++ WMI_TLV_WOW_ENABLE_DISABLE_WAKE_EVENT_CMDID, -++ .wow_enable_cmdid = WMI_TLV_WOW_ENABLE_CMDID, -++ .wow_hostwakeup_from_sleep_cmdid = -++ WMI_TLV_WOW_HOSTWAKEUP_FROM_SLEEP_CMDID, -++ .rtt_measreq_cmdid = WMI_TLV_RTT_MEASREQ_CMDID, -++ .rtt_tsf_cmdid = WMI_TLV_RTT_TSF_CMDID, -++ .vdev_spectral_scan_configure_cmdid = WMI_TLV_SPECTRAL_SCAN_CONF_CMDID, -++ .vdev_spectral_scan_enable_cmdid = WMI_TLV_SPECTRAL_SCAN_ENABLE_CMDID, -++ .request_stats_cmdid = WMI_TLV_REQUEST_STATS_CMDID, -++ .set_arp_ns_offload_cmdid = WMI_TLV_SET_ARP_NS_OFFLOAD_CMDID, -++ .network_list_offload_config_cmdid = -++ WMI_TLV_NETWORK_LIST_OFFLOAD_CONFIG_CMDID, -++ .gtk_offload_cmdid = WMI_TLV_GTK_OFFLOAD_CMDID, -++ .csa_offload_enable_cmdid = WMI_TLV_CSA_OFFLOAD_ENABLE_CMDID, -++ .csa_offload_chanswitch_cmdid = WMI_TLV_CSA_OFFLOAD_CHANSWITCH_CMDID, -++ .chatter_set_mode_cmdid = WMI_TLV_CHATTER_SET_MODE_CMDID, -++ .peer_tid_addba_cmdid = WMI_TLV_PEER_TID_ADDBA_CMDID, -++ .peer_tid_delba_cmdid = WMI_TLV_PEER_TID_DELBA_CMDID, -++ .sta_dtim_ps_method_cmdid = WMI_TLV_STA_DTIM_PS_METHOD_CMDID, -++ .sta_uapsd_auto_trig_cmdid = WMI_TLV_STA_UAPSD_AUTO_TRIG_CMDID, -++ .sta_keepalive_cmd = WMI_TLV_STA_KEEPALIVE_CMDID, -++ .echo_cmdid = WMI_TLV_ECHO_CMDID, -++ .pdev_utf_cmdid = WMI_TLV_PDEV_UTF_CMDID, -++ .dbglog_cfg_cmdid = WMI_TLV_DBGLOG_CFG_CMDID, -++ .pdev_qvit_cmdid = WMI_TLV_PDEV_QVIT_CMDID, -++ .pdev_ftm_intg_cmdid = WMI_TLV_PDEV_FTM_INTG_CMDID, -++ .vdev_set_keepalive_cmdid = WMI_TLV_VDEV_SET_KEEPALIVE_CMDID, -++ .vdev_get_keepalive_cmdid = WMI_TLV_VDEV_GET_KEEPALIVE_CMDID, -++ .force_fw_hang_cmdid = WMI_TLV_FORCE_FW_HANG_CMDID, -++ .gpio_config_cmdid = WMI_TLV_GPIO_CONFIG_CMDID, -++ .gpio_output_cmdid = WMI_TLV_GPIO_OUTPUT_CMDID, -++ .pdev_get_temperature_cmdid = WMI_TLV_CMD_UNSUPPORTED, -++ .vdev_set_wmm_params_cmdid = WMI_TLV_VDEV_SET_WMM_PARAMS_CMDID, -++}; -++ -++static struct wmi_pdev_param_map wmi_tlv_pdev_param_map = { -++ .tx_chain_mask = WMI_TLV_PDEV_PARAM_TX_CHAIN_MASK, -++ .rx_chain_mask = WMI_TLV_PDEV_PARAM_RX_CHAIN_MASK, -++ .txpower_limit2g = WMI_TLV_PDEV_PARAM_TXPOWER_LIMIT2G, -++ .txpower_limit5g = WMI_TLV_PDEV_PARAM_TXPOWER_LIMIT5G, -++ .txpower_scale = WMI_TLV_PDEV_PARAM_TXPOWER_SCALE, -++ .beacon_gen_mode = WMI_TLV_PDEV_PARAM_BEACON_GEN_MODE, -++ .beacon_tx_mode = WMI_TLV_PDEV_PARAM_BEACON_TX_MODE, -++ .resmgr_offchan_mode = WMI_TLV_PDEV_PARAM_RESMGR_OFFCHAN_MODE, -++ .protection_mode = WMI_TLV_PDEV_PARAM_PROTECTION_MODE, -++ .dynamic_bw = WMI_TLV_PDEV_PARAM_DYNAMIC_BW, -++ .non_agg_sw_retry_th = WMI_TLV_PDEV_PARAM_NON_AGG_SW_RETRY_TH, -++ .agg_sw_retry_th = WMI_TLV_PDEV_PARAM_AGG_SW_RETRY_TH, -++ .sta_kickout_th = WMI_TLV_PDEV_PARAM_STA_KICKOUT_TH, -++ .ac_aggrsize_scaling = WMI_TLV_PDEV_PARAM_AC_AGGRSIZE_SCALING, -++ .ltr_enable = WMI_TLV_PDEV_PARAM_LTR_ENABLE, -++ .ltr_ac_latency_be = WMI_TLV_PDEV_PARAM_LTR_AC_LATENCY_BE, -++ .ltr_ac_latency_bk = WMI_TLV_PDEV_PARAM_LTR_AC_LATENCY_BK, -++ .ltr_ac_latency_vi = WMI_TLV_PDEV_PARAM_LTR_AC_LATENCY_VI, -++ .ltr_ac_latency_vo = WMI_TLV_PDEV_PARAM_LTR_AC_LATENCY_VO, -++ .ltr_ac_latency_timeout = WMI_TLV_PDEV_PARAM_LTR_AC_LATENCY_TIMEOUT, -++ .ltr_sleep_override = WMI_TLV_PDEV_PARAM_LTR_SLEEP_OVERRIDE, -++ .ltr_rx_override = WMI_TLV_PDEV_PARAM_LTR_RX_OVERRIDE, -++ .ltr_tx_activity_timeout = WMI_TLV_PDEV_PARAM_LTR_TX_ACTIVITY_TIMEOUT, -++ .l1ss_enable = WMI_TLV_PDEV_PARAM_L1SS_ENABLE, -++ .dsleep_enable = WMI_TLV_PDEV_PARAM_DSLEEP_ENABLE, -++ .pcielp_txbuf_flush = WMI_TLV_PDEV_PARAM_PCIELP_TXBUF_FLUSH, -++ .pcielp_txbuf_watermark = WMI_TLV_PDEV_PARAM_PCIELP_TXBUF_TMO_EN, -++ .pcielp_txbuf_tmo_en = WMI_TLV_PDEV_PARAM_PCIELP_TXBUF_TMO_EN, -++ .pcielp_txbuf_tmo_value = WMI_TLV_PDEV_PARAM_PCIELP_TXBUF_TMO_VALUE, -++ .pdev_stats_update_period = WMI_TLV_PDEV_PARAM_PDEV_STATS_UPDATE_PERIOD, -++ .vdev_stats_update_period = WMI_TLV_PDEV_PARAM_VDEV_STATS_UPDATE_PERIOD, -++ .peer_stats_update_period = WMI_TLV_PDEV_PARAM_PEER_STATS_UPDATE_PERIOD, -++ .bcnflt_stats_update_period = -++ WMI_TLV_PDEV_PARAM_BCNFLT_STATS_UPDATE_PERIOD, -++ .pmf_qos = WMI_TLV_PDEV_PARAM_PMF_QOS, -++ .arp_ac_override = WMI_TLV_PDEV_PARAM_ARP_AC_OVERRIDE, -++ .dcs = WMI_TLV_PDEV_PARAM_DCS, -++ .ani_enable = WMI_TLV_PDEV_PARAM_ANI_ENABLE, -++ .ani_poll_period = WMI_TLV_PDEV_PARAM_ANI_POLL_PERIOD, -++ .ani_listen_period = WMI_TLV_PDEV_PARAM_ANI_LISTEN_PERIOD, -++ .ani_ofdm_level = WMI_TLV_PDEV_PARAM_ANI_OFDM_LEVEL, -++ .ani_cck_level = WMI_TLV_PDEV_PARAM_ANI_CCK_LEVEL, -++ .dyntxchain = WMI_TLV_PDEV_PARAM_DYNTXCHAIN, -++ .proxy_sta = WMI_TLV_PDEV_PARAM_PROXY_STA, -++ .idle_ps_config = WMI_TLV_PDEV_PARAM_IDLE_PS_CONFIG, -++ .power_gating_sleep = WMI_TLV_PDEV_PARAM_POWER_GATING_SLEEP, -++ .fast_channel_reset = WMI_TLV_PDEV_PARAM_UNSUPPORTED, -++ .burst_dur = WMI_TLV_PDEV_PARAM_BURST_DUR, -++ .burst_enable = WMI_TLV_PDEV_PARAM_BURST_ENABLE, -++ .cal_period = WMI_PDEV_PARAM_UNSUPPORTED, -++}; -++ -++static struct wmi_vdev_param_map wmi_tlv_vdev_param_map = { -++ .rts_threshold = WMI_TLV_VDEV_PARAM_RTS_THRESHOLD, -++ .fragmentation_threshold = WMI_TLV_VDEV_PARAM_FRAGMENTATION_THRESHOLD, -++ .beacon_interval = WMI_TLV_VDEV_PARAM_BEACON_INTERVAL, -++ .listen_interval = WMI_TLV_VDEV_PARAM_LISTEN_INTERVAL, -++ .multicast_rate = WMI_TLV_VDEV_PARAM_MULTICAST_RATE, -++ .mgmt_tx_rate = WMI_TLV_VDEV_PARAM_MGMT_TX_RATE, -++ .slot_time = WMI_TLV_VDEV_PARAM_SLOT_TIME, -++ .preamble = WMI_TLV_VDEV_PARAM_PREAMBLE, -++ .swba_time = WMI_TLV_VDEV_PARAM_SWBA_TIME, -++ .wmi_vdev_stats_update_period = WMI_TLV_VDEV_STATS_UPDATE_PERIOD, -++ .wmi_vdev_pwrsave_ageout_time = WMI_TLV_VDEV_PWRSAVE_AGEOUT_TIME, -++ .wmi_vdev_host_swba_interval = WMI_TLV_VDEV_HOST_SWBA_INTERVAL, -++ .dtim_period = WMI_TLV_VDEV_PARAM_DTIM_PERIOD, -++ .wmi_vdev_oc_scheduler_air_time_limit = -++ WMI_TLV_VDEV_OC_SCHEDULER_AIR_TIME_LIMIT, -++ .wds = WMI_TLV_VDEV_PARAM_WDS, -++ .atim_window = WMI_TLV_VDEV_PARAM_ATIM_WINDOW, -++ .bmiss_count_max = WMI_TLV_VDEV_PARAM_BMISS_COUNT_MAX, -++ .bmiss_first_bcnt = WMI_TLV_VDEV_PARAM_BMISS_FIRST_BCNT, -++ .bmiss_final_bcnt = WMI_TLV_VDEV_PARAM_BMISS_FINAL_BCNT, -++ .feature_wmm = WMI_TLV_VDEV_PARAM_FEATURE_WMM, -++ .chwidth = WMI_TLV_VDEV_PARAM_CHWIDTH, -++ .chextoffset = WMI_TLV_VDEV_PARAM_CHEXTOFFSET, -++ .disable_htprotection = WMI_TLV_VDEV_PARAM_DISABLE_HTPROTECTION, -++ .sta_quickkickout = WMI_TLV_VDEV_PARAM_STA_QUICKKICKOUT, -++ .mgmt_rate = WMI_TLV_VDEV_PARAM_MGMT_RATE, -++ .protection_mode = WMI_TLV_VDEV_PARAM_PROTECTION_MODE, -++ .fixed_rate = WMI_TLV_VDEV_PARAM_FIXED_RATE, -++ .sgi = WMI_TLV_VDEV_PARAM_SGI, -++ .ldpc = WMI_TLV_VDEV_PARAM_LDPC, -++ .tx_stbc = WMI_TLV_VDEV_PARAM_TX_STBC, -++ .rx_stbc = WMI_TLV_VDEV_PARAM_RX_STBC, -++ .intra_bss_fwd = WMI_TLV_VDEV_PARAM_INTRA_BSS_FWD, -++ .def_keyid = WMI_TLV_VDEV_PARAM_DEF_KEYID, -++ .nss = WMI_TLV_VDEV_PARAM_NSS, -++ .bcast_data_rate = WMI_TLV_VDEV_PARAM_BCAST_DATA_RATE, -++ .mcast_data_rate = WMI_TLV_VDEV_PARAM_MCAST_DATA_RATE, -++ .mcast_indicate = WMI_TLV_VDEV_PARAM_MCAST_INDICATE, -++ .dhcp_indicate = WMI_TLV_VDEV_PARAM_DHCP_INDICATE, -++ .unknown_dest_indicate = WMI_TLV_VDEV_PARAM_UNKNOWN_DEST_INDICATE, -++ .ap_keepalive_min_idle_inactive_time_secs = -++ WMI_TLV_VDEV_PARAM_AP_KEEPALIVE_MIN_IDLE_INACTIVE_TIME_SECS, -++ .ap_keepalive_max_idle_inactive_time_secs = -++ WMI_TLV_VDEV_PARAM_AP_KEEPALIVE_MAX_IDLE_INACTIVE_TIME_SECS, -++ .ap_keepalive_max_unresponsive_time_secs = -++ WMI_TLV_VDEV_PARAM_AP_KEEPALIVE_MAX_UNRESPONSIVE_TIME_SECS, -++ .ap_enable_nawds = WMI_TLV_VDEV_PARAM_AP_ENABLE_NAWDS, -++ .mcast2ucast_set = WMI_TLV_VDEV_PARAM_UNSUPPORTED, -++ .enable_rtscts = WMI_TLV_VDEV_PARAM_ENABLE_RTSCTS, -++ .txbf = WMI_TLV_VDEV_PARAM_TXBF, -++ .packet_powersave = WMI_TLV_VDEV_PARAM_PACKET_POWERSAVE, -++ .drop_unencry = WMI_TLV_VDEV_PARAM_DROP_UNENCRY, -++ .tx_encap_type = WMI_TLV_VDEV_PARAM_TX_ENCAP_TYPE, -++ .ap_detect_out_of_sync_sleeping_sta_time_secs = -++ WMI_TLV_VDEV_PARAM_UNSUPPORTED, -++}; -++ -++static const struct wmi_ops wmi_tlv_ops = { -++ .rx = ath10k_wmi_tlv_op_rx, -++ .map_svc = wmi_tlv_svc_map, -++ -++ .pull_scan = ath10k_wmi_tlv_op_pull_scan_ev, -++ .pull_mgmt_rx = ath10k_wmi_tlv_op_pull_mgmt_rx_ev, -++ .pull_ch_info = ath10k_wmi_tlv_op_pull_ch_info_ev, -++ .pull_vdev_start = ath10k_wmi_tlv_op_pull_vdev_start_ev, -++ .pull_peer_kick = ath10k_wmi_tlv_op_pull_peer_kick_ev, -++ .pull_swba = ath10k_wmi_tlv_op_pull_swba_ev, -++ .pull_phyerr = ath10k_wmi_tlv_op_pull_phyerr_ev, -++ .pull_svc_rdy = ath10k_wmi_tlv_op_pull_svc_rdy_ev, -++ .pull_rdy = ath10k_wmi_tlv_op_pull_rdy_ev, -++ .pull_fw_stats = ath10k_wmi_tlv_op_pull_fw_stats, -++ -++ .gen_pdev_suspend = ath10k_wmi_tlv_op_gen_pdev_suspend, -++ .gen_pdev_resume = ath10k_wmi_tlv_op_gen_pdev_resume, -++ .gen_pdev_set_rd = ath10k_wmi_tlv_op_gen_pdev_set_rd, -++ .gen_pdev_set_param = ath10k_wmi_tlv_op_gen_pdev_set_param, -++ .gen_init = ath10k_wmi_tlv_op_gen_init, -++ .gen_start_scan = ath10k_wmi_tlv_op_gen_start_scan, -++ .gen_stop_scan = ath10k_wmi_tlv_op_gen_stop_scan, -++ .gen_vdev_create = ath10k_wmi_tlv_op_gen_vdev_create, -++ .gen_vdev_delete = ath10k_wmi_tlv_op_gen_vdev_delete, -++ .gen_vdev_start = ath10k_wmi_tlv_op_gen_vdev_start, -++ .gen_vdev_stop = ath10k_wmi_tlv_op_gen_vdev_stop, -++ .gen_vdev_up = ath10k_wmi_tlv_op_gen_vdev_up, -++ .gen_vdev_down = ath10k_wmi_tlv_op_gen_vdev_down, -++ .gen_vdev_set_param = ath10k_wmi_tlv_op_gen_vdev_set_param, -++ .gen_vdev_install_key = ath10k_wmi_tlv_op_gen_vdev_install_key, -++ .gen_vdev_wmm_conf = ath10k_wmi_tlv_op_gen_vdev_wmm_conf, -++ .gen_peer_create = ath10k_wmi_tlv_op_gen_peer_create, -++ .gen_peer_delete = ath10k_wmi_tlv_op_gen_peer_delete, -++ .gen_peer_flush = ath10k_wmi_tlv_op_gen_peer_flush, -++ .gen_peer_set_param = ath10k_wmi_tlv_op_gen_peer_set_param, -++ .gen_peer_assoc = ath10k_wmi_tlv_op_gen_peer_assoc, -++ .gen_set_psmode = ath10k_wmi_tlv_op_gen_set_psmode, -++ .gen_set_sta_ps = ath10k_wmi_tlv_op_gen_set_sta_ps, -++ .gen_set_ap_ps = ath10k_wmi_tlv_op_gen_set_ap_ps, -++ .gen_scan_chan_list = ath10k_wmi_tlv_op_gen_scan_chan_list, -++ .gen_beacon_dma = ath10k_wmi_tlv_op_gen_beacon_dma, -++ .gen_pdev_set_wmm = ath10k_wmi_tlv_op_gen_pdev_set_wmm, -++ .gen_request_stats = ath10k_wmi_tlv_op_gen_request_stats, -++ .gen_force_fw_hang = ath10k_wmi_tlv_op_gen_force_fw_hang, -++ /* .gen_mgmt_tx = not implemented; HTT is used */ -++ .gen_dbglog_cfg = ath10k_wmi_tlv_op_gen_dbglog_cfg, -++ .gen_pktlog_enable = ath10k_wmi_tlv_op_gen_pktlog_enable, -++ .gen_pktlog_disable = ath10k_wmi_tlv_op_gen_pktlog_disable, -++ /* .gen_pdev_set_quiet_mode not implemented */ -++ /* .gen_pdev_get_temperature not implemented */ -++ /* .gen_addba_clear_resp not implemented */ -++ /* .gen_addba_send not implemented */ -++ /* .gen_addba_set_resp not implemented */ -++ /* .gen_delba_send not implemented */ -++ .gen_bcn_tmpl = ath10k_wmi_tlv_op_gen_bcn_tmpl, -++ .gen_prb_tmpl = ath10k_wmi_tlv_op_gen_prb_tmpl, -++ .gen_p2p_go_bcn_ie = ath10k_wmi_tlv_op_gen_p2p_go_bcn_ie, -++ .gen_vdev_sta_uapsd = ath10k_wmi_tlv_op_gen_vdev_sta_uapsd, -++ .gen_sta_keepalive = ath10k_wmi_tlv_op_gen_sta_keepalive, -++}; -++ -++/************/ -++/* TLV init */ -++/************/ -++ -++void ath10k_wmi_tlv_attach(struct ath10k *ar) -++{ -++ ar->wmi.cmd = &wmi_tlv_cmd_map; -++ ar->wmi.vdev_param = &wmi_tlv_vdev_param_map; -++ ar->wmi.pdev_param = &wmi_tlv_pdev_param_map; -++ ar->wmi.ops = &wmi_tlv_ops; -++} -+--- /dev/null -++++ b/drivers/net/wireless/ath/ath10k/wmi-tlv.h -+@@ -0,0 +1,1459 @@ -++/* -++ * Copyright (c) 2005-2011 Atheros Communications Inc. -++ * Copyright (c) 2011-2014 Qualcomm Atheros, Inc. -++ * -++ * Permission to use, copy, modify, and/or distribute this software for any -++ * purpose with or without fee is hereby granted, provided that the above -++ * copyright notice and this permission notice appear in all copies. -++ * -++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -++ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -++ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -++ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -++ */ -++#ifndef _WMI_TLV_H -++#define _WMI_TLV_H -++ -++#define WMI_TLV_CMD(grp_id) (((grp_id) << 12) | 0x1) -++#define WMI_TLV_EV(grp_id) (((grp_id) << 12) | 0x1) -++#define WMI_TLV_CMD_UNSUPPORTED 0 -++#define WMI_TLV_PDEV_PARAM_UNSUPPORTED 0 -++#define WMI_TLV_VDEV_PARAM_UNSUPPORTED 0 -++ -++enum wmi_tlv_grp_id { -++ WMI_TLV_GRP_START = 0x3, -++ WMI_TLV_GRP_SCAN = WMI_TLV_GRP_START, -++ WMI_TLV_GRP_PDEV, -++ WMI_TLV_GRP_VDEV, -++ WMI_TLV_GRP_PEER, -++ WMI_TLV_GRP_MGMT, -++ WMI_TLV_GRP_BA_NEG, -++ WMI_TLV_GRP_STA_PS, -++ WMI_TLV_GRP_DFS, -++ WMI_TLV_GRP_ROAM, -++ WMI_TLV_GRP_OFL_SCAN, -++ WMI_TLV_GRP_P2P, -++ WMI_TLV_GRP_AP_PS, -++ WMI_TLV_GRP_RATECTL, -++ WMI_TLV_GRP_PROFILE, -++ WMI_TLV_GRP_SUSPEND, -++ WMI_TLV_GRP_BCN_FILTER, -++ WMI_TLV_GRP_WOW, -++ WMI_TLV_GRP_RTT, -++ WMI_TLV_GRP_SPECTRAL, -++ WMI_TLV_GRP_STATS, -++ WMI_TLV_GRP_ARP_NS_OFL, -++ WMI_TLV_GRP_NLO_OFL, -++ WMI_TLV_GRP_GTK_OFL, -++ WMI_TLV_GRP_CSA_OFL, -++ WMI_TLV_GRP_CHATTER, -++ WMI_TLV_GRP_TID_ADDBA, -++ WMI_TLV_GRP_MISC, -++ WMI_TLV_GRP_GPIO, -++ WMI_TLV_GRP_FWTEST, -++ WMI_TLV_GRP_TDLS, -++ WMI_TLV_GRP_RESMGR, -++ WMI_TLV_GRP_STA_SMPS, -++ WMI_TLV_GRP_WLAN_HB, -++ WMI_TLV_GRP_RMC, -++ WMI_TLV_GRP_MHF_OFL, -++ WMI_TLV_GRP_LOCATION_SCAN, -++ WMI_TLV_GRP_OEM, -++ WMI_TLV_GRP_NAN, -++ WMI_TLV_GRP_COEX, -++ WMI_TLV_GRP_OBSS_OFL, -++ WMI_TLV_GRP_LPI, -++ WMI_TLV_GRP_EXTSCAN, -++ WMI_TLV_GRP_DHCP_OFL, -++ WMI_TLV_GRP_IPA, -++ WMI_TLV_GRP_MDNS_OFL, -++ WMI_TLV_GRP_SAP_OFL, -++}; -++ -++enum wmi_tlv_cmd_id { -++ WMI_TLV_INIT_CMDID = 0x1, -++ WMI_TLV_START_SCAN_CMDID = WMI_TLV_CMD(WMI_TLV_GRP_SCAN), -++ WMI_TLV_STOP_SCAN_CMDID, -++ WMI_TLV_SCAN_CHAN_LIST_CMDID, -++ WMI_TLV_SCAN_SCH_PRIO_TBL_CMDID, -++ WMI_TLV_SCAN_UPDATE_REQUEST_CMDID, -++ WMI_TLV_SCAN_PROB_REQ_OUI_CMDID, -++ WMI_TLV_PDEV_SET_REGDOMAIN_CMDID = WMI_TLV_CMD(WMI_TLV_GRP_PDEV), -++ WMI_TLV_PDEV_SET_CHANNEL_CMDID, -++ WMI_TLV_PDEV_SET_PARAM_CMDID, -++ WMI_TLV_PDEV_PKTLOG_ENABLE_CMDID, -++ WMI_TLV_PDEV_PKTLOG_DISABLE_CMDID, -++ WMI_TLV_PDEV_SET_WMM_PARAMS_CMDID, -++ WMI_TLV_PDEV_SET_HT_CAP_IE_CMDID, -++ WMI_TLV_PDEV_SET_VHT_CAP_IE_CMDID, -++ WMI_TLV_PDEV_SET_DSCP_TID_MAP_CMDID, -++ WMI_TLV_PDEV_SET_QUIET_MODE_CMDID, -++ WMI_TLV_PDEV_GREEN_AP_PS_ENABLE_CMDID, -++ WMI_TLV_PDEV_GET_TPC_CONFIG_CMDID, -++ WMI_TLV_PDEV_SET_BASE_MACADDR_CMDID, -++ WMI_TLV_PDEV_DUMP_CMDID, -++ WMI_TLV_PDEV_SET_LED_CONFIG_CMDID, -++ WMI_TLV_PDEV_GET_TEMPERATURE_CMDID, -++ WMI_TLV_PDEV_SET_LED_FLASHING_CMDID, -++ WMI_TLV_VDEV_CREATE_CMDID = WMI_TLV_CMD(WMI_TLV_GRP_VDEV), -++ WMI_TLV_VDEV_DELETE_CMDID, -++ WMI_TLV_VDEV_START_REQUEST_CMDID, -++ WMI_TLV_VDEV_RESTART_REQUEST_CMDID, -++ WMI_TLV_VDEV_UP_CMDID, -++ WMI_TLV_VDEV_STOP_CMDID, -++ WMI_TLV_VDEV_DOWN_CMDID, -++ WMI_TLV_VDEV_SET_PARAM_CMDID, -++ WMI_TLV_VDEV_INSTALL_KEY_CMDID, -++ WMI_TLV_VDEV_WNM_SLEEPMODE_CMDID, -++ WMI_TLV_VDEV_WMM_ADDTS_CMDID, -++ WMI_TLV_VDEV_WMM_DELTS_CMDID, -++ WMI_TLV_VDEV_SET_WMM_PARAMS_CMDID, -++ WMI_TLV_VDEV_SET_GTX_PARAMS_CMDID, -++ WMI_TLV_VDEV_IPSEC_NATKEEPALIVE_FILTER_CMDID, -++ WMI_TLV_VDEV_PLMREQ_START_CMDID, -++ WMI_TLV_VDEV_PLMREQ_STOP_CMDID, -++ WMI_TLV_PEER_CREATE_CMDID = WMI_TLV_CMD(WMI_TLV_GRP_PEER), -++ WMI_TLV_PEER_DELETE_CMDID, -++ WMI_TLV_PEER_FLUSH_TIDS_CMDID, -++ WMI_TLV_PEER_SET_PARAM_CMDID, -++ WMI_TLV_PEER_ASSOC_CMDID, -++ WMI_TLV_PEER_ADD_WDS_ENTRY_CMDID, -++ WMI_TLV_PEER_REMOVE_WDS_ENTRY_CMDID, -++ WMI_TLV_PEER_MCAST_GROUP_CMDID, -++ WMI_TLV_PEER_INFO_REQ_CMDID, -++ WMI_TLV_PEER_GET_ESTIMATED_LINKSPEED_CMDID, -++ WMI_TLV_BCN_TX_CMDID = WMI_TLV_CMD(WMI_TLV_GRP_MGMT), -++ WMI_TLV_PDEV_SEND_BCN_CMDID, -++ WMI_TLV_BCN_TMPL_CMDID, -++ WMI_TLV_BCN_FILTER_RX_CMDID, -++ WMI_TLV_PRB_REQ_FILTER_RX_CMDID, -++ WMI_TLV_MGMT_TX_CMDID, -++ WMI_TLV_PRB_TMPL_CMDID, -++ WMI_TLV_ADDBA_CLEAR_RESP_CMDID = WMI_TLV_CMD(WMI_TLV_GRP_BA_NEG), -++ WMI_TLV_ADDBA_SEND_CMDID, -++ WMI_TLV_ADDBA_STATUS_CMDID, -++ WMI_TLV_DELBA_SEND_CMDID, -++ WMI_TLV_ADDBA_SET_RESP_CMDID, -++ WMI_TLV_SEND_SINGLEAMSDU_CMDID, -++ WMI_TLV_STA_POWERSAVE_MODE_CMDID = WMI_TLV_CMD(WMI_TLV_GRP_STA_PS), -++ WMI_TLV_STA_POWERSAVE_PARAM_CMDID, -++ WMI_TLV_STA_MIMO_PS_MODE_CMDID, -++ WMI_TLV_PDEV_DFS_ENABLE_CMDID = WMI_TLV_CMD(WMI_TLV_GRP_DFS), -++ WMI_TLV_PDEV_DFS_DISABLE_CMDID, -++ WMI_TLV_DFS_PHYERR_FILTER_ENA_CMDID, -++ WMI_TLV_DFS_PHYERR_FILTER_DIS_CMDID, -++ WMI_TLV_ROAM_SCAN_MODE = WMI_TLV_CMD(WMI_TLV_GRP_ROAM), -++ WMI_TLV_ROAM_SCAN_RSSI_THRESHOLD, -++ WMI_TLV_ROAM_SCAN_PERIOD, -++ WMI_TLV_ROAM_SCAN_RSSI_CHANGE_THRESHOLD, -++ WMI_TLV_ROAM_AP_PROFILE, -++ WMI_TLV_ROAM_CHAN_LIST, -++ WMI_TLV_ROAM_SCAN_CMD, -++ WMI_TLV_ROAM_SYNCH_COMPLETE, -++ WMI_TLV_ROAM_SET_RIC_REQUEST_CMDID, -++ WMI_TLV_ROAM_INVOKE_CMDID, -++ WMI_TLV_OFL_SCAN_ADD_AP_PROFILE = WMI_TLV_CMD(WMI_TLV_GRP_OFL_SCAN), -++ WMI_TLV_OFL_SCAN_REMOVE_AP_PROFILE, -++ WMI_TLV_OFL_SCAN_PERIOD, -++ WMI_TLV_P2P_DEV_SET_DEVICE_INFO = WMI_TLV_CMD(WMI_TLV_GRP_P2P), -++ WMI_TLV_P2P_DEV_SET_DISCOVERABILITY, -++ WMI_TLV_P2P_GO_SET_BEACON_IE, -++ WMI_TLV_P2P_GO_SET_PROBE_RESP_IE, -++ WMI_TLV_P2P_SET_VENDOR_IE_DATA_CMDID, -++ WMI_TLV_P2P_DISC_OFFLOAD_CONFIG_CMDID, -++ WMI_TLV_P2P_DISC_OFFLOAD_APPIE_CMDID, -++ WMI_TLV_P2P_DISC_OFFLOAD_PATTERN_CMDID, -++ WMI_TLV_P2P_SET_OPPPS_PARAM_CMDID, -++ WMI_TLV_AP_PS_PEER_PARAM_CMDID = WMI_TLV_CMD(WMI_TLV_GRP_AP_PS), -++ WMI_TLV_AP_PS_PEER_UAPSD_COEX_CMDID, -++ WMI_TLV_PEER_RATE_RETRY_SCHED_CMDID = WMI_TLV_CMD(WMI_TLV_GRP_RATECTL), -++ WMI_TLV_WLAN_PROFILE_TRIGGER_CMDID = WMI_TLV_CMD(WMI_TLV_GRP_PROFILE), -++ WMI_TLV_WLAN_PROFILE_SET_HIST_INTVL_CMDID, -++ WMI_TLV_WLAN_PROFILE_GET_PROFILE_DATA_CMDID, -++ WMI_TLV_WLAN_PROFILE_ENABLE_PROFILE_ID_CMDID, -++ WMI_TLV_WLAN_PROFILE_LIST_PROFILE_ID_CMDID, -++ WMI_TLV_PDEV_SUSPEND_CMDID = WMI_TLV_CMD(WMI_TLV_GRP_SUSPEND), -++ WMI_TLV_PDEV_RESUME_CMDID, -++ WMI_TLV_ADD_BCN_FILTER_CMDID = WMI_TLV_CMD(WMI_TLV_GRP_BCN_FILTER), -++ WMI_TLV_RMV_BCN_FILTER_CMDID, -++ WMI_TLV_WOW_ADD_WAKE_PATTERN_CMDID = WMI_TLV_CMD(WMI_TLV_GRP_WOW), -++ WMI_TLV_WOW_DEL_WAKE_PATTERN_CMDID, -++ WMI_TLV_WOW_ENABLE_DISABLE_WAKE_EVENT_CMDID, -++ WMI_TLV_WOW_ENABLE_CMDID, -++ WMI_TLV_WOW_HOSTWAKEUP_FROM_SLEEP_CMDID, -++ WMI_TLV_WOW_ACER_IOAC_ADD_KEEPALIVE_CMDID, -++ WMI_TLV_WOW_ACER_IOAC_DEL_KEEPALIVE_CMDID, -++ WMI_TLV_WOW_ACER_IOAC_ADD_WAKE_PATTERN_CMDID, -++ WMI_TLV_WOW_ACER_IOAC_DEL_WAKE_PATTERN_CMDID, -++ WMI_TLV_D0_WOW_ENABLE_DISABLE_CMDID, -++ WMI_TLV_EXTWOW_ENABLE_CMDID, -++ WMI_TLV_EXTWOW_SET_APP_TYPE1_PARAMS_CMDID, -++ WMI_TLV_EXTWOW_SET_APP_TYPE2_PARAMS_CMDID, -++ WMI_TLV_RTT_MEASREQ_CMDID = WMI_TLV_CMD(WMI_TLV_GRP_RTT), -++ WMI_TLV_RTT_TSF_CMDID, -++ WMI_TLV_SPECTRAL_SCAN_CONF_CMDID = WMI_TLV_CMD(WMI_TLV_GRP_SPECTRAL), -++ WMI_TLV_SPECTRAL_SCAN_ENABLE_CMDID, -++ WMI_TLV_REQUEST_STATS_CMDID = WMI_TLV_CMD(WMI_TLV_GRP_STATS), -++ WMI_TLV_MCC_SCHED_TRAFFIC_STATS_CMDID, -++ WMI_TLV_REQUEST_STATS_EXT_CMDID, -++ WMI_TLV_REQUEST_LINK_STATS_CMDID, -++ WMI_TLV_START_LINK_STATS_CMDID, -++ WMI_TLV_CLEAR_LINK_STATS_CMDID, -++ WMI_TLV_SET_ARP_NS_OFFLOAD_CMDID = WMI_TLV_CMD(WMI_TLV_GRP_ARP_NS_OFL), -++ WMI_TLV_ADD_PROACTIVE_ARP_RSP_PATTERN_CMDID, -++ WMI_TLV_DEL_PROACTIVE_ARP_RSP_PATTERN_CMDID, -++ WMI_TLV_NETWORK_LIST_OFFLOAD_CONFIG_CMDID = -++ WMI_TLV_CMD(WMI_TLV_GRP_NLO_OFL), -++ WMI_TLV_APFIND_CMDID, -++ WMI_TLV_GTK_OFFLOAD_CMDID = WMI_TLV_CMD(WMI_TLV_GRP_GTK_OFL), -++ WMI_TLV_CSA_OFFLOAD_ENABLE_CMDID = WMI_TLV_CMD(WMI_TLV_GRP_CSA_OFL), -++ WMI_TLV_CSA_OFFLOAD_CHANSWITCH_CMDID, -++ WMI_TLV_CHATTER_SET_MODE_CMDID = WMI_TLV_CMD(WMI_TLV_GRP_CHATTER), -++ WMI_TLV_CHATTER_ADD_COALESCING_FILTER_CMDID, -++ WMI_TLV_CHATTER_DELETE_COALESCING_FILTER_CMDID, -++ WMI_TLV_CHATTER_COALESCING_QUERY_CMDID, -++ WMI_TLV_PEER_TID_ADDBA_CMDID = WMI_TLV_CMD(WMI_TLV_GRP_TID_ADDBA), -++ WMI_TLV_PEER_TID_DELBA_CMDID, -++ WMI_TLV_STA_DTIM_PS_METHOD_CMDID, -++ WMI_TLV_STA_UAPSD_AUTO_TRIG_CMDID, -++ WMI_TLV_STA_KEEPALIVE_CMDID, -++ WMI_TLV_BA_REQ_SSN_CMDID, -++ WMI_TLV_ECHO_CMDID = WMI_TLV_CMD(WMI_TLV_GRP_MISC), -++ WMI_TLV_PDEV_UTF_CMDID, -++ WMI_TLV_DBGLOG_CFG_CMDID, -++ WMI_TLV_PDEV_QVIT_CMDID, -++ WMI_TLV_PDEV_FTM_INTG_CMDID, -++ WMI_TLV_VDEV_SET_KEEPALIVE_CMDID, -++ WMI_TLV_VDEV_GET_KEEPALIVE_CMDID, -++ WMI_TLV_FORCE_FW_HANG_CMDID, -++ WMI_TLV_SET_MCASTBCAST_FILTER_CMDID, -++ WMI_TLV_THERMAL_MGMT_CMDID, -++ WMI_TLV_HOST_AUTO_SHUTDOWN_CFG_CMDID, -++ WMI_TLV_TPC_CHAINMASK_CONFIG_CMDID, -++ WMI_TLV_SET_ANTENNA_DIVERSITY_CMDID, -++ WMI_TLV_GPIO_CONFIG_CMDID = WMI_TLV_CMD(WMI_TLV_GRP_GPIO), -++ WMI_TLV_GPIO_OUTPUT_CMDID, -++ WMI_TLV_TXBF_CMDID, -++ WMI_TLV_FWTEST_VDEV_MCC_SET_TBTT_MODE_CMDID = -++ WMI_TLV_CMD(WMI_TLV_GRP_FWTEST), -++ WMI_TLV_FWTEST_P2P_SET_NOA_PARAM_CMDID, -++ WMI_TLV_UNIT_TEST_CMDID, -++ WMI_TLV_TDLS_SET_STATE_CMDID = WMI_TLV_CMD(WMI_TLV_GRP_TDLS), -++ WMI_TLV_TDLS_PEER_UPDATE_CMDID, -++ WMI_TLV_TDLS_SET_OFFCHAN_MODE_CMDID, -++ WMI_TLV_RESMGR_ADAPTIVE_OCS_CMDID = WMI_TLV_CMD(WMI_TLV_GRP_RESMGR), -++ WMI_TLV_RESMGR_SET_CHAN_TIME_QUOTA_CMDID, -++ WMI_TLV_RESMGR_SET_CHAN_LATENCY_CMDID, -++ WMI_TLV_STA_SMPS_FORCE_MODE_CMDID = WMI_TLV_CMD(WMI_TLV_GRP_STA_SMPS), -++ WMI_TLV_STA_SMPS_PARAM_CMDID, -++ WMI_TLV_HB_SET_ENABLE_CMDID = WMI_TLV_CMD(WMI_TLV_GRP_WLAN_HB), -++ WMI_TLV_HB_SET_TCP_PARAMS_CMDID, -++ WMI_TLV_HB_SET_TCP_PKT_FILTER_CMDID, -++ WMI_TLV_HB_SET_UDP_PARAMS_CMDID, -++ WMI_TLV_HB_SET_UDP_PKT_FILTER_CMDID, -++ WMI_TLV_RMC_SET_MODE_CMDID = WMI_TLV_CMD(WMI_TLV_GRP_RMC), -++ WMI_TLV_RMC_SET_ACTION_PERIOD_CMDID, -++ WMI_TLV_RMC_CONFIG_CMDID, -++ WMI_TLV_MHF_OFFLOAD_SET_MODE_CMDID = WMI_TLV_CMD(WMI_TLV_GRP_MHF_OFL), -++ WMI_TLV_MHF_OFFLOAD_PLUMB_ROUTING_TBL_CMDID, -++ WMI_TLV_BATCH_SCAN_ENABLE_CMDID = -++ WMI_TLV_CMD(WMI_TLV_GRP_LOCATION_SCAN), -++ WMI_TLV_BATCH_SCAN_DISABLE_CMDID, -++ WMI_TLV_BATCH_SCAN_TRIGGER_RESULT_CMDID, -++ WMI_TLV_OEM_REQ_CMDID = WMI_TLV_CMD(WMI_TLV_GRP_OEM), -++ WMI_TLV_NAN_CMDID = WMI_TLV_CMD(WMI_TLV_GRP_NAN), -++ WMI_TLV_MODEM_POWER_STATE_CMDID = WMI_TLV_CMD(WMI_TLV_GRP_COEX), -++ WMI_TLV_CHAN_AVOID_UPDATE_CMDID, -++ WMI_TLV_OBSS_SCAN_ENABLE_CMDID = WMI_TLV_CMD(WMI_TLV_GRP_OBSS_OFL), -++ WMI_TLV_OBSS_SCAN_DISABLE_CMDID, -++ WMI_TLV_LPI_MGMT_SNOOPING_CONFIG_CMDID = WMI_TLV_CMD(WMI_TLV_GRP_LPI), -++ WMI_TLV_LPI_START_SCAN_CMDID, -++ WMI_TLV_LPI_STOP_SCAN_CMDID, -++ WMI_TLV_EXTSCAN_START_CMDID = WMI_TLV_CMD(WMI_TLV_GRP_EXTSCAN), -++ WMI_TLV_EXTSCAN_STOP_CMDID, -++ WMI_TLV_EXTSCAN_CONFIGURE_WLAN_CHANGE_MONITOR_CMDID, -++ WMI_TLV_EXTSCAN_CONFIGURE_HOTLIST_MONITOR_CMDID, -++ WMI_TLV_EXTSCAN_GET_CACHED_RESULTS_CMDID, -++ WMI_TLV_EXTSCAN_GET_WLAN_CHANGE_RESULTS_CMDID, -++ WMI_TLV_EXTSCAN_SET_CAPABILITIES_CMDID, -++ WMI_TLV_EXTSCAN_GET_CAPABILITIES_CMDID, -++ WMI_TLV_SET_DHCP_SERVER_OFFLOAD_CMDID = -++ WMI_TLV_CMD(WMI_TLV_GRP_DHCP_OFL), -++ WMI_TLV_IPA_OFFLOAD_ENABLE_DISABLE_CMDID = WMI_TLV_CMD(WMI_TLV_GRP_IPA), -++ WMI_TLV_MDNS_OFFLOAD_ENABLE_CMDID = WMI_TLV_CMD(WMI_TLV_GRP_MDNS_OFL), -++ WMI_TLV_MDNS_SET_FQDN_CMDID, -++ WMI_TLV_MDNS_SET_RESPONSE_CMDID, -++ WMI_TLV_MDNS_GET_STATS_CMDID, -++ WMI_TLV_SAP_OFL_ENABLE_CMDID = WMI_TLV_CMD(WMI_TLV_GRP_SAP_OFL), -++}; -++ -++enum wmi_tlv_event_id { -++ WMI_TLV_SERVICE_READY_EVENTID = 0x1, -++ WMI_TLV_READY_EVENTID, -++ WMI_TLV_SCAN_EVENTID = WMI_TLV_EV(WMI_TLV_GRP_SCAN), -++ WMI_TLV_PDEV_TPC_CONFIG_EVENTID = WMI_TLV_EV(WMI_TLV_GRP_PDEV), -++ WMI_TLV_CHAN_INFO_EVENTID, -++ WMI_TLV_PHYERR_EVENTID, -++ WMI_TLV_PDEV_DUMP_EVENTID, -++ WMI_TLV_TX_PAUSE_EVENTID, -++ WMI_TLV_DFS_RADAR_EVENTID, -++ WMI_TLV_PDEV_L1SS_TRACK_EVENTID, -++ WMI_TLV_PDEV_TEMPERATURE_EVENTID, -++ WMI_TLV_VDEV_START_RESP_EVENTID = WMI_TLV_EV(WMI_TLV_GRP_VDEV), -++ WMI_TLV_VDEV_STOPPED_EVENTID, -++ WMI_TLV_VDEV_INSTALL_KEY_COMPLETE_EVENTID, -++ WMI_TLV_VDEV_MCC_BCN_INTERVAL_CHANGE_REQ_EVENTID, -++ WMI_TLV_PEER_STA_KICKOUT_EVENTID = WMI_TLV_EV(WMI_TLV_GRP_PEER), -++ WMI_TLV_PEER_INFO_EVENTID, -++ WMI_TLV_PEER_TX_FAIL_CNT_THR_EVENTID, -++ WMI_TLV_PEER_ESTIMATED_LINKSPEED_EVENTID, -++ WMI_TLV_PEER_STATE_EVENTID, -++ WMI_TLV_MGMT_RX_EVENTID = WMI_TLV_EV(WMI_TLV_GRP_MGMT), -++ WMI_TLV_HOST_SWBA_EVENTID, -++ WMI_TLV_TBTTOFFSET_UPDATE_EVENTID, -++ WMI_TLV_OFFLOAD_BCN_TX_STATUS_EVENTID, -++ WMI_TLV_OFFLOAD_PROB_RESP_TX_STATUS_EVENTID, -++ WMI_TLV_TX_DELBA_COMPLETE_EVENTID = WMI_TLV_EV(WMI_TLV_GRP_BA_NEG), -++ WMI_TLV_TX_ADDBA_COMPLETE_EVENTID, -++ WMI_TLV_BA_RSP_SSN_EVENTID, -++ WMI_TLV_AGGR_STATE_TRIG_EVENTID, -++ WMI_TLV_ROAM_EVENTID = WMI_TLV_EV(WMI_TLV_GRP_ROAM), -++ WMI_TLV_PROFILE_MATCH, -++ WMI_TLV_ROAM_SYNCH_EVENTID, -++ WMI_TLV_P2P_DISC_EVENTID = WMI_TLV_EV(WMI_TLV_GRP_P2P), -++ WMI_TLV_P2P_NOA_EVENTID, -++ WMI_TLV_PDEV_RESUME_EVENTID = WMI_TLV_EV(WMI_TLV_GRP_SUSPEND), -++ WMI_TLV_WOW_WAKEUP_HOST_EVENTID = WMI_TLV_EV(WMI_TLV_GRP_WOW), -++ WMI_TLV_D0_WOW_DISABLE_ACK_EVENTID, -++ WMI_TLV_RTT_MEASUREMENT_REPORT_EVENTID = WMI_TLV_EV(WMI_TLV_GRP_RTT), -++ WMI_TLV_TSF_MEASUREMENT_REPORT_EVENTID, -++ WMI_TLV_RTT_ERROR_REPORT_EVENTID, -++ WMI_TLV_STATS_EXT_EVENTID = WMI_TLV_EV(WMI_TLV_GRP_STATS), -++ WMI_TLV_IFACE_LINK_STATS_EVENTID, -++ WMI_TLV_PEER_LINK_STATS_EVENTID, -++ WMI_TLV_RADIO_LINK_STATS_EVENTID, -++ WMI_TLV_NLO_MATCH_EVENTID = WMI_TLV_EV(WMI_TLV_GRP_NLO_OFL), -++ WMI_TLV_NLO_SCAN_COMPLETE_EVENTID, -++ WMI_TLV_APFIND_EVENTID, -++ WMI_TLV_GTK_OFFLOAD_STATUS_EVENTID = WMI_TLV_EV(WMI_TLV_GRP_GTK_OFL), -++ WMI_TLV_GTK_REKEY_FAIL_EVENTID, -++ WMI_TLV_CSA_HANDLING_EVENTID = WMI_TLV_EV(WMI_TLV_GRP_CSA_OFL), -++ WMI_TLV_CHATTER_PC_QUERY_EVENTID = WMI_TLV_EV(WMI_TLV_GRP_CHATTER), -++ WMI_TLV_ECHO_EVENTID = WMI_TLV_EV(WMI_TLV_GRP_MISC), -++ WMI_TLV_PDEV_UTF_EVENTID, -++ WMI_TLV_DEBUG_MESG_EVENTID, -++ WMI_TLV_UPDATE_STATS_EVENTID, -++ WMI_TLV_DEBUG_PRINT_EVENTID, -++ WMI_TLV_DCS_INTERFERENCE_EVENTID, -++ WMI_TLV_PDEV_QVIT_EVENTID, -++ WMI_TLV_WLAN_PROFILE_DATA_EVENTID, -++ WMI_TLV_PDEV_FTM_INTG_EVENTID, -++ WMI_TLV_WLAN_FREQ_AVOID_EVENTID, -++ WMI_TLV_VDEV_GET_KEEPALIVE_EVENTID, -++ WMI_TLV_THERMAL_MGMT_EVENTID, -++ WMI_TLV_DIAG_DATA_CONTAINER_EVENTID, -++ WMI_TLV_HOST_AUTO_SHUTDOWN_EVENTID, -++ WMI_TLV_UPDATE_WHAL_MIB_STATS_EVENTID, -++ WMI_TLV_UPDATE_VDEV_RATE_STATS_EVENTID, -++ WMI_TLV_DIAG_EVENTID, -++ WMI_TLV_GPIO_INPUT_EVENTID = WMI_TLV_EV(WMI_TLV_GRP_GPIO), -++ WMI_TLV_UPLOADH_EVENTID, -++ WMI_TLV_CAPTUREH_EVENTID, -++ WMI_TLV_RFKILL_STATE_CHANGE_EVENTID, -++ WMI_TLV_TDLS_PEER_EVENTID = WMI_TLV_EV(WMI_TLV_GRP_TDLS), -++ WMI_TLV_BATCH_SCAN_ENABLED_EVENTID = -++ WMI_TLV_EV(WMI_TLV_GRP_LOCATION_SCAN), -++ WMI_TLV_BATCH_SCAN_RESULT_EVENTID, -++ WMI_TLV_OEM_CAPABILITY_EVENTID = WMI_TLV_EV(WMI_TLV_GRP_OEM), -++ WMI_TLV_OEM_MEASUREMENT_REPORT_EVENTID, -++ WMI_TLV_OEM_ERROR_REPORT_EVENTID, -++ WMI_TLV_NAN_EVENTID = WMI_TLV_EV(WMI_TLV_GRP_NAN), -++ WMI_TLV_LPI_RESULT_EVENTID = WMI_TLV_EV(WMI_TLV_GRP_LPI), -++ WMI_TLV_LPI_STATUS_EVENTID, -++ WMI_TLV_LPI_HANDOFF_EVENTID, -++ WMI_TLV_EXTSCAN_START_STOP_EVENTID = WMI_TLV_EV(WMI_TLV_GRP_EXTSCAN), -++ WMI_TLV_EXTSCAN_OPERATION_EVENTID, -++ WMI_TLV_EXTSCAN_TABLE_USAGE_EVENTID, -++ WMI_TLV_EXTSCAN_CACHED_RESULTS_EVENTID, -++ WMI_TLV_EXTSCAN_WLAN_CHANGE_RESULTS_EVENTID, -++ WMI_TLV_EXTSCAN_HOTLIST_MATCH_EVENTID, -++ WMI_TLV_EXTSCAN_CAPABILITIES_EVENTID, -++ WMI_TLV_MDNS_STATS_EVENTID = WMI_TLV_EV(WMI_TLV_GRP_MDNS_OFL), -++ WMI_TLV_SAP_OFL_ADD_STA_EVENTID = WMI_TLV_EV(WMI_TLV_GRP_SAP_OFL), -++ WMI_TLV_SAP_OFL_DEL_STA_EVENTID, -++}; -++ -++enum wmi_tlv_pdev_param { -++ WMI_TLV_PDEV_PARAM_TX_CHAIN_MASK = 0x1, -++ WMI_TLV_PDEV_PARAM_RX_CHAIN_MASK, -++ WMI_TLV_PDEV_PARAM_TXPOWER_LIMIT2G, -++ WMI_TLV_PDEV_PARAM_TXPOWER_LIMIT5G, -++ WMI_TLV_PDEV_PARAM_TXPOWER_SCALE, -++ WMI_TLV_PDEV_PARAM_BEACON_GEN_MODE, -++ WMI_TLV_PDEV_PARAM_BEACON_TX_MODE, -++ WMI_TLV_PDEV_PARAM_RESMGR_OFFCHAN_MODE, -++ WMI_TLV_PDEV_PARAM_PROTECTION_MODE, -++ WMI_TLV_PDEV_PARAM_DYNAMIC_BW, -++ WMI_TLV_PDEV_PARAM_NON_AGG_SW_RETRY_TH, -++ WMI_TLV_PDEV_PARAM_AGG_SW_RETRY_TH, -++ WMI_TLV_PDEV_PARAM_STA_KICKOUT_TH, -++ WMI_TLV_PDEV_PARAM_AC_AGGRSIZE_SCALING, -++ WMI_TLV_PDEV_PARAM_LTR_ENABLE, -++ WMI_TLV_PDEV_PARAM_LTR_AC_LATENCY_BE, -++ WMI_TLV_PDEV_PARAM_LTR_AC_LATENCY_BK, -++ WMI_TLV_PDEV_PARAM_LTR_AC_LATENCY_VI, -++ WMI_TLV_PDEV_PARAM_LTR_AC_LATENCY_VO, -++ WMI_TLV_PDEV_PARAM_LTR_AC_LATENCY_TIMEOUT, -++ WMI_TLV_PDEV_PARAM_LTR_SLEEP_OVERRIDE, -++ WMI_TLV_PDEV_PARAM_LTR_RX_OVERRIDE, -++ WMI_TLV_PDEV_PARAM_LTR_TX_ACTIVITY_TIMEOUT, -++ WMI_TLV_PDEV_PARAM_L1SS_ENABLE, -++ WMI_TLV_PDEV_PARAM_DSLEEP_ENABLE, -++ WMI_TLV_PDEV_PARAM_PCIELP_TXBUF_FLUSH, -++ WMI_TLV_PDEV_PARAM_PCIELP_TXBUF_WATERMARK, -++ WMI_TLV_PDEV_PARAM_PCIELP_TXBUF_TMO_EN, -++ WMI_TLV_PDEV_PARAM_PCIELP_TXBUF_TMO_VALUE, -++ WMI_TLV_PDEV_PARAM_PDEV_STATS_UPDATE_PERIOD, -++ WMI_TLV_PDEV_PARAM_VDEV_STATS_UPDATE_PERIOD, -++ WMI_TLV_PDEV_PARAM_PEER_STATS_UPDATE_PERIOD, -++ WMI_TLV_PDEV_PARAM_BCNFLT_STATS_UPDATE_PERIOD, -++ WMI_TLV_PDEV_PARAM_PMF_QOS, -++ WMI_TLV_PDEV_PARAM_ARP_AC_OVERRIDE, -++ WMI_TLV_PDEV_PARAM_DCS, -++ WMI_TLV_PDEV_PARAM_ANI_ENABLE, -++ WMI_TLV_PDEV_PARAM_ANI_POLL_PERIOD, -++ WMI_TLV_PDEV_PARAM_ANI_LISTEN_PERIOD, -++ WMI_TLV_PDEV_PARAM_ANI_OFDM_LEVEL, -++ WMI_TLV_PDEV_PARAM_ANI_CCK_LEVEL, -++ WMI_TLV_PDEV_PARAM_DYNTXCHAIN, -++ WMI_TLV_PDEV_PARAM_PROXY_STA, -++ WMI_TLV_PDEV_PARAM_IDLE_PS_CONFIG, -++ WMI_TLV_PDEV_PARAM_POWER_GATING_SLEEP, -++ WMI_TLV_PDEV_PARAM_RFKILL_ENABLE, -++ WMI_TLV_PDEV_PARAM_BURST_DUR, -++ WMI_TLV_PDEV_PARAM_BURST_ENABLE, -++ WMI_TLV_PDEV_PARAM_HW_RFKILL_CONFIG, -++ WMI_TLV_PDEV_PARAM_LOW_POWER_RF_ENABLE, -++ WMI_TLV_PDEV_PARAM_L1SS_TRACK, -++ WMI_TLV_PDEV_PARAM_HYST_EN, -++ WMI_TLV_PDEV_PARAM_POWER_COLLAPSE_ENABLE, -++ WMI_TLV_PDEV_PARAM_LED_SYS_STATE, -++ WMI_TLV_PDEV_PARAM_LED_ENABLE, -++ WMI_TLV_PDEV_PARAM_AUDIO_OVER_WLAN_LATENCY, -++ WMI_TLV_PDEV_PARAM_AUDIO_OVER_WLAN_ENABLE, -++ WMI_TLV_PDEV_PARAM_WHAL_MIB_STATS_UPDATE_ENABLE, -++ WMI_TLV_PDEV_PARAM_VDEV_RATE_STATS_UPDATE_PERIOD, -++ WMI_TLV_PDEV_PARAM_TXPOWER_REASON_NONE, -++ WMI_TLV_PDEV_PARAM_TXPOWER_REASON_SAR, -++ WMI_TLV_PDEV_PARAM_TXPOWER_REASON_MAX, -++}; -++ -++enum wmi_tlv_vdev_param { -++ WMI_TLV_VDEV_PARAM_RTS_THRESHOLD = 0x1, -++ WMI_TLV_VDEV_PARAM_FRAGMENTATION_THRESHOLD, -++ WMI_TLV_VDEV_PARAM_BEACON_INTERVAL, -++ WMI_TLV_VDEV_PARAM_LISTEN_INTERVAL, -++ WMI_TLV_VDEV_PARAM_MULTICAST_RATE, -++ WMI_TLV_VDEV_PARAM_MGMT_TX_RATE, -++ WMI_TLV_VDEV_PARAM_SLOT_TIME, -++ WMI_TLV_VDEV_PARAM_PREAMBLE, -++ WMI_TLV_VDEV_PARAM_SWBA_TIME, -++ WMI_TLV_VDEV_STATS_UPDATE_PERIOD, -++ WMI_TLV_VDEV_PWRSAVE_AGEOUT_TIME, -++ WMI_TLV_VDEV_HOST_SWBA_INTERVAL, -++ WMI_TLV_VDEV_PARAM_DTIM_PERIOD, -++ WMI_TLV_VDEV_OC_SCHEDULER_AIR_TIME_LIMIT, -++ WMI_TLV_VDEV_PARAM_WDS, -++ WMI_TLV_VDEV_PARAM_ATIM_WINDOW, -++ WMI_TLV_VDEV_PARAM_BMISS_COUNT_MAX, -++ WMI_TLV_VDEV_PARAM_BMISS_FIRST_BCNT, -++ WMI_TLV_VDEV_PARAM_BMISS_FINAL_BCNT, -++ WMI_TLV_VDEV_PARAM_FEATURE_WMM, -++ WMI_TLV_VDEV_PARAM_CHWIDTH, -++ WMI_TLV_VDEV_PARAM_CHEXTOFFSET, -++ WMI_TLV_VDEV_PARAM_DISABLE_HTPROTECTION, -++ WMI_TLV_VDEV_PARAM_STA_QUICKKICKOUT, -++ WMI_TLV_VDEV_PARAM_MGMT_RATE, -++ WMI_TLV_VDEV_PARAM_PROTECTION_MODE, -++ WMI_TLV_VDEV_PARAM_FIXED_RATE, -++ WMI_TLV_VDEV_PARAM_SGI, -++ WMI_TLV_VDEV_PARAM_LDPC, -++ WMI_TLV_VDEV_PARAM_TX_STBC, -++ WMI_TLV_VDEV_PARAM_RX_STBC, -++ WMI_TLV_VDEV_PARAM_INTRA_BSS_FWD, -++ WMI_TLV_VDEV_PARAM_DEF_KEYID, -++ WMI_TLV_VDEV_PARAM_NSS, -++ WMI_TLV_VDEV_PARAM_BCAST_DATA_RATE, -++ WMI_TLV_VDEV_PARAM_MCAST_DATA_RATE, -++ WMI_TLV_VDEV_PARAM_MCAST_INDICATE, -++ WMI_TLV_VDEV_PARAM_DHCP_INDICATE, -++ WMI_TLV_VDEV_PARAM_UNKNOWN_DEST_INDICATE, -++ WMI_TLV_VDEV_PARAM_AP_KEEPALIVE_MIN_IDLE_INACTIVE_TIME_SECS, -++ WMI_TLV_VDEV_PARAM_AP_KEEPALIVE_MAX_IDLE_INACTIVE_TIME_SECS, -++ WMI_TLV_VDEV_PARAM_AP_KEEPALIVE_MAX_UNRESPONSIVE_TIME_SECS, -++ WMI_TLV_VDEV_PARAM_AP_ENABLE_NAWDS, -++ WMI_TLV_VDEV_PARAM_ENABLE_RTSCTS, -++ WMI_TLV_VDEV_PARAM_TXBF, -++ WMI_TLV_VDEV_PARAM_PACKET_POWERSAVE, -++ WMI_TLV_VDEV_PARAM_DROP_UNENCRY, -++ WMI_TLV_VDEV_PARAM_TX_ENCAP_TYPE, -++ WMI_TLV_VDEV_PARAM_AP_DETECT_OUT_OF_SYNC_SLEEPING_STA_TIME_SECS, -++ WMI_TLV_VDEV_PARAM_EARLY_RX_ADJUST_ENABLE, -++ WMI_TLV_VDEV_PARAM_EARLY_RX_TGT_BMISS_NUM, -++ WMI_TLV_VDEV_PARAM_EARLY_RX_BMISS_SAMPLE_CYCLE, -++ WMI_TLV_VDEV_PARAM_EARLY_RX_SLOP_STEP, -++ WMI_TLV_VDEV_PARAM_EARLY_RX_INIT_SLOP, -++ WMI_TLV_VDEV_PARAM_EARLY_RX_ADJUST_PAUSE, -++ WMI_TLV_VDEV_PARAM_TX_PWRLIMIT, -++ WMI_TLV_VDEV_PARAM_SNR_NUM_FOR_CAL, -++ WMI_TLV_VDEV_PARAM_ROAM_FW_OFFLOAD, -++ WMI_TLV_VDEV_PARAM_ENABLE_RMC, -++ WMI_TLV_VDEV_PARAM_IBSS_MAX_BCN_LOST_MS, -++ WMI_TLV_VDEV_PARAM_MAX_RATE, -++ WMI_TLV_VDEV_PARAM_EARLY_RX_DRIFT_SAMPLE, -++ WMI_TLV_VDEV_PARAM_SET_IBSS_TX_FAIL_CNT_THR, -++ WMI_TLV_VDEV_PARAM_EBT_RESYNC_TIMEOUT, -++ WMI_TLV_VDEV_PARAM_AGGR_TRIG_EVENT_ENABLE, -++ WMI_TLV_VDEV_PARAM_IS_IBSS_POWER_SAVE_ALLOWED, -++ WMI_TLV_VDEV_PARAM_IS_POWER_COLLAPSE_ALLOWED, -++ WMI_TLV_VDEV_PARAM_IS_AWAKE_ON_TXRX_ENABLED, -++ WMI_TLV_VDEV_PARAM_INACTIVITY_CNT, -++ WMI_TLV_VDEV_PARAM_TXSP_END_INACTIVITY_TIME_MS, -++ WMI_TLV_VDEV_PARAM_DTIM_POLICY, -++ WMI_TLV_VDEV_PARAM_IBSS_PS_WARMUP_TIME_SECS, -++ WMI_TLV_VDEV_PARAM_IBSS_PS_1RX_CHAIN_IN_ATIM_WINDOW_ENABLE, -++}; -++ -++enum wmi_tlv_tag { -++ WMI_TLV_TAG_LAST_RESERVED = 15, -++ -++ WMI_TLV_TAG_FIRST_ARRAY_ENUM, -++ WMI_TLV_TAG_ARRAY_UINT32 = WMI_TLV_TAG_FIRST_ARRAY_ENUM, -++ WMI_TLV_TAG_ARRAY_BYTE, -++ WMI_TLV_TAG_ARRAY_STRUCT, -++ WMI_TLV_TAG_ARRAY_FIXED_STRUCT, -++ WMI_TLV_TAG_LAST_ARRAY_ENUM = 31, -++ -++ WMI_TLV_TAG_STRUCT_SERVICE_READY_EVENT, -++ WMI_TLV_TAG_STRUCT_HAL_REG_CAPABILITIES, -++ WMI_TLV_TAG_STRUCT_WLAN_HOST_MEM_REQ, -++ WMI_TLV_TAG_STRUCT_READY_EVENT, -++ WMI_TLV_TAG_STRUCT_SCAN_EVENT, -++ WMI_TLV_TAG_STRUCT_PDEV_TPC_CONFIG_EVENT, -++ WMI_TLV_TAG_STRUCT_CHAN_INFO_EVENT, -++ WMI_TLV_TAG_STRUCT_COMB_PHYERR_RX_HDR, -++ WMI_TLV_TAG_STRUCT_VDEV_START_RESPONSE_EVENT, -++ WMI_TLV_TAG_STRUCT_VDEV_STOPPED_EVENT, -++ WMI_TLV_TAG_STRUCT_VDEV_INSTALL_KEY_COMPLETE_EVENT, -++ WMI_TLV_TAG_STRUCT_PEER_STA_KICKOUT_EVENT, -++ WMI_TLV_TAG_STRUCT_MGMT_RX_HDR, -++ WMI_TLV_TAG_STRUCT_TBTT_OFFSET_EVENT, -++ WMI_TLV_TAG_STRUCT_TX_DELBA_COMPLETE_EVENT, -++ WMI_TLV_TAG_STRUCT_TX_ADDBA_COMPLETE_EVENT, -++ WMI_TLV_TAG_STRUCT_ROAM_EVENT, -++ WMI_TLV_TAG_STRUCT_WOW_EVENT_INFO, -++ WMI_TLV_TAG_STRUCT_WOW_EVENT_INFO_SECTION_BITMAP, -++ WMI_TLV_TAG_STRUCT_RTT_EVENT_HEADER, -++ WMI_TLV_TAG_STRUCT_RTT_ERROR_REPORT_EVENT, -++ WMI_TLV_TAG_STRUCT_RTT_MEAS_EVENT, -++ WMI_TLV_TAG_STRUCT_ECHO_EVENT, -++ WMI_TLV_TAG_STRUCT_FTM_INTG_EVENT, -++ WMI_TLV_TAG_STRUCT_VDEV_GET_KEEPALIVE_EVENT, -++ WMI_TLV_TAG_STRUCT_GPIO_INPUT_EVENT, -++ WMI_TLV_TAG_STRUCT_CSA_EVENT, -++ WMI_TLV_TAG_STRUCT_GTK_OFFLOAD_STATUS_EVENT, -++ WMI_TLV_TAG_STRUCT_IGTK_INFO, -++ WMI_TLV_TAG_STRUCT_DCS_INTERFERENCE_EVENT, -++ WMI_TLV_TAG_STRUCT_ATH_DCS_CW_INT, -++ WMI_TLV_TAG_STRUCT_ATH_DCS_WLAN_INT_STAT, -++ WMI_TLV_TAG_STRUCT_WLAN_PROFILE_CTX_T, -++ WMI_TLV_TAG_STRUCT_WLAN_PROFILE_T, -++ WMI_TLV_TAG_STRUCT_PDEV_QVIT_EVENT, -++ WMI_TLV_TAG_STRUCT_HOST_SWBA_EVENT, -++ WMI_TLV_TAG_STRUCT_TIM_INFO, -++ WMI_TLV_TAG_STRUCT_P2P_NOA_INFO, -++ WMI_TLV_TAG_STRUCT_STATS_EVENT, -++ WMI_TLV_TAG_STRUCT_AVOID_FREQ_RANGES_EVENT, -++ WMI_TLV_TAG_STRUCT_AVOID_FREQ_RANGE_DESC, -++ WMI_TLV_TAG_STRUCT_GTK_REKEY_FAIL_EVENT, -++ WMI_TLV_TAG_STRUCT_INIT_CMD, -++ WMI_TLV_TAG_STRUCT_RESOURCE_CONFIG, -++ WMI_TLV_TAG_STRUCT_WLAN_HOST_MEMORY_CHUNK, -++ WMI_TLV_TAG_STRUCT_START_SCAN_CMD, -++ WMI_TLV_TAG_STRUCT_STOP_SCAN_CMD, -++ WMI_TLV_TAG_STRUCT_SCAN_CHAN_LIST_CMD, -++ WMI_TLV_TAG_STRUCT_CHANNEL, -++ WMI_TLV_TAG_STRUCT_PDEV_SET_REGDOMAIN_CMD, -++ WMI_TLV_TAG_STRUCT_PDEV_SET_PARAM_CMD, -++ WMI_TLV_TAG_STRUCT_PDEV_SET_WMM_PARAMS_CMD, -++ WMI_TLV_TAG_STRUCT_WMM_PARAMS, -++ WMI_TLV_TAG_STRUCT_PDEV_SET_QUIET_CMD, -++ WMI_TLV_TAG_STRUCT_VDEV_CREATE_CMD, -++ WMI_TLV_TAG_STRUCT_VDEV_DELETE_CMD, -++ WMI_TLV_TAG_STRUCT_VDEV_START_REQUEST_CMD, -++ WMI_TLV_TAG_STRUCT_P2P_NOA_DESCRIPTOR, -++ WMI_TLV_TAG_STRUCT_P2P_GO_SET_BEACON_IE, -++ WMI_TLV_TAG_STRUCT_GTK_OFFLOAD_CMD, -++ WMI_TLV_TAG_STRUCT_VDEV_UP_CMD, -++ WMI_TLV_TAG_STRUCT_VDEV_STOP_CMD, -++ WMI_TLV_TAG_STRUCT_VDEV_DOWN_CMD, -++ WMI_TLV_TAG_STRUCT_VDEV_SET_PARAM_CMD, -++ WMI_TLV_TAG_STRUCT_VDEV_INSTALL_KEY_CMD, -++ WMI_TLV_TAG_STRUCT_PEER_CREATE_CMD, -++ WMI_TLV_TAG_STRUCT_PEER_DELETE_CMD, -++ WMI_TLV_TAG_STRUCT_PEER_FLUSH_TIDS_CMD, -++ WMI_TLV_TAG_STRUCT_PEER_SET_PARAM_CMD, -++ WMI_TLV_TAG_STRUCT_PEER_ASSOC_COMPLETE_CMD, -++ WMI_TLV_TAG_STRUCT_VHT_RATE_SET, -++ WMI_TLV_TAG_STRUCT_BCN_TMPL_CMD, -++ WMI_TLV_TAG_STRUCT_PRB_TMPL_CMD, -++ WMI_TLV_TAG_STRUCT_BCN_PRB_INFO, -++ WMI_TLV_TAG_STRUCT_PEER_TID_ADDBA_CMD, -++ WMI_TLV_TAG_STRUCT_PEER_TID_DELBA_CMD, -++ WMI_TLV_TAG_STRUCT_STA_POWERSAVE_MODE_CMD, -++ WMI_TLV_TAG_STRUCT_STA_POWERSAVE_PARAM_CMD, -++ WMI_TLV_TAG_STRUCT_STA_DTIM_PS_METHOD_CMD, -++ WMI_TLV_TAG_STRUCT_ROAM_SCAN_MODE, -++ WMI_TLV_TAG_STRUCT_ROAM_SCAN_RSSI_THRESHOLD, -++ WMI_TLV_TAG_STRUCT_ROAM_SCAN_PERIOD, -++ WMI_TLV_TAG_STRUCT_ROAM_SCAN_RSSI_CHANGE_THRESHOLD, -++ WMI_TLV_TAG_STRUCT_PDEV_SUSPEND_CMD, -++ WMI_TLV_TAG_STRUCT_PDEV_RESUME_CMD, -++ WMI_TLV_TAG_STRUCT_ADD_BCN_FILTER_CMD, -++ WMI_TLV_TAG_STRUCT_RMV_BCN_FILTER_CMD, -++ WMI_TLV_TAG_STRUCT_WOW_ENABLE_CMD, -++ WMI_TLV_TAG_STRUCT_WOW_HOSTWAKEUP_FROM_SLEEP_CMD, -++ WMI_TLV_TAG_STRUCT_STA_UAPSD_AUTO_TRIG_CMD, -++ WMI_TLV_TAG_STRUCT_STA_UAPSD_AUTO_TRIG_PARAM, -++ WMI_TLV_TAG_STRUCT_SET_ARP_NS_OFFLOAD_CMD, -++ WMI_TLV_TAG_STRUCT_ARP_OFFLOAD_TUPLE, -++ WMI_TLV_TAG_STRUCT_NS_OFFLOAD_TUPLE, -++ WMI_TLV_TAG_STRUCT_FTM_INTG_CMD, -++ WMI_TLV_TAG_STRUCT_STA_KEEPALIVE_CMD, -++ WMI_TLV_TAG_STRUCT_STA_KEEPALVE_ARP_RESPONSE, -++ WMI_TLV_TAG_STRUCT_P2P_SET_VENDOR_IE_DATA_CMD, -++ WMI_TLV_TAG_STRUCT_AP_PS_PEER_CMD, -++ WMI_TLV_TAG_STRUCT_PEER_RATE_RETRY_SCHED_CMD, -++ WMI_TLV_TAG_STRUCT_WLAN_PROFILE_TRIGGER_CMD, -++ WMI_TLV_TAG_STRUCT_WLAN_PROFILE_SET_HIST_INTVL_CMD, -++ WMI_TLV_TAG_STRUCT_WLAN_PROFILE_GET_PROF_DATA_CMD, -++ WMI_TLV_TAG_STRUCT_WLAN_PROFILE_ENABLE_PROFILE_ID_CMD, -++ WMI_TLV_TAG_STRUCT_WOW_DEL_PATTERN_CMD, -++ WMI_TLV_TAG_STRUCT_WOW_ADD_DEL_EVT_CMD, -++ WMI_TLV_TAG_STRUCT_RTT_MEASREQ_HEAD, -++ WMI_TLV_TAG_STRUCT_RTT_MEASREQ_BODY, -++ WMI_TLV_TAG_STRUCT_RTT_TSF_CMD, -++ WMI_TLV_TAG_STRUCT_VDEV_SPECTRAL_CONFIGURE_CMD, -++ WMI_TLV_TAG_STRUCT_VDEV_SPECTRAL_ENABLE_CMD, -++ WMI_TLV_TAG_STRUCT_REQUEST_STATS_CMD, -++ WMI_TLV_TAG_STRUCT_NLO_CONFIG_CMD, -++ WMI_TLV_TAG_STRUCT_NLO_CONFIGURED_PARAMETERS, -++ WMI_TLV_TAG_STRUCT_CSA_OFFLOAD_ENABLE_CMD, -++ WMI_TLV_TAG_STRUCT_CSA_OFFLOAD_CHANSWITCH_CMD, -++ WMI_TLV_TAG_STRUCT_CHATTER_SET_MODE_CMD, -++ WMI_TLV_TAG_STRUCT_ECHO_CMD, -++ WMI_TLV_TAG_STRUCT_VDEV_SET_KEEPALIVE_CMD, -++ WMI_TLV_TAG_STRUCT_VDEV_GET_KEEPALIVE_CMD, -++ WMI_TLV_TAG_STRUCT_FORCE_FW_HANG_CMD, -++ WMI_TLV_TAG_STRUCT_GPIO_CONFIG_CMD, -++ WMI_TLV_TAG_STRUCT_GPIO_OUTPUT_CMD, -++ WMI_TLV_TAG_STRUCT_PEER_ADD_WDS_ENTRY_CMD, -++ WMI_TLV_TAG_STRUCT_PEER_REMOVE_WDS_ENTRY_CMD, -++ WMI_TLV_TAG_STRUCT_BCN_TX_HDR, -++ WMI_TLV_TAG_STRUCT_BCN_SEND_FROM_HOST_CMD, -++ WMI_TLV_TAG_STRUCT_MGMT_TX_HDR, -++ WMI_TLV_TAG_STRUCT_ADDBA_CLEAR_RESP_CMD, -++ WMI_TLV_TAG_STRUCT_ADDBA_SEND_CMD, -++ WMI_TLV_TAG_STRUCT_DELBA_SEND_CMD, -++ WMI_TLV_TAG_STRUCT_ADDBA_SETRESPONSE_CMD, -++ WMI_TLV_TAG_STRUCT_SEND_SINGLEAMSDU_CMD, -++ WMI_TLV_TAG_STRUCT_PDEV_PKTLOG_ENABLE_CMD, -++ WMI_TLV_TAG_STRUCT_PDEV_PKTLOG_DISABLE_CMD, -++ WMI_TLV_TAG_STRUCT_PDEV_SET_HT_IE_CMD, -++ WMI_TLV_TAG_STRUCT_PDEV_SET_VHT_IE_CMD, -++ WMI_TLV_TAG_STRUCT_PDEV_SET_DSCP_TID_MAP_CMD, -++ WMI_TLV_TAG_STRUCT_PDEV_GREEN_AP_PS_ENABLE_CMD, -++ WMI_TLV_TAG_STRUCT_PDEV_GET_TPC_CONFIG_CMD, -++ WMI_TLV_TAG_STRUCT_PDEV_SET_BASE_MACADDR_CMD, -++ WMI_TLV_TAG_STRUCT_PEER_MCAST_GROUP_CMD, -++ WMI_TLV_TAG_STRUCT_ROAM_AP_PROFILE, -++ WMI_TLV_TAG_STRUCT_AP_PROFILE, -++ WMI_TLV_TAG_STRUCT_SCAN_SCH_PRIORITY_TABLE_CMD, -++ WMI_TLV_TAG_STRUCT_PDEV_DFS_ENABLE_CMD, -++ WMI_TLV_TAG_STRUCT_PDEV_DFS_DISABLE_CMD, -++ WMI_TLV_TAG_STRUCT_WOW_ADD_PATTERN_CMD, -++ WMI_TLV_TAG_STRUCT_WOW_BITMAP_PATTERN_T, -++ WMI_TLV_TAG_STRUCT_WOW_IPV4_SYNC_PATTERN_T, -++ WMI_TLV_TAG_STRUCT_WOW_IPV6_SYNC_PATTERN_T, -++ WMI_TLV_TAG_STRUCT_WOW_MAGIC_PATTERN_CMD, -++ WMI_TLV_TAG_STRUCT_SCAN_UPDATE_REQUEST_CMD, -++ WMI_TLV_TAG_STRUCT_CHATTER_PKT_COALESCING_FILTER, -++ WMI_TLV_TAG_STRUCT_CHATTER_COALESCING_ADD_FILTER_CMD, -++ WMI_TLV_TAG_STRUCT_CHATTER_COALESCING_DELETE_FILTER_CMD, -++ WMI_TLV_TAG_STRUCT_CHATTER_COALESCING_QUERY_CMD, -++ WMI_TLV_TAG_STRUCT_TXBF_CMD, -++ WMI_TLV_TAG_STRUCT_DEBUG_LOG_CONFIG_CMD, -++ WMI_TLV_TAG_STRUCT_NLO_EVENT, -++ WMI_TLV_TAG_STRUCT_CHATTER_QUERY_REPLY_EVENT, -++ WMI_TLV_TAG_STRUCT_UPLOAD_H_HDR, -++ WMI_TLV_TAG_STRUCT_CAPTURE_H_EVENT_HDR, -++ WMI_TLV_TAG_STRUCT_VDEV_WNM_SLEEPMODE_CMD, -++ WMI_TLV_TAG_STRUCT_VDEV_IPSEC_NATKEEPALIVE_FILTER_CMD, -++ WMI_TLV_TAG_STRUCT_VDEV_WMM_ADDTS_CMD, -++ WMI_TLV_TAG_STRUCT_VDEV_WMM_DELTS_CMD, -++ WMI_TLV_TAG_STRUCT_VDEV_SET_WMM_PARAMS_CMD, -++ WMI_TLV_TAG_STRUCT_TDLS_SET_STATE_CMD, -++ WMI_TLV_TAG_STRUCT_TDLS_PEER_UPDATE_CMD, -++ WMI_TLV_TAG_STRUCT_TDLS_PEER_EVENT, -++ WMI_TLV_TAG_STRUCT_TDLS_PEER_CAPABILITIES, -++ WMI_TLV_TAG_STRUCT_VDEV_MCC_SET_TBTT_MODE_CMD, -++ WMI_TLV_TAG_STRUCT_ROAM_CHAN_LIST, -++ WMI_TLV_TAG_STRUCT_VDEV_MCC_BCN_INTVL_CHANGE_EVENT, -++ WMI_TLV_TAG_STRUCT_RESMGR_ADAPTIVE_OCS_CMD, -++ WMI_TLV_TAG_STRUCT_RESMGR_SET_CHAN_TIME_QUOTA_CMD, -++ WMI_TLV_TAG_STRUCT_RESMGR_SET_CHAN_LATENCY_CMD, -++ WMI_TLV_TAG_STRUCT_BA_REQ_SSN_CMD, -++ WMI_TLV_TAG_STRUCT_BA_RSP_SSN_EVENT, -++ WMI_TLV_TAG_STRUCT_STA_SMPS_FORCE_MODE_CMD, -++ WMI_TLV_TAG_STRUCT_SET_MCASTBCAST_FILTER_CMD, -++ WMI_TLV_TAG_STRUCT_P2P_SET_OPPPS_CMD, -++ WMI_TLV_TAG_STRUCT_P2P_SET_NOA_CMD, -++ WMI_TLV_TAG_STRUCT_BA_REQ_SSN_CMD_SUB_STRUCT_PARAM, -++ WMI_TLV_TAG_STRUCT_BA_REQ_SSN_EVENT_SUB_STRUCT_PARAM, -++ WMI_TLV_TAG_STRUCT_STA_SMPS_PARAM_CMD, -++ WMI_TLV_TAG_STRUCT_VDEV_SET_GTX_PARAMS_CMD, -++ WMI_TLV_TAG_STRUCT_MCC_SCHED_TRAFFIC_STATS_CMD, -++ WMI_TLV_TAG_STRUCT_MCC_SCHED_STA_TRAFFIC_STATS, -++ WMI_TLV_TAG_STRUCT_OFFLOAD_BCN_TX_STATUS_EVENT, -++ WMI_TLV_TAG_STRUCT_P2P_NOA_EVENT, -++ WMI_TLV_TAG_STRUCT_HB_SET_ENABLE_CMD, -++ WMI_TLV_TAG_STRUCT_HB_SET_TCP_PARAMS_CMD, -++ WMI_TLV_TAG_STRUCT_HB_SET_TCP_PKT_FILTER_CMD, -++ WMI_TLV_TAG_STRUCT_HB_SET_UDP_PARAMS_CMD, -++ WMI_TLV_TAG_STRUCT_HB_SET_UDP_PKT_FILTER_CMD, -++ WMI_TLV_TAG_STRUCT_HB_IND_EVENT, -++ WMI_TLV_TAG_STRUCT_TX_PAUSE_EVENT, -++ WMI_TLV_TAG_STRUCT_RFKILL_EVENT, -++ WMI_TLV_TAG_STRUCT_DFS_RADAR_EVENT, -++ WMI_TLV_TAG_STRUCT_DFS_PHYERR_FILTER_ENA_CMD, -++ WMI_TLV_TAG_STRUCT_DFS_PHYERR_FILTER_DIS_CMD, -++ WMI_TLV_TAG_STRUCT_BATCH_SCAN_RESULT_SCAN_LIST, -++ WMI_TLV_TAG_STRUCT_BATCH_SCAN_RESULT_NETWORK_INFO, -++ WMI_TLV_TAG_STRUCT_BATCH_SCAN_ENABLE_CMD, -++ WMI_TLV_TAG_STRUCT_BATCH_SCAN_DISABLE_CMD, -++ WMI_TLV_TAG_STRUCT_BATCH_SCAN_TRIGGER_RESULT_CMD, -++ WMI_TLV_TAG_STRUCT_BATCH_SCAN_ENABLED_EVENT, -++ WMI_TLV_TAG_STRUCT_BATCH_SCAN_RESULT_EVENT, -++ WMI_TLV_TAG_STRUCT_VDEV_PLMREQ_START_CMD, -++ WMI_TLV_TAG_STRUCT_VDEV_PLMREQ_STOP_CMD, -++ WMI_TLV_TAG_STRUCT_THERMAL_MGMT_CMD, -++ WMI_TLV_TAG_STRUCT_THERMAL_MGMT_EVENT, -++ WMI_TLV_TAG_STRUCT_PEER_INFO_REQ_CMD, -++ WMI_TLV_TAG_STRUCT_PEER_INFO_EVENT, -++ WMI_TLV_TAG_STRUCT_PEER_INFO, -++ WMI_TLV_TAG_STRUCT_PEER_TX_FAIL_CNT_THR_EVENT, -++ WMI_TLV_TAG_STRUCT_RMC_SET_MODE_CMD, -++ WMI_TLV_TAG_STRUCT_RMC_SET_ACTION_PERIOD_CMD, -++ WMI_TLV_TAG_STRUCT_RMC_CONFIG_CMD, -++ WMI_TLV_TAG_STRUCT_MHF_OFFLOAD_SET_MODE_CMD, -++ WMI_TLV_TAG_STRUCT_MHF_OFFLOAD_PLUMB_ROUTING_TABLE_CMD, -++ WMI_TLV_TAG_STRUCT_ADD_PROACTIVE_ARP_RSP_PATTERN_CMD, -++ WMI_TLV_TAG_STRUCT_DEL_PROACTIVE_ARP_RSP_PATTERN_CMD, -++ WMI_TLV_TAG_STRUCT_NAN_CMD_PARAM, -++ WMI_TLV_TAG_STRUCT_NAN_EVENT_HDR, -++ WMI_TLV_TAG_STRUCT_PDEV_L1SS_TRACK_EVENT, -++ WMI_TLV_TAG_STRUCT_DIAG_DATA_CONTAINER_EVENT, -++ WMI_TLV_TAG_STRUCT_MODEM_POWER_STATE_CMD_PARAM, -++ WMI_TLV_TAG_STRUCT_PEER_GET_ESTIMATED_LINKSPEED_CMD, -++ WMI_TLV_TAG_STRUCT_PEER_ESTIMATED_LINKSPEED_EVENT, -++ WMI_TLV_TAG_STRUCT_AGGR_STATE_TRIG_EVENT, -++ WMI_TLV_TAG_STRUCT_MHF_OFFLOAD_ROUTING_TABLE_ENTRY, -++ WMI_TLV_TAG_STRUCT_ROAM_SCAN_CMD, -++ WMI_TLV_TAG_STRUCT_REQ_STATS_EXT_CMD, -++ WMI_TLV_TAG_STRUCT_STATS_EXT_EVENT, -++ WMI_TLV_TAG_STRUCT_OBSS_SCAN_ENABLE_CMD, -++ WMI_TLV_TAG_STRUCT_OBSS_SCAN_DISABLE_CMD, -++ WMI_TLV_TAG_STRUCT_OFFLOAD_PRB_RSP_TX_STATUS_EVENT, -++ WMI_TLV_TAG_STRUCT_PDEV_SET_LED_CONFIG_CMD, -++ WMI_TLV_TAG_STRUCT_HOST_AUTO_SHUTDOWN_CFG_CMD, -++ WMI_TLV_TAG_STRUCT_HOST_AUTO_SHUTDOWN_EVENT, -++ WMI_TLV_TAG_STRUCT_UPDATE_WHAL_MIB_STATS_EVENT, -++ WMI_TLV_TAG_STRUCT_CHAN_AVOID_UPDATE_CMD_PARAM, -++ WMI_TLV_TAG_STRUCT_WOW_ACER_IOAC_PKT_PATTERN_T, -++ WMI_TLV_TAG_STRUCT_WOW_ACER_IOAC_TMR_PATTERN_T, -++ WMI_TLV_TAG_STRUCT_WOW_IOAC_ADD_KEEPALIVE_CMD, -++ WMI_TLV_TAG_STRUCT_WOW_IOAC_DEL_KEEPALIVE_CMD, -++ WMI_TLV_TAG_STRUCT_WOW_IOAC_KEEPALIVE_T, -++ WMI_TLV_TAG_STRUCT_WOW_ACER_IOAC_ADD_PATTERN_CMD, -++ WMI_TLV_TAG_STRUCT_WOW_ACER_IOAC_DEL_PATTERN_CMD, -++ WMI_TLV_TAG_STRUCT_START_LINK_STATS_CMD, -++ WMI_TLV_TAG_STRUCT_CLEAR_LINK_STATS_CMD, -++ WMI_TLV_TAG_STRUCT_REQUEST_LINK_STATS_CMD, -++ WMI_TLV_TAG_STRUCT_IFACE_LINK_STATS_EVENT, -++ WMI_TLV_TAG_STRUCT_RADIO_LINK_STATS_EVENT, -++ WMI_TLV_TAG_STRUCT_PEER_STATS_EVENT, -++ WMI_TLV_TAG_STRUCT_CHANNEL_STATS, -++ WMI_TLV_TAG_STRUCT_RADIO_LINK_STATS, -++ WMI_TLV_TAG_STRUCT_RATE_STATS, -++ WMI_TLV_TAG_STRUCT_PEER_LINK_STATS, -++ WMI_TLV_TAG_STRUCT_WMM_AC_STATS, -++ WMI_TLV_TAG_STRUCT_IFACE_LINK_STATS, -++ WMI_TLV_TAG_STRUCT_LPI_MGMT_SNOOPING_CONFIG_CMD, -++ WMI_TLV_TAG_STRUCT_LPI_START_SCAN_CMD, -++ WMI_TLV_TAG_STRUCT_LPI_STOP_SCAN_CMD, -++ WMI_TLV_TAG_STRUCT_LPI_RESULT_EVENT, -++ WMI_TLV_TAG_STRUCT_PEER_STATE_EVENT, -++ WMI_TLV_TAG_STRUCT_EXTSCAN_BUCKET_CMD, -++ WMI_TLV_TAG_STRUCT_EXTSCAN_BUCKET_CHANNEL_EVENT, -++ WMI_TLV_TAG_STRUCT_EXTSCAN_START_CMD, -++ WMI_TLV_TAG_STRUCT_EXTSCAN_STOP_CMD, -++ WMI_TLV_TAG_STRUCT_EXTSCAN_CONFIGURE_WLAN_CHANGE_MONITOR_CMD, -++ WMI_TLV_TAG_STRUCT_EXTSCAN_WLAN_CHANGE_BSSID_PARAM_CMD, -++ WMI_TLV_TAG_STRUCT_EXTSCAN_CONFIGURE_HOTLIST_MONITOR_CMD, -++ WMI_TLV_TAG_STRUCT_EXTSCAN_GET_CACHED_RESULTS_CMD, -++ WMI_TLV_TAG_STRUCT_EXTSCAN_GET_WLAN_CHANGE_RESULTS_CMD, -++ WMI_TLV_TAG_STRUCT_EXTSCAN_SET_CAPABILITIES_CMD, -++ WMI_TLV_TAG_STRUCT_EXTSCAN_GET_CAPABILITIES_CMD, -++ WMI_TLV_TAG_STRUCT_EXTSCAN_OPERATION_EVENT, -++ WMI_TLV_TAG_STRUCT_EXTSCAN_START_STOP_EVENT, -++ WMI_TLV_TAG_STRUCT_EXTSCAN_TABLE_USAGE_EVENT, -++ WMI_TLV_TAG_STRUCT_EXTSCAN_WLAN_DESCRIPTOR_EVENT, -++ WMI_TLV_TAG_STRUCT_EXTSCAN_RSSI_INFO_EVENT, -++ WMI_TLV_TAG_STRUCT_EXTSCAN_CACHED_RESULTS_EVENT, -++ WMI_TLV_TAG_STRUCT_EXTSCAN_WLAN_CHANGE_RESULTS_EVENT, -++ WMI_TLV_TAG_STRUCT_EXTSCAN_WLAN_CHANGE_RESULT_BSSID_EVENT, -++ WMI_TLV_TAG_STRUCT_EXTSCAN_HOTLIST_MATCH_EVENT, -++ WMI_TLV_TAG_STRUCT_EXTSCAN_CAPABILITIES_EVENT, -++ WMI_TLV_TAG_STRUCT_EXTSCAN_CACHE_CAPABILITIES_EVENT, -++ WMI_TLV_TAG_STRUCT_EXTSCAN_WLAN_CHANGE_MONITOR_CAPABILITIES_EVENT, -++ WMI_TLV_TAG_STRUCT_EXTSCAN_HOTLIST_MONITOR_CAPABILITIES_EVENT, -++ WMI_TLV_TAG_STRUCT_D0_WOW_ENABLE_DISABLE_CMD, -++ WMI_TLV_TAG_STRUCT_D0_WOW_DISABLE_ACK_EVENT, -++ WMI_TLV_TAG_STRUCT_UNIT_TEST_CMD, -++ WMI_TLV_TAG_STRUCT_ROAM_OFFLOAD_TLV_PARAM, -++ WMI_TLV_TAG_STRUCT_ROAM_11I_OFFLOAD_TLV_PARAM, -++ WMI_TLV_TAG_STRUCT_ROAM_11R_OFFLOAD_TLV_PARAM, -++ WMI_TLV_TAG_STRUCT_ROAM_ESE_OFFLOAD_TLV_PARAM, -++ WMI_TLV_TAG_STRUCT_ROAM_SYNCH_EVENT, -++ WMI_TLV_TAG_STRUCT_ROAM_SYNCH_COMPLETE, -++ WMI_TLV_TAG_STRUCT_EXTWOW_ENABLE_CMD, -++ WMI_TLV_TAG_STRUCT_EXTWOW_SET_APP_TYPE1_PARAMS_CMD, -++ WMI_TLV_TAG_STRUCT_EXTWOW_SET_APP_TYPE2_PARAMS_CMD, -++ WMI_TLV_TAG_STRUCT_LPI_STATUS_EVENT, -++ WMI_TLV_TAG_STRUCT_LPI_HANDOFF_EVENT, -++ WMI_TLV_TAG_STRUCT_VDEV_RATE_STATS_EVENT, -++ WMI_TLV_TAG_STRUCT_VDEV_RATE_HT_INFO, -++ WMI_TLV_TAG_STRUCT_RIC_REQUEST, -++ WMI_TLV_TAG_STRUCT_PDEV_GET_TEMPERATURE_CMD, -++ WMI_TLV_TAG_STRUCT_PDEV_TEMPERATURE_EVENT, -++ WMI_TLV_TAG_STRUCT_SET_DHCP_SERVER_OFFLOAD_CMD, -++ WMI_TLV_TAG_STRUCT_TPC_CHAINMASK_CONFIG_CMD, -++ WMI_TLV_TAG_STRUCT_RIC_TSPEC, -++ WMI_TLV_TAG_STRUCT_TPC_CHAINMASK_CONFIG, -++ WMI_TLV_TAG_STRUCT_IPA_OFFLOAD_CMD, -++ WMI_TLV_TAG_STRUCT_SCAN_PROB_REQ_OUI_CMD, -++ WMI_TLV_TAG_STRUCT_KEY_MATERIAL, -++ WMI_TLV_TAG_STRUCT_TDLS_SET_OFFCHAN_MODE_CMD, -++ WMI_TLV_TAG_STRUCT_SET_LED_FLASHING_CMD, -++ WMI_TLV_TAG_STRUCT_MDNS_OFFLOAD_CMD, -++ WMI_TLV_TAG_STRUCT_MDNS_SET_FQDN_CMD, -++ WMI_TLV_TAG_STRUCT_MDNS_SET_RESP_CMD, -++ WMI_TLV_TAG_STRUCT_MDNS_GET_STATS_CMD, -++ WMI_TLV_TAG_STRUCT_MDNS_STATS_EVENT, -++ WMI_TLV_TAG_STRUCT_ROAM_INVOKE_CMD, -++ WMI_TLV_TAG_STRUCT_PDEV_RESUME_EVENT, -++ WMI_TLV_TAG_STRUCT_PDEV_SET_ANTENNA_DIVERSITY_CMD, -++ WMI_TLV_TAG_STRUCT_SAP_OFL_ENABLE_CMD, -++ WMI_TLV_TAG_STRUCT_SAP_OFL_ADD_STA_EVENT, -++ WMI_TLV_TAG_STRUCT_SAP_OFL_DEL_STA_EVENT, -++ WMI_TLV_TAG_STRUCT_APFIND_CMD_PARAM, -++ WMI_TLV_TAG_STRUCT_APFIND_EVENT_HDR, -++ -++ WMI_TLV_TAG_MAX -++}; -++ -++enum wmi_tlv_service { -++ WMI_TLV_SERVICE_BEACON_OFFLOAD = 0, -++ WMI_TLV_SERVICE_SCAN_OFFLOAD, -++ WMI_TLV_SERVICE_ROAM_SCAN_OFFLOAD, -++ WMI_TLV_SERVICE_BCN_MISS_OFFLOAD, -++ WMI_TLV_SERVICE_STA_PWRSAVE, -++ WMI_TLV_SERVICE_STA_ADVANCED_PWRSAVE, -++ WMI_TLV_SERVICE_AP_UAPSD, -++ WMI_TLV_SERVICE_AP_DFS, -++ WMI_TLV_SERVICE_11AC, -++ WMI_TLV_SERVICE_BLOCKACK, -++ WMI_TLV_SERVICE_PHYERR, -++ WMI_TLV_SERVICE_BCN_FILTER, -++ WMI_TLV_SERVICE_RTT, -++ WMI_TLV_SERVICE_WOW, -++ WMI_TLV_SERVICE_RATECTRL_CACHE, -++ WMI_TLV_SERVICE_IRAM_TIDS, -++ WMI_TLV_SERVICE_ARPNS_OFFLOAD, -++ WMI_TLV_SERVICE_NLO, -++ WMI_TLV_SERVICE_GTK_OFFLOAD, -++ WMI_TLV_SERVICE_SCAN_SCH, -++ WMI_TLV_SERVICE_CSA_OFFLOAD, -++ WMI_TLV_SERVICE_CHATTER, -++ WMI_TLV_SERVICE_COEX_FREQAVOID, -++ WMI_TLV_SERVICE_PACKET_POWER_SAVE, -++ WMI_TLV_SERVICE_FORCE_FW_HANG, -++ WMI_TLV_SERVICE_GPIO, -++ WMI_TLV_SERVICE_STA_DTIM_PS_MODULATED_DTIM, -++ WMI_TLV_SERVICE_STA_UAPSD_BASIC_AUTO_TRIG, -++ WMI_TLV_SERVICE_STA_UAPSD_VAR_AUTO_TRIG, -++ WMI_TLV_SERVICE_STA_KEEP_ALIVE, -++ WMI_TLV_SERVICE_TX_ENCAP, -++ WMI_TLV_SERVICE_AP_PS_DETECT_OUT_OF_SYNC, -++ WMI_TLV_SERVICE_EARLY_RX, -++ WMI_TLV_SERVICE_STA_SMPS, -++ WMI_TLV_SERVICE_FWTEST, -++ WMI_TLV_SERVICE_STA_WMMAC, -++ WMI_TLV_SERVICE_TDLS, -++ WMI_TLV_SERVICE_BURST, -++ WMI_TLV_SERVICE_MCC_BCN_INTERVAL_CHANGE, -++ WMI_TLV_SERVICE_ADAPTIVE_OCS, -++ WMI_TLV_SERVICE_BA_SSN_SUPPORT, -++ WMI_TLV_SERVICE_FILTER_IPSEC_NATKEEPALIVE, -++ WMI_TLV_SERVICE_WLAN_HB, -++ WMI_TLV_SERVICE_LTE_ANT_SHARE_SUPPORT, -++ WMI_TLV_SERVICE_BATCH_SCAN, -++ WMI_TLV_SERVICE_QPOWER, -++ WMI_TLV_SERVICE_PLMREQ, -++ WMI_TLV_SERVICE_THERMAL_MGMT, -++ WMI_TLV_SERVICE_RMC, -++ WMI_TLV_SERVICE_MHF_OFFLOAD, -++ WMI_TLV_SERVICE_COEX_SAR, -++ WMI_TLV_SERVICE_BCN_TXRATE_OVERRIDE, -++ WMI_TLV_SERVICE_NAN, -++ WMI_TLV_SERVICE_L1SS_STAT, -++ WMI_TLV_SERVICE_ESTIMATE_LINKSPEED, -++ WMI_TLV_SERVICE_OBSS_SCAN, -++ WMI_TLV_SERVICE_TDLS_OFFCHAN, -++ WMI_TLV_SERVICE_TDLS_UAPSD_BUFFER_STA, -++ WMI_TLV_SERVICE_TDLS_UAPSD_SLEEP_STA, -++ WMI_TLV_SERVICE_IBSS_PWRSAVE, -++ WMI_TLV_SERVICE_LPASS, -++ WMI_TLV_SERVICE_EXTSCAN, -++ WMI_TLV_SERVICE_D0WOW, -++ WMI_TLV_SERVICE_HSOFFLOAD, -++ WMI_TLV_SERVICE_ROAM_HO_OFFLOAD, -++ WMI_TLV_SERVICE_RX_FULL_REORDER, -++ WMI_TLV_SERVICE_DHCP_OFFLOAD, -++ WMI_TLV_SERVICE_STA_RX_IPA_OFFLOAD_SUPPORT, -++ WMI_TLV_SERVICE_MDNS_OFFLOAD, -++ WMI_TLV_SERVICE_SAP_AUTH_OFFLOAD, -++}; -++ -++#define WMI_SERVICE_IS_ENABLED(wmi_svc_bmap, svc_id, len) \ -++ ((svc_id) < (len) && \ -++ __le32_to_cpu((wmi_svc_bmap)[(svc_id)/(sizeof(u32))]) & \ -++ BIT((svc_id)%(sizeof(u32)))) -++ -++#define SVCMAP(x, y, len) \ -++ do { \ -++ if (WMI_SERVICE_IS_ENABLED((in), (x), (len))) \ -++ __set_bit(y, out); \ -++ } while (0) -++ -++static inline void -++wmi_tlv_svc_map(const __le32 *in, unsigned long *out, size_t len) -++{ -++ SVCMAP(WMI_TLV_SERVICE_BEACON_OFFLOAD, -++ WMI_SERVICE_BEACON_OFFLOAD, len); -++ SVCMAP(WMI_TLV_SERVICE_SCAN_OFFLOAD, -++ WMI_SERVICE_SCAN_OFFLOAD, len); -++ SVCMAP(WMI_TLV_SERVICE_ROAM_SCAN_OFFLOAD, -++ WMI_SERVICE_ROAM_SCAN_OFFLOAD, len); -++ SVCMAP(WMI_TLV_SERVICE_BCN_MISS_OFFLOAD, -++ WMI_SERVICE_BCN_MISS_OFFLOAD, len); -++ SVCMAP(WMI_TLV_SERVICE_STA_PWRSAVE, -++ WMI_SERVICE_STA_PWRSAVE, len); -++ SVCMAP(WMI_TLV_SERVICE_STA_ADVANCED_PWRSAVE, -++ WMI_SERVICE_STA_ADVANCED_PWRSAVE, len); -++ SVCMAP(WMI_TLV_SERVICE_AP_UAPSD, -++ WMI_SERVICE_AP_UAPSD, len); -++ SVCMAP(WMI_TLV_SERVICE_AP_DFS, -++ WMI_SERVICE_AP_DFS, len); -++ SVCMAP(WMI_TLV_SERVICE_11AC, -++ WMI_SERVICE_11AC, len); -++ SVCMAP(WMI_TLV_SERVICE_BLOCKACK, -++ WMI_SERVICE_BLOCKACK, len); -++ SVCMAP(WMI_TLV_SERVICE_PHYERR, -++ WMI_SERVICE_PHYERR, len); -++ SVCMAP(WMI_TLV_SERVICE_BCN_FILTER, -++ WMI_SERVICE_BCN_FILTER, len); -++ SVCMAP(WMI_TLV_SERVICE_RTT, -++ WMI_SERVICE_RTT, len); -++ SVCMAP(WMI_TLV_SERVICE_WOW, -++ WMI_SERVICE_WOW, len); -++ SVCMAP(WMI_TLV_SERVICE_RATECTRL_CACHE, -++ WMI_SERVICE_RATECTRL_CACHE, len); -++ SVCMAP(WMI_TLV_SERVICE_IRAM_TIDS, -++ WMI_SERVICE_IRAM_TIDS, len); -++ SVCMAP(WMI_TLV_SERVICE_ARPNS_OFFLOAD, -++ WMI_SERVICE_ARPNS_OFFLOAD, len); -++ SVCMAP(WMI_TLV_SERVICE_NLO, -++ WMI_SERVICE_NLO, len); -++ SVCMAP(WMI_TLV_SERVICE_GTK_OFFLOAD, -++ WMI_SERVICE_GTK_OFFLOAD, len); -++ SVCMAP(WMI_TLV_SERVICE_SCAN_SCH, -++ WMI_SERVICE_SCAN_SCH, len); -++ SVCMAP(WMI_TLV_SERVICE_CSA_OFFLOAD, -++ WMI_SERVICE_CSA_OFFLOAD, len); -++ SVCMAP(WMI_TLV_SERVICE_CHATTER, -++ WMI_SERVICE_CHATTER, len); -++ SVCMAP(WMI_TLV_SERVICE_COEX_FREQAVOID, -++ WMI_SERVICE_COEX_FREQAVOID, len); -++ SVCMAP(WMI_TLV_SERVICE_PACKET_POWER_SAVE, -++ WMI_SERVICE_PACKET_POWER_SAVE, len); -++ SVCMAP(WMI_TLV_SERVICE_FORCE_FW_HANG, -++ WMI_SERVICE_FORCE_FW_HANG, len); -++ SVCMAP(WMI_TLV_SERVICE_GPIO, -++ WMI_SERVICE_GPIO, len); -++ SVCMAP(WMI_TLV_SERVICE_STA_DTIM_PS_MODULATED_DTIM, -++ WMI_SERVICE_STA_DTIM_PS_MODULATED_DTIM, len); -++ SVCMAP(WMI_TLV_SERVICE_STA_UAPSD_BASIC_AUTO_TRIG, -++ WMI_SERVICE_STA_UAPSD_BASIC_AUTO_TRIG, len); -++ SVCMAP(WMI_TLV_SERVICE_STA_UAPSD_VAR_AUTO_TRIG, -++ WMI_SERVICE_STA_UAPSD_VAR_AUTO_TRIG, len); -++ SVCMAP(WMI_TLV_SERVICE_STA_KEEP_ALIVE, -++ WMI_SERVICE_STA_KEEP_ALIVE, len); -++ SVCMAP(WMI_TLV_SERVICE_TX_ENCAP, -++ WMI_SERVICE_TX_ENCAP, len); -++ SVCMAP(WMI_TLV_SERVICE_AP_PS_DETECT_OUT_OF_SYNC, -++ WMI_SERVICE_AP_PS_DETECT_OUT_OF_SYNC, len); -++ SVCMAP(WMI_TLV_SERVICE_EARLY_RX, -++ WMI_SERVICE_EARLY_RX, len); -++ SVCMAP(WMI_TLV_SERVICE_STA_SMPS, -++ WMI_SERVICE_STA_SMPS, len); -++ SVCMAP(WMI_TLV_SERVICE_FWTEST, -++ WMI_SERVICE_FWTEST, len); -++ SVCMAP(WMI_TLV_SERVICE_STA_WMMAC, -++ WMI_SERVICE_STA_WMMAC, len); -++ SVCMAP(WMI_TLV_SERVICE_TDLS, -++ WMI_SERVICE_TDLS, len); -++ SVCMAP(WMI_TLV_SERVICE_BURST, -++ WMI_SERVICE_BURST, len); -++ SVCMAP(WMI_TLV_SERVICE_MCC_BCN_INTERVAL_CHANGE, -++ WMI_SERVICE_MCC_BCN_INTERVAL_CHANGE, len); -++ SVCMAP(WMI_TLV_SERVICE_ADAPTIVE_OCS, -++ WMI_SERVICE_ADAPTIVE_OCS, len); -++ SVCMAP(WMI_TLV_SERVICE_BA_SSN_SUPPORT, -++ WMI_SERVICE_BA_SSN_SUPPORT, len); -++ SVCMAP(WMI_TLV_SERVICE_FILTER_IPSEC_NATKEEPALIVE, -++ WMI_SERVICE_FILTER_IPSEC_NATKEEPALIVE, len); -++ SVCMAP(WMI_TLV_SERVICE_WLAN_HB, -++ WMI_SERVICE_WLAN_HB, len); -++ SVCMAP(WMI_TLV_SERVICE_LTE_ANT_SHARE_SUPPORT, -++ WMI_SERVICE_LTE_ANT_SHARE_SUPPORT, len); -++ SVCMAP(WMI_TLV_SERVICE_BATCH_SCAN, -++ WMI_SERVICE_BATCH_SCAN, len); -++ SVCMAP(WMI_TLV_SERVICE_QPOWER, -++ WMI_SERVICE_QPOWER, len); -++ SVCMAP(WMI_TLV_SERVICE_PLMREQ, -++ WMI_SERVICE_PLMREQ, len); -++ SVCMAP(WMI_TLV_SERVICE_THERMAL_MGMT, -++ WMI_SERVICE_THERMAL_MGMT, len); -++ SVCMAP(WMI_TLV_SERVICE_RMC, -++ WMI_SERVICE_RMC, len); -++ SVCMAP(WMI_TLV_SERVICE_MHF_OFFLOAD, -++ WMI_SERVICE_MHF_OFFLOAD, len); -++ SVCMAP(WMI_TLV_SERVICE_COEX_SAR, -++ WMI_SERVICE_COEX_SAR, len); -++ SVCMAP(WMI_TLV_SERVICE_BCN_TXRATE_OVERRIDE, -++ WMI_SERVICE_BCN_TXRATE_OVERRIDE, len); -++ SVCMAP(WMI_TLV_SERVICE_NAN, -++ WMI_SERVICE_NAN, len); -++ SVCMAP(WMI_TLV_SERVICE_L1SS_STAT, -++ WMI_SERVICE_L1SS_STAT, len); -++ SVCMAP(WMI_TLV_SERVICE_ESTIMATE_LINKSPEED, -++ WMI_SERVICE_ESTIMATE_LINKSPEED, len); -++ SVCMAP(WMI_TLV_SERVICE_OBSS_SCAN, -++ WMI_SERVICE_OBSS_SCAN, len); -++ SVCMAP(WMI_TLV_SERVICE_TDLS_OFFCHAN, -++ WMI_SERVICE_TDLS_OFFCHAN, len); -++ SVCMAP(WMI_TLV_SERVICE_TDLS_UAPSD_BUFFER_STA, -++ WMI_SERVICE_TDLS_UAPSD_BUFFER_STA, len); -++ SVCMAP(WMI_TLV_SERVICE_TDLS_UAPSD_SLEEP_STA, -++ WMI_SERVICE_TDLS_UAPSD_SLEEP_STA, len); -++ SVCMAP(WMI_TLV_SERVICE_IBSS_PWRSAVE, -++ WMI_SERVICE_IBSS_PWRSAVE, len); -++ SVCMAP(WMI_TLV_SERVICE_LPASS, -++ WMI_SERVICE_LPASS, len); -++ SVCMAP(WMI_TLV_SERVICE_EXTSCAN, -++ WMI_SERVICE_EXTSCAN, len); -++ SVCMAP(WMI_TLV_SERVICE_D0WOW, -++ WMI_SERVICE_D0WOW, len); -++ SVCMAP(WMI_TLV_SERVICE_HSOFFLOAD, -++ WMI_SERVICE_HSOFFLOAD, len); -++ SVCMAP(WMI_TLV_SERVICE_ROAM_HO_OFFLOAD, -++ WMI_SERVICE_ROAM_HO_OFFLOAD, len); -++ SVCMAP(WMI_TLV_SERVICE_RX_FULL_REORDER, -++ WMI_SERVICE_RX_FULL_REORDER, len); -++ SVCMAP(WMI_TLV_SERVICE_DHCP_OFFLOAD, -++ WMI_SERVICE_DHCP_OFFLOAD, len); -++ SVCMAP(WMI_TLV_SERVICE_STA_RX_IPA_OFFLOAD_SUPPORT, -++ WMI_SERVICE_STA_RX_IPA_OFFLOAD_SUPPORT, len); -++ SVCMAP(WMI_TLV_SERVICE_MDNS_OFFLOAD, -++ WMI_SERVICE_MDNS_OFFLOAD, len); -++ SVCMAP(WMI_TLV_SERVICE_SAP_AUTH_OFFLOAD, -++ WMI_SERVICE_SAP_AUTH_OFFLOAD, len); -++} -++ -++#undef SVCMAP -++ -++struct wmi_tlv { -++ __le16 len; -++ __le16 tag; -++ u8 value[0]; -++} __packed; -++ -++#define WMI_TLV_MGMT_RX_NUM_RSSI 4 -++ -++struct wmi_tlv_mgmt_rx_ev { -++ __le32 channel; -++ __le32 snr; -++ __le32 rate; -++ __le32 phy_mode; -++ __le32 buf_len; -++ __le32 status; -++ __le32 rssi[WMI_TLV_MGMT_RX_NUM_RSSI]; -++} __packed; -++ -++struct wmi_tlv_abi_version { -++ __le32 abi_ver0; -++ __le32 abi_ver1; -++ __le32 abi_ver_ns0; -++ __le32 abi_ver_ns1; -++ __le32 abi_ver_ns2; -++ __le32 abi_ver_ns3; -++} __packed; -++ -++enum wmi_tlv_hw_bd_id { -++ WMI_TLV_HW_BD_LEGACY = 0, -++ WMI_TLV_HW_BD_QCA6174 = 1, -++ WMI_TLV_HW_BD_QCA2582 = 2, -++}; -++ -++struct wmi_tlv_hw_bd_info { -++ u8 rev; -++ u8 project_id; -++ u8 custom_id; -++ u8 reference_design_id; -++} __packed; -++ -++struct wmi_tlv_svc_rdy_ev { -++ __le32 fw_build_vers; -++ struct wmi_tlv_abi_version abi; -++ __le32 phy_capability; -++ __le32 max_frag_entry; -++ __le32 num_rf_chains; -++ __le32 ht_cap_info; -++ __le32 vht_cap_info; -++ __le32 vht_supp_mcs; -++ __le32 hw_min_tx_power; -++ __le32 hw_max_tx_power; -++ __le32 sys_cap_info; -++ __le32 min_pkt_size_enable; -++ __le32 max_bcn_ie_size; -++ __le32 num_mem_reqs; -++ __le32 max_num_scan_chans; -++ __le32 hw_bd_id; /* 0 means hw_bd_info is invalid */ -++ struct wmi_tlv_hw_bd_info hw_bd_info[5]; -++} __packed; -++ -++struct wmi_tlv_rdy_ev { -++ struct wmi_tlv_abi_version abi; -++ struct wmi_mac_addr mac_addr; -++ __le32 status; -++} __packed; -++ -++struct wmi_tlv_resource_config { -++ __le32 num_vdevs; -++ __le32 num_peers; -++ __le32 num_offload_peers; -++ __le32 num_offload_reorder_bufs; -++ __le32 num_peer_keys; -++ __le32 num_tids; -++ __le32 ast_skid_limit; -++ __le32 tx_chain_mask; -++ __le32 rx_chain_mask; -++ __le32 rx_timeout_pri[4]; -++ __le32 rx_decap_mode; -++ __le32 scan_max_pending_reqs; -++ __le32 bmiss_offload_max_vdev; -++ __le32 roam_offload_max_vdev; -++ __le32 roam_offload_max_ap_profiles; -++ __le32 num_mcast_groups; -++ __le32 num_mcast_table_elems; -++ __le32 mcast2ucast_mode; -++ __le32 tx_dbg_log_size; -++ __le32 num_wds_entries; -++ __le32 dma_burst_size; -++ __le32 mac_aggr_delim; -++ __le32 rx_skip_defrag_timeout_dup_detection_check; -++ __le32 vow_config; -++ __le32 gtk_offload_max_vdev; -++ __le32 num_msdu_desc; -++ __le32 max_frag_entries; -++ __le32 num_tdls_vdevs; -++ __le32 num_tdls_conn_table_entries; -++ __le32 beacon_tx_offload_max_vdev; -++ __le32 num_multicast_filter_entries; -++ __le32 num_wow_filters; -++ __le32 num_keep_alive_pattern; -++ __le32 keep_alive_pattern_size; -++ __le32 max_tdls_concurrent_sleep_sta; -++ __le32 max_tdls_concurrent_buffer_sta; -++} __packed; -++ -++struct wmi_tlv_init_cmd { -++ struct wmi_tlv_abi_version abi; -++ __le32 num_host_mem_chunks; -++} __packed; -++ -++struct wmi_tlv_pdev_set_param_cmd { -++ __le32 pdev_id; /* not used yet */ -++ __le32 param_id; -++ __le32 param_value; -++} __packed; -++ -++struct wmi_tlv_pdev_set_rd_cmd { -++ __le32 pdev_id; /* not used yet */ -++ __le32 regd; -++ __le32 regd_2ghz; -++ __le32 regd_5ghz; -++ __le32 conform_limit_2ghz; -++ __le32 conform_limit_5ghz; -++} __packed; -++ -++struct wmi_tlv_scan_chan_list_cmd { -++ __le32 num_scan_chans; -++} __packed; -++ -++struct wmi_tlv_start_scan_cmd { -++ struct wmi_start_scan_common common; -++ __le32 burst_duration_ms; -++ __le32 num_channels; -++ __le32 num_bssids; -++ __le32 num_ssids; -++ __le32 ie_len; -++ __le32 num_probes; -++} __packed; -++ -++struct wmi_tlv_vdev_start_cmd { -++ __le32 vdev_id; -++ __le32 requestor_id; -++ __le32 bcn_intval; -++ __le32 dtim_period; -++ __le32 flags; -++ struct wmi_ssid ssid; -++ __le32 bcn_tx_rate; -++ __le32 bcn_tx_power; -++ __le32 num_noa_descr; -++ __le32 disable_hw_ack; -++} __packed; -++ -++enum { -++ WMI_TLV_PEER_TYPE_DEFAULT = 0, /* generic / non-BSS / self-peer */ -++ WMI_TLV_PEER_TYPE_BSS = 1, -++ WMI_TLV_PEER_TYPE_TDLS = 2, -++ WMI_TLV_PEER_TYPE_HOST_MAX = 127, -++ WMI_TLV_PEER_TYPE_ROAMOFFLOAD_TMP = 128, -++}; -++ -++struct wmi_tlv_peer_create_cmd { -++ __le32 vdev_id; -++ struct wmi_mac_addr peer_addr; -++ __le32 peer_type; -++} __packed; -++ -++struct wmi_tlv_peer_assoc_cmd { -++ struct wmi_mac_addr mac_addr; -++ __le32 vdev_id; -++ __le32 new_assoc; -++ __le32 assoc_id; -++ __le32 flags; -++ __le32 caps; -++ __le32 listen_intval; -++ __le32 ht_caps; -++ __le32 max_mpdu; -++ __le32 mpdu_density; -++ __le32 rate_caps; -++ __le32 nss; -++ __le32 vht_caps; -++ __le32 phy_mode; -++ __le32 ht_info[2]; -++ __le32 num_legacy_rates; -++ __le32 num_ht_rates; -++} __packed; -++ -++struct wmi_tlv_pdev_suspend { -++ __le32 pdev_id; /* not used yet */ -++ __le32 opt; -++} __packed; -++ -++struct wmi_tlv_pdev_set_wmm_cmd { -++ __le32 pdev_id; /* not used yet */ -++ __le32 dg_type; /* no idea.. */ -++} __packed; -++ -++struct wmi_tlv_vdev_wmm_params { -++ __le32 dummy; -++ struct wmi_wmm_params params; -++} __packed; -++ -++struct wmi_tlv_vdev_set_wmm_cmd { -++ __le32 vdev_id; -++ struct wmi_tlv_vdev_wmm_params vdev_wmm_params[4]; -++} __packed; -++ -++struct wmi_tlv_phyerr_ev { -++ __le32 num_phyerrs; -++ __le32 tsf_l32; -++ __le32 tsf_u32; -++ __le32 buf_len; -++} __packed; -++ -++enum wmi_tlv_dbglog_param { -++ WMI_TLV_DBGLOG_PARAM_LOG_LEVEL = 1, -++ WMI_TLV_DBGLOG_PARAM_VDEV_ENABLE, -++ WMI_TLV_DBGLOG_PARAM_VDEV_DISABLE, -++ WMI_TLV_DBGLOG_PARAM_VDEV_ENABLE_BITMAP, -++ WMI_TLV_DBGLOG_PARAM_VDEV_DISABLE_BITMAP, -++}; -++ -++enum wmi_tlv_dbglog_log_level { -++ WMI_TLV_DBGLOG_LOG_LEVEL_VERBOSE = 0, -++ WMI_TLV_DBGLOG_LOG_LEVEL_INFO, -++ WMI_TLV_DBGLOG_LOG_LEVEL_INFO_LVL_1, -++ WMI_TLV_DBGLOG_LOG_LEVEL_INFO_LVL_2, -++ WMI_TLV_DBGLOG_LOG_LEVEL_WARN, -++ WMI_TLV_DBGLOG_LOG_LEVEL_ERR, -++}; -++ -++#define WMI_TLV_DBGLOG_BITMAP_MAX_IDS 512 -++#define WMI_TLV_DBGLOG_BITMAP_MAX_WORDS (WMI_TLV_DBGLOG_BITMAP_MAX_IDS / \ -++ sizeof(__le32)) -++#define WMI_TLV_DBGLOG_ALL_MODULES 0xffff -++#define WMI_TLV_DBGLOG_LOG_LEVEL_VALUE(module_id, log_level) \ -++ (((module_id << 16) & 0xffff0000) | \ -++ ((log_level << 0) & 0x000000ff)) -++ -++struct wmi_tlv_dbglog_cmd { -++ __le32 param; -++ __le32 value; -++} __packed; -++ -++struct wmi_tlv_resume_cmd { -++ __le32 reserved; -++} __packed; -++ -++struct wmi_tlv_req_stats_cmd { -++ __le32 stats_id; /* wmi_stats_id */ -++ __le32 vdev_id; -++ struct wmi_mac_addr peer_macaddr; -++} __packed; -++ -++struct wmi_tlv_vdev_stats { -++ __le32 vdev_id; -++ __le32 beacon_snr; -++ __le32 data_snr; -++ __le32 num_tx_frames[4]; /* per-AC */ -++ __le32 num_rx_frames; -++ __le32 num_tx_frames_retries[4]; -++ __le32 num_tx_frames_failures[4]; -++ __le32 num_rts_fail; -++ __le32 num_rts_success; -++ __le32 num_rx_err; -++ __le32 num_rx_discard; -++ __le32 num_tx_not_acked; -++ __le32 tx_rate_history[10]; -++ __le32 beacon_rssi_history[10]; -++} __packed; -++ -++struct wmi_tlv_pktlog_enable { -++ __le32 reserved; -++ __le32 filter; -++} __packed; -++ -++struct wmi_tlv_pktlog_disable { -++ __le32 reserved; -++} __packed; -++ -++enum wmi_tlv_bcn_tx_status { -++ WMI_TLV_BCN_TX_STATUS_OK, -++ WMI_TLV_BCN_TX_STATUS_XRETRY, -++ WMI_TLV_BCN_TX_STATUS_DROP, -++ WMI_TLV_BCN_TX_STATUS_FILTERED, -++}; -++ -++struct wmi_tlv_bcn_tx_status_ev { -++ __le32 vdev_id; -++ __le32 tx_status; -++} __packed; -++ -++struct wmi_tlv_bcn_prb_info { -++ __le32 caps; -++ __le32 erp; -++ u8 ies[0]; -++} __packed; -++ -++struct wmi_tlv_bcn_tmpl_cmd { -++ __le32 vdev_id; -++ __le32 tim_ie_offset; -++ __le32 buf_len; -++} __packed; -++ -++struct wmi_tlv_prb_tmpl_cmd { -++ __le32 vdev_id; -++ __le32 buf_len; -++} __packed; -++ -++struct wmi_tlv_p2p_go_bcn_ie { -++ __le32 vdev_id; -++ __le32 ie_len; -++} __packed; -++ -++enum wmi_tlv_diag_item_type { -++ WMI_TLV_DIAG_ITEM_TYPE_FW_EVENT, -++ WMI_TLV_DIAG_ITEM_TYPE_FW_LOG, -++ WMI_TLV_DIAG_ITEM_TYPE_FW_DEBUG_MSG, -++}; -++ -++struct wmi_tlv_diag_item { -++ u8 type; -++ u8 reserved; -++ __le16 len; -++ __le32 timestamp; -++ __le32 code; -++ u8 payload[0]; -++} __packed; -++ -++struct wmi_tlv_diag_data_ev { -++ __le32 num_items; -++} __packed; -++ -++struct wmi_tlv_sta_keepalive_cmd { -++ __le32 vdev_id; -++ __le32 enabled; -++ __le32 method; /* WMI_STA_KEEPALIVE_METHOD_ */ -++ __le32 interval; /* in seconds */ -++} __packed; -++ -++struct wmi_tlv_stats_ev { -++ __le32 stats_id; /* WMI_STAT_ */ -++ __le32 num_pdev_stats; -++ __le32 num_vdev_stats; -++ __le32 num_peer_stats; -++ __le32 num_bcnflt_stats; -++ __le32 num_chan_stats; -++} __packed; -++ -++void ath10k_wmi_tlv_attach(struct ath10k *ar); -++ -++#endif -+--- a/backport-include/linux/etherdevice.h -++++ b/backport-include/linux/etherdevice.h -+@@ -148,6 +148,29 @@ static inline bool ether_addr_equal_unal -+ return memcmp(addr1, addr2, ETH_ALEN) == 0; -+ #endif -+ } -++ -++/** -++ * ether_addr_copy - Copy an Ethernet address -++ * @dst: Pointer to a six-byte array Ethernet address destination -++ * @src: Pointer to a six-byte array Ethernet address source -++ * -++ * Please note: dst & src must both be aligned to u16. -++ */ -++#define ether_addr_copy LINUX_BACKPORT(ether_addr_copy) -++static inline void ether_addr_copy(u8 *dst, const u8 *src) -++{ -++#if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS) -++ *(u32 *)dst = *(const u32 *)src; -++ *(u16 *)(dst + 4) = *(const u16 *)(src + 4); -++#else -++ u16 *a = (u16 *)dst; -++ const u16 *b = (const u16 *)src; -++ -++ a[0] = b[0]; -++ a[1] = b[1]; -++ a[2] = b[2]; -++#endif -++} -+ #endif /* LINUX_VERSION_CODE < KERNEL_VERSION(3,14,0) */ -+ -+ #endif /* _BACKPORT_LINUX_ETHERDEVICE_H */ -+--- a/drivers/net/wireless/ath/spectral_common.h -++++ b/drivers/net/wireless/ath/spectral_common.h -+@@ -20,6 +20,11 @@ -+ #define SPECTRAL_HT20_NUM_BINS 56 -+ #define SPECTRAL_HT20_40_NUM_BINS 128 -+ -++/* TODO: could possibly be 512, but no samples this large -++ * could be acquired so far. -++ */ -++#define SPECTRAL_ATH10K_MAX_NUM_BINS 256 -++ -+ /* FFT sample format given to userspace via debugfs. -+ * -+ * Please keep the type/length at the front position and change -+@@ -31,6 +36,7 @@ -+ enum ath_fft_sample_type { -+ ATH_FFT_SAMPLE_HT20 = 1, -+ ATH_FFT_SAMPLE_HT20_40, -++ ATH_FFT_SAMPLE_ATH10K, -+ }; -+ -+ struct fft_sample_tlv { -+@@ -85,4 +91,23 @@ struct fft_sample_ht20_40 { -+ u8 data[SPECTRAL_HT20_40_NUM_BINS]; -+ } __packed; -+ -++struct fft_sample_ath10k { -++ struct fft_sample_tlv tlv; -++ u8 chan_width_mhz; -++ __be16 freq1; -++ __be16 freq2; -++ __be16 noise; -++ __be16 max_magnitude; -++ __be16 total_gain_db; -++ __be16 base_pwr_db; -++ __be64 tsf; -++ s8 max_index; -++ u8 rssi; -++ u8 relpwr_db; -++ u8 avgpwr_db; -++ u8 max_exp; -++ -++ u8 data[0]; -++} __packed; -++ -+ #endif /* SPECTRAL_COMMON_H */ -+--- a/compat/backport-3.13.c -++++ b/compat/backport-3.13.c -+@@ -12,6 +12,10 @@ -+ #include -+ #include -+ #include -++#include -++#include -++#include -++#include -+ -+ #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,5,0)) -+ #ifdef CPTCFG_REGULATOR -+@@ -200,3 +204,103 @@ bool __net_get_random_once(void *buf, in -+ } -+ EXPORT_SYMBOL_GPL(__net_get_random_once); -+ #endif /* __BACKPORT_NET_GET_RANDOM_ONCE */ -++ -++#ifdef CPTCFG_PCI -++#define pci_bus_read_dev_vendor_id LINUX_BACKPORT(pci_bus_read_dev_vendor_id) -++static bool pci_bus_read_dev_vendor_id(struct pci_bus *bus, int devfn, u32 *l, -++ int crs_timeout) -++{ -++ int delay = 1; -++ -++ if (pci_bus_read_config_dword(bus, devfn, PCI_VENDOR_ID, l)) -++ return false; -++ -++ /* some broken boards return 0 or ~0 if a slot is empty: */ -++ if (*l == 0xffffffff || *l == 0x00000000 || -++ *l == 0x0000ffff || *l == 0xffff0000) -++ return false; -++ -++ /* -++ * Configuration Request Retry Status. Some root ports return the -++ * actual device ID instead of the synthetic ID (0xFFFF) required -++ * by the PCIe spec. Ignore the device ID and only check for -++ * (vendor id == 1). -++ */ -++ while ((*l & 0xffff) == 0x0001) { -++ if (!crs_timeout) -++ return false; -++ -++ msleep(delay); -++ delay *= 2; -++ if (pci_bus_read_config_dword(bus, devfn, PCI_VENDOR_ID, l)) -++ return false; -++ /* Card hasn't responded in 60 seconds? Must be stuck. */ -++ if (delay > crs_timeout) { -++ printk(KERN_WARNING "pci %04x:%02x:%02x.%d: not responding\n", -++ pci_domain_nr(bus), bus->number, PCI_SLOT(devfn), -++ PCI_FUNC(devfn)); -++ return false; -++ } -++ } -++ -++ return true; -++} -++ -++bool pci_device_is_present(struct pci_dev *pdev) -++{ -++ u32 v; -++ -++ return pci_bus_read_dev_vendor_id(pdev->bus, pdev->devfn, &v, 0); -++} -++EXPORT_SYMBOL_GPL(pci_device_is_present); -++#endif /* CPTCFG_PCI */ -++ -++#ifdef CPTCFG_HWMON -++struct device* -++hwmon_device_register_with_groups(struct device *dev, const char *name, -++ void *drvdata, -++ const struct attribute_group **groups) -++{ -++ struct device *hwdev; -++ -++ hwdev = hwmon_device_register(dev); -++ hwdev->groups = groups; -++ dev_set_drvdata(hwdev, drvdata); -++ return hwdev; -++} -++ -++static void devm_hwmon_release(struct device *dev, void *res) -++{ -++ struct device *hwdev = *(struct device **)res; -++ -++ hwmon_device_unregister(hwdev); -++} -++ -++struct device * -++devm_hwmon_device_register_with_groups(struct device *dev, const char *name, -++ void *drvdata, -++ const struct attribute_group **groups) -++{ -++ struct device **ptr, *hwdev; -++ -++ if (!dev) -++ return ERR_PTR(-EINVAL); -++ -++ ptr = devres_alloc(devm_hwmon_release, sizeof(*ptr), GFP_KERNEL); -++ if (!ptr) -++ return ERR_PTR(-ENOMEM); -++ -++ hwdev = hwmon_device_register_with_groups(dev, name, drvdata, groups); -++ if (IS_ERR(hwdev)) -++ goto error; -++ -++ *ptr = hwdev; -++ devres_add(dev, ptr); -++ return hwdev; -++ -++error: -++ devres_free(ptr); -++ return hwdev; -++} -++EXPORT_SYMBOL_GPL(devm_hwmon_device_register_with_groups); -++#endif -+--- /dev/null -++++ b/backport-include/linux/hwmon.h -+@@ -0,0 +1,34 @@ -++#ifndef __BACKPORT_LINUX_HWMON_H -++#define __BACKPORT_LINUX_HWMON_H -++#include_next -++#include -++ -++#if LINUX_VERSION_CODE < KERNEL_VERSION(3,13,0) -++/* -++ * Backports -++ * -++ * commit bab2243ce1897865e31ea6d59b0478391f51812b -++ * Author: Guenter Roeck -++ * Date: Sat Jul 6 13:57:23 2013 -0700 -++ * -++ * hwmon: Introduce hwmon_device_register_with_groups -++ * -++ * hwmon_device_register_with_groups() lets callers register a hwmon device -++ * together with all sysfs attributes in a single call. -++ * -++ * When using hwmon_device_register_with_groups(), hwmon attributes are attached -++ * to the hwmon device directly and no longer with its parent device. -++ * -++ * Signed-off-by: Guenter Roeck -++ */ -++struct device * -++hwmon_device_register_with_groups(struct device *dev, const char *name, -++ void *drvdata, -++ const struct attribute_group **groups); -++struct device * -++devm_hwmon_device_register_with_groups(struct device *dev, const char *name, -++ void *drvdata, -++ const struct attribute_group **groups); -++#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(3,13,0) */ -++ -++#endif /* __BACKPORT_LINUX_HWMON_H */ -diff --git a/package/kernel/mac80211/patches/920-ath10k_allow_fallback_to_board_bin_on_empty_otp_stream.patch b/package/kernel/mac80211/patches/920-ath10k_allow_fallback_to_board_bin_on_empty_otp_stream.patch -index 6a5c766..6a3d2a4 100644 ---- a/package/kernel/mac80211/patches/920-ath10k_allow_fallback_to_board_bin_on_empty_otp_stream.patch -+++ b/package/kernel/mac80211/patches/920-ath10k_allow_fallback_to_board_bin_on_empty_otp_stream.patch -@@ -1,14 +1,14 @@ - --- a/drivers/net/wireless/ath/ath10k/core.c - +++ b/drivers/net/wireless/ath/ath10k/core.c --@@ -277,7 +277,10 @@ static int ath10k_download_and_run_otp(s -+@@ -387,7 +387,10 @@ static int ath10k_download_and_run_otp(s - -- ath10k_dbg(ATH10K_DBG_BOOT, "boot otp execute result %d\n", result); -+ ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot otp execute result %d\n", result); - --- if (result != 0) { -+- if (!skip_otp && result != 0) { - + if (result == 2) { --+ ath10k_warn("otp stream is empty, using board.bin contents"); -++ ath10k_warn(ar, "otp stream is empty, using board.bin contents"); - + return 0; --+ } else if (result != 0) { -- ath10k_err("otp calibration failed: %d", result); -++ } else if (!skip_otp && result != 0) { -+ ath10k_err(ar, "otp calibration failed: %d", result); - return -EINVAL; - } -diff --git a/package/kernel/mac80211/patches/921-ath10k_init_devices_synchronously.patch b/package/kernel/mac80211/patches/921-ath10k_init_devices_synchronously.patch -new file mode 100644 -index 0000000..c664faa ---- /dev/null -+++ b/package/kernel/mac80211/patches/921-ath10k_init_devices_synchronously.patch -@@ -0,0 +1,33 @@ -+From: Sven Eckelmann -+Date: Tue, 18 Nov 2014 12:29:28 +0100 -+Subject: [PATCH] ath10k: Don't initialize devices asynchronously -+ -+OpenWrt requires all PHYs to be initialized to create the configuration files -+during bootup. ath10k violates this because it delays the creation of the PHY -+to a not well defined point in the future. -+ -+Forcing the work to be done immediately works around this problem but may also -+delay the boot when firmware images cannot be found. -+ -+Signed-off-by: Sven Eckelmann -+--- -+ -+--- a/drivers/net/wireless/ath/ath10k/core.c -++++ b/drivers/net/wireless/ath/ath10k/core.c -+@@ -1321,6 +1321,16 @@ int ath10k_core_register(struct ath10k * -+ ar->chip_id = chip_id; -+ queue_work(ar->workqueue, &ar->register_work); -+ -++ /* OpenWrt requires all PHYs to be initialized to create the -++ * configuration files during bootup. ath10k violates this -++ * because it delays the creation of the PHY to a not well defined -++ * point in the future. -++ * -++ * Forcing the work to be done immediately works around this problem -++ * but may also delay the boot when firmware images cannot be found. -++ */ -++ flush_workqueue(ar->workqueue); -++ -+ return 0; -+ } -+ EXPORT_SYMBOL(ath10k_core_register); -diff --git a/package/kernel/mac80211/patches/930-ath10k_add_tpt_led_trigger.patch b/package/kernel/mac80211/patches/930-ath10k_add_tpt_led_trigger.patch -new file mode 100644 -index 0000000..54174b1 ---- /dev/null -+++ b/package/kernel/mac80211/patches/930-ath10k_add_tpt_led_trigger.patch -@@ -0,0 +1,37 @@ -+--- a/drivers/net/wireless/ath/ath10k/mac.c -++++ b/drivers/net/wireless/ath/ath10k/mac.c -+@@ -5405,6 +5405,21 @@ struct ath10k_vif *ath10k_get_arvif(stru -+ return arvif_iter.arvif; -+ } -+ -++#ifdef CPTCFG_MAC80211_LEDS -++static const struct ieee80211_tpt_blink ath10k_tpt_blink[] = { -++ { .throughput = 0 * 1024, .blink_time = 334 }, -++ { .throughput = 1 * 1024, .blink_time = 260 }, -++ { .throughput = 2 * 1024, .blink_time = 220 }, -++ { .throughput = 5 * 1024, .blink_time = 190 }, -++ { .throughput = 10 * 1024, .blink_time = 170 }, -++ { .throughput = 25 * 1024, .blink_time = 150 }, -++ { .throughput = 54 * 1024, .blink_time = 130 }, -++ { .throughput = 120 * 1024, .blink_time = 110 }, -++ { .throughput = 265 * 1024, .blink_time = 80 }, -++ { .throughput = 586 * 1024, .blink_time = 50 }, -++}; -++#endif -++ -+ int ath10k_mac_register(struct ath10k *ar) -+ { -+ struct ieee80211_supported_band *band; -+@@ -5567,6 +5582,12 @@ int ath10k_mac_register(struct ath10k *a -+ goto err_free; -+ } -+ -++#if CPTCFG_MAC80211_LEDS -++ ieee80211_create_tpt_led_trigger(ar->hw, -++ IEEE80211_TPT_LEDTRIG_FL_RADIO, ath10k_tpt_blink, -++ ARRAY_SIZE(ath10k_tpt_blink)); -++#endif -++ -+ ret = ieee80211_register_hw(ar->hw); -+ if (ret) { -+ ath10k_err(ar, "failed to register ieee80211: %d\n", ret); -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..0011b5d ---- /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 -+@@ -5253,6 +5253,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[] = { -+@@ -5260,6 +5264,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[] = { -+@@ -5555,6 +5563,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/0018-ath10k-update-firmware-to-the-latest-version.patch b/patches/openwrt/0018-ath10k-update-firmware-to-the-latest-version.patch deleted file mode 100644 index 56ddc5ea..00000000 --- a/patches/openwrt/0018-ath10k-update-firmware-to-the-latest-version.patch +++ /dev/null @@ -1,41 +0,0 @@ -From: Matthias Schiffer -Date: Tue, 10 Mar 2015 13:17:06 +0100 -Subject: ath10k: update firmware to the latest version - -Signed-off-by: Felix Fietkau - -diff --git a/package/kernel/mac80211/Makefile b/package/kernel/mac80211/Makefile -index b96e782..629692d 100644 ---- a/package/kernel/mac80211/Makefile -+++ b/package/kernel/mac80211/Makefile -@@ -129,7 +129,7 @@ endef - $(eval $(call Download,linux-firmware)) - - PKG_ATH10K_LINUX_FIRMWARE_NAME:=ath10k-firmware --PKG_ATH10K_LINUX_FIRMWARE_VERSION:=38eeda3ae6f90fde5546bdd48ee4ff3090f238c0 -+PKG_ATH10K_LINUX_FIRMWARE_VERSION:=232b419e71dab27b52b96e80ea7649ed67bdac77 - PKG_ATH10K_LINUX_FIRMWARE_SOURCE:=$(PKG_ATH10K_LINUX_FIRMWARE_NAME)-$(PKG_ATH10K_LINUX_FIRMWARE_VERSION).tar.bz2 - PKG_ATH10K_LINUX_FIRMWARE_PROTO:=git - PKG_ATH10K_LINUX_FIRMWARE_SOURCE_URL:=https://github.com/kvalo/ath10k-firmware.git -@@ -1821,18 +1821,17 @@ endef - - define KernelPackage/ath10k/install - $(INSTALL_DIR) $(1)/lib/firmware/ath10k/QCA988X/hw2.0 --ifeq ($(CONFIG_ATH10K_STA_FW),y) - $(INSTALL_DATA) \ - $(PKG_BUILD_DIR)/$(PKG_ATH10K_LINUX_FIRMWARE_SUBDIR)/ath10k/QCA988X/hw2.0/board.bin \ - $(1)/lib/firmware/ath10k/QCA988X/hw2.0/ -+ifeq ($(CONFIG_ATH10K_STA_FW),y) - $(INSTALL_DATA) \ - $(PKG_BUILD_DIR)/$(PKG_ATH10K_LINUX_FIRMWARE_SUBDIR)/main/firmware-2.bin_999.999.0.636 \ - $(1)/lib/firmware/ath10k/QCA988X/hw2.0/firmware-2.bin - else - $(INSTALL_DATA) \ -- $(PKG_BUILD_DIR)/$(PKG_ATH10K_LINUX_FIRMWARE_SUBDIR)/ath10k/QCA988X/hw2.0/board.bin \ -- $(PKG_BUILD_DIR)/$(PKG_ATH10K_LINUX_FIRMWARE_SUBDIR)/ath10k/QCA988X/hw2.0/firmware-2.bin \ -- $(1)/lib/firmware/ath10k/QCA988X/hw2.0/ -+ $(PKG_BUILD_DIR)/$(PKG_ATH10K_LINUX_FIRMWARE_SUBDIR)/10.2/firmware-3.bin_10.2-00082-4-2 \ -+ $(1)/lib/firmware/ath10k/QCA988X/hw2.0/firmware-3.bin - endif - endef - diff --git a/patches/openwrt/0020-at71xx-TP-LINK-Archer-add-5GHz-led-entry.patch b/patches/openwrt/0020-at71xx-TP-LINK-Archer-add-5GHz-led-entry.patch deleted file mode 100644 index 406fa13d..00000000 --- a/patches/openwrt/0020-at71xx-TP-LINK-Archer-add-5GHz-led-entry.patch +++ /dev/null @@ -1,20 +0,0 @@ -From: Matthias Schiffer -Date: Tue, 10 Mar 2015 13:17:23 +0100 -Subject: at71xx: TP-LINK Archer: add 5GHz led entry - -Add 5GHz led entry after r44033. - -Signed-off-by: Cezary Jackiewicz - -diff --git a/target/linux/ar71xx/base-files/etc/uci-defaults/01_leds b/target/linux/ar71xx/base-files/etc/uci-defaults/01_leds -index a74b8f4..36fe028 100755 ---- a/target/linux/ar71xx/base-files/etc/uci-defaults/01_leds -+++ b/target/linux/ar71xx/base-files/etc/uci-defaults/01_leds -@@ -326,6 +326,7 @@ tl-wdr4900-v2) - ucidef_set_led_usbdev "usb1" "USB1" "tp-link:green:usb1" "1-1" - ucidef_set_led_usbdev "usb2" "USB2" "tp-link:green:usb2" "2-1" - ucidef_set_led_wlan "wlan2g" "WLAN2G" "tp-link:blue:wlan2g" "phy0tpt" -+ ucidef_set_led_wlan "wlan5g" "WLAN5G" "tp-link:blue:wlan5g" "phy1tpt" - ;; - - tl-wr741nd) diff --git a/patches/openwrt/0021-ar71xx-fix-switched-WLAN-LEDs-on-TP-LINK-Archer-C5-C7.patch b/patches/openwrt/0021-ar71xx-fix-switched-WLAN-LEDs-on-TP-LINK-Archer-C5-C7.patch deleted file mode 100644 index 846a4734..00000000 --- a/patches/openwrt/0021-ar71xx-fix-switched-WLAN-LEDs-on-TP-LINK-Archer-C5-C7.patch +++ /dev/null @@ -1,34 +0,0 @@ -From: Matthias Schiffer -Date: Tue, 10 Mar 2015 14:06:01 +0100 -Subject: ar71xx: fix switched WLAN LEDs on TP-LINK Archer C5/C7 - -ath10k is loaded before ath9k, so the 5GHz adapter becomes phy0. - -diff --git a/target/linux/ar71xx/base-files/etc/uci-defaults/01_leds b/target/linux/ar71xx/base-files/etc/uci-defaults/01_leds -index 36fe028..315a9fd 100755 ---- a/target/linux/ar71xx/base-files/etc/uci-defaults/01_leds -+++ b/target/linux/ar71xx/base-files/etc/uci-defaults/01_leds -@@ -320,8 +320,6 @@ tl-wdr4300) - ucidef_set_led_wlan "wlan2g" "WLAN2G" "tp-link:blue:wlan2g" "phy0tpt" - ;; - --archer-c5|\ --archer-c7|\ - tl-wdr4900-v2) - ucidef_set_led_usbdev "usb1" "USB1" "tp-link:green:usb1" "1-1" - ucidef_set_led_usbdev "usb2" "USB2" "tp-link:green:usb2" "2-1" -@@ -329,6 +327,14 @@ tl-wdr4900-v2) - ucidef_set_led_wlan "wlan5g" "WLAN5G" "tp-link:blue:wlan5g" "phy1tpt" - ;; - -+archer-c5|\ -+archer-c7) -+ ucidef_set_led_usbdev "usb1" "USB1" "tp-link:green:usb1" "1-1" -+ ucidef_set_led_usbdev "usb2" "USB2" "tp-link:green:usb2" "2-1" -+ ucidef_set_led_wlan "wlan2g" "WLAN2G" "tp-link:blue:wlan2g" "phy1tpt" -+ ucidef_set_led_wlan "wlan5g" "WLAN5G" "tp-link:blue:wlan5g" "phy0tpt" -+ ;; -+ - tl-wr741nd) - ucidef_set_led_netdev "wan" "WAN" "tp-link:green:wan" "eth1" - ucidef_set_led_switch "lan1" "LAN1" "tp-link:green:lan1" "switch0" "0x02" diff --git a/patches/openwrt/0022-uClibc-fix-syscall-for-syscalls-with-6-arguments-on-PowerPC.patch b/patches/openwrt/0022-uClibc-fix-syscall-for-syscalls-with-6-arguments-on-PowerPC.patch deleted file mode 100644 index 50332a2b..00000000 --- a/patches/openwrt/0022-uClibc-fix-syscall-for-syscalls-with-6-arguments-on-PowerPC.patch +++ /dev/null @@ -1,24 +0,0 @@ -From: Matthias Schiffer -Date: Wed, 11 Mar 2015 18:30:54 +0100 -Subject: uClibc: fix syscall() for syscalls with 6 arguments on PowerPC - -Patch from the uClibc master. - -Fixes the package fastd on PowerPC. - -diff --git a/toolchain/uClibc/patches-0.9.33.2/470-powerpc_syscall6.patch b/toolchain/uClibc/patches-0.9.33.2/470-powerpc_syscall6.patch -new file mode 100644 -index 0000000..9511dcc ---- /dev/null -+++ b/toolchain/uClibc/patches-0.9.33.2/470-powerpc_syscall6.patch -@@ -0,0 +1,10 @@ -+--- a/libc/sysdeps/linux/powerpc/syscall.S -++++ b/libc/sysdeps/linux/powerpc/syscall.S -+@@ -30,6 +30,7 @@ syscall: -+ mr 5,6 -+ mr 6,7 -+ mr 7,8 -++ mr 8,9 -+ sc -+ bnslr; -+ diff --git a/patches/openwrt/0023-ar71xx-Add-build-profile-for-the-gl-inet-6416A-and-6408A.patch b/patches/openwrt/0023-ar71xx-Add-build-profile-for-the-gl-inet-6416A-and-6408A.patch deleted file mode 100644 index ce78a490..00000000 --- a/patches/openwrt/0023-ar71xx-Add-build-profile-for-the-gl-inet-6416A-and-6408A.patch +++ /dev/null @@ -1,35 +0,0 @@ -From: Matthias Schiffer -Date: Thu, 12 Mar 2015 16:57:32 +0100 -Subject: ar71xx: Add build profile for the gl-inet 6416A and 6408A - -Patch to add the buildprofile for the GL-Init-6408A-v1 and the GL-Inet-6416A-v1 -Both devices are identical, only difference is one comes with 8MB flash and -the other with 16MB flash - -Official website: http://www.gl-inet.com/w/?page_id=241&lang=en -Comprehensive list of specs: https://revspace.nl/GL-Inet - -Signed-off-by: Martijn Zilverschoon - -diff --git a/target/linux/ar71xx/image/Makefile b/target/linux/ar71xx/image/Makefile -index 8505ac4..fc59c33 100644 ---- a/target/linux/ar71xx/image/Makefile -+++ b/target/linux/ar71xx/image/Makefile -@@ -1216,7 +1216,8 @@ $(eval $(call SingleProfile,TPLINK-LZMA,64kraw,ARCHERC7V1,archer-c7-v1,ARCHER-C7 - $(eval $(call SingleProfile,TPLINK-LZMA,64kraw,ARCHERC7V2,archer-c7-v2,ARCHER-C7,ttyS0,115200,0xc7000002,1,16Mlzma)) - $(eval $(call SingleProfile,TPLINK-LZMA,64kraw,ELM150,el-m150,EL-M150,ttyATH0,115200,0x01500101,1,8Mlzma)) - $(eval $(call SingleProfile,TPLINK-LZMA,64kraw,ELMINI,el-mini,EL-MINI,ttyATH0,115200,0x01530001,1,8Mlzma)) --$(eval $(call SingleProfile,TPLINK-LZMA,64kraw,GLINET,gl-inet-v1,GL-INET,ttyATH0,115200,0x08000001,1,8Mlzma)) -+$(eval $(call SingleProfile,TPLINK-LZMA,64kraw,GLINET6408A,gl-inet-6408A-v1,GL-INET,ttyATH0,115200,0x08000001,1,8Mlzma)) -+$(eval $(call SingleProfile,TPLINK-LZMA,64kraw,GLINET6416A,gl-inet-6416A-v1,GL-INET,ttyATH0,115200,0x08000001,1,16Mlzma)) - $(eval $(call SingleProfile,TPLINK-LZMA,64kraw,TLMR10U,tl-mr10u-v1,TL-MR10U,ttyATH0,115200,0x00100101,1,4Mlzma)) - $(eval $(call SingleProfile,TPLINK-LZMA,64kraw,TLMR11UV1,tl-mr11u-v1,TL-MR11U,ttyATH0,115200,0x00110101,1,4Mlzma)) - $(eval $(call SingleProfile,TPLINK-LZMA,64kraw,TLMR11UV2,tl-mr11u-v2,TL-MR11U,ttyATH0,115200,0x00110102,1,4Mlzma)) -@@ -1304,6 +1305,7 @@ $(eval $(call MultiProfile,AP136,AP136_010 AP136_020)) - $(eval $(call MultiProfile,ARCHERC7, ARCHERC5 ARCHERC7V1 ARCHERC7V2)) - $(eval $(call MultiProfile,EWDORIN, EWDORINAP EWDORINRT EWDORIN16M)) - $(eval $(call MultiProfile,OPENMESH,OM2P OM5P MR600)) -+$(eval $(call MultiProfile,GLINET,GLINET6408A GLINET6416A)) - $(eval $(call MultiProfile,TEW652BRP,TEW652BRP_FW TEW652BRP_RECOVERY)) - $(eval $(call MultiProfile,TLMR11U,TLMR11UV1 TLMR11UV2)) - $(eval $(call MultiProfile,TLMR3040,TLMR3040V1 TLMR3040V2)) diff --git a/patches/openwrt/0024-ar71xx-detect-GL.iNet-model.patch b/patches/openwrt/0024-ar71xx-detect-GL.iNet-model.patch deleted file mode 100644 index 9996872a..00000000 --- a/patches/openwrt/0024-ar71xx-detect-GL.iNet-model.patch +++ /dev/null @@ -1,39 +0,0 @@ -From: Matthias Schiffer -Date: Fri, 13 Mar 2015 11:59:58 +0100 -Subject: ar71xx: detect GL.iNet model - -There are two versions of the GL.iNet, the 6408A and the 6416A. The only -difference is the flash size. - -diff --git a/target/linux/ar71xx/base-files/lib/ar71xx.sh b/target/linux/ar71xx/base-files/lib/ar71xx.sh -index 61a7936..a698ce5 100755 ---- a/target/linux/ar71xx/base-files/lib/ar71xx.sh -+++ b/target/linux/ar71xx/base-files/lib/ar71xx.sh -@@ -262,6 +262,19 @@ tplink_pharos_board_detect() { - [ -n "$model" ] && AR71XX_MODEL="$model v$2" - } - -+gl_inet_board_detect() { -+ local size="$(mtd_get_part_size 'firmware')" -+ -+ case "$size" in -+ 8192000) -+ AR71XX_MODEL='GL-iNet 6408A v1' -+ ;; -+ 16580608) -+ AR71XX_MODEL='GL-iNet 6416A v1' -+ ;; -+ esac -+} -+ - ar71xx_board_detect() { - local machine - local name -@@ -380,6 +393,7 @@ ar71xx_board_detect() { - ;; - *"GL-CONNECT INET v1") - name="gl-inet" -+ gl_inet_board_detect - ;; - *"EnGenius ESR1750") - name="esr1750" diff --git a/patches/openwrt/0025-firmware-utils-allow-passing-a-specific-MBR-signature-to-ptgen.patch b/patches/openwrt/0025-firmware-utils-allow-passing-a-specific-MBR-signature-to-ptgen.patch deleted file mode 100644 index f7635d30..00000000 --- a/patches/openwrt/0025-firmware-utils-allow-passing-a-specific-MBR-signature-to-ptgen.patch +++ /dev/null @@ -1,70 +0,0 @@ -From: Matthias Schiffer -Date: Sun, 15 Mar 2015 18:06:49 +0100 -Subject: firmware-utils: allow passing a specific MBR signature to ptgen - -Signed-off-by: Jo-Philipp Wich - -diff --git a/tools/firmware-utils/src/ptgen.c b/tools/firmware-utils/src/ptgen.c -index 0247fd0..6379ed7 100644 ---- a/tools/firmware-utils/src/ptgen.c -+++ b/tools/firmware-utils/src/ptgen.c -@@ -28,6 +28,7 @@ - #include - #include - #include -+#include - - #if __BYTE_ORDER == __BIG_ENDIAN - #define cpu_to_le16(x) bswap_16(x) -@@ -124,7 +125,7 @@ static inline unsigned long round_to_kb(long sect) { - } - - /* check the partition sizes and write the partition table */ --static int gen_ptable(int nr) -+static int gen_ptable(uint32_t signature, int nr) - { - struct pte pte[4]; - unsigned long sect = 0; -@@ -159,6 +160,12 @@ static int gen_ptable(int nr) - return -1; - } - -+ lseek(fd, 440, SEEK_SET); -+ if (write(fd, &signature, sizeof(signature)) != sizeof(signature)) { -+ fprintf(stderr, "write failed.\n"); -+ goto fail; -+ } -+ - lseek(fd, 446, SEEK_SET); - if (write(fd, pte, sizeof(struct pte) * 4) != sizeof(struct pte) * 4) { - fprintf(stderr, "write failed.\n"); -@@ -187,8 +194,9 @@ int main (int argc, char **argv) - char type = 0x83; - int ch; - int part = 0; -+ uint32_t signature = 0x5452574F; /* 'OWRT' */ - -- while ((ch = getopt(argc, argv, "h:s:p:a:t:o:vl:")) != -1) { -+ while ((ch = getopt(argc, argv, "h:s:p:a:t:o:vl:S:")) != -1) { - switch (ch) { - case 'o': - filename = optarg; -@@ -221,6 +229,9 @@ int main (int argc, char **argv) - case 'l': - kb_align = (int) strtoul(optarg, NULL, 0) * 2; - break; -+ case 'S': -+ signature = strtoul(optarg, NULL, 0); -+ break; - case '?': - default: - usage(argv[0]); -@@ -229,6 +240,6 @@ int main (int argc, char **argv) - argc -= optind; - if (argc || (heads <= 0) || (sectors <= 0) || !filename) - usage(argv[0]); -- -- return gen_ptable(part); -+ -+ return gen_ptable(signature, part); - } diff --git a/patches/openwrt/0026-x86-use-PARTUUID-instead-explicitly-specifying-the-device-by-default.patch b/patches/openwrt/0026-x86-use-PARTUUID-instead-explicitly-specifying-the-device-by-default.patch deleted file mode 100644 index a2e7e7d9..00000000 --- a/patches/openwrt/0026-x86-use-PARTUUID-instead-explicitly-specifying-the-device-by-default.patch +++ /dev/null @@ -1,180 +0,0 @@ -From: Matthias Schiffer -Date: Mon, 23 Mar 2015 21:11:41 +0100 -Subject: x86: use PARTUUID instead explicitly specifying the device by default - -This changes the x86 image generation to match x86_64, using the PARTUUID for -the rootfs instead of explicitly configuring the device. - -It unbreaks KVM with VirtIO, which uses /dev/vda2 instead of /dev/sda2. - -Tested in QEMU/KVM with VirtIO, VirtualBox and VMware. - -diff --git a/config/Config-images.in b/config/Config-images.in -index 39e51e4..f44ec73 100644 ---- a/config/Config-images.in -+++ b/config/Config-images.in -@@ -267,8 +267,6 @@ menu "Target Images" - config TARGET_ROOTFS_PARTNAME - string "Root partition on target device" - depends on OLPC_BOOTSCRIPT_IMAGES || GRUB_IMAGES -- default "/dev/xvda2" if TARGET_x86_xen_domu -- default "/dev/sda2" if ! TARGET_x86_xen_domu - help - The root partition on the final device. If you don't know, - you probably want the default (/dev/sda2). -diff --git a/target/linux/x86/base-files/lib/preinit/79_move_config b/target/linux/x86/base-files/lib/preinit/79_move_config -index 0bffbab..1d4873d 100644 ---- a/target/linux/x86/base-files/lib/preinit/79_move_config -+++ b/target/linux/x86/base-files/lib/preinit/79_move_config -@@ -1,21 +1,14 @@ - #!/bin/sh --# Copyright (C) 2012 OpenWrt.org -+# Copyright (C) 2012-2015 OpenWrt.org - - move_config() { -- local rootfsdev -- local rootfstype -- -- rootfstype="$(awk 'BEGIN { RS=" "; FS="="; } ($1 == "rootfstype") { print $2 }' < /proc/cmdline)" -- case "$rootfstype" in -- squashfs|jffs2) -- rootfsdev="$(awk 'BEGIN { RS=" "; FS="="; } ($1 == "block2mtd.block2mtd") { print substr($2,1,index($2, ",")-1) }' < /proc/cmdline)";; -- ext4) -- rootfsdev="$(awk 'BEGIN { RS=" "; FS="="; } ($1 == "root") { print $2 }' < /proc/cmdline)";; -- esac -+ . /lib/upgrade/platform.sh - -- mount -t ext4 -o rw,noatime "${rootfsdev%[0-9]}1" /mnt -- mv -f /mnt/sysupgrade.tgz / -- umount /mnt -+ if platform_export_bootpart; then -+ mount -t ext4 -o rw,noatime "$BOOTPART" /mnt -+ mv -f /mnt/sysupgrade.tgz / -+ umount /mnt -+ fi - } - - boot_hook_add preinit_mount_root move_config -diff --git a/target/linux/x86/base-files/lib/upgrade/platform.sh b/target/linux/x86/base-files/lib/upgrade/platform.sh -index a2dd20a..73ab5ef 100644 ---- a/target/linux/x86/base-files/lib/upgrade/platform.sh -+++ b/target/linux/x86/base-files/lib/upgrade/platform.sh -@@ -1,16 +1,38 @@ --x86_get_rootfs() { -- local rootfsdev -- local rootfstype -- -- rootfstype="$(awk 'BEGIN { RS=" "; FS="="; } ($1 == "rootfstype") { print $2 }' < /proc/cmdline)" -- case "$rootfstype" in -- squashfs|jffs2) -- rootfsdev="$(awk 'BEGIN { RS=" "; FS="="; } ($1 == "block2mtd.block2mtd") { print substr($2,1,index($2, ",")-1) }' < /proc/cmdline)";; -- ext4) -- rootfsdev="$(awk 'BEGIN { RS=" "; FS="="; } ($1 == "root") { print $2 }' < /proc/cmdline)";; -- esac -- -- echo "$rootfstype:$rootfsdev" -+platform_export_bootpart() { -+ local cmdline uuid disk -+ -+ if read cmdline < /proc/cmdline; then -+ case "$cmdline" in -+ *block2mtd=*) -+ disk="${cmdline##*block2mtd=}" -+ disk="${disk%%,*}" -+ ;; -+ *root=*) -+ disk="${cmdline##*root=}" -+ disk="${disk%% *}" -+ ;; -+ esac -+ -+ case "$disk" in -+ PARTUUID=[a-f0-9][a-f0-9][a-f0-9][a-f0-9][a-f0-9][a-f0-9][a-f0-9][a-f0-9]-02) -+ uuid="${disk#PARTUUID=}" -+ uuid="${uuid%-02}" -+ for disk in /dev/[hsv]d[a-z]; do -+ set -- $(dd if=$disk bs=1 skip=440 count=4 2>/dev/null | hexdump -v -e '4/1 "%02x "') -+ if [ "$4$3$2$1" = "$uuid" ]; then -+ export BOOTPART="${disk}1" -+ return 0 -+ fi -+ done -+ ;; -+ /dev/*) -+ export BOOTPART="${disk%[0-9]}1" -+ return 0 -+ ;; -+ esac -+ fi -+ -+ return 1 - } - - platform_check_image() { -@@ -26,19 +48,19 @@ platform_check_image() { - } - - platform_copy_config() { -- local rootfs="$(x86_get_rootfs)" -- local rootfsdev="${rootfs##*:}" -- -- mount -t ext4 -o rw,noatime "${rootfsdev%[0-9]}1" /mnt -- cp -af "$CONF_TAR" /mnt/ -- umount /mnt -+ if [ -b "$BOOTPART" ]; then -+ mount -t ext4 -o rw,noatime "$BOOTPART" /mnt -+ cp -af "$CONF_TAR" /mnt/ -+ umount /mnt -+ fi - } - - platform_do_upgrade() { -- local rootfs="$(x86_get_rootfs)" -- local rootfsdev="${rootfs##*:}" -+ platform_export_bootpart - -- sync -- [ -b ${rootfsdev%[0-9]} ] && get_image "$@" | dd of=${rootfsdev%[0-9]} bs=4096 conv=fsync -- sleep 1 -+ if [ -b "${BOOTPART%[0-9]}" ]; then -+ sync -+ get_image "$@" | dd of="${BOOTPART%[0-9]}" bs=4096 conv=fsync -+ sleep 1 -+ fi - } -diff --git a/target/linux/x86/image/Makefile b/target/linux/x86/image/Makefile -index 5983718..1f91b9f 100644 ---- a/target/linux/x86/image/Makefile -+++ b/target/linux/x86/image/Makefile -@@ -40,7 +40,9 @@ ifneq ($(GRUB_TERMINALS),) - GRUB_TERMINAL_CONFIG := terminal_input $(GRUB_TERMINALS); terminal_output $(GRUB_TERMINALS) - endif - -+SIGNATURE:=$(shell dd if=/dev/urandom bs=4 count=1 2>/dev/null | hexdump -v -e '"%08x"') - ROOTPART:=$(call qstrip,$(CONFIG_TARGET_ROOTFS_PARTNAME)) -+ROOTPART:=$(if $(ROOTPART),$(ROOTPART),PARTUUID=$(SIGNATURE)-02) - - GRUB_TIMEOUT:=$(call qstrip,$(CONFIG_GRUB_TIMEOUT)) - -@@ -82,7 +84,7 @@ ifneq ($(CONFIG_GRUB_IMAGES),) - -e 's#@CMDLINE@#$(strip $(call Image/cmdline/$(1)) $(BOOTOPTS) $(GRUB_CONSOLE_CMDLINE))#g' \ - -e 's#@TIMEOUT@#$(GRUB_TIMEOUT)#g' \ - ./grub.cfg > $(KDIR)/root.grub/boot/grub/grub.cfg -- PADDING="$(CONFIG_TARGET_IMAGES_PAD)" PATH="$(TARGET_PATH)" ./gen_image_generic.sh \ -+ PADDING="$(CONFIG_TARGET_IMAGES_PAD)" SIGNATURE="$(SIGNATURE)" PATH="$(TARGET_PATH)" ./gen_image_generic.sh \ - $(BIN_DIR)/$(IMG_PREFIX)-combined-$(1).img \ - $(CONFIG_TARGET_KERNEL_PARTSIZE) $(KDIR)/root.grub \ - $(CONFIG_TARGET_ROOTFS_PARTSIZE) $(KDIR)/root.$(1) \ -diff --git a/target/linux/x86/image/gen_image_generic.sh b/target/linux/x86/image/gen_image_generic.sh -index 9d11efb..3fb31f6 100755 ---- a/target/linux/x86/image/gen_image_generic.sh -+++ b/target/linux/x86/image/gen_image_generic.sh -@@ -20,7 +20,7 @@ sect=63 - cyl=$(( ($KERNELSIZE + $ROOTFSSIZE) * 1024 * 1024 / ($head * $sect * 512))) - - # create partition table --set `ptgen -o "$OUTPUT" -h $head -s $sect -p ${KERNELSIZE}m -p ${ROOTFSSIZE}m ${ALIGN:+-l $ALIGN}` -+set `ptgen -o "$OUTPUT" -h $head -s $sect -p ${KERNELSIZE}m -p ${ROOTFSSIZE}m ${ALIGN:+-l $ALIGN} ${SIGNATURE:+-S 0x$SIGNATURE}` - - KERNELOFFSET="$(($1 / 512))" - KERNELSIZE="$(($2 / 512))" diff --git a/patches/openwrt/0027-ar71xx-fix-model-string-detection-on-NETGEAR-WNDR3700-3800-WNDRMAC.patch b/patches/openwrt/0027-ar71xx-fix-model-string-detection-on-NETGEAR-WNDR3700-3800-WNDRMAC.patch deleted file mode 100644 index f4051a2d..00000000 --- a/patches/openwrt/0027-ar71xx-fix-model-string-detection-on-NETGEAR-WNDR3700-3800-WNDRMAC.patch +++ /dev/null @@ -1,65 +0,0 @@ -From: Matthias Schiffer -Date: Sun, 29 Mar 2015 13:23:26 +0200 -Subject: ar71xx: fix model string detection on NETGEAR WNDR3700/3800/WNDRMAC - -There were a few issues with the existing code to detect the model string: -* Always using the string starting with byte 56 would cut off the W of WNDR when - the ID starts with 29763654+16+64 instead of 29763654+16+128 -* The string contained garbage after the zero byte instead of cutting it off - after the zero (which wasn't always visible using busybox tools, but could - confuse other scripts) - -Tested on a WNDR3700v1 and a WNDR3700v2 using the new 29763654+16+64 ID in the -ART. Furthermore, tested against ART dumps of a WNDR3700v2 using the old -$'\xff...' value and a WNDR3800. - -The [ -z "$model" ] check was dropped as there is no way to actually hit this -unless no ART partition is found at all. - -The awk command was carefully crafted to work both with gawk and the (horribly -broken) busybox awk. - -Fixes #18992. - -Signed-off-by: Matthias Schiffer - -diff --git a/target/linux/ar71xx/base-files/lib/ar71xx.sh b/target/linux/ar71xx/base-files/lib/ar71xx.sh -index a698ce5..1838cb4 100755 ---- a/target/linux/ar71xx/base-files/lib/ar71xx.sh -+++ b/target/linux/ar71xx/base-files/lib/ar71xx.sh -@@ -37,16 +37,26 @@ wndr3700_board_detect() { - machine="NETGEAR WNDR3700" - ;; - "33373031") -- local model -- model=$(ar71xx_get_mtd_offset_size_format art 56 10 %c) -- if [ -z "$model" ] || [ "$model" = $'\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff' ]; then -- machine="NETGEAR WNDR3700v2" -- elif [ -z "$model" ] || [ "$model" = $'\xff\xff\xff\xff\xff\xff\xff\xff\xffN' ]; then -- machine="NETGEAR WNDRMAC" -- else -+ # Use awk to remove everything after the first zero byte -+ model="$(ar71xx_get_mtd_offset_size_format art 41 32 %c | awk 'BEGIN{FS="[[:cntrl:]]"} {print $1; exit}')" -+ case $model in -+ $'\xff'*) -+ if [ "${model:24:1}" = 'N' ]; then -+ machine="NETGEAR WNDRMAC" -+ else -+ machine="NETGEAR WNDR3700v2" -+ fi -+ ;; -+ '29763654+16+64'*) -+ machine="NETGEAR ${model:14}" -+ ;; -+ '29763654+16+128'*) -+ machine="NETGEAR ${model:15}" -+ ;; -+ *) -+ # Unknown ID - machine="NETGEAR $model" -- fi -- ;; -+ esac - esac - - AR71XX_BOARD_NAME="$name" diff --git a/patches/openwrt/0028-ar71xx-fix-TP-LINK-TL-WDR3600-4300-RFKILL-switch-positions.patch b/patches/openwrt/0028-ar71xx-fix-TP-LINK-TL-WDR3600-4300-RFKILL-switch-positions.patch deleted file mode 100644 index 6eb7100e..00000000 --- a/patches/openwrt/0028-ar71xx-fix-TP-LINK-TL-WDR3600-4300-RFKILL-switch-positions.patch +++ /dev/null @@ -1,22 +0,0 @@ -From: Matthias Schiffer -Date: Sun, 15 Mar 2015 21:03:25 +0100 -Subject: ar71xx: fix TP-LINK TL-WDR3600/4300 RFKILL switch positions - -While the switch positions aren't explicitly labeled as on and off, we've heard -complaints about them being wrong. This patch changes the handling to match the -stock firmware. - -Signed-off-by: Matthias Schiffer - -diff --git a/target/linux/ar71xx/files/arch/mips/ath79/mach-tl-wdr4300.c b/target/linux/ar71xx/files/arch/mips/ath79/mach-tl-wdr4300.c -index 99ae80d..3afc714 100644 ---- a/target/linux/ar71xx/files/arch/mips/ath79/mach-tl-wdr4300.c -+++ b/target/linux/ar71xx/files/arch/mips/ath79/mach-tl-wdr4300.c -@@ -103,6 +103,7 @@ static struct gpio_keys_button wdr4300_gpio_keys[] __initdata = { - .code = KEY_RFKILL, - .debounce_interval = WDR4300_KEYS_DEBOUNCE_INTERVAL, - .gpio = WDR4300_GPIO_BTN_RFKILL, -+ .active_low = 1, - }, - }; - diff --git a/patches/openwrt/0029-buildroot-make-it-easier-to-build-all-kmods.patch b/patches/openwrt/0029-buildroot-make-it-easier-to-build-all-kmods.patch deleted file mode 100644 index 3dfce311..00000000 --- a/patches/openwrt/0029-buildroot-make-it-easier-to-build-all-kmods.patch +++ /dev/null @@ -1,57 +0,0 @@ -From: Matthias Schiffer -Date: Mon, 16 Mar 2015 13:23:34 +0100 -Subject: buildroot: make it easier to build all kmods - -Split out kmods from ALL to make it easier to create local builds that -are compatible kmod-wise with releases. - -Signed-off-by: Jonas Gorski - -diff --git a/config/Config-build.in b/config/Config-build.in -index 371ae76..8b0ebbf 100644 ---- a/config/Config-build.in -+++ b/config/Config-build.in -@@ -6,8 +6,12 @@ - - menu "Global build settings" - -+ config ALL_KMODS -+ bool "Select all kernel module packages by default" -+ default ALL -+ - config ALL -- bool "Select all packages by default" -+ bool "Select all userspace packages by default" - default n - - comment "General build options" -diff --git a/include/version.mk b/include/version.mk -index 2fd605f..f6c0fe2 100644 ---- a/include/version.mk -+++ b/include/version.mk -@@ -50,7 +50,7 @@ $(lastword $(subst :, ,$(1))) - endef - - VERSION_TAINT_SPECS := \ -- -ALL:no-all \ -+ -ALL_KMODS:no-all \ - -IPV6:no-ipv6 \ - +USE_EGLIBC:eglibc \ - +USE_MKLIBS:mklibs \ -diff --git a/scripts/metadata.pl b/scripts/metadata.pl -index 79f930c..4eecb0c 100755 ---- a/scripts/metadata.pl -+++ b/scripts/metadata.pl -@@ -574,7 +574,11 @@ sub print_package_config_category($) { - print "\t\t".($pkg->{tristate} ? 'tristate' : 'bool')." $title\n"; - print "\t\tdefault y if DEFAULT_".$pkg->{name}."\n"; - unless ($pkg->{hidden}) { -- $pkg->{default} ||= "m if ALL"; -+ if ($pkg->{name} =~ /^kmod-/) { -+ $pkg->{default} ||= "m if ALL_KMODS"; -+ } else { -+ $pkg->{default} ||= "m if ALL"; -+ } - } - if ($pkg->{default}) { - foreach my $default (split /\s*,\s*/, $pkg->{default}) { diff --git a/patches/openwrt/0030-build-define-STAMP_CONFIGURED-recursively.patch b/patches/openwrt/0030-build-define-STAMP_CONFIGURED-recursively.patch deleted file mode 100644 index 5e68ad4c..00000000 --- a/patches/openwrt/0030-build-define-STAMP_CONFIGURED-recursively.patch +++ /dev/null @@ -1,26 +0,0 @@ -From: Matthias Schiffer -Date: Wed, 18 Mar 2015 20:07:22 +0100 -Subject: build: define STAMP_CONFIGURED recursively - -Defining STAMP_CONFIGURED statically caused it not to reflect changes to -PKG_CONFIG_DEPENDS made after including package.mk, like the additional options -added by feeds.mk for all packages. - -Furthermore, as STAMP_CONFIGURED_WILDCARD was already defined recursively, the -patsubst in its definition would never match, and in consequence, the stamps -were never removed. This caused packages not to be rebuilt when they should have -been. - -diff --git a/include/package.mk b/include/package.mk -index 53ca6de..402fb1a 100644 ---- a/include/package.mk -+++ b/include/package.mk -@@ -60,7 +60,7 @@ ifneq ($(PREV_STAMP_PREPARED),) - else - STAMP_PREPARED=$(PKG_BUILD_DIR)/.prepared$(if $(QUILT)$(DUMP),,_$(shell $(call find_md5,${CURDIR} $(PKG_FILE_DEPENDS),))$(call confvar,$(PKG_PREPARED_DEPENDS))) - endif --STAMP_CONFIGURED:=$(PKG_BUILD_DIR)/.configured$(if $(DUMP),,_$(call confvar,$(PKG_CONFIG_DEPENDS))) -+STAMP_CONFIGURED=$(PKG_BUILD_DIR)/.configured$(if $(DUMP),,_$(call confvar,$(PKG_CONFIG_DEPENDS))) - STAMP_CONFIGURED_WILDCARD=$(patsubst %_$(call confvar,$(PKG_CONFIG_DEPENDS)),%_*,$(STAMP_CONFIGURED)) - STAMP_BUILT:=$(PKG_BUILD_DIR)/.built - STAMP_INSTALLED:=$(STAGING_DIR)/stamp/.$(PKG_NAME)_installed diff --git a/patches/openwrt/0032-mpc85xx-move-newly-created-files-from-patch-files-to-files-directory.patch b/patches/openwrt/0032-mpc85xx-move-newly-created-files-from-patch-files-to-files-directory.patch deleted file mode 100644 index 656ffc27..00000000 --- a/patches/openwrt/0032-mpc85xx-move-newly-created-files-from-patch-files-to-files-directory.patch +++ /dev/null @@ -1,1111 +0,0 @@ -From: Matthias Schiffer -Date: Thu, 30 Apr 2015 03:21:01 +0200 -Subject: mpc85xx: move newly created files from patch files to files directory - -This will make these files much more maintainable. - -diff --git a/target/linux/mpc85xx/files/arch/powerpc/boot/cuboot-tl-wdr4900-v1.c b/target/linux/mpc85xx/files/arch/powerpc/boot/cuboot-tl-wdr4900-v1.c -new file mode 100644 -index 0000000..17459ef ---- /dev/null -+++ b/target/linux/mpc85xx/files/arch/powerpc/boot/cuboot-tl-wdr4900-v1.c -@@ -0,0 +1,168 @@ -+/* -+ * U-Boot compatibility wrapper for the TP-Link TL-WDR4900 v1 board -+ * -+ * Copyright (c) 2013 Gabor Juhos -+ * -+ * Based on: -+ * cuboot-85xx.c -+ * Author: Scott Wood -+ * Copyright (c) 2007 Freescale Semiconductor, Inc. -+ * -+ * simpleboot.c -+ * Authors: Scott Wood -+ * Grant Likely -+ * Copyright (c) 2007 Freescale Semiconductor, Inc. -+ * Copyright (c) 2008 Secret Lab Technologies Ltd. -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License version 2 as published -+ * by the Free Software Foundation. -+ */ -+ -+#include "ops.h" -+#include "types.h" -+#include "io.h" -+#include "stdio.h" -+#include -+ -+BSS_STACK(4*1024); -+ -+static unsigned long bus_freq; -+static unsigned long int_freq; -+static u64 mem_size; -+static unsigned char enetaddr[6]; -+ -+static void process_boot_dtb(void *boot_dtb) -+{ -+ const u32 *na, *ns, *reg, *val32; -+ const char *path; -+ u64 memsize64; -+ int node, size, i; -+ -+ /* Make sure FDT blob is sane */ -+ if (fdt_check_header(boot_dtb) != 0) -+ fatal("Invalid device tree blob\n"); -+ -+ /* Find the #address-cells and #size-cells properties */ -+ node = fdt_path_offset(boot_dtb, "/"); -+ if (node < 0) -+ fatal("Cannot find root node\n"); -+ na = fdt_getprop(boot_dtb, node, "#address-cells", &size); -+ if (!na || (size != 4)) -+ fatal("Cannot find #address-cells property"); -+ -+ ns = fdt_getprop(boot_dtb, node, "#size-cells", &size); -+ if (!ns || (size != 4)) -+ fatal("Cannot find #size-cells property"); -+ -+ /* Find the memory range */ -+ node = fdt_node_offset_by_prop_value(boot_dtb, -1, "device_type", -+ "memory", sizeof("memory")); -+ if (node < 0) -+ fatal("Cannot find memory node\n"); -+ reg = fdt_getprop(boot_dtb, node, "reg", &size); -+ if (size < (*na+*ns) * sizeof(u32)) -+ fatal("cannot get memory range\n"); -+ -+ /* Only interested in memory based at 0 */ -+ for (i = 0; i < *na; i++) -+ if (*reg++ != 0) -+ fatal("Memory range is not based at address 0\n"); -+ -+ /* get the memsize and trucate it to under 4G on 32 bit machines */ -+ memsize64 = 0; -+ for (i = 0; i < *ns; i++) -+ memsize64 = (memsize64 << 32) | *reg++; -+ if (sizeof(void *) == 4 && memsize64 >= 0x100000000ULL) -+ memsize64 = 0xffffffff; -+ -+ mem_size = memsize64; -+ -+ /* get clock frequencies */ -+ node = fdt_node_offset_by_prop_value(boot_dtb, -1, "device_type", -+ "cpu", sizeof("cpu")); -+ if (!node) -+ fatal("Cannot find cpu node\n"); -+ -+ val32 = fdt_getprop(boot_dtb, node, "clock-frequency", &size); -+ if (!val32 || (size != 4)) -+ fatal("Cannot get clock frequency"); -+ -+ int_freq = *val32; -+ -+ val32 = fdt_getprop(boot_dtb, node, "bus-frequency", &size); -+ if (!val32 || (size != 4)) -+ fatal("Cannot get bus frequency"); -+ -+ bus_freq = *val32; -+ -+ path = fdt_get_alias(boot_dtb, "ethernet0"); -+ if (path) { -+ const void *p; -+ -+ node = fdt_path_offset(boot_dtb, path); -+ if (node < 0) -+ fatal("Cannot find ethernet0 node"); -+ -+ p = fdt_getprop(boot_dtb, node, "mac-address", &size); -+ if (!p || (size < 6)) { -+ printf("no mac-address property, finding local\n\r"); -+ p = fdt_getprop(boot_dtb, node, "local-mac-address", &size); -+ } -+ -+ if (!p || (size < 6)) -+ fatal("cannot get MAC addres"); -+ -+ memcpy(enetaddr, p, sizeof(enetaddr)); -+ } -+} -+ -+static void platform_fixups(void) -+{ -+ void *soc, *mpic; -+ -+ dt_fixup_memory(0, mem_size); -+ -+ dt_fixup_mac_address_by_alias("ethernet0", enetaddr); -+ dt_fixup_cpu_clocks(int_freq, bus_freq / 8, bus_freq); -+ -+ /* Unfortunately, the specific model number is encoded in the -+ * soc node name in existing dts files -- once that is fixed, -+ * this can do a simple path lookup. -+ */ -+ soc = find_node_by_devtype(NULL, "soc"); -+ if (soc) { -+ void *serial = NULL; -+ -+ setprop(soc, "bus-frequency", &bus_freq, sizeof(bus_freq)); -+ -+ while ((serial = find_node_by_devtype(serial, "serial"))) { -+ if (get_parent(serial) != soc) -+ continue; -+ -+ setprop(serial, "clock-frequency", &bus_freq, -+ sizeof(bus_freq)); -+ } -+ } -+ -+ mpic = find_node_by_compatible(NULL, "fsl,mpic"); -+ if (mpic) -+ setprop(mpic, "clock-frequency", &bus_freq, sizeof(bus_freq)); -+} -+ -+void platform_init(unsigned long r3, unsigned long r4, unsigned long r5, -+ unsigned long r6, unsigned long r7) -+{ -+ mem_size = 64 * 1024 * 1024; -+ -+ simple_alloc_init(_end, mem_size - (u32)_end - 1024*1024, 32, 64); -+ -+ fdt_init(_dtb_start); -+ serial_console_init(); -+ -+ printf("\n\r-- TL-WDR4900 v1 boot wrapper --\n\r"); -+ -+ process_boot_dtb((void *) r3); -+ -+ platform_ops.fixups = platform_fixups; -+} -diff --git a/target/linux/mpc85xx/files/arch/powerpc/boot/dts/tl-wdr4900-v1.dts b/target/linux/mpc85xx/files/arch/powerpc/boot/dts/tl-wdr4900-v1.dts -new file mode 100644 -index 0000000..49e516c ---- /dev/null -+++ b/target/linux/mpc85xx/files/arch/powerpc/boot/dts/tl-wdr4900-v1.dts -@@ -0,0 +1,212 @@ -+/* -+ * TP-Link TL-WDR4900 v1 Device Tree Source -+ * -+ * Copyright 2013 Gabor Juhos -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License as published by the -+ * Free Software Foundation; either version 2 of the License, or (at your -+ * option) any later version. -+ */ -+ -+/include/ "fsl/p1010si-pre.dtsi" -+ -+/ { -+ model = "TP-Link TL-WDR4900 v1"; -+ compatible = "tp-link,TL-WDR4900v1"; -+ -+ chosen { -+ bootargs = "console=ttyS0,115200"; -+/* -+ linux,stdout-path = "/soc@ffe00000/serial@4500"; -+*/ -+ }; -+ -+ aliases { -+ spi0 = &spi0; -+ }; -+ -+ memory { -+ device_type = "memory"; -+ }; -+ -+ soc: soc@ffe00000 { -+ ranges = <0x0 0x0 0xffe00000 0x100000>; -+ -+ spi0: spi@7000 { -+ flash@0 { -+ #address-cells = <1>; -+ #size-cells = <1>; -+ compatible = "spansion,s25fl129p1"; -+ reg = <0>; -+ spi-max-frequency = <25000000>; -+ -+ u-boot@0 { -+ reg = <0x0 0x0050000>; -+ label = "u-boot"; -+ read-only; -+ }; -+ -+ dtb@50000 { -+ reg = <0x00050000 0x00010000>; -+ label = "dtb"; -+ read-only; -+ }; -+ -+ kernel@60000 { -+ reg = <0x00060000 0x002a0000>; -+ label = "kernel"; -+ }; -+ -+ rootfs@300000 { -+ reg = <0x00300000 0x00ce0000>; -+ label = "rootfs"; -+ }; -+ -+ config@fe0000 { -+ reg = <0x00fe0000 0x00010000>; -+ label = "config"; -+ read-only; -+ }; -+ -+ caldata@ff0000 { -+ reg = <0x00ff0000 0x00010000>; -+ label = "caldata"; -+ read-only; -+ }; -+ -+ firmware@60000 { -+ reg = <0x00060000 0x00f80000>; -+ label = "firmware"; -+ }; -+ }; -+ }; -+ -+ gpio0: gpio-controller@f000 { -+ }; -+ -+ usb@22000 { -+ phy_type = "utmi"; -+ dr_mode = "host"; -+ }; -+ -+ mdio@24000 { -+ phy0: ethernet-phy@0 { -+ reg = <0x0>; -+ qca,ar8327-initvals = < -+ 0x00004 0x07600000 /* PAD0_MODE */ -+ 0x00008 0x00000000 /* PAD5_MODE */ -+ 0x0000c 0x01000000 /* PAD6_MODE */ -+ 0x00010 0x40000000 /* POWER_ON_STRIP */ -+ 0x00050 0xcf35cf35 /* LED_CTRL0 */ -+ 0x00054 0xcf35cf35 /* LED_CTRL1 */ -+ 0x00058 0xcf35cf35 /* LED_CTRL2 */ -+ 0x0005c 0x03ffff00 /* LED_CTRL3 */ -+ 0x0007c 0x0000007e /* PORT0_STATUS */ -+ >; -+ }; -+ }; -+ -+ mdio@25000 { -+ status = "disabled"; -+ }; -+ -+ mdio@26000 { -+ status = "disabled"; -+ }; -+ -+ enet0: ethernet@b0000 { -+ phy-handle = <&phy0>; -+ phy-connection-type = "rgmii-id"; -+ }; -+ -+ enet1: ethernet@b1000 { -+ status = "disabled"; -+ }; -+ -+ enet2: ethernet@b2000 { -+ status = "disabled"; -+ }; -+ -+ sdhc@2e000 { -+ status = "disabled"; -+ }; -+ -+ serial1: serial@4600 { -+ status = "disabled"; -+ }; -+ -+ can0: can@1c000 { -+ status = "disabled"; -+ }; -+ -+ can1: can@1d000 { -+ status = "disabled"; -+ }; -+ }; -+ -+ pci0: pcie@ffe09000 { -+ reg = <0 0xffe09000 0 0x1000>; -+ ranges = <0x2000000 0x0 0xa0000000 0 0xa0000000 0x0 0x20000000 -+ 0x1000000 0x0 0x00000000 0 0xffc10000 0x0 0x10000>; -+ pcie@0 { -+ ranges = <0x2000000 0x0 0xa0000000 -+ 0x2000000 0x0 0xa0000000 -+ 0x0 0x20000000 -+ -+ 0x1000000 0x0 0x0 -+ 0x1000000 0x0 0x0 -+ 0x0 0x100000>; -+ }; -+ }; -+ -+ pci1: pcie@ffe0a000 { -+ reg = <0 0xffe0a000 0 0x1000>; -+ ranges = <0x2000000 0x0 0x80000000 0 0x80000000 0x0 0x20000000 -+ 0x1000000 0x0 0x00000000 0 0xffc00000 0x0 0x10000>; -+ pcie@0 { -+ ranges = <0x2000000 0x0 0x80000000 -+ 0x2000000 0x0 0x80000000 -+ 0x0 0x20000000 -+ -+ 0x1000000 0x0 0x0 -+ 0x1000000 0x0 0x0 -+ 0x0 0x100000>; -+ }; -+ }; -+ -+ ifc: ifc@ffe1e000 { -+ status = "disabled"; -+ }; -+ -+ leds { -+ compatible = "gpio-leds"; -+ -+ system { -+ gpios = <&gpio0 2 1>; /* active low */ -+ label = "tp-link:blue:system"; -+ }; -+ -+ usb1 { -+ gpios = <&gpio0 3 1>; /* active low */ -+ label = "tp-link:green:usb1"; -+ }; -+ -+ usb2 { -+ gpios = <&gpio0 4 1>; /* active low */ -+ label = "tp-link:green:usb2"; -+ }; -+ }; -+ -+ buttons { -+ compatible = "gpio-keys"; -+ -+ reset { -+ label = "Reset button"; -+ gpios = <&gpio0 5 1>; /* active low */ -+ linux,code = <0x198>; /* KEY_RESTART */ -+ }; -+ }; -+}; -+ -+/include/ "fsl/p1010si-post.dtsi" -diff --git a/target/linux/mpc85xx/files/arch/powerpc/platforms/85xx/tl_wdr4900_v1.c b/target/linux/mpc85xx/files/arch/powerpc/platforms/85xx/tl_wdr4900_v1.c -new file mode 100644 -index 0000000..95afa4d ---- /dev/null -+++ b/target/linux/mpc85xx/files/arch/powerpc/platforms/85xx/tl_wdr4900_v1.c -@@ -0,0 +1,145 @@ -+/* -+ * TL-WDR4900 v1 board setup -+ * -+ * Copyright (c) 2013 Gabor Juhos -+ * -+ * Based on: -+ * p1010rdb.c: -+ * P1010RDB Board Setup -+ * Copyright 2011 Freescale Semiconductor Inc. -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License as published by the -+ * Free Software Foundation; either version 2 of the License, or (at your -+ * option) any later version. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+ -+#include "mpc85xx.h" -+ -+void __init tl_wdr4900_v1_pic_init(void) -+{ -+ struct mpic *mpic = mpic_alloc(NULL, 0, MPIC_BIG_ENDIAN | -+ MPIC_SINGLE_DEST_CPU, -+ 0, 256, " OpenPIC "); -+ -+ BUG_ON(mpic == NULL); -+ -+ mpic_init(mpic); -+} -+ -+#ifdef CONFIG_PCI -+static struct gpio_led tl_wdr4900_v1_wmac_leds_gpio[] = { -+ { -+ .name = "tp-link:blue:wps", -+ .gpio = 1, -+ .active_low = 1, -+ }, -+}; -+ -+static struct ath9k_platform_data tl_wdr4900_v1_wmac0_data = { -+ .led_pin = 0, -+ .eeprom_name = "pci_wmac0.eeprom", -+ .leds = tl_wdr4900_v1_wmac_leds_gpio, -+ .num_leds = ARRAY_SIZE(tl_wdr4900_v1_wmac_leds_gpio), -+}; -+ -+static struct ath9k_platform_data tl_wdr4900_v1_wmac1_data = { -+ .led_pin = 0, -+ .eeprom_name = "pci_wmac1.eeprom", -+}; -+ -+static void tl_wdr4900_v1_pci_wmac_fixup(struct pci_dev *dev) -+{ -+ if (!machine_is(tl_wdr4900_v1)) -+ return; -+ -+ if (dev->bus->number == 1 && -+ PCI_SLOT(dev->devfn) == 0) { -+ dev->dev.platform_data = &tl_wdr4900_v1_wmac0_data; -+ return; -+ } -+ -+ if (dev->bus->number == 3 && -+ PCI_SLOT(dev->devfn) == 0 && -+ dev->device == 0xabcd) { -+ dev->dev.platform_data = &tl_wdr4900_v1_wmac1_data; -+ -+ /* -+ * The PCI header of the AR9381 chip is not programmed -+ * correctly by the bootloader and the device uses wrong -+ * data due to that. Replace the broken values with the -+ * correct ones. -+ */ -+ dev->device = 0x30; -+ dev->class = 0x028000; -+ -+ pr_info("pci %s: AR9381 fixup applied\n", pci_name(dev)); -+ } -+} -+ -+DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_ATHEROS, PCI_ANY_ID, -+ tl_wdr4900_v1_pci_wmac_fixup); -+#endif /* CONFIG_PCI */ -+ -+/* -+ * Setup the architecture -+ */ -+static void __init tl_wdr4900_v1_setup_arch(void) -+{ -+ if (ppc_md.progress) -+ ppc_md.progress("tl_wdr4900_v1_setup_arch()", 0); -+ -+ fsl_pci_assign_primary(); -+ -+ printk(KERN_INFO "TL-WDR4900 v1 board from TP-Link\n"); -+} -+ -+machine_arch_initcall(tl_wdr4900_v1, mpc85xx_common_publish_devices); -+machine_arch_initcall(tl_wdr4900_v1, swiotlb_setup_bus_notifier); -+ -+/* -+ * Called very early, device-tree isn't unflattened -+ */ -+static int __init tl_wdr4900_v1_probe(void) -+{ -+ unsigned long root = of_get_flat_dt_root(); -+ -+ if (of_flat_dt_is_compatible(root, "tp-link,TL-WDR4900v1")) -+ return 1; -+ -+ return 0; -+} -+ -+define_machine(tl_wdr4900_v1) { -+ .name = "Freescale P1014", -+ .probe = tl_wdr4900_v1_probe, -+ .setup_arch = tl_wdr4900_v1_setup_arch, -+ .init_IRQ = tl_wdr4900_v1_pic_init, -+#ifdef CONFIG_PCI -+ .pcibios_fixup_bus = fsl_pcibios_fixup_bus, -+#endif -+ .get_irq = mpic_get_irq, -+ .restart = fsl_rstcr_restart, -+ .calibrate_decr = generic_calibrate_decr, -+ .progress = udbg_progress, -+}; -diff --git a/target/linux/mpc85xx/patches-3.10/140-powerpc-85xx-tl-wdr4900-v1-support.patch b/target/linux/mpc85xx/patches-3.10/140-powerpc-85xx-tl-wdr4900-v1-support.patch -index 8407176..dae2305 100644 ---- a/target/linux/mpc85xx/patches-3.10/140-powerpc-85xx-tl-wdr4900-v1-support.patch -+++ b/target/linux/mpc85xx/patches-3.10/140-powerpc-85xx-tl-wdr4900-v1-support.patch -@@ -11,16 +11,9 @@ the Freescale P1014 SoC. - Signed-off-by: Gabor Juhos - --- - arch/powerpc/boot/Makefile | 3 + -- arch/powerpc/boot/cuboot-tl-wdr4900-v1.c | 164 ++++++++++++++++++++++++++ -- arch/powerpc/boot/dts/tl-wdr4900-v1.dts | 166 +++++++++++++++++++++++++++ - arch/powerpc/boot/wrapper | 4 + - arch/powerpc/platforms/85xx/Kconfig | 11 ++ - arch/powerpc/platforms/85xx/Makefile | 1 + -- arch/powerpc/platforms/85xx/tl_wdr4900_v1.c | 145 +++++++++++++++++++++++ -- 7 files changed, 494 insertions(+) -- create mode 100644 arch/powerpc/boot/cuboot-tl-wdr4900-v1.c -- create mode 100644 arch/powerpc/boot/dts/tl-wdr4900-v1.dts -- create mode 100644 arch/powerpc/platforms/85xx/tl_wdr4900_v1.c - - --- a/arch/powerpc/boot/Makefile - +++ b/arch/powerpc/boot/Makefile -@@ -41,388 +34,6 @@ Signed-off-by: Gabor Juhos - - # Board ports in arch/powerpc/platform/embedded6xx/Kconfig - image-$(CONFIG_STORCENTER) += cuImage.storcenter ----- /dev/null --+++ b/arch/powerpc/boot/cuboot-tl-wdr4900-v1.c --@@ -0,0 +1,164 @@ --+/* --+ * U-Boot compatibility wrapper for the TP-Link TL-WDR4900 v1 board --+ * --+ * Copyright (c) 2013 Gabor Juhos --+ * --+ * Based on: --+ * cuboot-85xx.c --+ * Author: Scott Wood --+ * Copyright (c) 2007 Freescale Semiconductor, Inc. --+ * --+ * simpleboot.c --+ * Authors: Scott Wood --+ * Grant Likely --+ * Copyright (c) 2007 Freescale Semiconductor, Inc. --+ * Copyright (c) 2008 Secret Lab Technologies Ltd. --+ * --+ * This program is free software; you can redistribute it and/or modify it --+ * under the terms of the GNU General Public License version 2 as published --+ * by the Free Software Foundation. --+ */ --+ --+#include "ops.h" --+#include "types.h" --+#include "io.h" --+#include "stdio.h" --+#include --+ --+BSS_STACK(4*1024); --+ --+static unsigned long bus_freq; --+static unsigned long int_freq; --+static u64 mem_size; --+static unsigned char enetaddr[6]; --+ --+static void process_boot_dtb(void *boot_dtb) --+{ --+ const u32 *na, *ns, *reg, *val32; --+ const char *path; --+ u64 memsize64; --+ int node, size, i; --+ --+ /* Make sure FDT blob is sane */ --+ if (fdt_check_header(boot_dtb) != 0) --+ fatal("Invalid device tree blob\n"); --+ --+ /* Find the #address-cells and #size-cells properties */ --+ node = fdt_path_offset(boot_dtb, "/"); --+ if (node < 0) --+ fatal("Cannot find root node\n"); --+ na = fdt_getprop(boot_dtb, node, "#address-cells", &size); --+ if (!na || (size != 4)) --+ fatal("Cannot find #address-cells property"); --+ --+ ns = fdt_getprop(boot_dtb, node, "#size-cells", &size); --+ if (!ns || (size != 4)) --+ fatal("Cannot find #size-cells property"); --+ --+ /* Find the memory range */ --+ node = fdt_node_offset_by_prop_value(boot_dtb, -1, "device_type", --+ "memory", sizeof("memory")); --+ if (node < 0) --+ fatal("Cannot find memory node\n"); --+ reg = fdt_getprop(boot_dtb, node, "reg", &size); --+ if (size < (*na+*ns) * sizeof(u32)) --+ fatal("cannot get memory range\n"); --+ --+ /* Only interested in memory based at 0 */ --+ for (i = 0; i < *na; i++) --+ if (*reg++ != 0) --+ fatal("Memory range is not based at address 0\n"); --+ --+ /* get the memsize and trucate it to under 4G on 32 bit machines */ --+ memsize64 = 0; --+ for (i = 0; i < *ns; i++) --+ memsize64 = (memsize64 << 32) | *reg++; --+ if (sizeof(void *) == 4 && memsize64 >= 0x100000000ULL) --+ memsize64 = 0xffffffff; --+ --+ mem_size = memsize64; --+ --+ /* get clock frequencies */ --+ node = fdt_node_offset_by_prop_value(boot_dtb, -1, "device_type", --+ "cpu", sizeof("cpu")); --+ if (!node) --+ fatal("Cannot find cpu node\n"); --+ --+ val32 = fdt_getprop(boot_dtb, node, "clock-frequency", &size); --+ if (!val32 || (size != 4)) --+ fatal("Cannot get clock frequency"); --+ --+ int_freq = *val32; --+ --+ val32 = fdt_getprop(boot_dtb, node, "bus-frequency", &size); --+ if (!val32 || (size != 4)) --+ fatal("Cannot get bus frequency"); --+ --+ bus_freq = *val32; --+ --+ path = fdt_get_alias(boot_dtb, "ethernet0"); --+ if (path) { --+ const void *p; --+ --+ node = fdt_path_offset(boot_dtb, path); --+ if (node < 0) --+ fatal("Cannot find ethernet0 node"); --+ --+ p = fdt_getprop(boot_dtb, node, "mac-address", &size); --+ if (!p || (size < 6)) { --+ printf("no mac-address property, finding local\n\r"); --+ p = fdt_getprop(boot_dtb, node, "local-mac-address", &size); --+ } --+ --+ if (!p || (size < 6)) --+ fatal("cannot get MAC addres"); --+ --+ memcpy(enetaddr, p, sizeof(enetaddr)); --+ } --+} --+ --+static void platform_fixups(void) --+{ --+ void *soc; --+ --+ dt_fixup_memory(0, mem_size); --+ --+ dt_fixup_mac_address_by_alias("ethernet0", enetaddr); --+ dt_fixup_cpu_clocks(int_freq, bus_freq / 8, bus_freq); --+ --+ /* Unfortunately, the specific model number is encoded in the --+ * soc node name in existing dts files -- once that is fixed, --+ * this can do a simple path lookup. --+ */ --+ soc = find_node_by_devtype(NULL, "soc"); --+ if (soc) { --+ void *serial = NULL; --+ --+ setprop(soc, "bus-frequency", &bus_freq, sizeof(bus_freq)); --+ --+ while ((serial = find_node_by_devtype(serial, "serial"))) { --+ if (get_parent(serial) != soc) --+ continue; --+ --+ setprop(serial, "clock-frequency", &bus_freq, --+ sizeof(bus_freq)); --+ } --+ } --+} --+ --+void platform_init(unsigned long r3, unsigned long r4, unsigned long r5, --+ unsigned long r6, unsigned long r7) --+{ --+ mem_size = 64 * 1024 * 1024; --+ --+ simple_alloc_init(_end, mem_size - (u32)_end - 1024*1024, 32, 64); --+ --+ fdt_init(_dtb_start); --+ serial_console_init(); --+ --+ printf("\n\r-- TL-WDR4900 v1 boot wrapper --\n\r"); --+ --+ process_boot_dtb((void *) r3); --+ --+ platform_ops.fixups = platform_fixups; --+} ----- /dev/null --+++ b/arch/powerpc/boot/dts/tl-wdr4900-v1.dts --@@ -0,0 +1,212 @@ --+/* --+ * TP-Link TL-WDR4900 v1 Device Tree Source --+ * --+ * Copyright 2013 Gabor Juhos --+ * --+ * This program is free software; you can redistribute it and/or modify it --+ * under the terms of the GNU General Public License as published by the --+ * Free Software Foundation; either version 2 of the License, or (at your --+ * option) any later version. --+ */ --+ --+/include/ "fsl/p1010si-pre.dtsi" --+ --+/ { --+ model = "TP-Link TL-WDR4900 v1"; --+ compatible = "tp-link,TL-WDR4900v1"; --+ --+ chosen { --+ bootargs = "console=ttyS0,115200"; --+/* --+ linux,stdout-path = "/soc@ffe00000/serial@4500"; --+*/ --+ }; --+ --+ aliases { --+ spi0 = &spi0; --+ }; --+ --+ memory { --+ device_type = "memory"; --+ }; --+ --+ soc: soc@ffe00000 { --+ ranges = <0x0 0x0 0xffe00000 0x100000>; --+ --+ spi0: spi@7000 { --+ flash@0 { --+ #address-cells = <1>; --+ #size-cells = <1>; --+ compatible = "spansion,s25fl129p1"; --+ reg = <0>; --+ spi-max-frequency = <25000000>; --+ --+ u-boot@0 { --+ reg = <0x0 0x0050000>; --+ label = "u-boot"; --+ read-only; --+ }; --+ --+ dtb@50000 { --+ reg = <0x00050000 0x00010000>; --+ label = "dtb"; --+ read-only; --+ }; --+ --+ kernel@60000 { --+ reg = <0x00060000 0x002a0000>; --+ label = "kernel"; --+ }; --+ --+ rootfs@300000 { --+ reg = <0x00300000 0x00ce0000>; --+ label = "rootfs"; --+ }; --+ --+ config@fe0000 { --+ reg = <0x00fe0000 0x00010000>; --+ label = "config"; --+ read-only; --+ }; --+ --+ caldata@ff0000 { --+ reg = <0x00ff0000 0x00010000>; --+ label = "caldata"; --+ read-only; --+ }; --+ --+ firmware@60000 { --+ reg = <0x00060000 0x00f80000>; --+ label = "firmware"; --+ }; --+ }; --+ }; --+ --+ gpio0: gpio-controller@f000 { --+ }; --+ --+ usb@22000 { --+ phy_type = "utmi"; --+ dr_mode = "host"; --+ }; --+ --+ mdio@24000 { --+ phy0: ethernet-phy@0 { --+ reg = <0x0>; --+ qca,ar8327-initvals = < --+ 0x00004 0x07600000 /* PAD0_MODE */ --+ 0x00008 0x00000000 /* PAD5_MODE */ --+ 0x0000c 0x01000000 /* PAD6_MODE */ --+ 0x00010 0x40000000 /* POWER_ON_STRIP */ --+ 0x00050 0xcf35cf35 /* LED_CTRL0 */ --+ 0x00054 0xcf35cf35 /* LED_CTRL1 */ --+ 0x00058 0xcf35cf35 /* LED_CTRL2 */ --+ 0x0005c 0x03ffff00 /* LED_CTRL3 */ --+ 0x0007c 0x0000007e /* PORT0_STATUS */ --+ >; --+ }; --+ }; --+ --+ mdio@25000 { --+ status = "disabled"; --+ }; --+ --+ mdio@26000 { --+ status = "disabled"; --+ }; --+ --+ enet0: ethernet@b0000 { --+ phy-handle = <&phy0>; --+ phy-connection-type = "rgmii-id"; --+ }; --+ --+ enet1: ethernet@b1000 { --+ status = "disabled"; --+ }; --+ --+ enet2: ethernet@b2000 { --+ status = "disabled"; --+ }; --+ --+ sdhc@2e000 { --+ status = "disabled"; --+ }; --+ --+ serial1: serial@4600 { --+ status = "disabled"; --+ }; --+ --+ can0: can@1c000 { --+ status = "disabled"; --+ }; --+ --+ can1: can@1d000 { --+ status = "disabled"; --+ }; --+ }; --+ --+ pci0: pcie@ffe09000 { --+ reg = <0 0xffe09000 0 0x1000>; --+ ranges = <0x2000000 0x0 0xa0000000 0 0xa0000000 0x0 0x20000000 --+ 0x1000000 0x0 0x00000000 0 0xffc10000 0x0 0x10000>; --+ pcie@0 { --+ ranges = <0x2000000 0x0 0xa0000000 --+ 0x2000000 0x0 0xa0000000 --+ 0x0 0x20000000 --+ --+ 0x1000000 0x0 0x0 --+ 0x1000000 0x0 0x0 --+ 0x0 0x100000>; --+ }; --+ }; --+ --+ pci1: pcie@ffe0a000 { --+ reg = <0 0xffe0a000 0 0x1000>; --+ ranges = <0x2000000 0x0 0x80000000 0 0x80000000 0x0 0x20000000 --+ 0x1000000 0x0 0x00000000 0 0xffc00000 0x0 0x10000>; --+ pcie@0 { --+ ranges = <0x2000000 0x0 0x80000000 --+ 0x2000000 0x0 0x80000000 --+ 0x0 0x20000000 --+ --+ 0x1000000 0x0 0x0 --+ 0x1000000 0x0 0x0 --+ 0x0 0x100000>; --+ }; --+ }; --+ --+ ifc: ifc@ffe1e000 { --+ status = "disabled"; --+ }; --+ --+ leds { --+ compatible = "gpio-leds"; --+ --+ system { --+ gpios = <&gpio0 2 1>; /* active low */ --+ label = "tp-link:blue:system"; --+ }; --+ --+ usb1 { --+ gpios = <&gpio0 3 1>; /* active low */ --+ label = "tp-link:green:usb1"; --+ }; --+ --+ usb2 { --+ gpios = <&gpio0 4 1>; /* active low */ --+ label = "tp-link:green:usb2"; --+ }; --+ }; --+ --+ buttons { --+ compatible = "gpio-keys"; --+ --+ reset { --+ label = "Reset button"; --+ gpios = <&gpio0 5 1>; /* active low */ --+ linux,code = <0x198>; /* KEY_RESTART */ --+ }; --+ }; --+}; --+ --+/include/ "fsl/p1010si-post.dtsi" - --- a/arch/powerpc/boot/wrapper - +++ b/arch/powerpc/boot/wrapper - @@ -197,6 +197,10 @@ cuboot*) -@@ -466,151 +77,3 @@ Signed-off-by: Gabor Juhos - obj-$(CONFIG_SBC8548) += sbc8548.o - obj-$(CONFIG_PPA8548) += ppa8548.o - obj-$(CONFIG_SOCRATES) += socrates.o socrates_fpga_pic.o ----- /dev/null --+++ b/arch/powerpc/platforms/85xx/tl_wdr4900_v1.c --@@ -0,0 +1,145 @@ --+/* --+ * TL-WDR4900 v1 board setup --+ * --+ * Copyright (c) 2013 Gabor Juhos --+ * --+ * Based on: --+ * p1010rdb.c: --+ * P1010RDB Board Setup --+ * Copyright 2011 Freescale Semiconductor Inc. --+ * --+ * This program is free software; you can redistribute it and/or modify it --+ * under the terms of the GNU General Public License as published by the --+ * Free Software Foundation; either version 2 of the License, or (at your --+ * option) any later version. --+ */ --+ --+#include --+#include --+#include --+#include --+#include --+#include --+#include --+#include --+ --+#include --+#include --+#include --+#include --+#include --+#include --+#include --+ --+#include --+#include --+ --+#include "mpc85xx.h" --+ --+void __init tl_wdr4900_v1_pic_init(void) --+{ --+ struct mpic *mpic = mpic_alloc(NULL, 0, MPIC_BIG_ENDIAN | --+ MPIC_SINGLE_DEST_CPU, --+ 0, 256, " OpenPIC "); --+ --+ BUG_ON(mpic == NULL); --+ --+ mpic_init(mpic); --+} --+ --+#ifdef CONFIG_PCI --+static struct gpio_led tl_wdr4900_v1_wmac_leds_gpio[] = { --+ { --+ .name = "tp-link:blue:wps", --+ .gpio = 1, --+ .active_low = 1, --+ }, --+}; --+ --+static struct ath9k_platform_data tl_wdr4900_v1_wmac0_data = { --+ .led_pin = 0, --+ .eeprom_name = "pci_wmac0.eeprom", --+ .leds = tl_wdr4900_v1_wmac_leds_gpio, --+ .num_leds = ARRAY_SIZE(tl_wdr4900_v1_wmac_leds_gpio), --+}; --+ --+static struct ath9k_platform_data tl_wdr4900_v1_wmac1_data = { --+ .led_pin = 0, --+ .eeprom_name = "pci_wmac1.eeprom", --+}; --+ --+static void tl_wdr4900_v1_pci_wmac_fixup(struct pci_dev *dev) --+{ --+ if (!machine_is(tl_wdr4900_v1)) --+ return; --+ --+ if (dev->bus->number == 1 && --+ PCI_SLOT(dev->devfn) == 0) { --+ dev->dev.platform_data = &tl_wdr4900_v1_wmac0_data; --+ return; --+ } --+ --+ if (dev->bus->number == 3 && --+ PCI_SLOT(dev->devfn) == 0 && --+ dev->device == 0xabcd) { --+ dev->dev.platform_data = &tl_wdr4900_v1_wmac1_data; --+ --+ /* --+ * The PCI header of the AR9381 chip is not programmed --+ * correctly by the bootloader and the device uses wrong --+ * data due to that. Replace the broken values with the --+ * correct ones. --+ */ --+ dev->device = 0x30; --+ dev->class = 0x028000; --+ --+ pr_info("pci %s: AR9381 fixup applied\n", pci_name(dev)); --+ } --+} --+ --+DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_ATHEROS, PCI_ANY_ID, --+ tl_wdr4900_v1_pci_wmac_fixup); --+#endif /* CONFIG_PCI */ --+ --+/* --+ * Setup the architecture --+ */ --+static void __init tl_wdr4900_v1_setup_arch(void) --+{ --+ if (ppc_md.progress) --+ ppc_md.progress("tl_wdr4900_v1_setup_arch()", 0); --+ --+ fsl_pci_assign_primary(); --+ --+ printk(KERN_INFO "TL-WDR4900 v1 board from TP-Link\n"); --+} --+ --+machine_arch_initcall(tl_wdr4900_v1, mpc85xx_common_publish_devices); --+machine_arch_initcall(tl_wdr4900_v1, swiotlb_setup_bus_notifier); --+ --+/* --+ * Called very early, device-tree isn't unflattened --+ */ --+static int __init tl_wdr4900_v1_probe(void) --+{ --+ unsigned long root = of_get_flat_dt_root(); --+ --+ if (of_flat_dt_is_compatible(root, "tp-link,TL-WDR4900v1")) --+ return 1; --+ --+ return 0; --+} --+ --+define_machine(tl_wdr4900_v1) { --+ .name = "Freescale P1014", --+ .probe = tl_wdr4900_v1_probe, --+ .setup_arch = tl_wdr4900_v1_setup_arch, --+ .init_IRQ = tl_wdr4900_v1_pic_init, --+#ifdef CONFIG_PCI --+ .pcibios_fixup_bus = fsl_pcibios_fixup_bus, --+#endif --+ .get_irq = mpic_get_irq, --+ .restart = fsl_rstcr_restart, --+ .calibrate_decr = generic_calibrate_decr, --+ .progress = udbg_progress, --+}; diff --git a/patches/openwrt/0033-mpc85xx-gianfar-add-add-mtd-mac-address-support.patch b/patches/openwrt/0033-mpc85xx-gianfar-add-add-mtd-mac-address-support.patch deleted file mode 100644 index 461e7479..00000000 --- a/patches/openwrt/0033-mpc85xx-gianfar-add-add-mtd-mac-address-support.patch +++ /dev/null @@ -1,168 +0,0 @@ -From: Matthias Schiffer -Date: Thu, 30 Apr 2015 02:10:54 +0200 -Subject: mpc85xx: gianfar: add add mtd-mac-address support - -diff --git a/target/linux/mpc85xx/patches-3.10/101-NET-add-of_get_mac_address_mtd.patch b/target/linux/mpc85xx/patches-3.10/101-NET-add-of_get_mac_address_mtd.patch -new file mode 100644 -index 0000000..cd88d2b ---- /dev/null -+++ b/target/linux/mpc85xx/patches-3.10/101-NET-add-of_get_mac_address_mtd.patch -@@ -0,0 +1,76 @@ -+From 92f38460229a8816404408f036f0a374f1013d0e Mon Sep 17 00:00:00 2001 -+From: John Crispin -+Date: Sun, 27 Jul 2014 09:40:01 +0100 -+Subject: NET: add of_get_mac_address_mtd() -+ -+Many embedded devices have information such as mac addresses stored inside mtd -+devices. This patch allows us to add a property inside a node describing a -+network interface. The new property points at a mtd partition with an offset -+where the mac address can be found. -+ -+Signed-off-by: John Crispin -+--- -+ drivers/of/of_net.c | 37 +++++++++++++++++++++++++++++++++++++ -+ include/linux/of_net.h | 1 + -+ 2 files changed, 38 insertions(+) -+ -+--- a/drivers/of/of_net.c -++++ b/drivers/of/of_net.c -+@@ -10,6 +10,7 @@ -+ #include -+ #include -+ #include -++#include -+ -+ /** -+ * It maps 'enum phy_interface_t' found in include/linux/phy.h -+@@ -92,3 +93,39 @@ const void *of_get_mac_address(struct de -+ return NULL; -+ } -+ EXPORT_SYMBOL(of_get_mac_address); -++ -++int of_get_mac_address_mtd(struct device_node *np, void *mac) -++{ -++ struct device_node *mtd_np = NULL; -++ size_t retlen; -++ int size, ret; -++ struct mtd_info *mtd; -++ const char *part; -++ const __be32 *list; -++ phandle phandle; -++ -++ list = of_get_property(np, "mtd-mac-address", &size); -++ if (!list || (size != (2 * sizeof(*list)))) -++ return -ENOENT; -++ -++ phandle = be32_to_cpup(list++); -++ if (phandle) -++ mtd_np = of_find_node_by_phandle(phandle); -++ -++ if (!mtd_np) -++ return -ENOENT; -++ -++ part = of_get_property(mtd_np, "label", NULL); -++ if (!part) -++ part = mtd_np->name; -++ -++ mtd = get_mtd_device_nm(part); -++ if (IS_ERR(mtd)) -++ return PTR_ERR(mtd); -++ -++ ret = mtd_read(mtd, be32_to_cpup(list), 6, &retlen, (u_char *) mac); -++ put_mtd_device(mtd); -++ -++ return ret; -++} -++EXPORT_SYMBOL_GPL(of_get_mac_address_mtd); -+--- a/include/linux/of_net.h -++++ b/include/linux/of_net.h -+@@ -11,6 +11,7 @@ -+ #include -+ extern const int of_get_phy_mode(struct device_node *np); -+ extern const void *of_get_mac_address(struct device_node *np); -++extern int of_get_mac_address_mtd(struct device_node *np, void *mac); -+ #else -+ static inline const int of_get_phy_mode(struct device_node *np) -+ { -diff --git a/target/linux/mpc85xx/patches-3.10/201-net-gianfar-use-mtd-mac-address.patch b/target/linux/mpc85xx/patches-3.10/201-net-gianfar-use-mtd-mac-address.patch -new file mode 100644 -index 0000000..1de4418 ---- /dev/null -+++ b/target/linux/mpc85xx/patches-3.10/201-net-gianfar-use-mtd-mac-address.patch -@@ -0,0 +1,19 @@ -+--- a/drivers/net/ethernet/freescale/gianfar.c -++++ b/drivers/net/ethernet/freescale/gianfar.c -+@@ -741,10 +741,13 @@ static int gfar_of_init(struct platform_ -+ if (stash_len || stash_idx) -+ priv->device_flags |= FSL_GIANFAR_DEV_HAS_BUF_STASHING; -+ -+- mac_addr = of_get_mac_address(np); -++ err = of_get_mac_address_mtd(np, dev->dev_addr); -++ if (err) { -++ mac_addr = of_get_mac_address(np); -+ -+- if (mac_addr) -+- memcpy(dev->dev_addr, mac_addr, ETH_ALEN); -++ if (mac_addr) -++ memcpy(dev->dev_addr, mac_addr, ETH_ALEN); -++ } -+ -+ if (model && !strcasecmp(model, "TSEC")) -+ priv->device_flags = FSL_GIANFAR_DEV_HAS_GIGABIT | -diff --git a/target/linux/mpc85xx/patches-3.10/220-fix_gianfar_reported_number_of_sent_bytes_to_BQL.patch b/target/linux/mpc85xx/patches-3.10/220-fix_gianfar_reported_number_of_sent_bytes_to_BQL.patch -index d0380ff..0d510bc 100644 ---- a/target/linux/mpc85xx/patches-3.10/220-fix_gianfar_reported_number_of_sent_bytes_to_BQL.patch -+++ b/target/linux/mpc85xx/patches-3.10/220-fix_gianfar_reported_number_of_sent_bytes_to_BQL.patch -@@ -1,6 +1,6 @@ - --- a/drivers/net/ethernet/freescale/gianfar.c - +++ b/drivers/net/ethernet/freescale/gianfar.c --@@ -2064,7 +2064,7 @@ static int gfar_start_xmit(struct sk_buf -+@@ -2067,7 +2067,7 @@ static int gfar_start_xmit(struct sk_buf - int i, rq = 0, do_tstamp = 0; - u32 bufaddr; - unsigned long flags; -@@ -9,7 +9,7 @@ - - /* TOE=1 frames larger than 2500 bytes may see excess delays - * before start of transmission. --@@ -2130,7 +2130,10 @@ static int gfar_start_xmit(struct sk_buf -+@@ -2133,7 +2133,10 @@ static int gfar_start_xmit(struct sk_buf - } - - /* Update transmit stats */ -@@ -21,7 +21,7 @@ - tx_queue->stats.tx_packets++; - - txbdp = txbdp_start = tx_queue->cur_tx; --@@ -2150,12 +2153,13 @@ static int gfar_start_xmit(struct sk_buf -+@@ -2153,12 +2156,13 @@ static int gfar_start_xmit(struct sk_buf - } else { - /* Place the fragment addresses and lengths into the TxBDs */ - for (i = 0; i < nr_frags; i++) { -@@ -37,7 +37,7 @@ - BD_LFLAG(TXBD_READY); - - /* Handle the last BD specially */ --@@ -2165,7 +2169,7 @@ static int gfar_start_xmit(struct sk_buf -+@@ -2168,7 +2172,7 @@ static int gfar_start_xmit(struct sk_buf - bufaddr = skb_frag_dma_map(priv->dev, - &skb_shinfo(skb)->frags[i], - 0, -@@ -46,7 +46,7 @@ - DMA_TO_DEVICE); - - /* set the TxBD length and buffer pointer */ --@@ -2231,7 +2235,7 @@ static int gfar_start_xmit(struct sk_buf -+@@ -2234,7 +2238,7 @@ static int gfar_start_xmit(struct sk_buf - lstatus |= BD_LFLAG(TXBD_CRC | TXBD_READY) | skb_headlen(skb); - } - -@@ -55,7 +55,7 @@ - - /* We can work in parallel with gfar_clean_tx_ring(), except - * when modifying num_txbdfree. Note that we didn't grab the lock --@@ -2551,7 +2555,7 @@ static void gfar_clean_tx_ring(struct gf -+@@ -2554,7 +2558,7 @@ static void gfar_clean_tx_ring(struct gf - bdp = next_txbd(bdp, base, tx_ring_size); - } - diff --git a/patches/openwrt/0034-mpc85xx-replace-WDR4900-uci-defaults-ethernet-MAC-address-hack-with-DTS-entry.patch b/patches/openwrt/0034-mpc85xx-replace-WDR4900-uci-defaults-ethernet-MAC-address-hack-with-DTS-entry.patch deleted file mode 100644 index d27b0f0d..00000000 --- a/patches/openwrt/0034-mpc85xx-replace-WDR4900-uci-defaults-ethernet-MAC-address-hack-with-DTS-entry.patch +++ /dev/null @@ -1,41 +0,0 @@ -From: Matthias Schiffer -Date: Thu, 30 Apr 2015 02:12:18 +0200 -Subject: mpc85xx: replace WDR4900 uci-defaults ethernet MAC address hack with DTS entry - -This also changes the MAC address to one of the adresses actually used by the -stock firmware on one of the ethernet interfaces. - -diff --git a/target/linux/mpc85xx/base-files/etc/uci-defaults/02_network b/target/linux/mpc85xx/base-files/etc/uci-defaults/02_network -index e4e3566..525a552 100755 ---- a/target/linux/mpc85xx/base-files/etc/uci-defaults/02_network -+++ b/target/linux/mpc85xx/base-files/etc/uci-defaults/02_network -@@ -20,8 +20,6 @@ tl-wdr4900-v1) - ucidef_add_switch "switch0" "1" "1" - ucidef_add_switch_vlan "switch0" "1" "0t 2 3 4 5" - ucidef_add_switch_vlan "switch0" "2" "0t 1" -- ucidef_set_interface_macaddr lan "$(mtd_get_mac_binary config 338)" -- ucidef_set_interface_macaddr wan "$(mtd_get_mac_binary config 344)" - ;; - *) - ucidef_set_interfaces_lan_wan "eth0" "eth1" -diff --git a/target/linux/mpc85xx/files/arch/powerpc/boot/dts/tl-wdr4900-v1.dts b/target/linux/mpc85xx/files/arch/powerpc/boot/dts/tl-wdr4900-v1.dts -index 49e516c..7e48e23 100644 ---- a/target/linux/mpc85xx/files/arch/powerpc/boot/dts/tl-wdr4900-v1.dts -+++ b/target/linux/mpc85xx/files/arch/powerpc/boot/dts/tl-wdr4900-v1.dts -@@ -63,7 +63,7 @@ - label = "rootfs"; - }; - -- config@fe0000 { -+ config: config@fe0000 { - reg = <0x00fe0000 0x00010000>; - label = "config"; - read-only; -@@ -118,6 +118,7 @@ - enet0: ethernet@b0000 { - phy-handle = <&phy0>; - phy-connection-type = "rgmii-id"; -+ mtd-mac-address = <&config 0x14c>; - }; - - enet1: ethernet@b1000 { diff --git a/patches/openwrt/0035-iwinfo-update-NanoStation-Loco-txpower-offsets.patch b/patches/openwrt/0035-iwinfo-update-NanoStation-Loco-txpower-offsets.patch deleted file mode 100644 index 0b5e1861..00000000 --- a/patches/openwrt/0035-iwinfo-update-NanoStation-Loco-txpower-offsets.patch +++ /dev/null @@ -1,20 +0,0 @@ -From: Matthias Schiffer -Date: Mon, 4 May 2015 20:38:37 +0200 -Subject: iwinfo: update NanoStation (Loco) txpower offsets - -diff --git a/package/network/utils/iwinfo/src/hardware.txt b/package/network/utils/iwinfo/src/hardware.txt -index 153ffeb..b8dfc51 100644 ---- a/package/network/utils/iwinfo/src/hardware.txt -+++ b/package/network/utils/iwinfo/src/hardware.txt -@@ -42,8 +42,9 @@ - 0x168c 0x0027 0x0777 0x4082 7 0 "Ubiquiti" "SR71" - 0x168c 0x0029 0x0777 0x4005 7 0 "Ubiquiti" "SR71-15" - 0x168c 0x002a 0x0777 0xe302 12 0 "Ubiquiti" "PicoStation M2" /* ToDo: confirm offset */ --0x168c 0x002a 0x0777 0xe012 12 0 "Ubiquiti" "NanoStation M2" /* ToDo: confirm offset */ --0x168c 0x002a 0x0777 0xe005 5 0 "Ubiquiti" "NanoStation M5" /* ToDo: confirm offset */ -+0x168c 0x002a 0x0777 0xe012 11 0 "Ubiquiti" "NanoStation M2" -+0x168c 0x002e 0x0777 0xe0a2 8 0 "Ubiquiti" "NanoStation Loco M2" -+0x168c 0x002a 0x0777 0xe005 16 0 "Ubiquiti" "NanoStation M5" - 0x168c 0x002a 0x0777 0xe202 12 0 "Ubiquiti" "Bullet M2" - 0x168c 0x002a 0x0777 0xe805 5 0 "Ubiquiti" "Bullet M5" - 0x168c 0x002a 0x0777 0xe345 0 0 "Ubiquiti" "WispStation M5" /* ToDo: confirm offset */ diff --git a/patches/packages/luci/0001-fvalue.html-add-label-that-can-be-styled.patch b/patches/packages/luci/0001-fvalue.html-add-label-that-can-be-styled.patch index 8a1e00a2..8a01351f 100644 --- a/patches/packages/luci/0001-fvalue.html-add-label-that-can-be-styled.patch +++ b/patches/packages/luci/0001-fvalue.html-add-label-that-can-be-styled.patch @@ -2,10 +2,10 @@ From: Nils Schneider Date: Sat, 9 Aug 2014 09:33:21 +0200 Subject: fvalue.html: add label that can be styled -diff --git a/modules/base/luasrc/view/cbi/fvalue.htm b/modules/base/luasrc/view/cbi/fvalue.htm +diff --git a/modules/luci-base/luasrc/view/cbi/fvalue.htm b/modules/luci-base/luasrc/view/cbi/fvalue.htm index a1e0808..a324ab2 100644 ---- a/modules/base/luasrc/view/cbi/fvalue.htm -+++ b/modules/base/luasrc/view/cbi/fvalue.htm +--- a/modules/luci-base/luasrc/view/cbi/fvalue.htm ++++ b/modules/luci-base/luasrc/view/cbi/fvalue.htm @@ -6,4 +6,5 @@ attr("id", cbid) .. attr("name", cbid) .. attr("value", self.enabled or 1) .. ifattr((self:cfgvalue(section) or self.default) == self.enabled, "checked", "checked") diff --git a/patches/packages/luci/0002-modules-base-dispatcher-set-default-language-if-none-provided-by-the-browser-matches.patch b/patches/packages/luci/0002-modules-base-dispatcher-set-default-language-if-none-provided-by-the-browser-matches.patch index 2e1da79c..745e6cef 100644 --- a/patches/packages/luci/0002-modules-base-dispatcher-set-default-language-if-none-provided-by-the-browser-matches.patch +++ b/patches/packages/luci/0002-modules-base-dispatcher-set-default-language-if-none-provided-by-the-browser-matches.patch @@ -2,11 +2,11 @@ From: Matthias Schiffer Date: Thu, 19 Mar 2015 18:44:52 +0100 Subject: modules/base: dispatcher: set default language if none provided by the browser matches -diff --git a/modules/base/luasrc/dispatcher.lua b/modules/base/luasrc/dispatcher.lua -index f7e16e7..479ac54 100644 ---- a/modules/base/luasrc/dispatcher.lua -+++ b/modules/base/luasrc/dispatcher.lua -@@ -211,6 +211,7 @@ function dispatch(request) +diff --git a/modules/luci-base/luasrc/dispatcher.lua b/modules/luci-base/luasrc/dispatcher.lua +index 8b8d1fa..27f9a15 100644 +--- a/modules/luci-base/luasrc/dispatcher.lua ++++ b/modules/luci-base/luasrc/dispatcher.lua +@@ -182,6 +182,7 @@ function dispatch(request) assert(conf.main, "/etc/config/luci seems to be corrupt, unable to find section 'main'") @@ -14,7 +14,7 @@ index f7e16e7..479ac54 100644 local lang = conf.main.lang or "auto" if lang == "auto" then local aclang = http.getenv("HTTP_ACCEPT_LANGUAGE") or "" -@@ -222,7 +223,10 @@ function dispatch(request) +@@ -193,7 +194,10 @@ function dispatch(request) end end end diff --git a/patches/packages/luci/0003-luci-base-depend-on-libubus-lua.patch b/patches/packages/luci/0003-luci-base-depend-on-libubus-lua.patch new file mode 100644 index 00000000..eb8f8aa2 --- /dev/null +++ b/patches/packages/luci/0003-luci-base-depend-on-libubus-lua.patch @@ -0,0 +1,17 @@ +From: Matthias Schiffer +Date: Thu, 21 May 2015 02:34:01 +0200 +Subject: luci-base: depend on libubus-lua + +diff --git a/modules/luci-base/Makefile b/modules/luci-base/Makefile +index 80bbda1..55c21eb 100644 +--- a/modules/luci-base/Makefile ++++ b/modules/luci-base/Makefile +@@ -12,7 +12,7 @@ LUCI_TYPE:=mod + LUCI_BASENAME:=base + + LUCI_TITLE:=LuCI core libraries +-LUCI_DEPENDS:=+lua +libuci-lua +luci-lib-nixio +luci-lib-ip +rpcd ++LUCI_DEPENDS:=+lua +libuci-lua +libubus-lua +luci-lib-nixio +luci-lib-ip +rpcd + + PKG_SOURCE:=LuaSrcDiet-0.12.1.tar.bz2 + PKG_SOURCE_URL:=https://luasrcdiet.googlecode.com/files diff --git a/patches/packages/openwrt/0001-haveged-start-directly-after-initial-setup-and-disable-tests.patch b/patches/packages/openwrt/0001-haveged-start-directly-after-initial-setup-and-disable-tests.patch deleted file mode 100644 index 985b7c69..00000000 --- a/patches/packages/openwrt/0001-haveged-start-directly-after-initial-setup-and-disable-tests.patch +++ /dev/null @@ -1,33 +0,0 @@ -From: Matthias Schiffer -Date: Sat, 26 Jul 2014 18:06:07 +0200 -Subject: haveged: start directly after initial setup and disable tests - -diff --git a/utils/haveged/Makefile b/utils/haveged/Makefile -index aff998d..94c8c34 100644 ---- a/utils/haveged/Makefile -+++ b/utils/haveged/Makefile -@@ -42,8 +42,9 @@ define Package/libhavege - endef - - CONFIGURE_ARGS+= \ -- --enable-daemon=yes -- --enable-threads=no -+ --enable-daemon=yes \ -+ --enable-threads=no \ -+ --enable-olt=no - - define Build/InstallDev - $(INSTALL_DIR) $(1)/usr/include -diff --git a/utils/haveged/files/haveged.init b/utils/haveged/files/haveged.init -index ce28e61..113d64f 100644 ---- a/utils/haveged/files/haveged.init -+++ b/utils/haveged/files/haveged.init -@@ -1,7 +1,7 @@ - #!/bin/sh /etc/rc.common - # Copyright (C) 2012 OpenWrt.org - --START=98 -+START=13 - - HAVEGED_THRESHOLD=1024 - HAVEGED_DCACHE=32 diff --git a/patches/packages/openwrt/0002-libuecc-update-to-v5.patch b/patches/packages/openwrt/0002-libuecc-update-to-v5.patch deleted file mode 100644 index 979961e0..00000000 --- a/patches/packages/openwrt/0002-libuecc-update-to-v5.patch +++ /dev/null @@ -1,35 +0,0 @@ -From: Matthias Schiffer -Date: Thu, 29 Jan 2015 07:46:26 +0100 -Subject: libuecc: update to v5 - -diff --git a/libs/libuecc/Makefile b/libs/libuecc/Makefile -index 0fe4833..63b6ebe 100644 ---- a/libs/libuecc/Makefile -+++ b/libs/libuecc/Makefile -@@ -1,5 +1,5 @@ - # --# Copyright (C) 2012-2014 OpenWrt.org -+# Copyright (C) 2012-2015 OpenWrt.org - # - # This is free software, licensed under the GNU General Public License v2. - # See /LICENSE for more information. -@@ -8,13 +8,16 @@ - include $(TOPDIR)/rules.mk - - PKG_NAME:=libuecc --PKG_VERSION:=4 -+PKG_VERSION:=5 - PKG_RELEASE:=1 - - PKG_MAINTAINER:=Matthias Schiffer - PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz --PKG_SOURCE_URL:=https://projects.universe-factory.net/attachments/download/71 --PKG_MD5SUM:=7f44df5dc69cb8686947562e2a11eea9 -+PKG_SOURCE_URL:=https://projects.universe-factory.net/attachments/download/80 -+PKG_MD5SUM:=cd03c947931c2f4b0eea0bf45654bd34 -+ -+PKG_LICENSE:=BSD-2-Clause -+PKG_LICENSE_FILES:=COPYRIGHT - - include $(INCLUDE_DIR)/package.mk - include $(INCLUDE_DIR)/cmake.mk diff --git a/patches/packages/openwrt/0003-fastd-update-to-v17.patch b/patches/packages/openwrt/0003-fastd-update-to-v17.patch deleted file mode 100644 index 33cc08bf..00000000 --- a/patches/packages/openwrt/0003-fastd-update-to-v17.patch +++ /dev/null @@ -1,213 +0,0 @@ -From: Matthias Schiffer -Date: Thu, 29 Jan 2015 07:48:03 +0100 -Subject: fastd: update to v17 - -diff --git a/net/fastd/Config.in b/net/fastd/Config.in -index ca4045c..5820b97 100644 ---- a/net/fastd/Config.in -+++ b/net/fastd/Config.in -@@ -11,6 +11,11 @@ config FASTD_ENABLE_METHOD_COMPOSED_GMAC - depends on PACKAGE_fastd - default y - -+config FASTD_ENABLE_METHOD_COMPOSED_UMAC -+ bool "Enable composed-umac method provider" -+ depends on PACKAGE_fastd -+ default y -+ - config FASTD_ENABLE_METHOD_GENERIC_GMAC - bool "Enable generic-gmac method provider" - depends on PACKAGE_fastd -@@ -21,6 +26,11 @@ config FASTD_ENABLE_METHOD_GENERIC_POLY1305 - depends on PACKAGE_fastd - default n - -+config FASTD_ENABLE_METHOD_GENERIC_UMAC -+ bool "Enable generic-umac method provider" -+ depends on PACKAGE_fastd -+ default y -+ - config FASTD_ENABLE_METHOD_NULL - bool "Enable null method" - depends on PACKAGE_fastd -@@ -58,6 +68,11 @@ config FASTD_ENABLE_MAC_GHASH - depends on PACKAGE_fastd - default y - -+config FASTD_ENABLE_MAC_UHASH -+ bool "Enable the UHASH message authentication code" -+ depends on PACKAGE_fastd -+ default y -+ - - config FASTD_WITH_CMDLINE_USER - bool "Include support for setting user/group related options on the command line" -@@ -79,9 +94,15 @@ config FASTD_WITH_CMDLINE_COMMANDS - depends on PACKAGE_fastd - default n - --config FASTD_WITH_VERIFY -- bool "Include support for on-verify handlers" -- depends on PACKAGE_fastd -- default n -+config FASTD_WITH_DYNAMIC_PEERS -+ bool "Include support for on-verify handlers" -+ depends on PACKAGE_fastd -+ default n -+ -+config FASTD_WITH_STATUS_SOCKET -+ bool "Include support for status sockets" -+ depends on PACKAGE_fastd -+ default y -+ - - endmenu -diff --git a/net/fastd/Makefile b/net/fastd/Makefile -index 0629cd7..027f549 100644 ---- a/net/fastd/Makefile -+++ b/net/fastd/Makefile -@@ -1,5 +1,5 @@ - # --# Copyright (C) 2012-2014 OpenWrt.org -+# Copyright (C) 2012-2015 OpenWrt.org - # - # This is free software, licensed under the GNU General Public License v2. - # See /LICENSE for more information. -@@ -8,19 +8,24 @@ - include $(TOPDIR)/rules.mk - - PKG_NAME:=fastd --PKG_VERSION:=14 -+PKG_VERSION:=17 - PKG_RELEASE:=1 - - PKG_MAINTAINER:=Matthias Schiffer - PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz --PKG_SOURCE_URL:=https://projects.universe-factory.net/attachments/download/75 --PKG_MD5SUM:=34f6bdebd0410a1fba7c8fd06fff7a05 -+PKG_SOURCE_URL:=https://projects.universe-factory.net/attachments/download/81 -+PKG_MD5SUM:=bad4f1948702f418b799578f83a0edb8 -+ -+PKG_LICENSE:=BSD-2-Clause -+PKG_LICENSE_FILES:=COPYRIGHT - - PKG_CONFIG_DEPENDS:=\ - CONFIG_FASTD_ENABLE_METHOD_CIPHER_TEST \ - CONFIG_FASTD_ENABLE_METHOD_COMPOSED_GMAC \ -+ CONFIG_FASTD_ENABLE_METHOD_COMPOSED_UMAC \ - CONFIG_FASTD_ENABLE_METHOD_GENERIC_GMAC \ - CONFIG_FASTD_ENABLE_METHOD_GENERIC_POLY1305 \ -+ CONFIG_FASTD_ENABLE_METHOD_GENERIC_UMAC \ - CONFIG_FASTD_ENABLE_METHOD_NULL \ - CONFIG_FASTD_ENABLE_METHOD_XSALSA20_POLY1305 \ - CONFIG_FASTD_ENABLE_CIPHER_AES128_CTR \ -@@ -28,11 +33,13 @@ PKG_CONFIG_DEPENDS:=\ - CONFIG_FASTD_ENABLE_CIPHER_SALSA20 \ - CONFIG_FASTD_ENABLE_CIPHER_SALSA2012 \ - CONFIG_FASTD_ENABLE_MAC_GHASH \ -+ CONFIG_FASTD_ENABLE_MAC_UHASH \ - CONFIG_FASTD_WITH_CMDLINE_USER \ - CONFIG_FASTD_WITH_CMDLINE_LOGGING \ - CONFIG_FASTD_WITH_CMDLINE_OPERATION \ - CONFIG_FASTD_WITH_CMDLINE_COMMANDS \ -- CONFIG_FASTD_WITH_VERIFY -+ CONFIG_FASTD_WITH_DYNAMIC_PEERS \ -+ CONFIG_FASTD_WITH_STATUS_SOCKET - - - PKG_BUILD_DEPENDS:=nacl libuecc -@@ -43,7 +50,7 @@ include $(INCLUDE_DIR)/cmake.mk - define Package/fastd - SECTION:=net - CATEGORY:=Network -- DEPENDS:=+kmod-tun +librt +libpthread -+ DEPENDS:=+kmod-tun +librt +libpthread +FASTD_WITH_STATUS_SOCKET:libjson-c - TITLE:=Fast and Secure Tunneling Daemon - URL:=https://projects.universe-factory.net/projects/fastd - SUBMENU:=VPN -@@ -60,8 +67,10 @@ CMAKE_OPTIONS += \ - -DCMAKE_BUILD_TYPE:STRING=MINSIZEREL \ - -DWITH_METHOD_CIPHER_TEST:BOOL=FALSE \ - -DWITH_METHOD_COMPOSED_GMAC:BOOL=FALSE \ -+ -DWITH_METHOD_COMPOSED_UMAC:BOOL=FALSE \ - -DWITH_METHOD_GENERIC_GMAC:BOOL=FALSE \ - -DWITH_METHOD_GENERIC_POLY1305:BOOL=FALSE \ -+ -DWITH_METHOD_GENERIC_UMAC:BOOL=FALSE \ - -DWITH_METHOD_NULL:BOOL=FALSE \ - -DWITH_METHOD_XSALSA20_POLY1305:BOOL=FALSE \ - -DWITH_CIPHER_AES128_CTR:BOOL=FALSE \ -@@ -69,11 +78,13 @@ CMAKE_OPTIONS += \ - -DWITH_CIPHER_SALSA20:BOOL=FALSE \ - -DWITH_CIPHER_SALSA2012:BOOL=FALSE \ - -DWITH_MAC_GHASH:BOOL=FALSE \ -+ -DWITH_MAC_UHASH:BOOL=FALSE \ - -DWITH_CMDLINE_USER:BOOL=FALSE \ - -DWITH_CMDLINE_LOGGING:BOOL=FALSE \ - -DWITH_CMDLINE_OPERATION:BOOL=FALSE \ - -DWITH_CMDLINE_COMMANDS:BOOL=FALSE \ -- -DWITH_VERIFY:BOOL=FALSE \ -+ -DWITH_DYNAMIC_PEERS:BOOL=FALSE \ -+ -DWITH_STATUS_SOCKET:BOOL=FALSE \ - -DWITH_CAPABILITIES:BOOL=FALSE \ - -DENABLE_SYSTEMD:BOOL=FALSE \ - -DENABLE_LIBSODIUM:BOOL=FALSE \ -@@ -88,6 +99,10 @@ ifeq ($(CONFIG_FASTD_ENABLE_METHOD_COMPOSED_GMAC),y) - CMAKE_OPTIONS += -DWITH_METHOD_COMPOSED_GMAC:BOOL=TRUE - endif - -+ifeq ($(CONFIG_FASTD_ENABLE_METHOD_COMPOSED_UMAC),y) -+CMAKE_OPTIONS += -DWITH_METHOD_COMPOSED_UMAC:BOOL=TRUE -+endif -+ - ifeq ($(CONFIG_FASTD_ENABLE_METHOD_GENERIC_GMAC),y) - CMAKE_OPTIONS += -DWITH_METHOD_GENERIC_GMAC:BOOL=TRUE - endif -@@ -96,6 +111,10 @@ ifeq ($(CONFIG_FASTD_ENABLE_METHOD_GENERIC_POLY1305),y) - CMAKE_OPTIONS += -DWITH_METHOD_GENERIC_POLY1305:BOOL=TRUE - endif - -+ifeq ($(CONFIG_FASTD_ENABLE_METHOD_GENERIC_UMAC),y) -+CMAKE_OPTIONS += -DWITH_METHOD_GENERIC_UMAC:BOOL=TRUE -+endif -+ - ifeq ($(CONFIG_FASTD_ENABLE_METHOD_NULL),y) - CMAKE_OPTIONS += -DWITH_METHOD_NULL:BOOL=TRUE - endif -@@ -126,6 +145,10 @@ ifeq ($(CONFIG_FASTD_ENABLE_MAC_GHASH),y) - CMAKE_OPTIONS += -DWITH_MAC_GHASH:BOOL=TRUE - endif - -+ifeq ($(CONFIG_FASTD_ENABLE_MAC_UHASH),y) -+CMAKE_OPTIONS += -DWITH_MAC_UHASH:BOOL=TRUE -+endif -+ - - ifeq ($(CONFIG_FASTD_WITH_CMDLINE_USER),y) - CMAKE_OPTIONS += -DWITH_CMDLINE_USER:BOOL=TRUE -@@ -143,8 +166,12 @@ ifeq ($(CONFIG_FASTD_WITH_CMDLINE_COMMANDS),y) - CMAKE_OPTIONS += -DWITH_CMDLINE_COMMANDS:BOOL=TRUE - endif - --ifeq ($(CONFIG_FASTD_WITH_VERIFY),y) --CMAKE_OPTIONS += -DWITH_VERIFY:BOOL=TRUE -+ifeq ($(CONFIG_FASTD_WITH_DYNAMIC_PEERS),y) -+CMAKE_OPTIONS += -DWITH_DYNAMIC_PEERS:BOOL=TRUE -+endif -+ -+ifeq ($(CONFIG_FASTD_WITH_STATUS_SOCKET),y) -+CMAKE_OPTIONS += -DWITH_STATUS_SOCKET:BOOL=TRUE - endif - - -@@ -161,9 +188,9 @@ define Package/fastd/install - $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/fastd $(1)/usr/bin/ - - $(INSTALL_DIR) $(1)/etc/init.d/ -- $(INSTALL_BIN) files/fastd.init $(1)/etc/init.d/fastd -+ $(INSTALL_BIN) $(PKG_BUILD_DIR)/doc/examples/openwrt/fastd.init $(1)/etc/init.d/fastd - $(INSTALL_DIR) $(1)/etc/config -- $(INSTALL_CONF) files/fastd.config $(1)/etc/config/fastd -+ $(INSTALL_CONF) $(PKG_BUILD_DIR)/doc/examples/openwrt/fastd.config $(1)/etc/config/fastd - $(INSTALL_DIR) $(1)/etc/fastd - $(INSTALL_DIR) $(1)/lib/upgrade/keep.d - $(INSTALL_DATA) files/fastd.upgrade $(1)/lib/upgrade/keep.d/fastd diff --git a/patches/packages/routing/0001-Update-batman-adv-and-alfred-to-v2014.4.patch b/patches/packages/routing/0001-Update-batman-adv-and-alfred-to-v2014.4.patch deleted file mode 100644 index e46c8c2c..00000000 --- a/patches/packages/routing/0001-Update-batman-adv-and-alfred-to-v2014.4.patch +++ /dev/null @@ -1,52 +0,0 @@ -From: Matthias Schiffer -Date: Wed, 7 Jan 2015 16:40:43 +0100 -Subject: Update batman-adv and alfred to v2014.4 - -diff --git a/alfred/Makefile b/alfred/Makefile -index 648a5ef..0a5fcac 100644 ---- a/alfred/Makefile -+++ b/alfred/Makefile -@@ -11,9 +11,9 @@ include $(TOPDIR)/rules.mk - # The latest alfred git hash in PKG_REV can be obtained from http://git.open-mesh.org/alfred.git - # - PKG_NAME:=alfred --PKG_VERSION:=2014.3.0 -+PKG_VERSION:=2014.4.0 - PKG_RELEASE:=0 --PKG_MD5SUM:=b8ab5677ed73d817b02b0e4fae10357a -+PKG_MD5SUM:=053cb5d9e7ca9384598e82944343dea2 - - PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz - PKG_SOURCE_URL:=http://downloads.open-mesh.org/batman/releases/batman-adv-$(PKG_VERSION) -diff --git a/batctl/Makefile b/batctl/Makefile -index ae22286..1009b03 100644 ---- a/batctl/Makefile -+++ b/batctl/Makefile -@@ -9,9 +9,9 @@ include $(TOPDIR)/rules.mk - - PKG_NAME:=batctl - --PKG_VERSION:=2014.2.0 -+PKG_VERSION:=2014.4.0 - PKG_RELEASE:=1 --PKG_MD5SUM:=c196cf95b7324d9123b701a56b06b31d -+PKG_MD5SUM:=f3a14565699313258ee6ba3de783eb0a - - PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz - PKG_SOURCE_URL:=http://downloads.open-mesh.org/batman/releases/batman-adv-$(PKG_VERSION) -diff --git a/batman-adv/Makefile b/batman-adv/Makefile -index 889dea7..0d5ed33 100644 ---- a/batman-adv/Makefile -+++ b/batman-adv/Makefile -@@ -10,9 +10,9 @@ include $(TOPDIR)/rules.mk - - PKG_NAME:=batman-adv - --PKG_VERSION:=2014.2.0 -+PKG_VERSION:=2014.4.0 - PKG_RELEASE:=1 --PKG_MD5SUM:=1243029b3a3e2f4fa721d1a59c2faaf5 -+PKG_MD5SUM:=b1518e84ce530883d224c6ca4c673ce8 - - PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz - PKG_SOURCE_URL:=http://downloads.open-mesh.org/batman/releases/batman-adv-$(PKG_VERSION) diff --git a/patches/packages/routing/0002-alfred-adjust-intervals.patch b/patches/packages/routing/0001-alfred-adjust-intervals.patch similarity index 100% rename from patches/packages/routing/0002-alfred-adjust-intervals.patch rename to patches/packages/routing/0001-alfred-adjust-intervals.patch diff --git a/patches/packages/routing/0003-batman-adv-introduce-no_rebroadcast-option.patch b/patches/packages/routing/0002-batman-adv-introduce-no_rebroadcast-option.patch similarity index 100% rename from patches/packages/routing/0003-batman-adv-introduce-no_rebroadcast-option.patch rename to patches/packages/routing/0002-batman-adv-introduce-no_rebroadcast-option.patch diff --git a/targets/ar71xx-generic/profiles.mk b/targets/ar71xx-generic/profiles.mk index 27ebf827..e22fe62c 100644 --- a/targets/ar71xx-generic/profiles.mk +++ b/targets/ar71xx-generic/profiles.mk @@ -112,10 +112,13 @@ $(eval $(call GluonProfile,TLMR3040)) $(eval $(call GluonModel,TLMR3040,tl-mr3040-v1,tp-link-tl-mr3040-v1)) $(eval $(call GluonModel,TLMR3040,tl-mr3040-v2,tp-link-tl-mr3040-v2)) -# TL-MR3220 v1, v2 -$(eval $(call GluonProfile,TLMR3220)) -$(eval $(call GluonModel,TLMR3220,tl-mr3220-v1,tp-link-tl-mr3220-v1)) -$(eval $(call GluonModel,TLMR3220,tl-mr3220-v2,tp-link-tl-mr3220-v2)) +# TL-MR3220 v1 +$(eval $(call GluonProfile,TLMR3220V1)) +$(eval $(call GluonModel,TLMR3220V1,tl-mr3220-v1,tp-link-tl-mr3220-v1)) + +# TL-MR3220 v2 +$(eval $(call GluonProfile,TLMR3220V2)) +$(eval $(call GluonModel,TLMR3220V2,tl-mr3220-v2,tp-link-tl-mr3220-v2)) # TL-MR3420 v1, v2 $(eval $(call GluonProfile,TLMR3420)) diff --git a/targets/ar71xx-generic/vermagic b/targets/ar71xx-generic/vermagic index 7a493135..ab5f8c55 100644 --- a/targets/ar71xx-generic/vermagic +++ b/targets/ar71xx-generic/vermagic @@ -1 +1 @@ -0114c71ed85677c9c1e4911437af4743 +c9110281555cccc9dd13e092c2acaeaf diff --git a/targets/ar71xx-nand/vermagic b/targets/ar71xx-nand/vermagic index 1e8c75b0..e3613a7a 100644 --- a/targets/ar71xx-nand/vermagic +++ b/targets/ar71xx-nand/vermagic @@ -1 +1 @@ -41123e63bc43f61af09d064504300966 +689cae9c23d40bdba3f46c59a12ca179 diff --git a/targets/mpc85xx-generic/vermagic b/targets/mpc85xx-generic/vermagic index bf824cec..9f75ad13 100644 --- a/targets/mpc85xx-generic/vermagic +++ b/targets/mpc85xx-generic/vermagic @@ -1 +1 @@ -c1a44dd429e530bed2958b8e6cb54a52 +18b3b28a5f70d5040f741bd44916dc57 diff --git a/targets/ramips-rt305x/vermagic b/targets/ramips-rt305x/vermagic index 6b3ea89d..c6652242 100644 --- a/targets/ramips-rt305x/vermagic +++ b/targets/ramips-rt305x/vermagic @@ -1 +1 @@ -194d0e9ee3ca8df976c737e78e8b2194 +4d806b94ed2b1e50df33a69891888e4a diff --git a/targets/x86-generic/vermagic b/targets/x86-generic/vermagic index f3bb33e2..457dc764 100644 --- a/targets/x86-generic/vermagic +++ b/targets/x86-generic/vermagic @@ -1 +1 @@ -3051dee8f07064b727e9d57fbfeb05ec +6581cdee9837e0761056ab3c80d05a2e diff --git a/targets/x86-kvm_guest/vermagic b/targets/x86-kvm_guest/vermagic index 47c31ca4..89969699 100644 --- a/targets/x86-kvm_guest/vermagic +++ b/targets/x86-kvm_guest/vermagic @@ -1 +1 @@ -5e81ad3c25d4a4f02e749f398f1868c5 +23b9575454f0084518a8c2f51423207c From b21109f5511647b090b1e07f9f10f149ffec177b Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Fri, 22 May 2015 02:05:47 +0200 Subject: [PATCH 59/62] Update gluon packages --- modules | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules b/modules index 8c31b718..d0c43d05 100644 --- a/modules +++ b/modules @@ -8,7 +8,7 @@ PACKAGES_OPENWRT_COMMIT=914beae80e848c161214464fba7a9826c66bbf26 PACKAGES_OPENWRT_BRANCH=for-15.05 PACKAGES_GLUON_REPO=git://github.com/freifunk-gluon/packages.git -PACKAGES_GLUON_COMMIT=e8ee21d116a0abc2e328b0ee181d79845654582e +PACKAGES_GLUON_COMMIT=dcc5a5ab74822492877eadcba5fc3ad845ee65db PACKAGES_ROUTING_REPO=git://github.com/openwrt-routing/packages.git PACKAGES_ROUTING_COMMIT=b1c3bdfbf47003088198bf8ef699a94cc29e3eca From a42db7a71f0b25e92338b52ee24416f14e24542b Mon Sep 17 00:00:00 2001 From: Nils Schneider Date: Fri, 22 May 2015 11:51:12 +0200 Subject: [PATCH 60/62] gluon-luci-admin: fix translation of "Export Mode" Export Mode -> Expert Mode --- package/gluon-luci-admin/i18n/de.po | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package/gluon-luci-admin/i18n/de.po b/package/gluon-luci-admin/i18n/de.po index e3a1aa20..ec109ae0 100644 --- a/package/gluon-luci-admin/i18n/de.po +++ b/package/gluon-luci-admin/i18n/de.po @@ -27,7 +27,7 @@ msgid "Don't switch off the device in any circumstance!" msgstr "Unterbrich auf keinen Fall die Stromversorgung!" msgid "Expert Mode" -msgstr "Export Mode" +msgstr "Expert Mode" msgid "Firmware image" msgstr "Firmware-Datei" From 317478e2b739252039a007732c1666314c42df69 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Thu, 28 May 2015 01:44:25 +0200 Subject: [PATCH 61/62] gluon-mesh-batman-adv-core: don't break network configuration on upgrades with mesh_on_lan=true --- ...340-gluon-mesh-batman-adv-core-mesh-on-lan | 29 ++++++++++++------- 1 file changed, 19 insertions(+), 10 deletions(-) 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-mesh-batman-adv-core/files/lib/gluon/upgrade/340-gluon-mesh-batman-adv-core-mesh-on-lan index f9cbde03..d9831bfc 100755 --- a/package/gluon-mesh-batman-adv-core/files/lib/gluon/upgrade/340-gluon-mesh-batman-adv-core-mesh-on-lan +++ b/package/gluon-mesh-batman-adv-core/files/lib/gluon/upgrade/340-gluon-mesh-batman-adv-core-mesh-on-lan @@ -1,23 +1,32 @@ #!/usr/bin/lua local site = require 'gluon.site_config' -local uci = require 'luci.model.uci' local util = require 'gluon.util' local sysconfig = require 'gluon.sysconfig' -local c = uci.cursor() +local uci = require('luci.model.uci').cursor() +local lutil = require 'luci.util' -if sysconfig.lan_ifname then - if not c:get('network', 'mesh_lan') then - c:section('network', 'interface', 'mesh_lan', +if sysconfig.lan_ifname and not uci:get('network', 'mesh_lan') then + local enable = site.mesh_on_lan + + if enable then + local interfaces = uci:get('network', 'client', 'ifname') + + if interfaces and lutil.contains(interfaces:split(' '), sysconfig.lan_ifname) then + enable = false + end + end + + uci:section('network', 'interface', 'mesh_lan', { ifname = sysconfig.lan_ifname , proto = 'batadv' , mesh = 'bat0' , macaddr = util.generate_mac(1, 1) - , auto = site.mesh_on_lan and 1 or 0 - }) - end + , auto = enable and 1 or 0 + }) + + uci:save('network') + uci:commit('network') end -c:save('network') -c:commit('network') From e6c00c1ad78daed7e79122ff2e1e9cddfa9b860b Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Thu, 28 May 2015 02:45:19 +0200 Subject: [PATCH 62/62] build: ensure prereq has been run at the beginning of prepare-tmpinfo --- Makefile | 11 ++++++----- include/toplevel.mk | 4 ---- 2 files changed, 6 insertions(+), 9 deletions(-) diff --git a/Makefile b/Makefile index a4fe82b8..4420b387 100644 --- a/Makefile +++ b/Makefile @@ -179,11 +179,8 @@ include $(INCLUDE_DIR)/target.mk prereq: FORCE +$(NO_TRACE_MAKE) prereq -gluon-tools: FORCE - +$(GLUONMAKE_EARLY) tools/sed/install - +$(GLUONMAKE_EARLY) package/lua/host/install - prepare-tmpinfo: FORCE + @+$(MAKE) -r -s staging_dir/host/.prereq-build OPENWRT_BUILD= QUIET=0 mkdir -p tmp/info $(_SINGLE)$(NO_TRACE_MAKE) -j1 -r -s -f include/scan.mk SCAN_TARGET="packageinfo" SCAN_DIR="package" SCAN_NAME="package" SCAN_DEPS="$(TOPDIR)/include/package*.mk $(TOPDIR)/overlay/*/*.mk" SCAN_EXTRA="" $(_SINGLE)$(NO_TRACE_MAKE) -j1 -r -s -f include/scan.mk SCAN_TARGET="targetinfo" SCAN_DIR="target/linux" SCAN_NAME="target" SCAN_DEPS="profiles/*.mk $(TOPDIR)/include/kernel*.mk $(TOPDIR)/include/target.mk" SCAN_DEPTH=2 SCAN_EXTRA="" SCAN_MAKEOPTS="TARGET_BUILD=1" @@ -204,8 +201,12 @@ feeds: FORCE . $(GLUONDIR)/modules && for feed in $$GLUON_FEEDS; do ln -s ../../../packages/$$feed $(TOPDIR)/package/feeds/module_$$feed; done +$(GLUONMAKE_EARLY) prepare-tmpinfo +gluon-tools: FORCE + +$(GLUONMAKE_EARLY) tools/sed/install + +$(GLUONMAKE_EARLY) package/lua/host/install + config: FORCE - +$(NO_TRACE_MAKE) scripts/config/conf OPENWRT_BUILD=0 + +$(NO_TRACE_MAKE) scripts/config/conf OPENWRT_BUILD= QUIET=0 +$(GLUONMAKE) prepare-tmpinfo ( \ cat $(GLUONDIR)/include/config $(GLUONDIR)/targets/$(GLUON_TARGET)/config; \ diff --git a/include/toplevel.mk b/include/toplevel.mk index 74a95997..72522da5 100644 --- a/include/toplevel.mk +++ b/include/toplevel.mk @@ -48,10 +48,6 @@ else export HOSTCC_WRAPPER:=$(HOSTCC) endif -ifeq ($(FORCE),) - .config scripts/config/conf scripts/config/mconf: tmp/.prereq-build -endif - SCAN_COOKIE?=$(shell echo $$$$) export SCAN_COOKIE