2013-06-12 17:52:10 +00:00
|
|
|
/*
|
|
|
|
* Copyright (c) 2005-2011 Atheros Communications Inc.
|
2017-12-22 16:31:13 +00:00
|
|
|
* Copyright (c) 2011-2017 Qualcomm Atheros, Inc.
|
2018-02-05 04:11:34 +00:00
|
|
|
* Copyright (c) 2018, The Linux Foundation. All rights reserved.
|
2013-06-12 17:52:10 +00:00
|
|
|
*
|
|
|
|
* 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 <linux/module.h>
|
|
|
|
#include <linux/firmware.h>
|
2014-12-02 08:55:54 +00:00
|
|
|
#include <linux/of.h>
|
ath10k: search SMBIOS for OEM board file extension
Board Data File (BDF) is loaded upon driver boot-up procedure. The right
board data file is identified, among others, by device and sybsystem ids.
The problem, however, can occur when the (default) board data file cannot
fulfill with the vendor requirements and it is necessary to use a different
board data file.
To solve the issue QCA uses SMBIOS type 0xF8 to store Board Data File Name
Extension to specify the extension/variant name. The driver will take the
extension suffix into consideration and will load the right (non-default)
board data file if necessary.
If it is unnecessary to use extension board data file, please leave the
SMBIOS field blank and default configuration will be used.
Example:
If a default board data file for a specific board is identified by a string
"bus=pci,vendor=168c,device=003e,subsystem-vendor=1028,
subsystem-device=0310"
then the OEM specific data file, if used, could be identified by variant
suffix:
"bus=pci,vendor=168c,device=003e,subsystem-vendor=1028,
subsystem-device=0310,variant=DE_1AB"
If board data file name extension is set but board-2.bin does not contain
board data file for the variant, the driver will fallback to the default
board data file not to break backward compatibility.
This was first applied in commit f2593cb1b291 ("ath10k: Search SMBIOS for OEM
board file extension") but later reverted in commit 005c3490e9db ("Revert
"ath10k: Search SMBIOS for OEM board file extension"". This patch is now
otherwise the same as commit f2593cb1b291 except the regression fixed.
Signed-off-by: Waldemar Rymarkiewicz <ext.waldemar.rymarkiewicz@tieto.com>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
2017-02-24 22:30:03 +00:00
|
|
|
#include <linux/dmi.h>
|
|
|
|
#include <linux/ctype.h>
|
2016-06-02 14:59:50 +00:00
|
|
|
#include <asm/byteorder.h>
|
2013-06-12 17:52:10 +00:00
|
|
|
|
|
|
|
#include "core.h"
|
|
|
|
#include "mac.h"
|
|
|
|
#include "htc.h"
|
|
|
|
#include "hif.h"
|
|
|
|
#include "wmi.h"
|
|
|
|
#include "bmi.h"
|
|
|
|
#include "debug.h"
|
|
|
|
#include "htt.h"
|
2014-09-10 15:23:30 +00:00
|
|
|
#include "testmode.h"
|
2014-12-03 08:10:54 +00:00
|
|
|
#include "wmi-ops.h"
|
2017-12-22 13:38:43 +00:00
|
|
|
#include "coredump.h"
|
2013-06-12 17:52:10 +00:00
|
|
|
|
|
|
|
unsigned int ath10k_debug_mask;
|
ath10k: enable raw encap mode and software crypto engine
This patch enables raw Rx/Tx encap mode to support software based
crypto engine. This patch introduces a new module param 'cryptmode'.
cryptmode:
0: Use hardware crypto engine globally with native Wi-Fi mode TX/RX
encapsulation to the firmware. This is the default mode.
1: Use sofware crypto engine globally with raw mode TX/RX
encapsulation to the firmware.
Known limitation:
A-MSDU must be disabled for RAW Tx encap mode to perform well when
heavy traffic is applied.
Testing: (by Michal Kazior <michal.kazior@tieto.com>)
a) Performance Testing
cryptmode=1
ap=qca988x sta=killer1525
killer1525 -> qca988x 194.496 mbps [tcp1 ip4]
killer1525 -> qca988x 238.309 mbps [tcp5 ip4]
killer1525 -> qca988x 266.958 mbps [udp1 ip4]
killer1525 -> qca988x 477.468 mbps [udp5 ip4]
qca988x -> killer1525 301.378 mbps [tcp1 ip4]
qca988x -> killer1525 297.949 mbps [tcp5 ip4]
qca988x -> killer1525 331.351 mbps [udp1 ip4]
qca988x -> killer1525 371.528 mbps [udp5 ip4]
ap=killer1525 sta=qca988x
qca988x -> killer1525 331.447 mbps [tcp1 ip4]
qca988x -> killer1525 328.783 mbps [tcp5 ip4]
qca988x -> killer1525 375.309 mbps [udp1 ip4]
qca988x -> killer1525 403.379 mbps [udp5 ip4]
killer1525 -> qca988x 203.689 mbps [tcp1 ip4]
killer1525 -> qca988x 222.339 mbps [tcp5 ip4]
killer1525 -> qca988x 264.199 mbps [udp1 ip4]
killer1525 -> qca988x 479.371 mbps [udp5 ip4]
Note:
- only open network tested for RAW vs nwifi performance comparison
- killer1525 (qca6174 hw2.2) is 2x2 device (hence max 866mbps)
- used iperf
- OTA, devices a few cm apart from each other, no shielding
- tcpX/udpX, X - means number of threads used
Overview:
- relative Tx performance drop is seen but is within reasonable and
expected threshold (A-MSDU must be disabled with RAW Tx)
b) Connectivity Testing
cryptmode=1
ap=iwl6205 sta1=qca988x crypto=open topology-1ap1sta OK
ap=iwl6205 sta1=qca988x crypto=wep1 topology-1ap1sta OK
ap=iwl6205 sta1=qca988x crypto=wpa topology-1ap1sta OK
ap=iwl6205 sta1=qca988x crypto=wpa-ccmp topology-1ap1sta OK
ap=qca988x sta1=iwl6205 crypto=open topology-1ap1sta OK
ap=qca988x sta1=iwl6205 crypto=wep1 topology-1ap1sta OK
ap=qca988x sta1=iwl6205 crypto=wpa topology-1ap1sta OK
ap=qca988x sta1=iwl6205 crypto=wpa-ccmp topology-1ap1sta OK
ap=iwl6205 sta1=qca988x crypto=open topology-1ap1sta2br OK
ap=iwl6205 sta1=qca988x crypto=wep1 topology-1ap1sta2br OK
ap=iwl6205 sta1=qca988x crypto=wpa topology-1ap1sta2br OK
ap=iwl6205 sta1=qca988x crypto=wpa-ccmp topology-1ap1sta2br OK
ap=qca988x sta1=iwl6205 crypto=open topology-1ap1sta2br OK
ap=qca988x sta1=iwl6205 crypto=wep1 topology-1ap1sta2br OK
ap=qca988x sta1=iwl6205 crypto=wpa topology-1ap1sta2br OK
ap=qca988x sta1=iwl6205 crypto=wpa-ccmp topology-1ap1sta2br OK
ap=iwl6205 sta1=qca988x crypto=open topology-1ap1sta2br1vlan OK
ap=iwl6205 sta1=qca988x crypto=wep1 topology-1ap1sta2br1vlan OK
ap=iwl6205 sta1=qca988x crypto=wpa topology-1ap1sta2br1vlan OK
ap=iwl6205 sta1=qca988x crypto=wpa-ccmp topology-1ap1sta2br1vlan OK
ap=qca988x sta1=iwl6205 crypto=open topology-1ap1sta2br1vlan OK
ap=qca988x sta1=iwl6205 crypto=wep1 topology-1ap1sta2br1vlan OK
ap=qca988x sta1=iwl6205 crypto=wpa topology-1ap1sta2br1vlan OK
ap=qca988x sta1=iwl6205 crypto=wpa-ccmp topology-1ap1sta2br1vlan OK
Note:
- each test takes all possible endpoint pairs and pings
- each pair-ping flushes arp table
- ip6 is used
c) Testbed Topology:
1ap1sta:
[ap] ---- [sta]
endpoints: ap, sta
1ap1sta2br:
[veth0] [ap] ---- [sta] [veth2]
| | | |
[veth1] | \ [veth3]
\ / \ /
[br0] [br1]
endpoints: veth0, veth2, br0, br1
note: STA works in 4addr mode, AP has wds_sta=1
1ap1sta2br1vlan:
[veth0] [ap] ---- [sta] [veth2]
| | | |
[veth1] | \ [veth3]
\ / \ /
[br0] [br1]
| |
[vlan0_id2] [vlan1_id2]
endpoints: vlan0_id2, vlan1_id2
note: STA works in 4addr mode, AP has wds_sta=1
Credits:
Thanks to Michal Kazior <michal.kazior@tieto.com> who helped find the
amsdu issue, contributed a workaround (already squashed into this
patch), and contributed the throughput and connectivity tests results.
Signed-off-by: David Liu <cfliu.tw@gmail.com>
Signed-off-by: Michal Kazior <michal.kazior@tieto.com>
Tested-by: Michal Kazior <michal.kazior@tieto.com>
Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
2015-07-24 17:25:32 +00:00
|
|
|
static unsigned int ath10k_cryptmode_param;
|
2013-06-12 17:52:10 +00:00
|
|
|
static bool uart_print;
|
2014-11-17 14:44:14 +00:00
|
|
|
static bool skip_otp;
|
2015-09-09 16:47:36 +00:00
|
|
|
static bool rawmode;
|
2014-11-17 14:44:14 +00:00
|
|
|
|
2018-06-11 18:19:35 +00:00
|
|
|
unsigned long ath10k_coredump_mask = BIT(ATH10K_FW_CRASH_DUMP_REGISTERS) |
|
|
|
|
BIT(ATH10K_FW_CRASH_DUMP_CE_DATA);
|
2017-12-22 13:39:15 +00:00
|
|
|
|
|
|
|
/* FIXME: most of these should be readonly */
|
2013-06-12 17:52:10 +00:00
|
|
|
module_param_named(debug_mask, ath10k_debug_mask, uint, 0644);
|
ath10k: enable raw encap mode and software crypto engine
This patch enables raw Rx/Tx encap mode to support software based
crypto engine. This patch introduces a new module param 'cryptmode'.
cryptmode:
0: Use hardware crypto engine globally with native Wi-Fi mode TX/RX
encapsulation to the firmware. This is the default mode.
1: Use sofware crypto engine globally with raw mode TX/RX
encapsulation to the firmware.
Known limitation:
A-MSDU must be disabled for RAW Tx encap mode to perform well when
heavy traffic is applied.
Testing: (by Michal Kazior <michal.kazior@tieto.com>)
a) Performance Testing
cryptmode=1
ap=qca988x sta=killer1525
killer1525 -> qca988x 194.496 mbps [tcp1 ip4]
killer1525 -> qca988x 238.309 mbps [tcp5 ip4]
killer1525 -> qca988x 266.958 mbps [udp1 ip4]
killer1525 -> qca988x 477.468 mbps [udp5 ip4]
qca988x -> killer1525 301.378 mbps [tcp1 ip4]
qca988x -> killer1525 297.949 mbps [tcp5 ip4]
qca988x -> killer1525 331.351 mbps [udp1 ip4]
qca988x -> killer1525 371.528 mbps [udp5 ip4]
ap=killer1525 sta=qca988x
qca988x -> killer1525 331.447 mbps [tcp1 ip4]
qca988x -> killer1525 328.783 mbps [tcp5 ip4]
qca988x -> killer1525 375.309 mbps [udp1 ip4]
qca988x -> killer1525 403.379 mbps [udp5 ip4]
killer1525 -> qca988x 203.689 mbps [tcp1 ip4]
killer1525 -> qca988x 222.339 mbps [tcp5 ip4]
killer1525 -> qca988x 264.199 mbps [udp1 ip4]
killer1525 -> qca988x 479.371 mbps [udp5 ip4]
Note:
- only open network tested for RAW vs nwifi performance comparison
- killer1525 (qca6174 hw2.2) is 2x2 device (hence max 866mbps)
- used iperf
- OTA, devices a few cm apart from each other, no shielding
- tcpX/udpX, X - means number of threads used
Overview:
- relative Tx performance drop is seen but is within reasonable and
expected threshold (A-MSDU must be disabled with RAW Tx)
b) Connectivity Testing
cryptmode=1
ap=iwl6205 sta1=qca988x crypto=open topology-1ap1sta OK
ap=iwl6205 sta1=qca988x crypto=wep1 topology-1ap1sta OK
ap=iwl6205 sta1=qca988x crypto=wpa topology-1ap1sta OK
ap=iwl6205 sta1=qca988x crypto=wpa-ccmp topology-1ap1sta OK
ap=qca988x sta1=iwl6205 crypto=open topology-1ap1sta OK
ap=qca988x sta1=iwl6205 crypto=wep1 topology-1ap1sta OK
ap=qca988x sta1=iwl6205 crypto=wpa topology-1ap1sta OK
ap=qca988x sta1=iwl6205 crypto=wpa-ccmp topology-1ap1sta OK
ap=iwl6205 sta1=qca988x crypto=open topology-1ap1sta2br OK
ap=iwl6205 sta1=qca988x crypto=wep1 topology-1ap1sta2br OK
ap=iwl6205 sta1=qca988x crypto=wpa topology-1ap1sta2br OK
ap=iwl6205 sta1=qca988x crypto=wpa-ccmp topology-1ap1sta2br OK
ap=qca988x sta1=iwl6205 crypto=open topology-1ap1sta2br OK
ap=qca988x sta1=iwl6205 crypto=wep1 topology-1ap1sta2br OK
ap=qca988x sta1=iwl6205 crypto=wpa topology-1ap1sta2br OK
ap=qca988x sta1=iwl6205 crypto=wpa-ccmp topology-1ap1sta2br OK
ap=iwl6205 sta1=qca988x crypto=open topology-1ap1sta2br1vlan OK
ap=iwl6205 sta1=qca988x crypto=wep1 topology-1ap1sta2br1vlan OK
ap=iwl6205 sta1=qca988x crypto=wpa topology-1ap1sta2br1vlan OK
ap=iwl6205 sta1=qca988x crypto=wpa-ccmp topology-1ap1sta2br1vlan OK
ap=qca988x sta1=iwl6205 crypto=open topology-1ap1sta2br1vlan OK
ap=qca988x sta1=iwl6205 crypto=wep1 topology-1ap1sta2br1vlan OK
ap=qca988x sta1=iwl6205 crypto=wpa topology-1ap1sta2br1vlan OK
ap=qca988x sta1=iwl6205 crypto=wpa-ccmp topology-1ap1sta2br1vlan OK
Note:
- each test takes all possible endpoint pairs and pings
- each pair-ping flushes arp table
- ip6 is used
c) Testbed Topology:
1ap1sta:
[ap] ---- [sta]
endpoints: ap, sta
1ap1sta2br:
[veth0] [ap] ---- [sta] [veth2]
| | | |
[veth1] | \ [veth3]
\ / \ /
[br0] [br1]
endpoints: veth0, veth2, br0, br1
note: STA works in 4addr mode, AP has wds_sta=1
1ap1sta2br1vlan:
[veth0] [ap] ---- [sta] [veth2]
| | | |
[veth1] | \ [veth3]
\ / \ /
[br0] [br1]
| |
[vlan0_id2] [vlan1_id2]
endpoints: vlan0_id2, vlan1_id2
note: STA works in 4addr mode, AP has wds_sta=1
Credits:
Thanks to Michal Kazior <michal.kazior@tieto.com> who helped find the
amsdu issue, contributed a workaround (already squashed into this
patch), and contributed the throughput and connectivity tests results.
Signed-off-by: David Liu <cfliu.tw@gmail.com>
Signed-off-by: Michal Kazior <michal.kazior@tieto.com>
Tested-by: Michal Kazior <michal.kazior@tieto.com>
Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
2015-07-24 17:25:32 +00:00
|
|
|
module_param_named(cryptmode, ath10k_cryptmode_param, uint, 0644);
|
2013-06-12 17:52:10 +00:00
|
|
|
module_param(uart_print, bool, 0644);
|
2014-11-17 14:44:14 +00:00
|
|
|
module_param(skip_otp, bool, 0644);
|
2015-09-09 16:47:36 +00:00
|
|
|
module_param(rawmode, bool, 0644);
|
2017-12-22 13:39:15 +00:00
|
|
|
module_param_named(coredump_mask, ath10k_coredump_mask, ulong, 0444);
|
2014-11-17 14:44:14 +00:00
|
|
|
|
2013-06-12 17:52:10 +00:00
|
|
|
MODULE_PARM_DESC(debug_mask, "Debugging mask");
|
|
|
|
MODULE_PARM_DESC(uart_print, "Uart target debugging");
|
2014-11-17 14:44:14 +00:00
|
|
|
MODULE_PARM_DESC(skip_otp, "Skip otp failure for calibration in testmode");
|
ath10k: enable raw encap mode and software crypto engine
This patch enables raw Rx/Tx encap mode to support software based
crypto engine. This patch introduces a new module param 'cryptmode'.
cryptmode:
0: Use hardware crypto engine globally with native Wi-Fi mode TX/RX
encapsulation to the firmware. This is the default mode.
1: Use sofware crypto engine globally with raw mode TX/RX
encapsulation to the firmware.
Known limitation:
A-MSDU must be disabled for RAW Tx encap mode to perform well when
heavy traffic is applied.
Testing: (by Michal Kazior <michal.kazior@tieto.com>)
a) Performance Testing
cryptmode=1
ap=qca988x sta=killer1525
killer1525 -> qca988x 194.496 mbps [tcp1 ip4]
killer1525 -> qca988x 238.309 mbps [tcp5 ip4]
killer1525 -> qca988x 266.958 mbps [udp1 ip4]
killer1525 -> qca988x 477.468 mbps [udp5 ip4]
qca988x -> killer1525 301.378 mbps [tcp1 ip4]
qca988x -> killer1525 297.949 mbps [tcp5 ip4]
qca988x -> killer1525 331.351 mbps [udp1 ip4]
qca988x -> killer1525 371.528 mbps [udp5 ip4]
ap=killer1525 sta=qca988x
qca988x -> killer1525 331.447 mbps [tcp1 ip4]
qca988x -> killer1525 328.783 mbps [tcp5 ip4]
qca988x -> killer1525 375.309 mbps [udp1 ip4]
qca988x -> killer1525 403.379 mbps [udp5 ip4]
killer1525 -> qca988x 203.689 mbps [tcp1 ip4]
killer1525 -> qca988x 222.339 mbps [tcp5 ip4]
killer1525 -> qca988x 264.199 mbps [udp1 ip4]
killer1525 -> qca988x 479.371 mbps [udp5 ip4]
Note:
- only open network tested for RAW vs nwifi performance comparison
- killer1525 (qca6174 hw2.2) is 2x2 device (hence max 866mbps)
- used iperf
- OTA, devices a few cm apart from each other, no shielding
- tcpX/udpX, X - means number of threads used
Overview:
- relative Tx performance drop is seen but is within reasonable and
expected threshold (A-MSDU must be disabled with RAW Tx)
b) Connectivity Testing
cryptmode=1
ap=iwl6205 sta1=qca988x crypto=open topology-1ap1sta OK
ap=iwl6205 sta1=qca988x crypto=wep1 topology-1ap1sta OK
ap=iwl6205 sta1=qca988x crypto=wpa topology-1ap1sta OK
ap=iwl6205 sta1=qca988x crypto=wpa-ccmp topology-1ap1sta OK
ap=qca988x sta1=iwl6205 crypto=open topology-1ap1sta OK
ap=qca988x sta1=iwl6205 crypto=wep1 topology-1ap1sta OK
ap=qca988x sta1=iwl6205 crypto=wpa topology-1ap1sta OK
ap=qca988x sta1=iwl6205 crypto=wpa-ccmp topology-1ap1sta OK
ap=iwl6205 sta1=qca988x crypto=open topology-1ap1sta2br OK
ap=iwl6205 sta1=qca988x crypto=wep1 topology-1ap1sta2br OK
ap=iwl6205 sta1=qca988x crypto=wpa topology-1ap1sta2br OK
ap=iwl6205 sta1=qca988x crypto=wpa-ccmp topology-1ap1sta2br OK
ap=qca988x sta1=iwl6205 crypto=open topology-1ap1sta2br OK
ap=qca988x sta1=iwl6205 crypto=wep1 topology-1ap1sta2br OK
ap=qca988x sta1=iwl6205 crypto=wpa topology-1ap1sta2br OK
ap=qca988x sta1=iwl6205 crypto=wpa-ccmp topology-1ap1sta2br OK
ap=iwl6205 sta1=qca988x crypto=open topology-1ap1sta2br1vlan OK
ap=iwl6205 sta1=qca988x crypto=wep1 topology-1ap1sta2br1vlan OK
ap=iwl6205 sta1=qca988x crypto=wpa topology-1ap1sta2br1vlan OK
ap=iwl6205 sta1=qca988x crypto=wpa-ccmp topology-1ap1sta2br1vlan OK
ap=qca988x sta1=iwl6205 crypto=open topology-1ap1sta2br1vlan OK
ap=qca988x sta1=iwl6205 crypto=wep1 topology-1ap1sta2br1vlan OK
ap=qca988x sta1=iwl6205 crypto=wpa topology-1ap1sta2br1vlan OK
ap=qca988x sta1=iwl6205 crypto=wpa-ccmp topology-1ap1sta2br1vlan OK
Note:
- each test takes all possible endpoint pairs and pings
- each pair-ping flushes arp table
- ip6 is used
c) Testbed Topology:
1ap1sta:
[ap] ---- [sta]
endpoints: ap, sta
1ap1sta2br:
[veth0] [ap] ---- [sta] [veth2]
| | | |
[veth1] | \ [veth3]
\ / \ /
[br0] [br1]
endpoints: veth0, veth2, br0, br1
note: STA works in 4addr mode, AP has wds_sta=1
1ap1sta2br1vlan:
[veth0] [ap] ---- [sta] [veth2]
| | | |
[veth1] | \ [veth3]
\ / \ /
[br0] [br1]
| |
[vlan0_id2] [vlan1_id2]
endpoints: vlan0_id2, vlan1_id2
note: STA works in 4addr mode, AP has wds_sta=1
Credits:
Thanks to Michal Kazior <michal.kazior@tieto.com> who helped find the
amsdu issue, contributed a workaround (already squashed into this
patch), and contributed the throughput and connectivity tests results.
Signed-off-by: David Liu <cfliu.tw@gmail.com>
Signed-off-by: Michal Kazior <michal.kazior@tieto.com>
Tested-by: Michal Kazior <michal.kazior@tieto.com>
Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
2015-07-24 17:25:32 +00:00
|
|
|
MODULE_PARM_DESC(cryptmode, "Crypto mode: 0-hardware, 1-software");
|
2015-09-09 16:47:36 +00:00
|
|
|
MODULE_PARM_DESC(rawmode, "Use raw 802.11 frame datapath");
|
2017-12-22 13:39:15 +00:00
|
|
|
MODULE_PARM_DESC(coredump_mask, "Bitfield of what to include in firmware crash file");
|
2013-06-12 17:52:10 +00:00
|
|
|
|
|
|
|
static const struct ath10k_hw_params ath10k_hw_params_list[] = {
|
|
|
|
{
|
|
|
|
.id = QCA988X_HW_2_0_VERSION,
|
2015-11-05 08:50:42 +00:00
|
|
|
.dev_id = QCA988X_2_0_DEVICE_ID,
|
2013-06-12 17:52:10 +00:00
|
|
|
.name = "qca988x hw2.0",
|
|
|
|
.patch_load_addr = QCA988X_HW_2_0_PATCH_LOAD_ADDR,
|
2014-12-02 08:55:55 +00:00
|
|
|
.uart_pin = 7,
|
2016-06-07 12:47:05 +00:00
|
|
|
.cc_wraparound_type = ATH10K_HW_CC_WRAP_SHIFTED_ALL,
|
2015-06-18 07:01:10 +00:00
|
|
|
.otp_exe_param = 0,
|
2015-08-12 10:54:05 +00:00
|
|
|
.channel_counters_freq_hz = 88000,
|
2015-08-31 11:04:55 +00:00
|
|
|
.max_probe_resp_desc_thres = 0,
|
2016-03-18 09:44:22 +00:00
|
|
|
.cal_data_len = 2116,
|
2013-06-12 17:52:10 +00:00
|
|
|
.fw = {
|
|
|
|
.dir = QCA988X_HW_2_0_FW_DIR,
|
|
|
|
.board = QCA988X_HW_2_0_BOARD_DATA_FILE,
|
2014-12-02 08:55:54 +00:00
|
|
|
.board_size = QCA988X_BOARD_DATA_SZ,
|
|
|
|
.board_ext_size = QCA988X_BOARD_EXT_DATA_SZ,
|
2013-06-12 17:52:10 +00:00
|
|
|
},
|
2016-09-09 14:25:22 +00:00
|
|
|
.hw_ops = &qca988x_ops,
|
2016-09-26 18:56:24 +00:00
|
|
|
.decap_align_bytes = 4,
|
2017-04-10 15:38:17 +00:00
|
|
|
.spectral_bin_discard = 0,
|
2018-05-29 11:31:13 +00:00
|
|
|
.spectral_bin_offset = 0,
|
ath10k: configure rxnss_override for QCA9984
QCA9984 hardware can do 4x4 at 80Mhz, but only 2x2 at 160Mhz.
First, report this to user-space by setting the max-tx-speed
and max-rx-speed vht capabilities.
Second, if the peer rx-speed is configured, and if we
are in 160 or 80+80 mode, and the peer rx-speed matches
the max speed for 2x2 or 1x1 at 160Mhz (long guard interval),
then use that info to set the peer_bw_rxnss_override appropriately.
Without this, a 9984 firmware will not use 2x2 ratesets when
transmitting to peer (it will be stuck at 1x1), because
the firmware would not have configured the rxnss_override.
Signed-off-by: Ben Greear <greearb@candelatech.com>
[sven.eckelmann@openmesh.com: rebase, cleanup, drop 160Mhz workaround cleanup]
Signed-off-by: Sven Eckelmann <sven.eckelmann@openmesh.com>
[kvalo@qca.qualcomm.com: use hw_params, rename the title]
Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
2017-06-16 07:37:45 +00:00
|
|
|
.vht160_mcs_rx_highest = 0,
|
|
|
|
.vht160_mcs_tx_highest = 0,
|
2017-09-25 22:29:41 +00:00
|
|
|
.n_cipher_suites = 8,
|
2017-12-11 14:22:54 +00:00
|
|
|
.num_peers = TARGET_TLV_NUM_PEERS,
|
|
|
|
.ast_skid_limit = 0x10,
|
|
|
|
.num_wds_entries = 0x20,
|
2018-01-30 12:06:05 +00:00
|
|
|
.target_64bit = false,
|
|
|
|
.rx_ring_fill_level = HTT_RX_RING_FILL_LEVEL,
|
2018-04-17 12:06:58 +00:00
|
|
|
.shadow_reg_support = false,
|
2018-04-17 12:07:00 +00:00
|
|
|
.rri_on_ddr = false,
|
2018-01-30 12:06:05 +00:00
|
|
|
},
|
|
|
|
{
|
|
|
|
.id = QCA988X_HW_2_0_VERSION,
|
|
|
|
.dev_id = QCA988X_2_0_DEVICE_ID_UBNT,
|
|
|
|
.name = "qca988x hw2.0 ubiquiti",
|
|
|
|
.patch_load_addr = QCA988X_HW_2_0_PATCH_LOAD_ADDR,
|
|
|
|
.uart_pin = 7,
|
|
|
|
.cc_wraparound_type = ATH10K_HW_CC_WRAP_SHIFTED_ALL,
|
|
|
|
.otp_exe_param = 0,
|
|
|
|
.channel_counters_freq_hz = 88000,
|
|
|
|
.max_probe_resp_desc_thres = 0,
|
|
|
|
.cal_data_len = 2116,
|
|
|
|
.fw = {
|
|
|
|
.dir = QCA988X_HW_2_0_FW_DIR,
|
|
|
|
.board = QCA988X_HW_2_0_BOARD_DATA_FILE,
|
|
|
|
.board_size = QCA988X_BOARD_DATA_SZ,
|
|
|
|
.board_ext_size = QCA988X_BOARD_EXT_DATA_SZ,
|
|
|
|
},
|
|
|
|
.hw_ops = &qca988x_ops,
|
|
|
|
.decap_align_bytes = 4,
|
|
|
|
.spectral_bin_discard = 0,
|
2018-05-29 11:31:13 +00:00
|
|
|
.spectral_bin_offset = 0,
|
2018-01-30 12:06:05 +00:00
|
|
|
.vht160_mcs_rx_highest = 0,
|
|
|
|
.vht160_mcs_tx_highest = 0,
|
|
|
|
.n_cipher_suites = 8,
|
|
|
|
.num_peers = TARGET_TLV_NUM_PEERS,
|
|
|
|
.ast_skid_limit = 0x10,
|
|
|
|
.num_wds_entries = 0x20,
|
2017-12-21 09:00:50 +00:00
|
|
|
.target_64bit = false,
|
2017-12-21 09:00:56 +00:00
|
|
|
.rx_ring_fill_level = HTT_RX_RING_FILL_LEVEL,
|
2018-04-10 15:01:32 +00:00
|
|
|
.per_ce_irq = false,
|
2018-04-17 12:06:58 +00:00
|
|
|
.shadow_reg_support = false,
|
2018-04-17 12:07:00 +00:00
|
|
|
.rri_on_ddr = false,
|
2013-06-12 17:52:10 +00:00
|
|
|
},
|
2016-06-02 14:59:49 +00:00
|
|
|
{
|
|
|
|
.id = QCA9887_HW_1_0_VERSION,
|
|
|
|
.dev_id = QCA9887_1_0_DEVICE_ID,
|
|
|
|
.name = "qca9887 hw1.0",
|
|
|
|
.patch_load_addr = QCA9887_HW_1_0_PATCH_LOAD_ADDR,
|
|
|
|
.uart_pin = 7,
|
2016-06-07 12:47:05 +00:00
|
|
|
.cc_wraparound_type = ATH10K_HW_CC_WRAP_SHIFTED_ALL,
|
2016-06-02 14:59:49 +00:00
|
|
|
.otp_exe_param = 0,
|
|
|
|
.channel_counters_freq_hz = 88000,
|
|
|
|
.max_probe_resp_desc_thres = 0,
|
|
|
|
.cal_data_len = 2116,
|
|
|
|
.fw = {
|
|
|
|
.dir = QCA9887_HW_1_0_FW_DIR,
|
|
|
|
.board = QCA9887_HW_1_0_BOARD_DATA_FILE,
|
|
|
|
.board_size = QCA9887_BOARD_DATA_SZ,
|
|
|
|
.board_ext_size = QCA9887_BOARD_EXT_DATA_SZ,
|
|
|
|
},
|
2016-09-09 14:25:22 +00:00
|
|
|
.hw_ops = &qca988x_ops,
|
2016-09-26 18:56:24 +00:00
|
|
|
.decap_align_bytes = 4,
|
2017-04-10 15:38:17 +00:00
|
|
|
.spectral_bin_discard = 0,
|
2018-05-29 11:31:13 +00:00
|
|
|
.spectral_bin_offset = 0,
|
ath10k: configure rxnss_override for QCA9984
QCA9984 hardware can do 4x4 at 80Mhz, but only 2x2 at 160Mhz.
First, report this to user-space by setting the max-tx-speed
and max-rx-speed vht capabilities.
Second, if the peer rx-speed is configured, and if we
are in 160 or 80+80 mode, and the peer rx-speed matches
the max speed for 2x2 or 1x1 at 160Mhz (long guard interval),
then use that info to set the peer_bw_rxnss_override appropriately.
Without this, a 9984 firmware will not use 2x2 ratesets when
transmitting to peer (it will be stuck at 1x1), because
the firmware would not have configured the rxnss_override.
Signed-off-by: Ben Greear <greearb@candelatech.com>
[sven.eckelmann@openmesh.com: rebase, cleanup, drop 160Mhz workaround cleanup]
Signed-off-by: Sven Eckelmann <sven.eckelmann@openmesh.com>
[kvalo@qca.qualcomm.com: use hw_params, rename the title]
Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
2017-06-16 07:37:45 +00:00
|
|
|
.vht160_mcs_rx_highest = 0,
|
|
|
|
.vht160_mcs_tx_highest = 0,
|
2017-09-25 22:29:41 +00:00
|
|
|
.n_cipher_suites = 8,
|
2017-12-11 14:22:54 +00:00
|
|
|
.num_peers = TARGET_TLV_NUM_PEERS,
|
|
|
|
.ast_skid_limit = 0x10,
|
|
|
|
.num_wds_entries = 0x20,
|
2017-12-21 09:00:50 +00:00
|
|
|
.target_64bit = false,
|
2017-12-21 09:00:56 +00:00
|
|
|
.rx_ring_fill_level = HTT_RX_RING_FILL_LEVEL,
|
2018-04-10 15:01:32 +00:00
|
|
|
.per_ce_irq = false,
|
2018-04-17 12:06:58 +00:00
|
|
|
.shadow_reg_support = false,
|
2018-04-17 12:07:00 +00:00
|
|
|
.rri_on_ddr = false,
|
2016-06-02 14:59:49 +00:00
|
|
|
},
|
2015-01-24 10:14:49 +00:00
|
|
|
{
|
|
|
|
.id = QCA6174_HW_2_1_VERSION,
|
2015-11-05 08:50:42 +00:00
|
|
|
.dev_id = QCA6164_2_1_DEVICE_ID,
|
|
|
|
.name = "qca6164 hw2.1",
|
|
|
|
.patch_load_addr = QCA6174_HW_2_1_PATCH_LOAD_ADDR,
|
|
|
|
.uart_pin = 6,
|
|
|
|
.otp_exe_param = 0,
|
|
|
|
.channel_counters_freq_hz = 88000,
|
|
|
|
.max_probe_resp_desc_thres = 0,
|
2016-03-18 09:44:22 +00:00
|
|
|
.cal_data_len = 8124,
|
2015-11-05 08:50:42 +00:00
|
|
|
.fw = {
|
|
|
|
.dir = QCA6174_HW_2_1_FW_DIR,
|
|
|
|
.board = QCA6174_HW_2_1_BOARD_DATA_FILE,
|
|
|
|
.board_size = QCA6174_BOARD_DATA_SZ,
|
|
|
|
.board_ext_size = QCA6174_BOARD_EXT_DATA_SZ,
|
|
|
|
},
|
2016-09-09 14:25:22 +00:00
|
|
|
.hw_ops = &qca988x_ops,
|
2016-09-26 18:56:24 +00:00
|
|
|
.decap_align_bytes = 4,
|
2017-04-10 15:38:17 +00:00
|
|
|
.spectral_bin_discard = 0,
|
2018-05-29 11:31:13 +00:00
|
|
|
.spectral_bin_offset = 0,
|
ath10k: configure rxnss_override for QCA9984
QCA9984 hardware can do 4x4 at 80Mhz, but only 2x2 at 160Mhz.
First, report this to user-space by setting the max-tx-speed
and max-rx-speed vht capabilities.
Second, if the peer rx-speed is configured, and if we
are in 160 or 80+80 mode, and the peer rx-speed matches
the max speed for 2x2 or 1x1 at 160Mhz (long guard interval),
then use that info to set the peer_bw_rxnss_override appropriately.
Without this, a 9984 firmware will not use 2x2 ratesets when
transmitting to peer (it will be stuck at 1x1), because
the firmware would not have configured the rxnss_override.
Signed-off-by: Ben Greear <greearb@candelatech.com>
[sven.eckelmann@openmesh.com: rebase, cleanup, drop 160Mhz workaround cleanup]
Signed-off-by: Sven Eckelmann <sven.eckelmann@openmesh.com>
[kvalo@qca.qualcomm.com: use hw_params, rename the title]
Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
2017-06-16 07:37:45 +00:00
|
|
|
.vht160_mcs_rx_highest = 0,
|
|
|
|
.vht160_mcs_tx_highest = 0,
|
2017-09-25 22:29:41 +00:00
|
|
|
.n_cipher_suites = 8,
|
2017-12-11 14:22:54 +00:00
|
|
|
.num_peers = TARGET_TLV_NUM_PEERS,
|
|
|
|
.ast_skid_limit = 0x10,
|
|
|
|
.num_wds_entries = 0x20,
|
2017-12-21 09:00:50 +00:00
|
|
|
.target_64bit = false,
|
2017-12-21 09:00:56 +00:00
|
|
|
.rx_ring_fill_level = HTT_RX_RING_FILL_LEVEL,
|
2018-04-10 15:01:32 +00:00
|
|
|
.per_ce_irq = false,
|
2018-04-17 12:06:58 +00:00
|
|
|
.shadow_reg_support = false,
|
2018-04-17 12:07:00 +00:00
|
|
|
.rri_on_ddr = false,
|
2015-11-05 08:50:42 +00:00
|
|
|
},
|
|
|
|
{
|
|
|
|
.id = QCA6174_HW_2_1_VERSION,
|
|
|
|
.dev_id = QCA6174_2_1_DEVICE_ID,
|
2015-01-24 10:14:49 +00:00
|
|
|
.name = "qca6174 hw2.1",
|
|
|
|
.patch_load_addr = QCA6174_HW_2_1_PATCH_LOAD_ADDR,
|
|
|
|
.uart_pin = 6,
|
2015-06-18 07:01:10 +00:00
|
|
|
.otp_exe_param = 0,
|
2015-08-12 10:54:05 +00:00
|
|
|
.channel_counters_freq_hz = 88000,
|
2015-08-31 11:04:55 +00:00
|
|
|
.max_probe_resp_desc_thres = 0,
|
2016-03-18 09:44:22 +00:00
|
|
|
.cal_data_len = 8124,
|
2015-01-24 10:14:49 +00:00
|
|
|
.fw = {
|
|
|
|
.dir = QCA6174_HW_2_1_FW_DIR,
|
|
|
|
.board = QCA6174_HW_2_1_BOARD_DATA_FILE,
|
|
|
|
.board_size = QCA6174_BOARD_DATA_SZ,
|
|
|
|
.board_ext_size = QCA6174_BOARD_EXT_DATA_SZ,
|
|
|
|
},
|
2016-09-09 14:25:22 +00:00
|
|
|
.hw_ops = &qca988x_ops,
|
2016-09-26 18:56:24 +00:00
|
|
|
.decap_align_bytes = 4,
|
2017-04-10 15:38:17 +00:00
|
|
|
.spectral_bin_discard = 0,
|
2018-05-29 11:31:13 +00:00
|
|
|
.spectral_bin_offset = 0,
|
ath10k: configure rxnss_override for QCA9984
QCA9984 hardware can do 4x4 at 80Mhz, but only 2x2 at 160Mhz.
First, report this to user-space by setting the max-tx-speed
and max-rx-speed vht capabilities.
Second, if the peer rx-speed is configured, and if we
are in 160 or 80+80 mode, and the peer rx-speed matches
the max speed for 2x2 or 1x1 at 160Mhz (long guard interval),
then use that info to set the peer_bw_rxnss_override appropriately.
Without this, a 9984 firmware will not use 2x2 ratesets when
transmitting to peer (it will be stuck at 1x1), because
the firmware would not have configured the rxnss_override.
Signed-off-by: Ben Greear <greearb@candelatech.com>
[sven.eckelmann@openmesh.com: rebase, cleanup, drop 160Mhz workaround cleanup]
Signed-off-by: Sven Eckelmann <sven.eckelmann@openmesh.com>
[kvalo@qca.qualcomm.com: use hw_params, rename the title]
Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
2017-06-16 07:37:45 +00:00
|
|
|
.vht160_mcs_rx_highest = 0,
|
|
|
|
.vht160_mcs_tx_highest = 0,
|
2017-09-25 22:29:41 +00:00
|
|
|
.n_cipher_suites = 8,
|
2017-12-11 14:22:54 +00:00
|
|
|
.num_peers = TARGET_TLV_NUM_PEERS,
|
|
|
|
.ast_skid_limit = 0x10,
|
|
|
|
.num_wds_entries = 0x20,
|
2017-12-21 09:00:50 +00:00
|
|
|
.target_64bit = false,
|
2017-12-21 09:00:56 +00:00
|
|
|
.rx_ring_fill_level = HTT_RX_RING_FILL_LEVEL,
|
2018-04-10 15:01:32 +00:00
|
|
|
.per_ce_irq = false,
|
2018-04-17 12:06:58 +00:00
|
|
|
.shadow_reg_support = false,
|
2018-04-17 12:07:00 +00:00
|
|
|
.rri_on_ddr = false,
|
2015-01-24 10:14:49 +00:00
|
|
|
},
|
|
|
|
{
|
|
|
|
.id = QCA6174_HW_3_0_VERSION,
|
2015-11-05 08:50:42 +00:00
|
|
|
.dev_id = QCA6174_2_1_DEVICE_ID,
|
2015-01-24 10:14:49 +00:00
|
|
|
.name = "qca6174 hw3.0",
|
|
|
|
.patch_load_addr = QCA6174_HW_3_0_PATCH_LOAD_ADDR,
|
|
|
|
.uart_pin = 6,
|
2015-06-18 07:01:10 +00:00
|
|
|
.otp_exe_param = 0,
|
2015-08-12 10:54:05 +00:00
|
|
|
.channel_counters_freq_hz = 88000,
|
2015-08-31 11:04:55 +00:00
|
|
|
.max_probe_resp_desc_thres = 0,
|
2016-03-18 09:44:22 +00:00
|
|
|
.cal_data_len = 8124,
|
2015-01-24 10:14:49 +00:00
|
|
|
.fw = {
|
|
|
|
.dir = QCA6174_HW_3_0_FW_DIR,
|
|
|
|
.board = QCA6174_HW_3_0_BOARD_DATA_FILE,
|
|
|
|
.board_size = QCA6174_BOARD_DATA_SZ,
|
|
|
|
.board_ext_size = QCA6174_BOARD_EXT_DATA_SZ,
|
|
|
|
},
|
2016-09-09 14:25:22 +00:00
|
|
|
.hw_ops = &qca988x_ops,
|
2016-09-26 18:56:24 +00:00
|
|
|
.decap_align_bytes = 4,
|
2017-04-10 15:38:17 +00:00
|
|
|
.spectral_bin_discard = 0,
|
2018-05-29 11:31:13 +00:00
|
|
|
.spectral_bin_offset = 0,
|
ath10k: configure rxnss_override for QCA9984
QCA9984 hardware can do 4x4 at 80Mhz, but only 2x2 at 160Mhz.
First, report this to user-space by setting the max-tx-speed
and max-rx-speed vht capabilities.
Second, if the peer rx-speed is configured, and if we
are in 160 or 80+80 mode, and the peer rx-speed matches
the max speed for 2x2 or 1x1 at 160Mhz (long guard interval),
then use that info to set the peer_bw_rxnss_override appropriately.
Without this, a 9984 firmware will not use 2x2 ratesets when
transmitting to peer (it will be stuck at 1x1), because
the firmware would not have configured the rxnss_override.
Signed-off-by: Ben Greear <greearb@candelatech.com>
[sven.eckelmann@openmesh.com: rebase, cleanup, drop 160Mhz workaround cleanup]
Signed-off-by: Sven Eckelmann <sven.eckelmann@openmesh.com>
[kvalo@qca.qualcomm.com: use hw_params, rename the title]
Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
2017-06-16 07:37:45 +00:00
|
|
|
.vht160_mcs_rx_highest = 0,
|
|
|
|
.vht160_mcs_tx_highest = 0,
|
2017-09-25 22:29:41 +00:00
|
|
|
.n_cipher_suites = 8,
|
2017-12-11 14:22:54 +00:00
|
|
|
.num_peers = TARGET_TLV_NUM_PEERS,
|
|
|
|
.ast_skid_limit = 0x10,
|
|
|
|
.num_wds_entries = 0x20,
|
2017-12-21 09:00:50 +00:00
|
|
|
.target_64bit = false,
|
2017-12-21 09:00:56 +00:00
|
|
|
.rx_ring_fill_level = HTT_RX_RING_FILL_LEVEL,
|
2018-04-10 15:01:32 +00:00
|
|
|
.per_ce_irq = false,
|
2018-04-17 12:06:58 +00:00
|
|
|
.shadow_reg_support = false,
|
2018-04-17 12:07:00 +00:00
|
|
|
.rri_on_ddr = false,
|
2015-01-24 10:14:49 +00:00
|
|
|
},
|
2015-01-29 12:24:33 +00:00
|
|
|
{
|
|
|
|
.id = QCA6174_HW_3_2_VERSION,
|
2015-11-05 08:50:42 +00:00
|
|
|
.dev_id = QCA6174_2_1_DEVICE_ID,
|
2015-01-29 12:24:33 +00:00
|
|
|
.name = "qca6174 hw3.2",
|
|
|
|
.patch_load_addr = QCA6174_HW_3_0_PATCH_LOAD_ADDR,
|
|
|
|
.uart_pin = 6,
|
2015-06-18 07:01:10 +00:00
|
|
|
.otp_exe_param = 0,
|
2015-08-12 10:54:05 +00:00
|
|
|
.channel_counters_freq_hz = 88000,
|
2015-08-31 11:04:55 +00:00
|
|
|
.max_probe_resp_desc_thres = 0,
|
2016-03-18 09:44:22 +00:00
|
|
|
.cal_data_len = 8124,
|
2015-01-29 12:24:33 +00:00
|
|
|
.fw = {
|
|
|
|
/* uses same binaries as hw3.0 */
|
|
|
|
.dir = QCA6174_HW_3_0_FW_DIR,
|
|
|
|
.board = QCA6174_HW_3_0_BOARD_DATA_FILE,
|
|
|
|
.board_size = QCA6174_BOARD_DATA_SZ,
|
|
|
|
.board_ext_size = QCA6174_BOARD_EXT_DATA_SZ,
|
|
|
|
},
|
2017-03-08 11:52:04 +00:00
|
|
|
.hw_ops = &qca6174_ops,
|
|
|
|
.hw_clk = qca6174_clk,
|
|
|
|
.target_cpu_freq = 176000000,
|
2016-09-26 18:56:24 +00:00
|
|
|
.decap_align_bytes = 4,
|
2017-04-10 15:38:17 +00:00
|
|
|
.spectral_bin_discard = 0,
|
2018-05-29 11:31:13 +00:00
|
|
|
.spectral_bin_offset = 0,
|
ath10k: configure rxnss_override for QCA9984
QCA9984 hardware can do 4x4 at 80Mhz, but only 2x2 at 160Mhz.
First, report this to user-space by setting the max-tx-speed
and max-rx-speed vht capabilities.
Second, if the peer rx-speed is configured, and if we
are in 160 or 80+80 mode, and the peer rx-speed matches
the max speed for 2x2 or 1x1 at 160Mhz (long guard interval),
then use that info to set the peer_bw_rxnss_override appropriately.
Without this, a 9984 firmware will not use 2x2 ratesets when
transmitting to peer (it will be stuck at 1x1), because
the firmware would not have configured the rxnss_override.
Signed-off-by: Ben Greear <greearb@candelatech.com>
[sven.eckelmann@openmesh.com: rebase, cleanup, drop 160Mhz workaround cleanup]
Signed-off-by: Sven Eckelmann <sven.eckelmann@openmesh.com>
[kvalo@qca.qualcomm.com: use hw_params, rename the title]
Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
2017-06-16 07:37:45 +00:00
|
|
|
.vht160_mcs_rx_highest = 0,
|
|
|
|
.vht160_mcs_tx_highest = 0,
|
2017-09-25 22:29:41 +00:00
|
|
|
.n_cipher_suites = 8,
|
2017-12-11 14:22:54 +00:00
|
|
|
.num_peers = TARGET_TLV_NUM_PEERS,
|
|
|
|
.ast_skid_limit = 0x10,
|
|
|
|
.num_wds_entries = 0x20,
|
2017-12-21 09:00:50 +00:00
|
|
|
.target_64bit = false,
|
2017-12-21 09:00:56 +00:00
|
|
|
.rx_ring_fill_level = HTT_RX_RING_FILL_LEVEL,
|
2018-04-10 15:01:32 +00:00
|
|
|
.per_ce_irq = false,
|
2018-04-17 12:06:58 +00:00
|
|
|
.shadow_reg_support = false,
|
2018-04-17 12:07:00 +00:00
|
|
|
.rri_on_ddr = false,
|
2015-01-29 12:24:33 +00:00
|
|
|
},
|
2015-06-18 07:01:03 +00:00
|
|
|
{
|
|
|
|
.id = QCA99X0_HW_2_0_DEV_VERSION,
|
2015-11-05 08:50:42 +00:00
|
|
|
.dev_id = QCA99X0_2_0_DEVICE_ID,
|
2015-06-18 07:01:03 +00:00
|
|
|
.name = "qca99x0 hw2.0",
|
|
|
|
.patch_load_addr = QCA99X0_HW_2_0_PATCH_LOAD_ADDR,
|
|
|
|
.uart_pin = 7,
|
2015-06-18 07:01:10 +00:00
|
|
|
.otp_exe_param = 0x00000700,
|
2015-06-22 14:52:27 +00:00
|
|
|
.continuous_frag_desc = true,
|
2016-06-07 12:47:04 +00:00
|
|
|
.cck_rate_map_rev2 = true,
|
2015-08-12 10:54:05 +00:00
|
|
|
.channel_counters_freq_hz = 150000,
|
2015-08-31 11:04:55 +00:00
|
|
|
.max_probe_resp_desc_thres = 24,
|
2016-01-29 11:05:12 +00:00
|
|
|
.tx_chain_mask = 0xf,
|
|
|
|
.rx_chain_mask = 0xf,
|
|
|
|
.max_spatial_stream = 4,
|
2016-03-18 09:44:22 +00:00
|
|
|
.cal_data_len = 12064,
|
2015-06-18 07:01:03 +00:00
|
|
|
.fw = {
|
|
|
|
.dir = QCA99X0_HW_2_0_FW_DIR,
|
|
|
|
.board = QCA99X0_HW_2_0_BOARD_DATA_FILE,
|
|
|
|
.board_size = QCA99X0_BOARD_DATA_SZ,
|
|
|
|
.board_ext_size = QCA99X0_BOARD_EXT_DATA_SZ,
|
|
|
|
},
|
2016-08-09 06:31:51 +00:00
|
|
|
.sw_decrypt_mcast_mgmt = true,
|
2016-09-09 14:25:22 +00:00
|
|
|
.hw_ops = &qca99x0_ops,
|
2016-09-26 18:56:24 +00:00
|
|
|
.decap_align_bytes = 1,
|
2017-04-10 15:38:17 +00:00
|
|
|
.spectral_bin_discard = 4,
|
2018-05-29 11:31:13 +00:00
|
|
|
.spectral_bin_offset = 0,
|
ath10k: configure rxnss_override for QCA9984
QCA9984 hardware can do 4x4 at 80Mhz, but only 2x2 at 160Mhz.
First, report this to user-space by setting the max-tx-speed
and max-rx-speed vht capabilities.
Second, if the peer rx-speed is configured, and if we
are in 160 or 80+80 mode, and the peer rx-speed matches
the max speed for 2x2 or 1x1 at 160Mhz (long guard interval),
then use that info to set the peer_bw_rxnss_override appropriately.
Without this, a 9984 firmware will not use 2x2 ratesets when
transmitting to peer (it will be stuck at 1x1), because
the firmware would not have configured the rxnss_override.
Signed-off-by: Ben Greear <greearb@candelatech.com>
[sven.eckelmann@openmesh.com: rebase, cleanup, drop 160Mhz workaround cleanup]
Signed-off-by: Sven Eckelmann <sven.eckelmann@openmesh.com>
[kvalo@qca.qualcomm.com: use hw_params, rename the title]
Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
2017-06-16 07:37:45 +00:00
|
|
|
.vht160_mcs_rx_highest = 0,
|
|
|
|
.vht160_mcs_tx_highest = 0,
|
2017-09-25 22:29:41 +00:00
|
|
|
.n_cipher_suites = 11,
|
2017-12-11 14:22:54 +00:00
|
|
|
.num_peers = TARGET_TLV_NUM_PEERS,
|
|
|
|
.ast_skid_limit = 0x10,
|
|
|
|
.num_wds_entries = 0x20,
|
2017-12-21 09:00:50 +00:00
|
|
|
.target_64bit = false,
|
2017-12-21 09:00:56 +00:00
|
|
|
.rx_ring_fill_level = HTT_RX_RING_FILL_LEVEL,
|
2018-04-10 15:01:32 +00:00
|
|
|
.per_ce_irq = false,
|
2018-04-17 12:06:58 +00:00
|
|
|
.shadow_reg_support = false,
|
2018-04-17 12:07:00 +00:00
|
|
|
.rri_on_ddr = false,
|
2015-06-18 07:01:03 +00:00
|
|
|
},
|
2016-05-23 20:12:45 +00:00
|
|
|
{
|
|
|
|
.id = QCA9984_HW_1_0_DEV_VERSION,
|
|
|
|
.dev_id = QCA9984_1_0_DEVICE_ID,
|
|
|
|
.name = "qca9984/qca9994 hw1.0",
|
|
|
|
.patch_load_addr = QCA9984_HW_1_0_PATCH_LOAD_ADDR,
|
|
|
|
.uart_pin = 7,
|
2016-09-28 12:11:53 +00:00
|
|
|
.cc_wraparound_type = ATH10K_HW_CC_WRAP_SHIFTED_EACH,
|
2016-05-23 20:12:45 +00:00
|
|
|
.otp_exe_param = 0x00000700,
|
|
|
|
.continuous_frag_desc = true,
|
2016-06-07 12:47:04 +00:00
|
|
|
.cck_rate_map_rev2 = true,
|
2016-05-23 20:12:45 +00:00
|
|
|
.channel_counters_freq_hz = 150000,
|
|
|
|
.max_probe_resp_desc_thres = 24,
|
|
|
|
.tx_chain_mask = 0xf,
|
|
|
|
.rx_chain_mask = 0xf,
|
|
|
|
.max_spatial_stream = 4,
|
|
|
|
.cal_data_len = 12064,
|
|
|
|
.fw = {
|
|
|
|
.dir = QCA9984_HW_1_0_FW_DIR,
|
|
|
|
.board = QCA9984_HW_1_0_BOARD_DATA_FILE,
|
|
|
|
.board_size = QCA99X0_BOARD_DATA_SZ,
|
|
|
|
.board_ext_size = QCA99X0_BOARD_EXT_DATA_SZ,
|
|
|
|
},
|
2016-08-09 06:31:51 +00:00
|
|
|
.sw_decrypt_mcast_mgmt = true,
|
2016-09-09 14:25:22 +00:00
|
|
|
.hw_ops = &qca99x0_ops,
|
2016-09-26 18:56:24 +00:00
|
|
|
.decap_align_bytes = 1,
|
2017-04-10 15:38:17 +00:00
|
|
|
.spectral_bin_discard = 12,
|
2018-05-29 11:31:13 +00:00
|
|
|
.spectral_bin_offset = 8,
|
ath10k: configure rxnss_override for QCA9984
QCA9984 hardware can do 4x4 at 80Mhz, but only 2x2 at 160Mhz.
First, report this to user-space by setting the max-tx-speed
and max-rx-speed vht capabilities.
Second, if the peer rx-speed is configured, and if we
are in 160 or 80+80 mode, and the peer rx-speed matches
the max speed for 2x2 or 1x1 at 160Mhz (long guard interval),
then use that info to set the peer_bw_rxnss_override appropriately.
Without this, a 9984 firmware will not use 2x2 ratesets when
transmitting to peer (it will be stuck at 1x1), because
the firmware would not have configured the rxnss_override.
Signed-off-by: Ben Greear <greearb@candelatech.com>
[sven.eckelmann@openmesh.com: rebase, cleanup, drop 160Mhz workaround cleanup]
Signed-off-by: Sven Eckelmann <sven.eckelmann@openmesh.com>
[kvalo@qca.qualcomm.com: use hw_params, rename the title]
Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
2017-06-16 07:37:45 +00:00
|
|
|
|
|
|
|
/* Can do only 2x2 VHT160 or 80+80. 1560Mbps is 4x4 80Mhz
|
|
|
|
* or 2x2 160Mhz, long-guard-interval.
|
|
|
|
*/
|
|
|
|
.vht160_mcs_rx_highest = 1560,
|
|
|
|
.vht160_mcs_tx_highest = 1560,
|
2017-09-25 22:29:41 +00:00
|
|
|
.n_cipher_suites = 11,
|
2017-12-11 14:22:54 +00:00
|
|
|
.num_peers = TARGET_TLV_NUM_PEERS,
|
|
|
|
.ast_skid_limit = 0x10,
|
|
|
|
.num_wds_entries = 0x20,
|
2017-12-21 09:00:50 +00:00
|
|
|
.target_64bit = false,
|
2017-12-21 09:00:56 +00:00
|
|
|
.rx_ring_fill_level = HTT_RX_RING_FILL_LEVEL,
|
2018-04-10 15:01:32 +00:00
|
|
|
.per_ce_irq = false,
|
2018-04-17 12:06:58 +00:00
|
|
|
.shadow_reg_support = false,
|
2018-04-17 12:07:00 +00:00
|
|
|
.rri_on_ddr = false,
|
2016-05-23 20:12:45 +00:00
|
|
|
},
|
2016-06-30 12:24:00 +00:00
|
|
|
{
|
|
|
|
.id = QCA9888_HW_2_0_DEV_VERSION,
|
|
|
|
.dev_id = QCA9888_2_0_DEVICE_ID,
|
|
|
|
.name = "qca9888 hw2.0",
|
|
|
|
.patch_load_addr = QCA9888_HW_2_0_PATCH_LOAD_ADDR,
|
|
|
|
.uart_pin = 7,
|
2016-09-28 12:11:53 +00:00
|
|
|
.cc_wraparound_type = ATH10K_HW_CC_WRAP_SHIFTED_EACH,
|
2016-06-30 12:24:00 +00:00
|
|
|
.otp_exe_param = 0x00000700,
|
|
|
|
.continuous_frag_desc = true,
|
|
|
|
.channel_counters_freq_hz = 150000,
|
|
|
|
.max_probe_resp_desc_thres = 24,
|
|
|
|
.tx_chain_mask = 3,
|
|
|
|
.rx_chain_mask = 3,
|
|
|
|
.max_spatial_stream = 2,
|
|
|
|
.cal_data_len = 12064,
|
|
|
|
.fw = {
|
|
|
|
.dir = QCA9888_HW_2_0_FW_DIR,
|
|
|
|
.board = QCA9888_HW_2_0_BOARD_DATA_FILE,
|
|
|
|
.board_size = QCA99X0_BOARD_DATA_SZ,
|
|
|
|
.board_ext_size = QCA99X0_BOARD_EXT_DATA_SZ,
|
|
|
|
},
|
2016-08-09 06:31:51 +00:00
|
|
|
.sw_decrypt_mcast_mgmt = true,
|
2016-09-09 14:25:22 +00:00
|
|
|
.hw_ops = &qca99x0_ops,
|
2016-09-26 18:56:24 +00:00
|
|
|
.decap_align_bytes = 1,
|
2017-04-10 15:38:17 +00:00
|
|
|
.spectral_bin_discard = 12,
|
2018-05-29 11:31:13 +00:00
|
|
|
.spectral_bin_offset = 8,
|
2017-06-16 07:37:46 +00:00
|
|
|
|
|
|
|
/* Can do only 1x1 VHT160 or 80+80. 780Mbps is 2x2 80Mhz or
|
|
|
|
* 1x1 160Mhz, long-guard-interval.
|
|
|
|
*/
|
|
|
|
.vht160_mcs_rx_highest = 780,
|
|
|
|
.vht160_mcs_tx_highest = 780,
|
2017-09-25 22:29:41 +00:00
|
|
|
.n_cipher_suites = 11,
|
2017-12-11 14:22:54 +00:00
|
|
|
.num_peers = TARGET_TLV_NUM_PEERS,
|
|
|
|
.ast_skid_limit = 0x10,
|
|
|
|
.num_wds_entries = 0x20,
|
2017-12-21 09:00:50 +00:00
|
|
|
.target_64bit = false,
|
2017-12-21 09:00:56 +00:00
|
|
|
.rx_ring_fill_level = HTT_RX_RING_FILL_LEVEL,
|
2018-04-10 15:01:32 +00:00
|
|
|
.per_ce_irq = false,
|
2018-04-17 12:06:58 +00:00
|
|
|
.shadow_reg_support = false,
|
2018-04-17 12:07:00 +00:00
|
|
|
.rri_on_ddr = false,
|
2016-06-30 12:24:00 +00:00
|
|
|
},
|
2015-11-05 08:50:43 +00:00
|
|
|
{
|
|
|
|
.id = QCA9377_HW_1_0_DEV_VERSION,
|
|
|
|
.dev_id = QCA9377_1_0_DEVICE_ID,
|
|
|
|
.name = "qca9377 hw1.0",
|
|
|
|
.patch_load_addr = QCA9377_HW_1_0_PATCH_LOAD_ADDR,
|
|
|
|
.uart_pin = 6,
|
|
|
|
.otp_exe_param = 0,
|
|
|
|
.channel_counters_freq_hz = 88000,
|
|
|
|
.max_probe_resp_desc_thres = 0,
|
2016-03-18 09:44:22 +00:00
|
|
|
.cal_data_len = 8124,
|
2015-11-05 08:50:43 +00:00
|
|
|
.fw = {
|
|
|
|
.dir = QCA9377_HW_1_0_FW_DIR,
|
|
|
|
.board = QCA9377_HW_1_0_BOARD_DATA_FILE,
|
|
|
|
.board_size = QCA9377_BOARD_DATA_SZ,
|
|
|
|
.board_ext_size = QCA9377_BOARD_EXT_DATA_SZ,
|
|
|
|
},
|
2016-09-09 14:25:22 +00:00
|
|
|
.hw_ops = &qca988x_ops,
|
2016-09-26 18:56:24 +00:00
|
|
|
.decap_align_bytes = 4,
|
2017-04-10 15:38:17 +00:00
|
|
|
.spectral_bin_discard = 0,
|
2018-05-29 11:31:13 +00:00
|
|
|
.spectral_bin_offset = 0,
|
ath10k: configure rxnss_override for QCA9984
QCA9984 hardware can do 4x4 at 80Mhz, but only 2x2 at 160Mhz.
First, report this to user-space by setting the max-tx-speed
and max-rx-speed vht capabilities.
Second, if the peer rx-speed is configured, and if we
are in 160 or 80+80 mode, and the peer rx-speed matches
the max speed for 2x2 or 1x1 at 160Mhz (long guard interval),
then use that info to set the peer_bw_rxnss_override appropriately.
Without this, a 9984 firmware will not use 2x2 ratesets when
transmitting to peer (it will be stuck at 1x1), because
the firmware would not have configured the rxnss_override.
Signed-off-by: Ben Greear <greearb@candelatech.com>
[sven.eckelmann@openmesh.com: rebase, cleanup, drop 160Mhz workaround cleanup]
Signed-off-by: Sven Eckelmann <sven.eckelmann@openmesh.com>
[kvalo@qca.qualcomm.com: use hw_params, rename the title]
Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
2017-06-16 07:37:45 +00:00
|
|
|
.vht160_mcs_rx_highest = 0,
|
|
|
|
.vht160_mcs_tx_highest = 0,
|
2017-09-25 22:29:41 +00:00
|
|
|
.n_cipher_suites = 8,
|
2017-12-11 14:22:54 +00:00
|
|
|
.num_peers = TARGET_TLV_NUM_PEERS,
|
|
|
|
.ast_skid_limit = 0x10,
|
|
|
|
.num_wds_entries = 0x20,
|
2017-12-21 09:00:50 +00:00
|
|
|
.target_64bit = false,
|
2017-12-21 09:00:56 +00:00
|
|
|
.rx_ring_fill_level = HTT_RX_RING_FILL_LEVEL,
|
2018-04-10 15:01:32 +00:00
|
|
|
.per_ce_irq = false,
|
2018-04-17 12:06:58 +00:00
|
|
|
.shadow_reg_support = false,
|
2018-04-17 12:07:00 +00:00
|
|
|
.rri_on_ddr = false,
|
2015-11-05 08:50:43 +00:00
|
|
|
},
|
2015-10-28 14:09:53 +00:00
|
|
|
{
|
2015-11-05 08:50:40 +00:00
|
|
|
.id = QCA9377_HW_1_1_DEV_VERSION,
|
2015-11-05 08:50:42 +00:00
|
|
|
.dev_id = QCA9377_1_0_DEVICE_ID,
|
2015-11-05 08:50:40 +00:00
|
|
|
.name = "qca9377 hw1.1",
|
2015-10-28 14:09:53 +00:00
|
|
|
.patch_load_addr = QCA9377_HW_1_0_PATCH_LOAD_ADDR,
|
2015-11-05 08:50:41 +00:00
|
|
|
.uart_pin = 6,
|
2015-10-28 14:09:53 +00:00
|
|
|
.otp_exe_param = 0,
|
2015-11-05 08:50:41 +00:00
|
|
|
.channel_counters_freq_hz = 88000,
|
|
|
|
.max_probe_resp_desc_thres = 0,
|
2016-03-18 09:44:22 +00:00
|
|
|
.cal_data_len = 8124,
|
2015-10-28 14:09:53 +00:00
|
|
|
.fw = {
|
|
|
|
.dir = QCA9377_HW_1_0_FW_DIR,
|
|
|
|
.board = QCA9377_HW_1_0_BOARD_DATA_FILE,
|
|
|
|
.board_size = QCA9377_BOARD_DATA_SZ,
|
|
|
|
.board_ext_size = QCA9377_BOARD_EXT_DATA_SZ,
|
|
|
|
},
|
2017-03-08 11:52:05 +00:00
|
|
|
.hw_ops = &qca6174_ops,
|
|
|
|
.hw_clk = qca6174_clk,
|
|
|
|
.target_cpu_freq = 176000000,
|
2016-09-26 18:56:24 +00:00
|
|
|
.decap_align_bytes = 4,
|
2017-04-10 15:38:17 +00:00
|
|
|
.spectral_bin_discard = 0,
|
2018-05-29 11:31:13 +00:00
|
|
|
.spectral_bin_offset = 0,
|
ath10k: configure rxnss_override for QCA9984
QCA9984 hardware can do 4x4 at 80Mhz, but only 2x2 at 160Mhz.
First, report this to user-space by setting the max-tx-speed
and max-rx-speed vht capabilities.
Second, if the peer rx-speed is configured, and if we
are in 160 or 80+80 mode, and the peer rx-speed matches
the max speed for 2x2 or 1x1 at 160Mhz (long guard interval),
then use that info to set the peer_bw_rxnss_override appropriately.
Without this, a 9984 firmware will not use 2x2 ratesets when
transmitting to peer (it will be stuck at 1x1), because
the firmware would not have configured the rxnss_override.
Signed-off-by: Ben Greear <greearb@candelatech.com>
[sven.eckelmann@openmesh.com: rebase, cleanup, drop 160Mhz workaround cleanup]
Signed-off-by: Sven Eckelmann <sven.eckelmann@openmesh.com>
[kvalo@qca.qualcomm.com: use hw_params, rename the title]
Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
2017-06-16 07:37:45 +00:00
|
|
|
.vht160_mcs_rx_highest = 0,
|
|
|
|
.vht160_mcs_tx_highest = 0,
|
2017-09-25 22:29:41 +00:00
|
|
|
.n_cipher_suites = 8,
|
2017-12-11 14:22:54 +00:00
|
|
|
.num_peers = TARGET_TLV_NUM_PEERS,
|
|
|
|
.ast_skid_limit = 0x10,
|
|
|
|
.num_wds_entries = 0x20,
|
2017-12-21 09:00:50 +00:00
|
|
|
.target_64bit = false,
|
2017-12-21 09:00:56 +00:00
|
|
|
.rx_ring_fill_level = HTT_RX_RING_FILL_LEVEL,
|
2018-04-10 15:01:32 +00:00
|
|
|
.per_ce_irq = false,
|
2018-04-17 12:06:58 +00:00
|
|
|
.shadow_reg_support = false,
|
2018-04-17 12:07:00 +00:00
|
|
|
.rri_on_ddr = false,
|
2015-10-28 14:09:53 +00:00
|
|
|
},
|
2016-01-29 11:05:11 +00:00
|
|
|
{
|
|
|
|
.id = QCA4019_HW_1_0_DEV_VERSION,
|
|
|
|
.dev_id = 0,
|
|
|
|
.name = "qca4019 hw1.0",
|
|
|
|
.patch_load_addr = QCA4019_HW_1_0_PATCH_LOAD_ADDR,
|
|
|
|
.uart_pin = 7,
|
2016-06-07 12:47:06 +00:00
|
|
|
.cc_wraparound_type = ATH10K_HW_CC_WRAP_SHIFTED_EACH,
|
2016-01-29 11:05:11 +00:00
|
|
|
.otp_exe_param = 0x0010000,
|
|
|
|
.continuous_frag_desc = true,
|
2016-06-07 12:47:04 +00:00
|
|
|
.cck_rate_map_rev2 = true,
|
2016-01-29 11:05:11 +00:00
|
|
|
.channel_counters_freq_hz = 125000,
|
|
|
|
.max_probe_resp_desc_thres = 24,
|
2016-01-29 11:05:12 +00:00
|
|
|
.tx_chain_mask = 0x3,
|
|
|
|
.rx_chain_mask = 0x3,
|
|
|
|
.max_spatial_stream = 2,
|
2016-03-18 09:44:22 +00:00
|
|
|
.cal_data_len = 12064,
|
2016-01-29 11:05:11 +00:00
|
|
|
.fw = {
|
|
|
|
.dir = QCA4019_HW_1_0_FW_DIR,
|
|
|
|
.board = QCA4019_HW_1_0_BOARD_DATA_FILE,
|
|
|
|
.board_size = QCA4019_BOARD_DATA_SZ,
|
|
|
|
.board_ext_size = QCA4019_BOARD_EXT_DATA_SZ,
|
|
|
|
},
|
2016-08-09 06:31:51 +00:00
|
|
|
.sw_decrypt_mcast_mgmt = true,
|
2016-09-09 14:25:22 +00:00
|
|
|
.hw_ops = &qca99x0_ops,
|
2016-09-26 18:56:24 +00:00
|
|
|
.decap_align_bytes = 1,
|
2017-04-10 15:38:17 +00:00
|
|
|
.spectral_bin_discard = 4,
|
2018-05-29 11:31:13 +00:00
|
|
|
.spectral_bin_offset = 0,
|
ath10k: configure rxnss_override for QCA9984
QCA9984 hardware can do 4x4 at 80Mhz, but only 2x2 at 160Mhz.
First, report this to user-space by setting the max-tx-speed
and max-rx-speed vht capabilities.
Second, if the peer rx-speed is configured, and if we
are in 160 or 80+80 mode, and the peer rx-speed matches
the max speed for 2x2 or 1x1 at 160Mhz (long guard interval),
then use that info to set the peer_bw_rxnss_override appropriately.
Without this, a 9984 firmware will not use 2x2 ratesets when
transmitting to peer (it will be stuck at 1x1), because
the firmware would not have configured the rxnss_override.
Signed-off-by: Ben Greear <greearb@candelatech.com>
[sven.eckelmann@openmesh.com: rebase, cleanup, drop 160Mhz workaround cleanup]
Signed-off-by: Sven Eckelmann <sven.eckelmann@openmesh.com>
[kvalo@qca.qualcomm.com: use hw_params, rename the title]
Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
2017-06-16 07:37:45 +00:00
|
|
|
.vht160_mcs_rx_highest = 0,
|
|
|
|
.vht160_mcs_tx_highest = 0,
|
2017-09-25 22:29:41 +00:00
|
|
|
.n_cipher_suites = 11,
|
2017-12-11 14:22:54 +00:00
|
|
|
.num_peers = TARGET_TLV_NUM_PEERS,
|
|
|
|
.ast_skid_limit = 0x10,
|
|
|
|
.num_wds_entries = 0x20,
|
2017-12-21 09:00:50 +00:00
|
|
|
.target_64bit = false,
|
2017-12-21 09:00:56 +00:00
|
|
|
.rx_ring_fill_level = HTT_RX_RING_FILL_LEVEL,
|
2018-04-10 15:01:32 +00:00
|
|
|
.per_ce_irq = false,
|
2018-04-17 12:06:58 +00:00
|
|
|
.shadow_reg_support = false,
|
2018-04-17 12:07:00 +00:00
|
|
|
.rri_on_ddr = false,
|
2016-01-29 11:05:11 +00:00
|
|
|
},
|
2017-12-11 14:22:55 +00:00
|
|
|
{
|
|
|
|
.id = WCN3990_HW_1_0_DEV_VERSION,
|
|
|
|
.dev_id = 0,
|
|
|
|
.name = "wcn3990 hw1.0",
|
|
|
|
.continuous_frag_desc = true,
|
|
|
|
.tx_chain_mask = 0x7,
|
|
|
|
.rx_chain_mask = 0x7,
|
|
|
|
.max_spatial_stream = 4,
|
|
|
|
.fw = {
|
|
|
|
.dir = WCN3990_HW_1_0_FW_DIR,
|
|
|
|
},
|
|
|
|
.sw_decrypt_mcast_mgmt = true,
|
|
|
|
.hw_ops = &wcn3990_ops,
|
|
|
|
.decap_align_bytes = 1,
|
|
|
|
.num_peers = TARGET_HL_10_TLV_NUM_PEERS,
|
|
|
|
.ast_skid_limit = TARGET_HL_10_TLV_AST_SKID_LIMIT,
|
|
|
|
.num_wds_entries = TARGET_HL_10_TLV_NUM_WDS_ENTRIES,
|
2017-12-21 09:00:50 +00:00
|
|
|
.target_64bit = true,
|
2017-12-21 09:00:56 +00:00
|
|
|
.rx_ring_fill_level = HTT_RX_RING_FILL_LEVEL_DUAL_MAC,
|
2018-04-10 15:01:32 +00:00
|
|
|
.per_ce_irq = true,
|
2018-04-17 12:06:58 +00:00
|
|
|
.shadow_reg_support = true,
|
2018-04-17 12:07:00 +00:00
|
|
|
.rri_on_ddr = true,
|
2017-12-11 14:22:55 +00:00
|
|
|
},
|
2013-06-12 17:52:10 +00:00
|
|
|
};
|
|
|
|
|
2015-06-15 11:46:40 +00:00
|
|
|
static const char *const ath10k_core_fw_feature_str[] = {
|
|
|
|
[ATH10K_FW_FEATURE_EXT_WMI_MGMT_RX] = "wmi-mgmt-rx",
|
|
|
|
[ATH10K_FW_FEATURE_WMI_10X] = "wmi-10.x",
|
|
|
|
[ATH10K_FW_FEATURE_HAS_WMI_MGMT_TX] = "has-wmi-mgmt-tx",
|
|
|
|
[ATH10K_FW_FEATURE_NO_P2P] = "no-p2p",
|
|
|
|
[ATH10K_FW_FEATURE_WMI_10_2] = "wmi-10.2",
|
|
|
|
[ATH10K_FW_FEATURE_MULTI_VIF_PS_SUPPORT] = "multi-vif-ps",
|
|
|
|
[ATH10K_FW_FEATURE_WOWLAN_SUPPORT] = "wowlan",
|
|
|
|
[ATH10K_FW_FEATURE_IGNORE_OTP_RESULT] = "ignore-otp",
|
|
|
|
[ATH10K_FW_FEATURE_NO_NWIFI_DECAP_4ADDR_PADDING] = "no-4addr-pad",
|
|
|
|
[ATH10K_FW_FEATURE_SUPPORTS_SKIP_CLOCK_INIT] = "skip-clock-init",
|
2015-09-09 08:34:37 +00:00
|
|
|
[ATH10K_FW_FEATURE_RAW_MODE_SUPPORT] = "raw-mode",
|
2015-10-21 08:49:18 +00:00
|
|
|
[ATH10K_FW_FEATURE_SUPPORTS_ADAPTIVE_CCA] = "adaptive-cca",
|
2015-10-29 12:27:42 +00:00
|
|
|
[ATH10K_FW_FEATURE_MFP_SUPPORT] = "mfp",
|
2016-01-21 13:13:25 +00:00
|
|
|
[ATH10K_FW_FEATURE_PEER_FLOW_CONTROL] = "peer-flow-ctrl",
|
2016-05-27 14:45:58 +00:00
|
|
|
[ATH10K_FW_FEATURE_BTCOEX_PARAM] = "btcoex-param",
|
2016-08-26 08:12:20 +00:00
|
|
|
[ATH10K_FW_FEATURE_SKIP_NULL_FUNC_WAR] = "skip-null-func-war",
|
2016-11-23 14:58:11 +00:00
|
|
|
[ATH10K_FW_FEATURE_ALLOWS_MESH_BCAST] = "allows-mesh-bcast",
|
2017-10-04 09:22:57 +00:00
|
|
|
[ATH10K_FW_FEATURE_NO_PS] = "no-ps",
|
2017-12-11 14:22:53 +00:00
|
|
|
[ATH10K_FW_FEATURE_MGMT_TX_BY_REF] = "mgmt-tx-by-reference",
|
2017-12-21 16:16:49 +00:00
|
|
|
[ATH10K_FW_FEATURE_NON_BMI] = "non-bmi",
|
2015-06-15 11:46:40 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
static unsigned int ath10k_core_get_fw_feature_str(char *buf,
|
|
|
|
size_t buf_len,
|
|
|
|
enum ath10k_fw_features feat)
|
|
|
|
{
|
2015-09-09 08:34:37 +00:00
|
|
|
/* make sure that ath10k_core_fw_feature_str[] gets updated */
|
|
|
|
BUILD_BUG_ON(ARRAY_SIZE(ath10k_core_fw_feature_str) !=
|
|
|
|
ATH10K_FW_FEATURE_COUNT);
|
|
|
|
|
2015-06-15 11:46:40 +00:00
|
|
|
if (feat >= ARRAY_SIZE(ath10k_core_fw_feature_str) ||
|
|
|
|
WARN_ON(!ath10k_core_fw_feature_str[feat])) {
|
|
|
|
return scnprintf(buf, buf_len, "bit%d", feat);
|
|
|
|
}
|
|
|
|
|
|
|
|
return scnprintf(buf, buf_len, "%s", ath10k_core_fw_feature_str[feat]);
|
|
|
|
}
|
|
|
|
|
|
|
|
void ath10k_core_get_fw_features_str(struct ath10k *ar,
|
|
|
|
char *buf,
|
|
|
|
size_t buf_len)
|
|
|
|
{
|
2017-02-13 10:38:38 +00:00
|
|
|
size_t len = 0;
|
2015-06-15 11:46:40 +00:00
|
|
|
int i;
|
|
|
|
|
|
|
|
for (i = 0; i < ATH10K_FW_FEATURE_COUNT; i++) {
|
2016-04-20 16:45:18 +00:00
|
|
|
if (test_bit(i, ar->normal_mode_fw.fw_file.fw_features)) {
|
2015-06-15 11:46:40 +00:00
|
|
|
if (len > 0)
|
|
|
|
len += scnprintf(buf + len, buf_len - len, ",");
|
|
|
|
|
|
|
|
len += ath10k_core_get_fw_feature_str(buf + len,
|
|
|
|
buf_len - len,
|
|
|
|
i);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-06-12 17:52:10 +00:00
|
|
|
static void ath10k_send_suspend_complete(struct ath10k *ar)
|
|
|
|
{
|
2014-08-25 10:09:38 +00:00
|
|
|
ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot suspend complete\n");
|
2013-06-12 17:52:10 +00:00
|
|
|
|
2014-02-10 16:14:23 +00:00
|
|
|
complete(&ar->target_suspend);
|
2013-06-12 17:52:10 +00:00
|
|
|
}
|
|
|
|
|
2017-04-26 09:17:56 +00:00
|
|
|
static void ath10k_init_sdio(struct ath10k *ar)
|
|
|
|
{
|
|
|
|
u32 param = 0;
|
|
|
|
|
|
|
|
ath10k_bmi_write32(ar, hi_mbox_io_block_sz, 256);
|
|
|
|
ath10k_bmi_write32(ar, hi_mbox_isr_yield_limit, 99);
|
|
|
|
ath10k_bmi_read32(ar, hi_acs_flags, ¶m);
|
|
|
|
|
|
|
|
param |= (HI_ACS_FLAGS_SDIO_SWAP_MAILBOX_SET |
|
|
|
|
HI_ACS_FLAGS_SDIO_REDUCE_TX_COMPL_SET |
|
|
|
|
HI_ACS_FLAGS_ALT_DATA_CREDIT_SIZE);
|
|
|
|
|
|
|
|
ath10k_bmi_write32(ar, hi_acs_flags, param);
|
|
|
|
}
|
|
|
|
|
2013-06-12 17:52:10 +00:00
|
|
|
static int ath10k_init_configure_target(struct ath10k *ar)
|
|
|
|
{
|
|
|
|
u32 param_host;
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
/* tell target which HTC version it is used*/
|
|
|
|
ret = ath10k_bmi_write32(ar, hi_app_host_interest,
|
|
|
|
HTC_PROTOCOL_VERSION);
|
|
|
|
if (ret) {
|
2014-08-25 10:09:38 +00:00
|
|
|
ath10k_err(ar, "settings HTC version failed\n");
|
2013-06-12 17:52:10 +00:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* set the firmware mode to STA/IBSS/AP */
|
|
|
|
ret = ath10k_bmi_read32(ar, hi_option_flag, ¶m_host);
|
|
|
|
if (ret) {
|
2014-08-25 10:09:38 +00:00
|
|
|
ath10k_err(ar, "setting firmware mode (1/2) failed\n");
|
2013-06-12 17:52:10 +00:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* TODO following parameters need to be re-visited. */
|
|
|
|
/* num_device */
|
|
|
|
param_host |= (1 << HI_OPTION_NUM_DEV_SHIFT);
|
|
|
|
/* Firmware mode */
|
|
|
|
/* FIXME: Why FW_MODE_AP ??.*/
|
|
|
|
param_host |= (HI_OPTION_FW_MODE_AP << HI_OPTION_FW_MODE_SHIFT);
|
|
|
|
/* mac_addr_method */
|
|
|
|
param_host |= (1 << HI_OPTION_MAC_ADDR_METHOD_SHIFT);
|
|
|
|
/* firmware_bridge */
|
|
|
|
param_host |= (0 << HI_OPTION_FW_BRIDGE_SHIFT);
|
|
|
|
/* fwsubmode */
|
|
|
|
param_host |= (0 << HI_OPTION_FW_SUBMODE_SHIFT);
|
|
|
|
|
|
|
|
ret = ath10k_bmi_write32(ar, hi_option_flag, param_host);
|
|
|
|
if (ret) {
|
2014-08-25 10:09:38 +00:00
|
|
|
ath10k_err(ar, "setting firmware mode (2/2) failed\n");
|
2013-06-12 17:52:10 +00:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* We do all byte-swapping on the host */
|
|
|
|
ret = ath10k_bmi_write32(ar, hi_be, 0);
|
|
|
|
if (ret) {
|
2014-08-25 10:09:38 +00:00
|
|
|
ath10k_err(ar, "setting host CPU BE mode failed\n");
|
2013-06-12 17:52:10 +00:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* FW descriptor/Data swap flags */
|
|
|
|
ret = ath10k_bmi_write32(ar, hi_fw_swap, 0);
|
|
|
|
|
|
|
|
if (ret) {
|
2014-08-25 10:09:38 +00:00
|
|
|
ath10k_err(ar, "setting FW data/desc swap flags failed\n");
|
2013-06-12 17:52:10 +00:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2015-08-13 12:32:26 +00:00
|
|
|
/* Some devices have a special sanity check that verifies the PCI
|
|
|
|
* Device ID is written to this host interest var. It is known to be
|
|
|
|
* required to boot QCA6164.
|
|
|
|
*/
|
|
|
|
ret = ath10k_bmi_write32(ar, hi_hci_uart_pwr_mgmt_params_ext,
|
|
|
|
ar->dev_id);
|
|
|
|
if (ret) {
|
|
|
|
ath10k_err(ar, "failed to set pwr_mgmt_params: %d\n", ret);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2013-06-12 17:52:10 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static const struct firmware *ath10k_fetch_fw_file(struct ath10k *ar,
|
|
|
|
const char *dir,
|
|
|
|
const char *file)
|
|
|
|
{
|
|
|
|
char filename[100];
|
|
|
|
const struct firmware *fw;
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
if (file == NULL)
|
|
|
|
return ERR_PTR(-ENOENT);
|
|
|
|
|
|
|
|
if (dir == NULL)
|
|
|
|
dir = ".";
|
|
|
|
|
|
|
|
snprintf(filename, sizeof(filename), "%s/%s", dir, file);
|
2018-05-10 20:08:46 +00:00
|
|
|
ret = firmware_request_nowarn(&fw, filename, ar->dev);
|
2017-02-13 10:38:42 +00:00
|
|
|
ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot fw request '%s': %d\n",
|
|
|
|
filename, ret);
|
|
|
|
|
2013-06-12 17:52:10 +00:00
|
|
|
if (ret)
|
|
|
|
return ERR_PTR(ret);
|
|
|
|
|
|
|
|
return fw;
|
|
|
|
}
|
|
|
|
|
2014-10-13 06:40:59 +00:00
|
|
|
static int ath10k_push_board_ext_data(struct ath10k *ar, const void *data,
|
|
|
|
size_t data_len)
|
2013-06-12 17:52:10 +00:00
|
|
|
{
|
2014-12-02 08:55:54 +00:00
|
|
|
u32 board_data_size = ar->hw_params.fw.board_size;
|
|
|
|
u32 board_ext_data_size = ar->hw_params.fw.board_ext_size;
|
2013-06-12 17:52:10 +00:00
|
|
|
u32 board_ext_data_addr;
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
ret = ath10k_bmi_read32(ar, hi_board_ext_data, &board_ext_data_addr);
|
|
|
|
if (ret) {
|
2014-08-25 10:09:38 +00:00
|
|
|
ath10k_err(ar, "could not read board ext data addr (%d)\n",
|
|
|
|
ret);
|
2013-06-12 17:52:10 +00:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2014-08-25 10:09:38 +00:00
|
|
|
ath10k_dbg(ar, ATH10K_DBG_BOOT,
|
2013-09-08 14:55:44 +00:00
|
|
|
"boot push board extended data addr 0x%x\n",
|
2013-06-12 17:52:10 +00:00
|
|
|
board_ext_data_addr);
|
|
|
|
|
|
|
|
if (board_ext_data_addr == 0)
|
|
|
|
return 0;
|
|
|
|
|
2014-10-13 06:40:59 +00:00
|
|
|
if (data_len != (board_data_size + board_ext_data_size)) {
|
2014-08-25 10:09:38 +00:00
|
|
|
ath10k_err(ar, "invalid board (ext) data sizes %zu != %d+%d\n",
|
2014-10-13 06:40:59 +00:00
|
|
|
data_len, board_data_size, board_ext_data_size);
|
2013-06-12 17:52:10 +00:00
|
|
|
return -EINVAL;
|
|
|
|
}
|
|
|
|
|
|
|
|
ret = ath10k_bmi_write_memory(ar, board_ext_data_addr,
|
2014-10-13 06:40:59 +00:00
|
|
|
data + board_data_size,
|
2013-06-12 17:52:10 +00:00
|
|
|
board_ext_data_size);
|
|
|
|
if (ret) {
|
2014-08-25 10:09:38 +00:00
|
|
|
ath10k_err(ar, "could not write board ext data (%d)\n", ret);
|
2013-06-12 17:52:10 +00:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
ret = ath10k_bmi_write32(ar, hi_board_ext_data_config,
|
|
|
|
(board_ext_data_size << 16) | 1);
|
|
|
|
if (ret) {
|
2014-08-25 10:09:38 +00:00
|
|
|
ath10k_err(ar, "could not write board ext data bit (%d)\n",
|
|
|
|
ret);
|
2013-06-12 17:52:10 +00:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2014-10-13 06:40:59 +00:00
|
|
|
static int ath10k_download_board_data(struct ath10k *ar, const void *data,
|
|
|
|
size_t data_len)
|
2013-06-12 17:52:10 +00:00
|
|
|
{
|
2014-12-02 08:55:54 +00:00
|
|
|
u32 board_data_size = ar->hw_params.fw.board_size;
|
2013-06-12 17:52:10 +00:00
|
|
|
u32 address;
|
|
|
|
int ret;
|
|
|
|
|
2014-10-13 06:40:59 +00:00
|
|
|
ret = ath10k_push_board_ext_data(ar, data, data_len);
|
2013-06-12 17:52:10 +00:00
|
|
|
if (ret) {
|
2014-08-25 10:09:38 +00:00
|
|
|
ath10k_err(ar, "could not push board ext data (%d)\n", ret);
|
2013-06-12 17:52:10 +00:00
|
|
|
goto exit;
|
|
|
|
}
|
|
|
|
|
|
|
|
ret = ath10k_bmi_read32(ar, hi_board_data, &address);
|
|
|
|
if (ret) {
|
2014-08-25 10:09:38 +00:00
|
|
|
ath10k_err(ar, "could not read board data addr (%d)\n", ret);
|
2013-06-12 17:52:10 +00:00
|
|
|
goto exit;
|
|
|
|
}
|
|
|
|
|
2014-10-13 06:40:59 +00:00
|
|
|
ret = ath10k_bmi_write_memory(ar, address, data,
|
2013-09-27 16:55:01 +00:00
|
|
|
min_t(u32, board_data_size,
|
2014-10-13 06:40:59 +00:00
|
|
|
data_len));
|
2013-06-12 17:52:10 +00:00
|
|
|
if (ret) {
|
2014-08-25 10:09:38 +00:00
|
|
|
ath10k_err(ar, "could not write board data (%d)\n", ret);
|
2013-06-12 17:52:10 +00:00
|
|
|
goto exit;
|
|
|
|
}
|
|
|
|
|
|
|
|
ret = ath10k_bmi_write32(ar, hi_board_data_initialized, 1);
|
|
|
|
if (ret) {
|
2014-08-25 10:09:38 +00:00
|
|
|
ath10k_err(ar, "could not write board data bit (%d)\n", ret);
|
2013-06-12 17:52:10 +00:00
|
|
|
goto exit;
|
|
|
|
}
|
|
|
|
|
|
|
|
exit:
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2016-03-18 09:44:21 +00:00
|
|
|
static int ath10k_download_cal_file(struct ath10k *ar,
|
|
|
|
const struct firmware *file)
|
2014-10-13 06:40:59 +00:00
|
|
|
{
|
|
|
|
int ret;
|
|
|
|
|
2016-03-18 09:44:21 +00:00
|
|
|
if (!file)
|
2014-10-13 06:40:59 +00:00
|
|
|
return -ENOENT;
|
|
|
|
|
2016-03-18 09:44:21 +00:00
|
|
|
if (IS_ERR(file))
|
|
|
|
return PTR_ERR(file);
|
2014-10-13 06:40:59 +00:00
|
|
|
|
2016-03-18 09:44:21 +00:00
|
|
|
ret = ath10k_download_board_data(ar, file->data, file->size);
|
2014-10-13 06:40:59 +00:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2016-03-18 09:44:21 +00:00
|
|
|
static int ath10k_download_cal_dt(struct ath10k *ar, const char *dt_name)
|
2014-12-02 08:55:54 +00:00
|
|
|
{
|
|
|
|
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;
|
|
|
|
|
2016-03-18 09:44:21 +00:00
|
|
|
if (!of_get_property(node, dt_name, &data_len)) {
|
2014-12-02 08:55:54 +00:00
|
|
|
/* The calibration data node is optional */
|
|
|
|
return -ENOENT;
|
|
|
|
}
|
|
|
|
|
2016-03-18 09:44:22 +00:00
|
|
|
if (data_len != ar->hw_params.cal_data_len) {
|
2014-12-02 08:55:54 +00:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2016-03-18 09:44:21 +00:00
|
|
|
ret = of_property_read_u8_array(node, dt_name, data, data_len);
|
2014-12-02 08:55:54 +00:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2016-06-02 14:59:50 +00:00
|
|
|
static int ath10k_download_cal_eeprom(struct ath10k *ar)
|
|
|
|
{
|
|
|
|
size_t data_len;
|
|
|
|
void *data = NULL;
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
ret = ath10k_hif_fetch_cal_eeprom(ar, &data, &data_len);
|
|
|
|
if (ret) {
|
|
|
|
if (ret != -EOPNOTSUPP)
|
|
|
|
ath10k_warn(ar, "failed to read calibration data from EEPROM: %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 EEPROM: %d\n",
|
|
|
|
ret);
|
|
|
|
goto out_free;
|
|
|
|
}
|
|
|
|
|
|
|
|
ret = 0;
|
|
|
|
|
|
|
|
out_free:
|
|
|
|
kfree(data);
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2015-10-09 08:55:59 +00:00
|
|
|
static int ath10k_core_get_board_id_from_otp(struct ath10k *ar)
|
|
|
|
{
|
|
|
|
u32 result, address;
|
|
|
|
u8 board_id, chip_id;
|
2017-05-31 11:21:27 +00:00
|
|
|
int ret, bmi_board_id_param;
|
2015-10-09 08:55:59 +00:00
|
|
|
|
|
|
|
address = ar->hw_params.patch_load_addr;
|
|
|
|
|
2016-04-20 16:44:51 +00:00
|
|
|
if (!ar->normal_mode_fw.fw_file.otp_data ||
|
|
|
|
!ar->normal_mode_fw.fw_file.otp_len) {
|
2015-10-09 08:55:59 +00:00
|
|
|
ath10k_warn(ar,
|
|
|
|
"failed to retrieve board id because of invalid otp\n");
|
|
|
|
return -ENODATA;
|
|
|
|
}
|
|
|
|
|
|
|
|
ath10k_dbg(ar, ATH10K_DBG_BOOT,
|
|
|
|
"boot upload otp to 0x%x len %zd for board id\n",
|
2016-04-20 16:44:51 +00:00
|
|
|
address, ar->normal_mode_fw.fw_file.otp_len);
|
2015-10-09 08:55:59 +00:00
|
|
|
|
2016-04-20 16:44:51 +00:00
|
|
|
ret = ath10k_bmi_fast_download(ar, address,
|
|
|
|
ar->normal_mode_fw.fw_file.otp_data,
|
|
|
|
ar->normal_mode_fw.fw_file.otp_len);
|
2015-10-09 08:55:59 +00:00
|
|
|
if (ret) {
|
|
|
|
ath10k_err(ar, "could not write otp for board id check: %d\n",
|
|
|
|
ret);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2017-05-31 11:21:27 +00:00
|
|
|
if (ar->cal_mode == ATH10K_PRE_CAL_MODE_DT ||
|
|
|
|
ar->cal_mode == ATH10K_PRE_CAL_MODE_FILE)
|
|
|
|
bmi_board_id_param = BMI_PARAM_GET_FLASH_BOARD_ID;
|
|
|
|
else
|
|
|
|
bmi_board_id_param = BMI_PARAM_GET_EEPROM_BOARD_ID;
|
|
|
|
|
|
|
|
ret = ath10k_bmi_execute(ar, address, bmi_board_id_param, &result);
|
2015-10-09 08:55:59 +00:00
|
|
|
if (ret) {
|
|
|
|
ath10k_err(ar, "could not execute otp for board id check: %d\n",
|
|
|
|
ret);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
board_id = MS(result, ATH10K_BMI_BOARD_ID_FROM_OTP);
|
|
|
|
chip_id = MS(result, ATH10K_BMI_CHIP_ID_FROM_OTP);
|
|
|
|
|
|
|
|
ath10k_dbg(ar, ATH10K_DBG_BOOT,
|
|
|
|
"boot get otp board id result 0x%08x board_id %d chip_id %d\n",
|
|
|
|
result, board_id, chip_id);
|
|
|
|
|
2016-12-22 23:02:37 +00:00
|
|
|
if ((result & ATH10K_BMI_BOARD_ID_STATUS_MASK) != 0 ||
|
|
|
|
(board_id == 0)) {
|
2017-02-13 10:38:43 +00:00
|
|
|
ath10k_dbg(ar, ATH10K_DBG_BOOT,
|
|
|
|
"board id does not exist in otp, ignore it\n");
|
2015-10-09 08:55:59 +00:00
|
|
|
return -EOPNOTSUPP;
|
2016-12-22 23:02:37 +00:00
|
|
|
}
|
2015-10-09 08:55:59 +00:00
|
|
|
|
|
|
|
ar->id.bmi_ids_valid = true;
|
|
|
|
ar->id.bmi_board_id = board_id;
|
|
|
|
ar->id.bmi_chip_id = chip_id;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
ath10k: search SMBIOS for OEM board file extension
Board Data File (BDF) is loaded upon driver boot-up procedure. The right
board data file is identified, among others, by device and sybsystem ids.
The problem, however, can occur when the (default) board data file cannot
fulfill with the vendor requirements and it is necessary to use a different
board data file.
To solve the issue QCA uses SMBIOS type 0xF8 to store Board Data File Name
Extension to specify the extension/variant name. The driver will take the
extension suffix into consideration and will load the right (non-default)
board data file if necessary.
If it is unnecessary to use extension board data file, please leave the
SMBIOS field blank and default configuration will be used.
Example:
If a default board data file for a specific board is identified by a string
"bus=pci,vendor=168c,device=003e,subsystem-vendor=1028,
subsystem-device=0310"
then the OEM specific data file, if used, could be identified by variant
suffix:
"bus=pci,vendor=168c,device=003e,subsystem-vendor=1028,
subsystem-device=0310,variant=DE_1AB"
If board data file name extension is set but board-2.bin does not contain
board data file for the variant, the driver will fallback to the default
board data file not to break backward compatibility.
This was first applied in commit f2593cb1b291 ("ath10k: Search SMBIOS for OEM
board file extension") but later reverted in commit 005c3490e9db ("Revert
"ath10k: Search SMBIOS for OEM board file extension"". This patch is now
otherwise the same as commit f2593cb1b291 except the regression fixed.
Signed-off-by: Waldemar Rymarkiewicz <ext.waldemar.rymarkiewicz@tieto.com>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
2017-02-24 22:30:03 +00:00
|
|
|
static void ath10k_core_check_bdfext(const struct dmi_header *hdr, void *data)
|
|
|
|
{
|
|
|
|
struct ath10k *ar = data;
|
|
|
|
const char *bdf_ext;
|
|
|
|
const char *magic = ATH10K_SMBIOS_BDF_EXT_MAGIC;
|
|
|
|
u8 bdf_enabled;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
if (hdr->type != ATH10K_SMBIOS_BDF_EXT_TYPE)
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (hdr->length != ATH10K_SMBIOS_BDF_EXT_LENGTH) {
|
|
|
|
ath10k_dbg(ar, ATH10K_DBG_BOOT,
|
|
|
|
"wrong smbios bdf ext type length (%d).\n",
|
|
|
|
hdr->length);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
bdf_enabled = *((u8 *)hdr + ATH10K_SMBIOS_BDF_EXT_OFFSET);
|
|
|
|
if (!bdf_enabled) {
|
|
|
|
ath10k_dbg(ar, ATH10K_DBG_BOOT, "bdf variant name not found.\n");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Only one string exists (per spec) */
|
|
|
|
bdf_ext = (char *)hdr + hdr->length;
|
|
|
|
|
|
|
|
if (memcmp(bdf_ext, magic, strlen(magic)) != 0) {
|
|
|
|
ath10k_dbg(ar, ATH10K_DBG_BOOT,
|
|
|
|
"bdf variant magic does not match.\n");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (i = 0; i < strlen(bdf_ext); i++) {
|
|
|
|
if (!isascii(bdf_ext[i]) || !isprint(bdf_ext[i])) {
|
|
|
|
ath10k_dbg(ar, ATH10K_DBG_BOOT,
|
|
|
|
"bdf variant name contains non ascii chars.\n");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Copy extension name without magic suffix */
|
|
|
|
if (strscpy(ar->id.bdf_ext, bdf_ext + strlen(magic),
|
|
|
|
sizeof(ar->id.bdf_ext)) < 0) {
|
|
|
|
ath10k_dbg(ar, ATH10K_DBG_BOOT,
|
|
|
|
"bdf variant string is longer than the buffer can accommodate (variant: %s)\n",
|
|
|
|
bdf_ext);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
ath10k_dbg(ar, ATH10K_DBG_BOOT,
|
|
|
|
"found and validated bdf variant smbios_type 0x%x bdf %s\n",
|
|
|
|
ATH10K_SMBIOS_BDF_EXT_TYPE, bdf_ext);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int ath10k_core_check_smbios(struct ath10k *ar)
|
|
|
|
{
|
|
|
|
ar->id.bdf_ext[0] = '\0';
|
|
|
|
dmi_walk(ath10k_core_check_bdfext, ar);
|
|
|
|
|
|
|
|
if (ar->id.bdf_ext[0] == '\0')
|
|
|
|
return -ENODATA;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
ath10k: search DT for qcom,ath10k-calibration-variant
Board Data File (BDF) is loaded upon driver boot-up procedure. The right
board data file is identified on QCA4019 using bus, bmi-chip-id and
bmi-board-id.
The problem, however, can occur when the (default) board data file cannot
fulfill with the vendor requirements and it is necessary to use a different
board data file.
This problem was solved for SMBIOS by adding a special SMBIOS type 0xF8.
Something similar has to be provided for systems without SMBIOS but with
device trees. No solution was specified by QCA and therefore a new one has
to be found for ath10k.
The device tree requires addition strings to define the variant name
wifi@a000000 {
status = "okay";
qcom,ath10k-calibration-variant = "RT-AC58U";
};
wifi@a800000 {
status = "okay";
qcom,ath10k-calibration-variant = "RT-AC58U";
};
This would create the boarddata identifiers for the board-2.bin search
* bus=ahb,bmi-chip-id=0,bmi-board-id=16,variant=RT-AC58U
* bus=ahb,bmi-chip-id=0,bmi-board-id=17,variant=RT-AC58U
Signed-off-by: Sven Eckelmann <sven.eckelmann@openmesh.com>
Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
2017-12-08 10:37:42 +00:00
|
|
|
static int ath10k_core_check_dt(struct ath10k *ar)
|
|
|
|
{
|
|
|
|
struct device_node *node;
|
|
|
|
const char *variant = NULL;
|
|
|
|
|
|
|
|
node = ar->dev->of_node;
|
|
|
|
if (!node)
|
|
|
|
return -ENOENT;
|
|
|
|
|
|
|
|
of_property_read_string(node, "qcom,ath10k-calibration-variant",
|
|
|
|
&variant);
|
|
|
|
if (!variant)
|
|
|
|
return -ENODATA;
|
|
|
|
|
|
|
|
if (strscpy(ar->id.bdf_ext, variant, sizeof(ar->id.bdf_ext)) < 0)
|
|
|
|
ath10k_dbg(ar, ATH10K_DBG_BOOT,
|
|
|
|
"bdf variant string is longer than the buffer can accommodate (variant: %s)\n",
|
|
|
|
variant);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2013-06-12 17:52:10 +00:00
|
|
|
static int ath10k_download_and_run_otp(struct ath10k *ar)
|
|
|
|
{
|
2014-03-11 15:33:19 +00:00
|
|
|
u32 result, address = ar->hw_params.patch_load_addr;
|
2015-06-18 07:01:10 +00:00
|
|
|
u32 bmi_otp_exe_param = ar->hw_params.otp_exe_param;
|
2013-06-12 17:52:10 +00:00
|
|
|
int ret;
|
|
|
|
|
2016-04-20 16:44:51 +00:00
|
|
|
ret = ath10k_download_board_data(ar,
|
|
|
|
ar->running_fw->board_data,
|
|
|
|
ar->running_fw->board_len);
|
2014-10-13 06:40:53 +00:00
|
|
|
if (ret) {
|
|
|
|
ath10k_err(ar, "failed to download board data: %d\n", ret);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2013-06-12 17:52:10 +00:00
|
|
|
/* OTP is optional */
|
|
|
|
|
2016-04-20 16:44:51 +00:00
|
|
|
if (!ar->running_fw->fw_file.otp_data ||
|
|
|
|
!ar->running_fw->fw_file.otp_len) {
|
2016-08-04 13:51:51 +00:00
|
|
|
ath10k_warn(ar, "Not running otp, calibration will be incorrect (otp-data %pK otp_len %zd)!\n",
|
2016-04-20 16:44:51 +00:00
|
|
|
ar->running_fw->fw_file.otp_data,
|
|
|
|
ar->running_fw->fw_file.otp_len);
|
2013-06-12 17:52:10 +00:00
|
|
|
return 0;
|
2014-03-11 15:33:28 +00:00
|
|
|
}
|
|
|
|
|
2014-08-25 10:09:38 +00:00
|
|
|
ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot upload otp to 0x%x len %zd\n",
|
2016-04-20 16:44:51 +00:00
|
|
|
address, ar->running_fw->fw_file.otp_len);
|
2013-06-12 17:52:10 +00:00
|
|
|
|
2016-04-20 16:44:51 +00:00
|
|
|
ret = ath10k_bmi_fast_download(ar, address,
|
|
|
|
ar->running_fw->fw_file.otp_data,
|
|
|
|
ar->running_fw->fw_file.otp_len);
|
2013-06-12 17:52:10 +00:00
|
|
|
if (ret) {
|
2014-08-25 10:09:38 +00:00
|
|
|
ath10k_err(ar, "could not write otp (%d)\n", ret);
|
2014-03-11 15:33:28 +00:00
|
|
|
return ret;
|
2013-06-12 17:52:10 +00:00
|
|
|
}
|
|
|
|
|
2017-05-31 11:21:27 +00:00
|
|
|
/* As of now pre-cal is valid for 10_4 variants */
|
|
|
|
if (ar->cal_mode == ATH10K_PRE_CAL_MODE_DT ||
|
|
|
|
ar->cal_mode == ATH10K_PRE_CAL_MODE_FILE)
|
|
|
|
bmi_otp_exe_param = BMI_PARAM_FLASH_SECTION_ALL;
|
|
|
|
|
2015-06-18 07:01:10 +00:00
|
|
|
ret = ath10k_bmi_execute(ar, address, bmi_otp_exe_param, &result);
|
2013-06-12 17:52:10 +00:00
|
|
|
if (ret) {
|
2014-08-25 10:09:38 +00:00
|
|
|
ath10k_err(ar, "could not execute otp (%d)\n", ret);
|
2014-03-11 15:33:28 +00:00
|
|
|
return ret;
|
2013-06-12 17:52:10 +00:00
|
|
|
}
|
|
|
|
|
2014-08-25 10:09:38 +00:00
|
|
|
ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot otp execute result %d\n", result);
|
2014-03-11 15:33:28 +00:00
|
|
|
|
2015-04-28 17:19:30 +00:00
|
|
|
if (!(skip_otp || test_bit(ATH10K_FW_FEATURE_IGNORE_OTP_RESULT,
|
2016-04-20 16:45:18 +00:00
|
|
|
ar->running_fw->fw_file.fw_features)) &&
|
2015-10-05 14:56:34 +00:00
|
|
|
result != 0) {
|
2014-08-25 10:09:38 +00:00
|
|
|
ath10k_err(ar, "otp calibration failed: %d", result);
|
2014-03-11 15:33:28 +00:00
|
|
|
return -EINVAL;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
2013-06-12 17:52:10 +00:00
|
|
|
}
|
|
|
|
|
2016-04-20 16:44:51 +00:00
|
|
|
static int ath10k_download_fw(struct ath10k *ar)
|
2013-06-12 17:52:10 +00:00
|
|
|
{
|
2014-09-10 15:23:30 +00:00
|
|
|
u32 address, data_len;
|
|
|
|
const void *data;
|
2013-06-12 17:52:10 +00:00
|
|
|
int ret;
|
|
|
|
|
|
|
|
address = ar->hw_params.patch_load_addr;
|
|
|
|
|
2016-04-20 16:44:51 +00:00
|
|
|
data = ar->running_fw->fw_file.firmware_data;
|
|
|
|
data_len = ar->running_fw->fw_file.firmware_len;
|
|
|
|
|
2016-08-19 10:37:39 +00:00
|
|
|
ret = ath10k_swap_code_seg_configure(ar, &ar->running_fw->fw_file);
|
2016-04-20 16:44:51 +00:00
|
|
|
if (ret) {
|
|
|
|
ath10k_err(ar, "failed to configure fw code swap: %d\n",
|
|
|
|
ret);
|
|
|
|
return ret;
|
2014-09-10 15:23:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
ath10k_dbg(ar, ATH10K_DBG_BOOT,
|
2016-08-04 13:51:51 +00:00
|
|
|
"boot uploading firmware image %pK len %d\n",
|
2016-04-20 16:44:51 +00:00
|
|
|
data, data_len);
|
2014-09-10 15:23:30 +00:00
|
|
|
|
|
|
|
ret = ath10k_bmi_fast_download(ar, address, data, data_len);
|
2013-06-12 17:52:10 +00:00
|
|
|
if (ret) {
|
2016-04-20 16:44:51 +00:00
|
|
|
ath10k_err(ar, "failed to download firmware: %d\n",
|
|
|
|
ret);
|
2014-09-10 15:23:30 +00:00
|
|
|
return ret;
|
2013-06-12 17:52:10 +00:00
|
|
|
}
|
|
|
|
|
2013-07-16 07:38:58 +00:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2015-10-09 08:55:58 +00:00
|
|
|
static void ath10k_core_free_board_files(struct ath10k *ar)
|
2013-07-16 07:38:58 +00:00
|
|
|
{
|
2016-04-20 16:44:51 +00:00
|
|
|
if (!IS_ERR(ar->normal_mode_fw.board))
|
|
|
|
release_firmware(ar->normal_mode_fw.board);
|
2013-07-16 07:38:58 +00:00
|
|
|
|
2016-04-20 16:44:51 +00:00
|
|
|
ar->normal_mode_fw.board = NULL;
|
|
|
|
ar->normal_mode_fw.board_data = NULL;
|
|
|
|
ar->normal_mode_fw.board_len = 0;
|
2015-10-09 08:55:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void ath10k_core_free_firmware_files(struct ath10k *ar)
|
|
|
|
{
|
2016-04-20 16:44:51 +00:00
|
|
|
if (!IS_ERR(ar->normal_mode_fw.fw_file.firmware))
|
|
|
|
release_firmware(ar->normal_mode_fw.fw_file.firmware);
|
2013-07-16 07:38:58 +00:00
|
|
|
|
2015-02-04 18:30:23 +00:00
|
|
|
if (!IS_ERR(ar->cal_file))
|
2014-10-13 06:40:59 +00:00
|
|
|
release_firmware(ar->cal_file);
|
|
|
|
|
2016-04-27 10:56:26 +00:00
|
|
|
if (!IS_ERR(ar->pre_cal_file))
|
|
|
|
release_firmware(ar->pre_cal_file);
|
|
|
|
|
2016-08-19 10:37:39 +00:00
|
|
|
ath10k_swap_code_seg_release(ar, &ar->normal_mode_fw.fw_file);
|
2015-06-18 07:01:09 +00:00
|
|
|
|
2016-04-20 16:44:51 +00:00
|
|
|
ar->normal_mode_fw.fw_file.otp_data = NULL;
|
|
|
|
ar->normal_mode_fw.fw_file.otp_len = 0;
|
2013-09-27 16:55:01 +00:00
|
|
|
|
2016-04-20 16:44:51 +00:00
|
|
|
ar->normal_mode_fw.fw_file.firmware = NULL;
|
|
|
|
ar->normal_mode_fw.fw_file.firmware_data = NULL;
|
|
|
|
ar->normal_mode_fw.fw_file.firmware_len = 0;
|
2014-10-13 06:40:59 +00:00
|
|
|
|
|
|
|
ar->cal_file = NULL;
|
2016-04-27 10:56:26 +00:00
|
|
|
ar->pre_cal_file = NULL;
|
2014-10-13 06:40:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static int ath10k_fetch_cal_file(struct ath10k *ar)
|
|
|
|
{
|
|
|
|
char filename[100];
|
|
|
|
|
2016-03-18 09:44:22 +00:00
|
|
|
/* pre-cal-<bus>-<id>.bin */
|
|
|
|
scnprintf(filename, sizeof(filename), "pre-cal-%s-%s.bin",
|
|
|
|
ath10k_bus_str(ar->hif.bus), dev_name(ar->dev));
|
|
|
|
|
|
|
|
ar->pre_cal_file = ath10k_fetch_fw_file(ar, ATH10K_FW_DIR, filename);
|
|
|
|
if (!IS_ERR(ar->pre_cal_file))
|
|
|
|
goto success;
|
|
|
|
|
2014-10-13 06:40:59 +00:00
|
|
|
/* cal-<bus>-<id>.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);
|
2016-03-18 09:44:22 +00:00
|
|
|
success:
|
2014-10-13 06:40:59 +00:00
|
|
|
ath10k_dbg(ar, ATH10K_DBG_BOOT, "found calibration file %s/%s\n",
|
|
|
|
ATH10K_FW_DIR, filename);
|
|
|
|
|
|
|
|
return 0;
|
2013-07-16 07:38:58 +00:00
|
|
|
}
|
|
|
|
|
2015-10-09 08:55:58 +00:00
|
|
|
static int ath10k_core_fetch_board_data_api_1(struct ath10k *ar)
|
2013-07-16 07:38:58 +00:00
|
|
|
{
|
2015-10-09 08:55:58 +00:00
|
|
|
if (!ar->hw_params.fw.board) {
|
|
|
|
ath10k_err(ar, "failed to find board file fw entry\n");
|
|
|
|
return -EINVAL;
|
|
|
|
}
|
2015-04-17 09:19:17 +00:00
|
|
|
|
2016-04-20 16:44:51 +00:00
|
|
|
ar->normal_mode_fw.board = ath10k_fetch_fw_file(ar,
|
|
|
|
ar->hw_params.fw.dir,
|
|
|
|
ar->hw_params.fw.board);
|
|
|
|
if (IS_ERR(ar->normal_mode_fw.board))
|
|
|
|
return PTR_ERR(ar->normal_mode_fw.board);
|
2015-04-17 09:19:17 +00:00
|
|
|
|
2016-04-20 16:44:51 +00:00
|
|
|
ar->normal_mode_fw.board_data = ar->normal_mode_fw.board->data;
|
|
|
|
ar->normal_mode_fw.board_len = ar->normal_mode_fw.board->size;
|
2013-07-16 07:38:58 +00:00
|
|
|
|
2015-04-17 09:19:17 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2015-10-09 08:55:58 +00:00
|
|
|
static int ath10k_core_parse_bd_ie_board(struct ath10k *ar,
|
|
|
|
const void *buf, size_t buf_len,
|
|
|
|
const char *boardname)
|
2015-04-17 09:19:17 +00:00
|
|
|
{
|
2015-10-09 08:55:58 +00:00
|
|
|
const struct ath10k_fw_ie *hdr;
|
|
|
|
bool name_match_found;
|
|
|
|
int ret, board_ie_id;
|
|
|
|
size_t board_ie_len;
|
|
|
|
const void *board_ie_data;
|
|
|
|
|
|
|
|
name_match_found = false;
|
|
|
|
|
|
|
|
/* go through ATH10K_BD_IE_BOARD_ elements */
|
|
|
|
while (buf_len > sizeof(struct ath10k_fw_ie)) {
|
|
|
|
hdr = buf;
|
|
|
|
board_ie_id = le32_to_cpu(hdr->id);
|
|
|
|
board_ie_len = le32_to_cpu(hdr->len);
|
|
|
|
board_ie_data = hdr->data;
|
|
|
|
|
|
|
|
buf_len -= sizeof(*hdr);
|
|
|
|
buf += sizeof(*hdr);
|
|
|
|
|
|
|
|
if (buf_len < ALIGN(board_ie_len, 4)) {
|
|
|
|
ath10k_err(ar, "invalid ATH10K_BD_IE_BOARD length: %zu < %zu\n",
|
|
|
|
buf_len, ALIGN(board_ie_len, 4));
|
|
|
|
ret = -EINVAL;
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
|
|
|
|
switch (board_ie_id) {
|
|
|
|
case ATH10K_BD_IE_BOARD_NAME:
|
|
|
|
ath10k_dbg_dump(ar, ATH10K_DBG_BOOT, "board name", "",
|
|
|
|
board_ie_data, board_ie_len);
|
|
|
|
|
|
|
|
if (board_ie_len != strlen(boardname))
|
|
|
|
break;
|
|
|
|
|
|
|
|
ret = memcmp(board_ie_data, boardname, strlen(boardname));
|
|
|
|
if (ret)
|
|
|
|
break;
|
|
|
|
|
|
|
|
name_match_found = true;
|
|
|
|
ath10k_dbg(ar, ATH10K_DBG_BOOT,
|
|
|
|
"boot found match for name '%s'",
|
|
|
|
boardname);
|
|
|
|
break;
|
|
|
|
case ATH10K_BD_IE_BOARD_DATA:
|
|
|
|
if (!name_match_found)
|
|
|
|
/* no match found */
|
|
|
|
break;
|
|
|
|
|
|
|
|
ath10k_dbg(ar, ATH10K_DBG_BOOT,
|
|
|
|
"boot found board data for '%s'",
|
|
|
|
boardname);
|
|
|
|
|
2016-04-20 16:44:51 +00:00
|
|
|
ar->normal_mode_fw.board_data = board_ie_data;
|
|
|
|
ar->normal_mode_fw.board_len = board_ie_len;
|
2015-10-09 08:55:58 +00:00
|
|
|
|
|
|
|
ret = 0;
|
|
|
|
goto out;
|
|
|
|
default:
|
|
|
|
ath10k_warn(ar, "unknown ATH10K_BD_IE_BOARD found: %d\n",
|
|
|
|
board_ie_id);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* jump over the padding */
|
|
|
|
board_ie_len = ALIGN(board_ie_len, 4);
|
|
|
|
|
|
|
|
buf_len -= board_ie_len;
|
|
|
|
buf += board_ie_len;
|
2013-07-16 07:38:58 +00:00
|
|
|
}
|
|
|
|
|
2015-10-09 08:55:58 +00:00
|
|
|
/* no match found */
|
|
|
|
ret = -ENOENT;
|
|
|
|
|
|
|
|
out:
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
ath10k: search all IEs for variant before falling back
commit f2593cb1b291 ("ath10k: Search SMBIOS for OEM board file
extension") added a feature to ath10k that allows Board Data File
(BDF) conflicts between multiple devices that use the same device IDs
but have different calibration requirements to be resolved by allowing
a "variant" string to be stored in SMBIOS [and later device tree, added
by commit d06f26c5c8a4 ("ath10k: search DT for qcom,ath10k-calibration-
variant")] that gets appended to the ID stored in board-2.bin.
This original patch had a regression, however. Namely that devices with
a variant present in SMBIOS that didn't need custom BDFs could no longer
find the default BDF, which has no variant appended. The patch was
reverted and re-applied with a fix for this issue in commit 1657b8f84ed9
("search SMBIOS for OEM board file extension").
But the fix to fall back to a default BDF introduced another issue: the
driver currently parses IEs in board-2.bin one by one, and for each one
it first checks to see if it matches the ID with the variant appended.
If it doesn't, it checks to see if it matches the "fallback" ID with no
variant. If a matching BDF is found at any point during this search, the
search is terminated and that BDF is used. The issue is that it's very
possible (and is currently the case for board-2.bin files present in the
ath10k-firmware repository) for the default BDF to occur in an earlier
IE than the variant-specific BDF. In this case, the current code will
happily choose the default BDF even though a better-matching BDF is
present later in the file.
This patch fixes the issue by first searching the entire file for the ID
with variant, and searching for the fallback ID only if that search
fails. It also includes some code cleanup in the area, as
ath10k_core_fetch_board_data_api_n() no longer does its own string
mangling to remove the variant from an ID, instead leaving that job to a
new flag passed to ath10k_core_create_board_name().
I've tested this patch on a QCA4019 and verified that the driver behaves
correctly for 1) both fallback and variant BDFs present, 2) only fallback
BDF present, and 3) no matching BDFs present.
Fixes: 1657b8f84ed9 ("ath10k: search SMBIOS for OEM board file extension")
Signed-off-by: Thomas Hebb <tommyhebb@gmail.com>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
2018-04-13 14:40:26 +00:00
|
|
|
static int ath10k_core_search_bd(struct ath10k *ar,
|
|
|
|
const char *boardname,
|
|
|
|
const u8 *data,
|
|
|
|
size_t len)
|
|
|
|
{
|
|
|
|
size_t ie_len;
|
|
|
|
struct ath10k_fw_ie *hdr;
|
|
|
|
int ret = -ENOENT, ie_id;
|
|
|
|
|
|
|
|
while (len > sizeof(struct ath10k_fw_ie)) {
|
|
|
|
hdr = (struct ath10k_fw_ie *)data;
|
|
|
|
ie_id = le32_to_cpu(hdr->id);
|
|
|
|
ie_len = le32_to_cpu(hdr->len);
|
|
|
|
|
|
|
|
len -= sizeof(*hdr);
|
|
|
|
data = hdr->data;
|
|
|
|
|
|
|
|
if (len < ALIGN(ie_len, 4)) {
|
|
|
|
ath10k_err(ar, "invalid length for board ie_id %d ie_len %zu len %zu\n",
|
|
|
|
ie_id, ie_len, len);
|
|
|
|
return -EINVAL;
|
|
|
|
}
|
|
|
|
|
|
|
|
switch (ie_id) {
|
|
|
|
case ATH10K_BD_IE_BOARD:
|
|
|
|
ret = ath10k_core_parse_bd_ie_board(ar, data, ie_len,
|
|
|
|
boardname);
|
|
|
|
if (ret == -ENOENT)
|
|
|
|
/* no match found, continue */
|
|
|
|
break;
|
|
|
|
|
|
|
|
/* either found or error, so stop searching */
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* jump over the padding */
|
|
|
|
ie_len = ALIGN(ie_len, 4);
|
|
|
|
|
|
|
|
len -= ie_len;
|
|
|
|
data += ie_len;
|
|
|
|
}
|
|
|
|
|
|
|
|
out:
|
|
|
|
/* return result of parse_bd_ie_board() or -ENOENT */
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2015-10-09 08:55:58 +00:00
|
|
|
static int ath10k_core_fetch_board_data_api_n(struct ath10k *ar,
|
|
|
|
const char *boardname,
|
ath10k: search all IEs for variant before falling back
commit f2593cb1b291 ("ath10k: Search SMBIOS for OEM board file
extension") added a feature to ath10k that allows Board Data File
(BDF) conflicts between multiple devices that use the same device IDs
but have different calibration requirements to be resolved by allowing
a "variant" string to be stored in SMBIOS [and later device tree, added
by commit d06f26c5c8a4 ("ath10k: search DT for qcom,ath10k-calibration-
variant")] that gets appended to the ID stored in board-2.bin.
This original patch had a regression, however. Namely that devices with
a variant present in SMBIOS that didn't need custom BDFs could no longer
find the default BDF, which has no variant appended. The patch was
reverted and re-applied with a fix for this issue in commit 1657b8f84ed9
("search SMBIOS for OEM board file extension").
But the fix to fall back to a default BDF introduced another issue: the
driver currently parses IEs in board-2.bin one by one, and for each one
it first checks to see if it matches the ID with the variant appended.
If it doesn't, it checks to see if it matches the "fallback" ID with no
variant. If a matching BDF is found at any point during this search, the
search is terminated and that BDF is used. The issue is that it's very
possible (and is currently the case for board-2.bin files present in the
ath10k-firmware repository) for the default BDF to occur in an earlier
IE than the variant-specific BDF. In this case, the current code will
happily choose the default BDF even though a better-matching BDF is
present later in the file.
This patch fixes the issue by first searching the entire file for the ID
with variant, and searching for the fallback ID only if that search
fails. It also includes some code cleanup in the area, as
ath10k_core_fetch_board_data_api_n() no longer does its own string
mangling to remove the variant from an ID, instead leaving that job to a
new flag passed to ath10k_core_create_board_name().
I've tested this patch on a QCA4019 and verified that the driver behaves
correctly for 1) both fallback and variant BDFs present, 2) only fallback
BDF present, and 3) no matching BDFs present.
Fixes: 1657b8f84ed9 ("ath10k: search SMBIOS for OEM board file extension")
Signed-off-by: Thomas Hebb <tommyhebb@gmail.com>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
2018-04-13 14:40:26 +00:00
|
|
|
const char *fallback_boardname,
|
2015-10-09 08:55:58 +00:00
|
|
|
const char *filename)
|
|
|
|
{
|
ath10k: search all IEs for variant before falling back
commit f2593cb1b291 ("ath10k: Search SMBIOS for OEM board file
extension") added a feature to ath10k that allows Board Data File
(BDF) conflicts between multiple devices that use the same device IDs
but have different calibration requirements to be resolved by allowing
a "variant" string to be stored in SMBIOS [and later device tree, added
by commit d06f26c5c8a4 ("ath10k: search DT for qcom,ath10k-calibration-
variant")] that gets appended to the ID stored in board-2.bin.
This original patch had a regression, however. Namely that devices with
a variant present in SMBIOS that didn't need custom BDFs could no longer
find the default BDF, which has no variant appended. The patch was
reverted and re-applied with a fix for this issue in commit 1657b8f84ed9
("search SMBIOS for OEM board file extension").
But the fix to fall back to a default BDF introduced another issue: the
driver currently parses IEs in board-2.bin one by one, and for each one
it first checks to see if it matches the ID with the variant appended.
If it doesn't, it checks to see if it matches the "fallback" ID with no
variant. If a matching BDF is found at any point during this search, the
search is terminated and that BDF is used. The issue is that it's very
possible (and is currently the case for board-2.bin files present in the
ath10k-firmware repository) for the default BDF to occur in an earlier
IE than the variant-specific BDF. In this case, the current code will
happily choose the default BDF even though a better-matching BDF is
present later in the file.
This patch fixes the issue by first searching the entire file for the ID
with variant, and searching for the fallback ID only if that search
fails. It also includes some code cleanup in the area, as
ath10k_core_fetch_board_data_api_n() no longer does its own string
mangling to remove the variant from an ID, instead leaving that job to a
new flag passed to ath10k_core_create_board_name().
I've tested this patch on a QCA4019 and verified that the driver behaves
correctly for 1) both fallback and variant BDFs present, 2) only fallback
BDF present, and 3) no matching BDFs present.
Fixes: 1657b8f84ed9 ("ath10k: search SMBIOS for OEM board file extension")
Signed-off-by: Thomas Hebb <tommyhebb@gmail.com>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
2018-04-13 14:40:26 +00:00
|
|
|
size_t len, magic_len;
|
2015-10-09 08:55:58 +00:00
|
|
|
const u8 *data;
|
ath10k: search all IEs for variant before falling back
commit f2593cb1b291 ("ath10k: Search SMBIOS for OEM board file
extension") added a feature to ath10k that allows Board Data File
(BDF) conflicts between multiple devices that use the same device IDs
but have different calibration requirements to be resolved by allowing
a "variant" string to be stored in SMBIOS [and later device tree, added
by commit d06f26c5c8a4 ("ath10k: search DT for qcom,ath10k-calibration-
variant")] that gets appended to the ID stored in board-2.bin.
This original patch had a regression, however. Namely that devices with
a variant present in SMBIOS that didn't need custom BDFs could no longer
find the default BDF, which has no variant appended. The patch was
reverted and re-applied with a fix for this issue in commit 1657b8f84ed9
("search SMBIOS for OEM board file extension").
But the fix to fall back to a default BDF introduced another issue: the
driver currently parses IEs in board-2.bin one by one, and for each one
it first checks to see if it matches the ID with the variant appended.
If it doesn't, it checks to see if it matches the "fallback" ID with no
variant. If a matching BDF is found at any point during this search, the
search is terminated and that BDF is used. The issue is that it's very
possible (and is currently the case for board-2.bin files present in the
ath10k-firmware repository) for the default BDF to occur in an earlier
IE than the variant-specific BDF. In this case, the current code will
happily choose the default BDF even though a better-matching BDF is
present later in the file.
This patch fixes the issue by first searching the entire file for the ID
with variant, and searching for the fallback ID only if that search
fails. It also includes some code cleanup in the area, as
ath10k_core_fetch_board_data_api_n() no longer does its own string
mangling to remove the variant from an ID, instead leaving that job to a
new flag passed to ath10k_core_create_board_name().
I've tested this patch on a QCA4019 and verified that the driver behaves
correctly for 1) both fallback and variant BDFs present, 2) only fallback
BDF present, and 3) no matching BDFs present.
Fixes: 1657b8f84ed9 ("ath10k: search SMBIOS for OEM board file extension")
Signed-off-by: Thomas Hebb <tommyhebb@gmail.com>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
2018-04-13 14:40:26 +00:00
|
|
|
int ret;
|
2015-10-09 08:55:58 +00:00
|
|
|
|
2016-04-20 16:44:51 +00:00
|
|
|
ar->normal_mode_fw.board = ath10k_fetch_fw_file(ar,
|
|
|
|
ar->hw_params.fw.dir,
|
|
|
|
filename);
|
|
|
|
if (IS_ERR(ar->normal_mode_fw.board))
|
|
|
|
return PTR_ERR(ar->normal_mode_fw.board);
|
2013-07-16 07:38:58 +00:00
|
|
|
|
2016-04-20 16:44:51 +00:00
|
|
|
data = ar->normal_mode_fw.board->data;
|
|
|
|
len = ar->normal_mode_fw.board->size;
|
2015-10-09 08:55:58 +00:00
|
|
|
|
|
|
|
/* magic has extra null byte padded */
|
|
|
|
magic_len = strlen(ATH10K_BOARD_MAGIC) + 1;
|
|
|
|
if (len < magic_len) {
|
|
|
|
ath10k_err(ar, "failed to find magic value in %s/%s, file too short: %zu\n",
|
|
|
|
ar->hw_params.fw.dir, filename, len);
|
|
|
|
ret = -EINVAL;
|
|
|
|
goto err;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (memcmp(data, ATH10K_BOARD_MAGIC, magic_len)) {
|
|
|
|
ath10k_err(ar, "found invalid board magic\n");
|
|
|
|
ret = -EINVAL;
|
|
|
|
goto err;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* magic is padded to 4 bytes */
|
|
|
|
magic_len = ALIGN(magic_len, 4);
|
|
|
|
if (len < magic_len) {
|
|
|
|
ath10k_err(ar, "failed: %s/%s too small to contain board data, len: %zu\n",
|
|
|
|
ar->hw_params.fw.dir, filename, len);
|
|
|
|
ret = -EINVAL;
|
|
|
|
goto err;
|
|
|
|
}
|
|
|
|
|
|
|
|
data += magic_len;
|
|
|
|
len -= magic_len;
|
|
|
|
|
ath10k: search all IEs for variant before falling back
commit f2593cb1b291 ("ath10k: Search SMBIOS for OEM board file
extension") added a feature to ath10k that allows Board Data File
(BDF) conflicts between multiple devices that use the same device IDs
but have different calibration requirements to be resolved by allowing
a "variant" string to be stored in SMBIOS [and later device tree, added
by commit d06f26c5c8a4 ("ath10k: search DT for qcom,ath10k-calibration-
variant")] that gets appended to the ID stored in board-2.bin.
This original patch had a regression, however. Namely that devices with
a variant present in SMBIOS that didn't need custom BDFs could no longer
find the default BDF, which has no variant appended. The patch was
reverted and re-applied with a fix for this issue in commit 1657b8f84ed9
("search SMBIOS for OEM board file extension").
But the fix to fall back to a default BDF introduced another issue: the
driver currently parses IEs in board-2.bin one by one, and for each one
it first checks to see if it matches the ID with the variant appended.
If it doesn't, it checks to see if it matches the "fallback" ID with no
variant. If a matching BDF is found at any point during this search, the
search is terminated and that BDF is used. The issue is that it's very
possible (and is currently the case for board-2.bin files present in the
ath10k-firmware repository) for the default BDF to occur in an earlier
IE than the variant-specific BDF. In this case, the current code will
happily choose the default BDF even though a better-matching BDF is
present later in the file.
This patch fixes the issue by first searching the entire file for the ID
with variant, and searching for the fallback ID only if that search
fails. It also includes some code cleanup in the area, as
ath10k_core_fetch_board_data_api_n() no longer does its own string
mangling to remove the variant from an ID, instead leaving that job to a
new flag passed to ath10k_core_create_board_name().
I've tested this patch on a QCA4019 and verified that the driver behaves
correctly for 1) both fallback and variant BDFs present, 2) only fallback
BDF present, and 3) no matching BDFs present.
Fixes: 1657b8f84ed9 ("ath10k: search SMBIOS for OEM board file extension")
Signed-off-by: Thomas Hebb <tommyhebb@gmail.com>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
2018-04-13 14:40:26 +00:00
|
|
|
/* attempt to find boardname in the IE list */
|
|
|
|
ret = ath10k_core_search_bd(ar, boardname, data, len);
|
2015-10-09 08:55:58 +00:00
|
|
|
|
ath10k: search all IEs for variant before falling back
commit f2593cb1b291 ("ath10k: Search SMBIOS for OEM board file
extension") added a feature to ath10k that allows Board Data File
(BDF) conflicts between multiple devices that use the same device IDs
but have different calibration requirements to be resolved by allowing
a "variant" string to be stored in SMBIOS [and later device tree, added
by commit d06f26c5c8a4 ("ath10k: search DT for qcom,ath10k-calibration-
variant")] that gets appended to the ID stored in board-2.bin.
This original patch had a regression, however. Namely that devices with
a variant present in SMBIOS that didn't need custom BDFs could no longer
find the default BDF, which has no variant appended. The patch was
reverted and re-applied with a fix for this issue in commit 1657b8f84ed9
("search SMBIOS for OEM board file extension").
But the fix to fall back to a default BDF introduced another issue: the
driver currently parses IEs in board-2.bin one by one, and for each one
it first checks to see if it matches the ID with the variant appended.
If it doesn't, it checks to see if it matches the "fallback" ID with no
variant. If a matching BDF is found at any point during this search, the
search is terminated and that BDF is used. The issue is that it's very
possible (and is currently the case for board-2.bin files present in the
ath10k-firmware repository) for the default BDF to occur in an earlier
IE than the variant-specific BDF. In this case, the current code will
happily choose the default BDF even though a better-matching BDF is
present later in the file.
This patch fixes the issue by first searching the entire file for the ID
with variant, and searching for the fallback ID only if that search
fails. It also includes some code cleanup in the area, as
ath10k_core_fetch_board_data_api_n() no longer does its own string
mangling to remove the variant from an ID, instead leaving that job to a
new flag passed to ath10k_core_create_board_name().
I've tested this patch on a QCA4019 and verified that the driver behaves
correctly for 1) both fallback and variant BDFs present, 2) only fallback
BDF present, and 3) no matching BDFs present.
Fixes: 1657b8f84ed9 ("ath10k: search SMBIOS for OEM board file extension")
Signed-off-by: Thomas Hebb <tommyhebb@gmail.com>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
2018-04-13 14:40:26 +00:00
|
|
|
/* if we didn't find it and have a fallback name, try that */
|
|
|
|
if (ret == -ENOENT && fallback_boardname)
|
|
|
|
ret = ath10k_core_search_bd(ar, fallback_boardname, data, len);
|
2015-10-09 08:55:58 +00:00
|
|
|
|
ath10k: search all IEs for variant before falling back
commit f2593cb1b291 ("ath10k: Search SMBIOS for OEM board file
extension") added a feature to ath10k that allows Board Data File
(BDF) conflicts between multiple devices that use the same device IDs
but have different calibration requirements to be resolved by allowing
a "variant" string to be stored in SMBIOS [and later device tree, added
by commit d06f26c5c8a4 ("ath10k: search DT for qcom,ath10k-calibration-
variant")] that gets appended to the ID stored in board-2.bin.
This original patch had a regression, however. Namely that devices with
a variant present in SMBIOS that didn't need custom BDFs could no longer
find the default BDF, which has no variant appended. The patch was
reverted and re-applied with a fix for this issue in commit 1657b8f84ed9
("search SMBIOS for OEM board file extension").
But the fix to fall back to a default BDF introduced another issue: the
driver currently parses IEs in board-2.bin one by one, and for each one
it first checks to see if it matches the ID with the variant appended.
If it doesn't, it checks to see if it matches the "fallback" ID with no
variant. If a matching BDF is found at any point during this search, the
search is terminated and that BDF is used. The issue is that it's very
possible (and is currently the case for board-2.bin files present in the
ath10k-firmware repository) for the default BDF to occur in an earlier
IE than the variant-specific BDF. In this case, the current code will
happily choose the default BDF even though a better-matching BDF is
present later in the file.
This patch fixes the issue by first searching the entire file for the ID
with variant, and searching for the fallback ID only if that search
fails. It also includes some code cleanup in the area, as
ath10k_core_fetch_board_data_api_n() no longer does its own string
mangling to remove the variant from an ID, instead leaving that job to a
new flag passed to ath10k_core_create_board_name().
I've tested this patch on a QCA4019 and verified that the driver behaves
correctly for 1) both fallback and variant BDFs present, 2) only fallback
BDF present, and 3) no matching BDFs present.
Fixes: 1657b8f84ed9 ("ath10k: search SMBIOS for OEM board file extension")
Signed-off-by: Thomas Hebb <tommyhebb@gmail.com>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
2018-04-13 14:40:26 +00:00
|
|
|
if (ret == -ENOENT) {
|
2015-10-09 08:55:58 +00:00
|
|
|
ath10k_err(ar,
|
|
|
|
"failed to fetch board data for %s from %s/%s\n",
|
2015-11-20 17:33:14 +00:00
|
|
|
boardname, ar->hw_params.fw.dir, filename);
|
2015-10-09 08:55:58 +00:00
|
|
|
ret = -ENODATA;
|
|
|
|
}
|
|
|
|
|
ath10k: search all IEs for variant before falling back
commit f2593cb1b291 ("ath10k: Search SMBIOS for OEM board file
extension") added a feature to ath10k that allows Board Data File
(BDF) conflicts between multiple devices that use the same device IDs
but have different calibration requirements to be resolved by allowing
a "variant" string to be stored in SMBIOS [and later device tree, added
by commit d06f26c5c8a4 ("ath10k: search DT for qcom,ath10k-calibration-
variant")] that gets appended to the ID stored in board-2.bin.
This original patch had a regression, however. Namely that devices with
a variant present in SMBIOS that didn't need custom BDFs could no longer
find the default BDF, which has no variant appended. The patch was
reverted and re-applied with a fix for this issue in commit 1657b8f84ed9
("search SMBIOS for OEM board file extension").
But the fix to fall back to a default BDF introduced another issue: the
driver currently parses IEs in board-2.bin one by one, and for each one
it first checks to see if it matches the ID with the variant appended.
If it doesn't, it checks to see if it matches the "fallback" ID with no
variant. If a matching BDF is found at any point during this search, the
search is terminated and that BDF is used. The issue is that it's very
possible (and is currently the case for board-2.bin files present in the
ath10k-firmware repository) for the default BDF to occur in an earlier
IE than the variant-specific BDF. In this case, the current code will
happily choose the default BDF even though a better-matching BDF is
present later in the file.
This patch fixes the issue by first searching the entire file for the ID
with variant, and searching for the fallback ID only if that search
fails. It also includes some code cleanup in the area, as
ath10k_core_fetch_board_data_api_n() no longer does its own string
mangling to remove the variant from an ID, instead leaving that job to a
new flag passed to ath10k_core_create_board_name().
I've tested this patch on a QCA4019 and verified that the driver behaves
correctly for 1) both fallback and variant BDFs present, 2) only fallback
BDF present, and 3) no matching BDFs present.
Fixes: 1657b8f84ed9 ("ath10k: search SMBIOS for OEM board file extension")
Signed-off-by: Thomas Hebb <tommyhebb@gmail.com>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
2018-04-13 14:40:26 +00:00
|
|
|
if (ret)
|
|
|
|
goto err;
|
|
|
|
|
2015-10-09 08:55:58 +00:00
|
|
|
return 0;
|
|
|
|
|
|
|
|
err:
|
|
|
|
ath10k_core_free_board_files(ar);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int ath10k_core_create_board_name(struct ath10k *ar, char *name,
|
ath10k: search all IEs for variant before falling back
commit f2593cb1b291 ("ath10k: Search SMBIOS for OEM board file
extension") added a feature to ath10k that allows Board Data File
(BDF) conflicts between multiple devices that use the same device IDs
but have different calibration requirements to be resolved by allowing
a "variant" string to be stored in SMBIOS [and later device tree, added
by commit d06f26c5c8a4 ("ath10k: search DT for qcom,ath10k-calibration-
variant")] that gets appended to the ID stored in board-2.bin.
This original patch had a regression, however. Namely that devices with
a variant present in SMBIOS that didn't need custom BDFs could no longer
find the default BDF, which has no variant appended. The patch was
reverted and re-applied with a fix for this issue in commit 1657b8f84ed9
("search SMBIOS for OEM board file extension").
But the fix to fall back to a default BDF introduced another issue: the
driver currently parses IEs in board-2.bin one by one, and for each one
it first checks to see if it matches the ID with the variant appended.
If it doesn't, it checks to see if it matches the "fallback" ID with no
variant. If a matching BDF is found at any point during this search, the
search is terminated and that BDF is used. The issue is that it's very
possible (and is currently the case for board-2.bin files present in the
ath10k-firmware repository) for the default BDF to occur in an earlier
IE than the variant-specific BDF. In this case, the current code will
happily choose the default BDF even though a better-matching BDF is
present later in the file.
This patch fixes the issue by first searching the entire file for the ID
with variant, and searching for the fallback ID only if that search
fails. It also includes some code cleanup in the area, as
ath10k_core_fetch_board_data_api_n() no longer does its own string
mangling to remove the variant from an ID, instead leaving that job to a
new flag passed to ath10k_core_create_board_name().
I've tested this patch on a QCA4019 and verified that the driver behaves
correctly for 1) both fallback and variant BDFs present, 2) only fallback
BDF present, and 3) no matching BDFs present.
Fixes: 1657b8f84ed9 ("ath10k: search SMBIOS for OEM board file extension")
Signed-off-by: Thomas Hebb <tommyhebb@gmail.com>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
2018-04-13 14:40:26 +00:00
|
|
|
size_t name_len, bool with_variant)
|
2015-10-09 08:55:58 +00:00
|
|
|
{
|
ath10k: search SMBIOS for OEM board file extension
Board Data File (BDF) is loaded upon driver boot-up procedure. The right
board data file is identified, among others, by device and sybsystem ids.
The problem, however, can occur when the (default) board data file cannot
fulfill with the vendor requirements and it is necessary to use a different
board data file.
To solve the issue QCA uses SMBIOS type 0xF8 to store Board Data File Name
Extension to specify the extension/variant name. The driver will take the
extension suffix into consideration and will load the right (non-default)
board data file if necessary.
If it is unnecessary to use extension board data file, please leave the
SMBIOS field blank and default configuration will be used.
Example:
If a default board data file for a specific board is identified by a string
"bus=pci,vendor=168c,device=003e,subsystem-vendor=1028,
subsystem-device=0310"
then the OEM specific data file, if used, could be identified by variant
suffix:
"bus=pci,vendor=168c,device=003e,subsystem-vendor=1028,
subsystem-device=0310,variant=DE_1AB"
If board data file name extension is set but board-2.bin does not contain
board data file for the variant, the driver will fallback to the default
board data file not to break backward compatibility.
This was first applied in commit f2593cb1b291 ("ath10k: Search SMBIOS for OEM
board file extension") but later reverted in commit 005c3490e9db ("Revert
"ath10k: Search SMBIOS for OEM board file extension"". This patch is now
otherwise the same as commit f2593cb1b291 except the regression fixed.
Signed-off-by: Waldemar Rymarkiewicz <ext.waldemar.rymarkiewicz@tieto.com>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
2017-02-24 22:30:03 +00:00
|
|
|
/* strlen(',variant=') + strlen(ar->id.bdf_ext) */
|
|
|
|
char variant[9 + ATH10K_SMBIOS_BDF_EXT_STR_LENGTH] = { 0 };
|
|
|
|
|
ath10k: search all IEs for variant before falling back
commit f2593cb1b291 ("ath10k: Search SMBIOS for OEM board file
extension") added a feature to ath10k that allows Board Data File
(BDF) conflicts between multiple devices that use the same device IDs
but have different calibration requirements to be resolved by allowing
a "variant" string to be stored in SMBIOS [and later device tree, added
by commit d06f26c5c8a4 ("ath10k: search DT for qcom,ath10k-calibration-
variant")] that gets appended to the ID stored in board-2.bin.
This original patch had a regression, however. Namely that devices with
a variant present in SMBIOS that didn't need custom BDFs could no longer
find the default BDF, which has no variant appended. The patch was
reverted and re-applied with a fix for this issue in commit 1657b8f84ed9
("search SMBIOS for OEM board file extension").
But the fix to fall back to a default BDF introduced another issue: the
driver currently parses IEs in board-2.bin one by one, and for each one
it first checks to see if it matches the ID with the variant appended.
If it doesn't, it checks to see if it matches the "fallback" ID with no
variant. If a matching BDF is found at any point during this search, the
search is terminated and that BDF is used. The issue is that it's very
possible (and is currently the case for board-2.bin files present in the
ath10k-firmware repository) for the default BDF to occur in an earlier
IE than the variant-specific BDF. In this case, the current code will
happily choose the default BDF even though a better-matching BDF is
present later in the file.
This patch fixes the issue by first searching the entire file for the ID
with variant, and searching for the fallback ID only if that search
fails. It also includes some code cleanup in the area, as
ath10k_core_fetch_board_data_api_n() no longer does its own string
mangling to remove the variant from an ID, instead leaving that job to a
new flag passed to ath10k_core_create_board_name().
I've tested this patch on a QCA4019 and verified that the driver behaves
correctly for 1) both fallback and variant BDFs present, 2) only fallback
BDF present, and 3) no matching BDFs present.
Fixes: 1657b8f84ed9 ("ath10k: search SMBIOS for OEM board file extension")
Signed-off-by: Thomas Hebb <tommyhebb@gmail.com>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
2018-04-13 14:40:26 +00:00
|
|
|
if (with_variant && ar->id.bdf_ext[0] != '\0')
|
ath10k: search DT for qcom,ath10k-calibration-variant
Board Data File (BDF) is loaded upon driver boot-up procedure. The right
board data file is identified on QCA4019 using bus, bmi-chip-id and
bmi-board-id.
The problem, however, can occur when the (default) board data file cannot
fulfill with the vendor requirements and it is necessary to use a different
board data file.
This problem was solved for SMBIOS by adding a special SMBIOS type 0xF8.
Something similar has to be provided for systems without SMBIOS but with
device trees. No solution was specified by QCA and therefore a new one has
to be found for ath10k.
The device tree requires addition strings to define the variant name
wifi@a000000 {
status = "okay";
qcom,ath10k-calibration-variant = "RT-AC58U";
};
wifi@a800000 {
status = "okay";
qcom,ath10k-calibration-variant = "RT-AC58U";
};
This would create the boarddata identifiers for the board-2.bin search
* bus=ahb,bmi-chip-id=0,bmi-board-id=16,variant=RT-AC58U
* bus=ahb,bmi-chip-id=0,bmi-board-id=17,variant=RT-AC58U
Signed-off-by: Sven Eckelmann <sven.eckelmann@openmesh.com>
Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
2017-12-08 10:37:42 +00:00
|
|
|
scnprintf(variant, sizeof(variant), ",variant=%s",
|
|
|
|
ar->id.bdf_ext);
|
|
|
|
|
2015-10-09 08:55:59 +00:00
|
|
|
if (ar->id.bmi_ids_valid) {
|
|
|
|
scnprintf(name, name_len,
|
ath10k: search DT for qcom,ath10k-calibration-variant
Board Data File (BDF) is loaded upon driver boot-up procedure. The right
board data file is identified on QCA4019 using bus, bmi-chip-id and
bmi-board-id.
The problem, however, can occur when the (default) board data file cannot
fulfill with the vendor requirements and it is necessary to use a different
board data file.
This problem was solved for SMBIOS by adding a special SMBIOS type 0xF8.
Something similar has to be provided for systems without SMBIOS but with
device trees. No solution was specified by QCA and therefore a new one has
to be found for ath10k.
The device tree requires addition strings to define the variant name
wifi@a000000 {
status = "okay";
qcom,ath10k-calibration-variant = "RT-AC58U";
};
wifi@a800000 {
status = "okay";
qcom,ath10k-calibration-variant = "RT-AC58U";
};
This would create the boarddata identifiers for the board-2.bin search
* bus=ahb,bmi-chip-id=0,bmi-board-id=16,variant=RT-AC58U
* bus=ahb,bmi-chip-id=0,bmi-board-id=17,variant=RT-AC58U
Signed-off-by: Sven Eckelmann <sven.eckelmann@openmesh.com>
Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
2017-12-08 10:37:42 +00:00
|
|
|
"bus=%s,bmi-chip-id=%d,bmi-board-id=%d%s",
|
2015-10-09 08:55:59 +00:00
|
|
|
ath10k_bus_str(ar->hif.bus),
|
|
|
|
ar->id.bmi_chip_id,
|
ath10k: search DT for qcom,ath10k-calibration-variant
Board Data File (BDF) is loaded upon driver boot-up procedure. The right
board data file is identified on QCA4019 using bus, bmi-chip-id and
bmi-board-id.
The problem, however, can occur when the (default) board data file cannot
fulfill with the vendor requirements and it is necessary to use a different
board data file.
This problem was solved for SMBIOS by adding a special SMBIOS type 0xF8.
Something similar has to be provided for systems without SMBIOS but with
device trees. No solution was specified by QCA and therefore a new one has
to be found for ath10k.
The device tree requires addition strings to define the variant name
wifi@a000000 {
status = "okay";
qcom,ath10k-calibration-variant = "RT-AC58U";
};
wifi@a800000 {
status = "okay";
qcom,ath10k-calibration-variant = "RT-AC58U";
};
This would create the boarddata identifiers for the board-2.bin search
* bus=ahb,bmi-chip-id=0,bmi-board-id=16,variant=RT-AC58U
* bus=ahb,bmi-chip-id=0,bmi-board-id=17,variant=RT-AC58U
Signed-off-by: Sven Eckelmann <sven.eckelmann@openmesh.com>
Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
2017-12-08 10:37:42 +00:00
|
|
|
ar->id.bmi_board_id, variant);
|
2015-10-09 08:55:59 +00:00
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
|
2015-10-09 08:55:58 +00:00
|
|
|
scnprintf(name, name_len,
|
ath10k: search SMBIOS for OEM board file extension
Board Data File (BDF) is loaded upon driver boot-up procedure. The right
board data file is identified, among others, by device and sybsystem ids.
The problem, however, can occur when the (default) board data file cannot
fulfill with the vendor requirements and it is necessary to use a different
board data file.
To solve the issue QCA uses SMBIOS type 0xF8 to store Board Data File Name
Extension to specify the extension/variant name. The driver will take the
extension suffix into consideration and will load the right (non-default)
board data file if necessary.
If it is unnecessary to use extension board data file, please leave the
SMBIOS field blank and default configuration will be used.
Example:
If a default board data file for a specific board is identified by a string
"bus=pci,vendor=168c,device=003e,subsystem-vendor=1028,
subsystem-device=0310"
then the OEM specific data file, if used, could be identified by variant
suffix:
"bus=pci,vendor=168c,device=003e,subsystem-vendor=1028,
subsystem-device=0310,variant=DE_1AB"
If board data file name extension is set but board-2.bin does not contain
board data file for the variant, the driver will fallback to the default
board data file not to break backward compatibility.
This was first applied in commit f2593cb1b291 ("ath10k: Search SMBIOS for OEM
board file extension") but later reverted in commit 005c3490e9db ("Revert
"ath10k: Search SMBIOS for OEM board file extension"". This patch is now
otherwise the same as commit f2593cb1b291 except the regression fixed.
Signed-off-by: Waldemar Rymarkiewicz <ext.waldemar.rymarkiewicz@tieto.com>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
2017-02-24 22:30:03 +00:00
|
|
|
"bus=%s,vendor=%04x,device=%04x,subsystem-vendor=%04x,subsystem-device=%04x%s",
|
2015-10-09 08:55:58 +00:00
|
|
|
ath10k_bus_str(ar->hif.bus),
|
|
|
|
ar->id.vendor, ar->id.device,
|
ath10k: search SMBIOS for OEM board file extension
Board Data File (BDF) is loaded upon driver boot-up procedure. The right
board data file is identified, among others, by device and sybsystem ids.
The problem, however, can occur when the (default) board data file cannot
fulfill with the vendor requirements and it is necessary to use a different
board data file.
To solve the issue QCA uses SMBIOS type 0xF8 to store Board Data File Name
Extension to specify the extension/variant name. The driver will take the
extension suffix into consideration and will load the right (non-default)
board data file if necessary.
If it is unnecessary to use extension board data file, please leave the
SMBIOS field blank and default configuration will be used.
Example:
If a default board data file for a specific board is identified by a string
"bus=pci,vendor=168c,device=003e,subsystem-vendor=1028,
subsystem-device=0310"
then the OEM specific data file, if used, could be identified by variant
suffix:
"bus=pci,vendor=168c,device=003e,subsystem-vendor=1028,
subsystem-device=0310,variant=DE_1AB"
If board data file name extension is set but board-2.bin does not contain
board data file for the variant, the driver will fallback to the default
board data file not to break backward compatibility.
This was first applied in commit f2593cb1b291 ("ath10k: Search SMBIOS for OEM
board file extension") but later reverted in commit 005c3490e9db ("Revert
"ath10k: Search SMBIOS for OEM board file extension"". This patch is now
otherwise the same as commit f2593cb1b291 except the regression fixed.
Signed-off-by: Waldemar Rymarkiewicz <ext.waldemar.rymarkiewicz@tieto.com>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
2017-02-24 22:30:03 +00:00
|
|
|
ar->id.subsystem_vendor, ar->id.subsystem_device, variant);
|
2015-10-09 08:55:59 +00:00
|
|
|
out:
|
2015-10-09 08:55:58 +00:00
|
|
|
ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot using board name '%s'\n", name);
|
2015-04-17 09:19:17 +00:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int ath10k_core_fetch_board_file(struct ath10k *ar)
|
|
|
|
{
|
ath10k: search all IEs for variant before falling back
commit f2593cb1b291 ("ath10k: Search SMBIOS for OEM board file
extension") added a feature to ath10k that allows Board Data File
(BDF) conflicts between multiple devices that use the same device IDs
but have different calibration requirements to be resolved by allowing
a "variant" string to be stored in SMBIOS [and later device tree, added
by commit d06f26c5c8a4 ("ath10k: search DT for qcom,ath10k-calibration-
variant")] that gets appended to the ID stored in board-2.bin.
This original patch had a regression, however. Namely that devices with
a variant present in SMBIOS that didn't need custom BDFs could no longer
find the default BDF, which has no variant appended. The patch was
reverted and re-applied with a fix for this issue in commit 1657b8f84ed9
("search SMBIOS for OEM board file extension").
But the fix to fall back to a default BDF introduced another issue: the
driver currently parses IEs in board-2.bin one by one, and for each one
it first checks to see if it matches the ID with the variant appended.
If it doesn't, it checks to see if it matches the "fallback" ID with no
variant. If a matching BDF is found at any point during this search, the
search is terminated and that BDF is used. The issue is that it's very
possible (and is currently the case for board-2.bin files present in the
ath10k-firmware repository) for the default BDF to occur in an earlier
IE than the variant-specific BDF. In this case, the current code will
happily choose the default BDF even though a better-matching BDF is
present later in the file.
This patch fixes the issue by first searching the entire file for the ID
with variant, and searching for the fallback ID only if that search
fails. It also includes some code cleanup in the area, as
ath10k_core_fetch_board_data_api_n() no longer does its own string
mangling to remove the variant from an ID, instead leaving that job to a
new flag passed to ath10k_core_create_board_name().
I've tested this patch on a QCA4019 and verified that the driver behaves
correctly for 1) both fallback and variant BDFs present, 2) only fallback
BDF present, and 3) no matching BDFs present.
Fixes: 1657b8f84ed9 ("ath10k: search SMBIOS for OEM board file extension")
Signed-off-by: Thomas Hebb <tommyhebb@gmail.com>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
2018-04-13 14:40:26 +00:00
|
|
|
char boardname[100], fallback_boardname[100];
|
2015-04-17 09:19:17 +00:00
|
|
|
int ret;
|
|
|
|
|
ath10k: search all IEs for variant before falling back
commit f2593cb1b291 ("ath10k: Search SMBIOS for OEM board file
extension") added a feature to ath10k that allows Board Data File
(BDF) conflicts between multiple devices that use the same device IDs
but have different calibration requirements to be resolved by allowing
a "variant" string to be stored in SMBIOS [and later device tree, added
by commit d06f26c5c8a4 ("ath10k: search DT for qcom,ath10k-calibration-
variant")] that gets appended to the ID stored in board-2.bin.
This original patch had a regression, however. Namely that devices with
a variant present in SMBIOS that didn't need custom BDFs could no longer
find the default BDF, which has no variant appended. The patch was
reverted and re-applied with a fix for this issue in commit 1657b8f84ed9
("search SMBIOS for OEM board file extension").
But the fix to fall back to a default BDF introduced another issue: the
driver currently parses IEs in board-2.bin one by one, and for each one
it first checks to see if it matches the ID with the variant appended.
If it doesn't, it checks to see if it matches the "fallback" ID with no
variant. If a matching BDF is found at any point during this search, the
search is terminated and that BDF is used. The issue is that it's very
possible (and is currently the case for board-2.bin files present in the
ath10k-firmware repository) for the default BDF to occur in an earlier
IE than the variant-specific BDF. In this case, the current code will
happily choose the default BDF even though a better-matching BDF is
present later in the file.
This patch fixes the issue by first searching the entire file for the ID
with variant, and searching for the fallback ID only if that search
fails. It also includes some code cleanup in the area, as
ath10k_core_fetch_board_data_api_n() no longer does its own string
mangling to remove the variant from an ID, instead leaving that job to a
new flag passed to ath10k_core_create_board_name().
I've tested this patch on a QCA4019 and verified that the driver behaves
correctly for 1) both fallback and variant BDFs present, 2) only fallback
BDF present, and 3) no matching BDFs present.
Fixes: 1657b8f84ed9 ("ath10k: search SMBIOS for OEM board file extension")
Signed-off-by: Thomas Hebb <tommyhebb@gmail.com>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
2018-04-13 14:40:26 +00:00
|
|
|
ret = ath10k_core_create_board_name(ar, boardname,
|
|
|
|
sizeof(boardname), true);
|
2015-10-09 08:55:58 +00:00
|
|
|
if (ret) {
|
|
|
|
ath10k_err(ar, "failed to create board name: %d", ret);
|
|
|
|
return ret;
|
2015-04-17 09:19:17 +00:00
|
|
|
}
|
|
|
|
|
ath10k: search all IEs for variant before falling back
commit f2593cb1b291 ("ath10k: Search SMBIOS for OEM board file
extension") added a feature to ath10k that allows Board Data File
(BDF) conflicts between multiple devices that use the same device IDs
but have different calibration requirements to be resolved by allowing
a "variant" string to be stored in SMBIOS [and later device tree, added
by commit d06f26c5c8a4 ("ath10k: search DT for qcom,ath10k-calibration-
variant")] that gets appended to the ID stored in board-2.bin.
This original patch had a regression, however. Namely that devices with
a variant present in SMBIOS that didn't need custom BDFs could no longer
find the default BDF, which has no variant appended. The patch was
reverted and re-applied with a fix for this issue in commit 1657b8f84ed9
("search SMBIOS for OEM board file extension").
But the fix to fall back to a default BDF introduced another issue: the
driver currently parses IEs in board-2.bin one by one, and for each one
it first checks to see if it matches the ID with the variant appended.
If it doesn't, it checks to see if it matches the "fallback" ID with no
variant. If a matching BDF is found at any point during this search, the
search is terminated and that BDF is used. The issue is that it's very
possible (and is currently the case for board-2.bin files present in the
ath10k-firmware repository) for the default BDF to occur in an earlier
IE than the variant-specific BDF. In this case, the current code will
happily choose the default BDF even though a better-matching BDF is
present later in the file.
This patch fixes the issue by first searching the entire file for the ID
with variant, and searching for the fallback ID only if that search
fails. It also includes some code cleanup in the area, as
ath10k_core_fetch_board_data_api_n() no longer does its own string
mangling to remove the variant from an ID, instead leaving that job to a
new flag passed to ath10k_core_create_board_name().
I've tested this patch on a QCA4019 and verified that the driver behaves
correctly for 1) both fallback and variant BDFs present, 2) only fallback
BDF present, and 3) no matching BDFs present.
Fixes: 1657b8f84ed9 ("ath10k: search SMBIOS for OEM board file extension")
Signed-off-by: Thomas Hebb <tommyhebb@gmail.com>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
2018-04-13 14:40:26 +00:00
|
|
|
ret = ath10k_core_create_board_name(ar, fallback_boardname,
|
|
|
|
sizeof(boardname), false);
|
|
|
|
if (ret) {
|
|
|
|
ath10k_err(ar, "failed to create fallback board name: %d", ret);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2015-10-09 08:55:58 +00:00
|
|
|
ar->bd_api = 2;
|
|
|
|
ret = ath10k_core_fetch_board_data_api_n(ar, boardname,
|
ath10k: search all IEs for variant before falling back
commit f2593cb1b291 ("ath10k: Search SMBIOS for OEM board file
extension") added a feature to ath10k that allows Board Data File
(BDF) conflicts between multiple devices that use the same device IDs
but have different calibration requirements to be resolved by allowing
a "variant" string to be stored in SMBIOS [and later device tree, added
by commit d06f26c5c8a4 ("ath10k: search DT for qcom,ath10k-calibration-
variant")] that gets appended to the ID stored in board-2.bin.
This original patch had a regression, however. Namely that devices with
a variant present in SMBIOS that didn't need custom BDFs could no longer
find the default BDF, which has no variant appended. The patch was
reverted and re-applied with a fix for this issue in commit 1657b8f84ed9
("search SMBIOS for OEM board file extension").
But the fix to fall back to a default BDF introduced another issue: the
driver currently parses IEs in board-2.bin one by one, and for each one
it first checks to see if it matches the ID with the variant appended.
If it doesn't, it checks to see if it matches the "fallback" ID with no
variant. If a matching BDF is found at any point during this search, the
search is terminated and that BDF is used. The issue is that it's very
possible (and is currently the case for board-2.bin files present in the
ath10k-firmware repository) for the default BDF to occur in an earlier
IE than the variant-specific BDF. In this case, the current code will
happily choose the default BDF even though a better-matching BDF is
present later in the file.
This patch fixes the issue by first searching the entire file for the ID
with variant, and searching for the fallback ID only if that search
fails. It also includes some code cleanup in the area, as
ath10k_core_fetch_board_data_api_n() no longer does its own string
mangling to remove the variant from an ID, instead leaving that job to a
new flag passed to ath10k_core_create_board_name().
I've tested this patch on a QCA4019 and verified that the driver behaves
correctly for 1) both fallback and variant BDFs present, 2) only fallback
BDF present, and 3) no matching BDFs present.
Fixes: 1657b8f84ed9 ("ath10k: search SMBIOS for OEM board file extension")
Signed-off-by: Thomas Hebb <tommyhebb@gmail.com>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
2018-04-13 14:40:26 +00:00
|
|
|
fallback_boardname,
|
2015-10-09 08:55:58 +00:00
|
|
|
ATH10K_BOARD_API2_FILE);
|
|
|
|
if (!ret)
|
|
|
|
goto success;
|
|
|
|
|
|
|
|
ar->bd_api = 1;
|
|
|
|
ret = ath10k_core_fetch_board_data_api_1(ar);
|
2015-04-17 09:19:17 +00:00
|
|
|
if (ret) {
|
2017-02-13 10:38:41 +00:00
|
|
|
ath10k_err(ar, "failed to fetch board-2.bin or board.bin from %s\n",
|
|
|
|
ar->hw_params.fw.dir);
|
2015-04-17 09:19:17 +00:00
|
|
|
return ret;
|
|
|
|
}
|
2013-09-27 16:55:01 +00:00
|
|
|
|
2015-10-09 08:55:58 +00:00
|
|
|
success:
|
|
|
|
ath10k_dbg(ar, ATH10K_DBG_BOOT, "using board api %d\n", ar->bd_api);
|
2015-04-17 09:19:16 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2016-04-20 16:46:01 +00:00
|
|
|
int ath10k_core_fetch_firmware_api_n(struct ath10k *ar, const char *name,
|
|
|
|
struct ath10k_fw_file *fw_file)
|
2013-09-27 16:55:07 +00:00
|
|
|
{
|
|
|
|
size_t magic_len, len, ie_len;
|
|
|
|
int ie_id, i, index, bit, ret;
|
|
|
|
struct ath10k_fw_ie *hdr;
|
|
|
|
const u8 *data;
|
2014-12-03 08:10:08 +00:00
|
|
|
__le32 *timestamp, *version;
|
2013-09-27 16:55:07 +00:00
|
|
|
|
|
|
|
/* first fetch the firmware file (firmware-*.bin) */
|
2016-04-20 16:44:51 +00:00
|
|
|
fw_file->firmware = ath10k_fetch_fw_file(ar, ar->hw_params.fw.dir,
|
|
|
|
name);
|
2017-02-13 10:38:42 +00:00
|
|
|
if (IS_ERR(fw_file->firmware))
|
2016-04-20 16:44:51 +00:00
|
|
|
return PTR_ERR(fw_file->firmware);
|
2013-09-27 16:55:07 +00:00
|
|
|
|
2016-04-20 16:44:51 +00:00
|
|
|
data = fw_file->firmware->data;
|
|
|
|
len = fw_file->firmware->size;
|
2013-09-27 16:55:07 +00:00
|
|
|
|
|
|
|
/* magic also includes the null byte, check that as well */
|
|
|
|
magic_len = strlen(ATH10K_FIRMWARE_MAGIC) + 1;
|
|
|
|
|
|
|
|
if (len < magic_len) {
|
2014-08-25 10:09:38 +00:00
|
|
|
ath10k_err(ar, "firmware file '%s/%s' too small to contain magic: %zu\n",
|
2014-03-24 19:20:41 +00:00
|
|
|
ar->hw_params.fw.dir, name, len);
|
2013-10-04 06:13:20 +00:00
|
|
|
ret = -EINVAL;
|
|
|
|
goto err;
|
2013-09-27 16:55:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (memcmp(data, ATH10K_FIRMWARE_MAGIC, magic_len) != 0) {
|
2014-08-25 10:09:38 +00:00
|
|
|
ath10k_err(ar, "invalid firmware magic\n");
|
2013-10-04 06:13:20 +00:00
|
|
|
ret = -EINVAL;
|
|
|
|
goto err;
|
2013-09-27 16:55:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* jump over the padding */
|
|
|
|
magic_len = ALIGN(magic_len, 4);
|
|
|
|
|
|
|
|
len -= magic_len;
|
|
|
|
data += magic_len;
|
|
|
|
|
|
|
|
/* loop elements */
|
|
|
|
while (len > sizeof(struct ath10k_fw_ie)) {
|
|
|
|
hdr = (struct ath10k_fw_ie *)data;
|
|
|
|
|
|
|
|
ie_id = le32_to_cpu(hdr->id);
|
|
|
|
ie_len = le32_to_cpu(hdr->len);
|
|
|
|
|
|
|
|
len -= sizeof(*hdr);
|
|
|
|
data += sizeof(*hdr);
|
|
|
|
|
|
|
|
if (len < ie_len) {
|
2014-08-25 10:09:38 +00:00
|
|
|
ath10k_err(ar, "invalid length for FW IE %d (%zu < %zu)\n",
|
2013-09-27 16:55:07 +00:00
|
|
|
ie_id, len, ie_len);
|
2013-10-04 06:13:20 +00:00
|
|
|
ret = -EINVAL;
|
|
|
|
goto err;
|
2013-09-27 16:55:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
switch (ie_id) {
|
|
|
|
case ATH10K_FW_IE_FW_VERSION:
|
2016-04-20 16:45:05 +00:00
|
|
|
if (ie_len > sizeof(fw_file->fw_version) - 1)
|
2013-09-27 16:55:07 +00:00
|
|
|
break;
|
|
|
|
|
2016-04-20 16:45:05 +00:00
|
|
|
memcpy(fw_file->fw_version, data, ie_len);
|
|
|
|
fw_file->fw_version[ie_len] = '\0';
|
2013-09-27 16:55:07 +00:00
|
|
|
|
2014-08-25 10:09:38 +00:00
|
|
|
ath10k_dbg(ar, ATH10K_DBG_BOOT,
|
2013-09-27 16:55:07 +00:00
|
|
|
"found fw version %s\n",
|
2016-04-20 16:45:05 +00:00
|
|
|
fw_file->fw_version);
|
2013-09-27 16:55:07 +00:00
|
|
|
break;
|
|
|
|
case ATH10K_FW_IE_TIMESTAMP:
|
|
|
|
if (ie_len != sizeof(u32))
|
|
|
|
break;
|
|
|
|
|
|
|
|
timestamp = (__le32 *)data;
|
|
|
|
|
2014-08-25 10:09:38 +00:00
|
|
|
ath10k_dbg(ar, ATH10K_DBG_BOOT, "found fw timestamp %d\n",
|
2013-09-27 16:55:07 +00:00
|
|
|
le32_to_cpup(timestamp));
|
|
|
|
break;
|
|
|
|
case ATH10K_FW_IE_FEATURES:
|
2014-08-25 10:09:38 +00:00
|
|
|
ath10k_dbg(ar, ATH10K_DBG_BOOT,
|
2013-09-27 16:55:07 +00:00
|
|
|
"found firmware features ie (%zd B)\n",
|
|
|
|
ie_len);
|
|
|
|
|
|
|
|
for (i = 0; i < ATH10K_FW_FEATURE_COUNT; i++) {
|
|
|
|
index = i / 8;
|
|
|
|
bit = i % 8;
|
|
|
|
|
|
|
|
if (index == ie_len)
|
|
|
|
break;
|
|
|
|
|
2014-02-04 17:51:38 +00:00
|
|
|
if (data[index] & (1 << bit)) {
|
2014-08-25 10:09:38 +00:00
|
|
|
ath10k_dbg(ar, ATH10K_DBG_BOOT,
|
2014-02-04 17:51:38 +00:00
|
|
|
"Enabling feature bit: %i\n",
|
|
|
|
i);
|
2016-04-20 16:45:18 +00:00
|
|
|
__set_bit(i, fw_file->fw_features);
|
2014-02-04 17:51:38 +00:00
|
|
|
}
|
2013-09-27 16:55:07 +00:00
|
|
|
}
|
|
|
|
|
2014-08-25 10:09:38 +00:00
|
|
|
ath10k_dbg_dump(ar, ATH10K_DBG_BOOT, "features", "",
|
2016-06-02 14:59:54 +00:00
|
|
|
fw_file->fw_features,
|
2016-04-20 16:45:18 +00:00
|
|
|
sizeof(fw_file->fw_features));
|
2013-09-27 16:55:07 +00:00
|
|
|
break;
|
|
|
|
case ATH10K_FW_IE_FW_IMAGE:
|
2014-08-25 10:09:38 +00:00
|
|
|
ath10k_dbg(ar, ATH10K_DBG_BOOT,
|
2013-09-27 16:55:07 +00:00
|
|
|
"found fw image ie (%zd B)\n",
|
|
|
|
ie_len);
|
|
|
|
|
2016-04-20 16:44:51 +00:00
|
|
|
fw_file->firmware_data = data;
|
|
|
|
fw_file->firmware_len = ie_len;
|
2013-09-27 16:55:07 +00:00
|
|
|
|
|
|
|
break;
|
|
|
|
case ATH10K_FW_IE_OTP_IMAGE:
|
2014-08-25 10:09:38 +00:00
|
|
|
ath10k_dbg(ar, ATH10K_DBG_BOOT,
|
2013-09-27 16:55:07 +00:00
|
|
|
"found otp image ie (%zd B)\n",
|
|
|
|
ie_len);
|
|
|
|
|
2016-04-20 16:44:51 +00:00
|
|
|
fw_file->otp_data = data;
|
|
|
|
fw_file->otp_len = ie_len;
|
2013-09-27 16:55:07 +00:00
|
|
|
|
|
|
|
break;
|
2014-12-03 08:10:08 +00:00
|
|
|
case ATH10K_FW_IE_WMI_OP_VERSION:
|
|
|
|
if (ie_len != sizeof(u32))
|
|
|
|
break;
|
|
|
|
|
|
|
|
version = (__le32 *)data;
|
|
|
|
|
2016-04-20 16:45:33 +00:00
|
|
|
fw_file->wmi_op_version = le32_to_cpup(version);
|
2014-12-03 08:10:08 +00:00
|
|
|
|
|
|
|
ath10k_dbg(ar, ATH10K_DBG_BOOT, "found fw ie wmi op version %d\n",
|
2016-04-20 16:45:33 +00:00
|
|
|
fw_file->wmi_op_version);
|
2014-12-03 08:10:08 +00:00
|
|
|
break;
|
2015-03-25 11:12:27 +00:00
|
|
|
case ATH10K_FW_IE_HTT_OP_VERSION:
|
|
|
|
if (ie_len != sizeof(u32))
|
|
|
|
break;
|
|
|
|
|
|
|
|
version = (__le32 *)data;
|
|
|
|
|
2016-04-20 16:45:47 +00:00
|
|
|
fw_file->htt_op_version = le32_to_cpup(version);
|
2015-03-25 11:12:27 +00:00
|
|
|
|
|
|
|
ath10k_dbg(ar, ATH10K_DBG_BOOT, "found fw ie htt op version %d\n",
|
2016-04-20 16:45:47 +00:00
|
|
|
fw_file->htt_op_version);
|
2015-03-25 11:12:27 +00:00
|
|
|
break;
|
2015-06-18 07:01:09 +00:00
|
|
|
case ATH10K_FW_IE_FW_CODE_SWAP_IMAGE:
|
|
|
|
ath10k_dbg(ar, ATH10K_DBG_BOOT,
|
|
|
|
"found fw code swap image ie (%zd B)\n",
|
|
|
|
ie_len);
|
2016-04-20 16:44:51 +00:00
|
|
|
fw_file->codeswap_data = data;
|
|
|
|
fw_file->codeswap_len = ie_len;
|
2015-06-18 07:01:09 +00:00
|
|
|
break;
|
2013-09-27 16:55:07 +00:00
|
|
|
default:
|
2014-08-25 10:09:38 +00:00
|
|
|
ath10k_warn(ar, "Unknown FW IE: %u\n",
|
2013-09-27 16:55:07 +00:00
|
|
|
le32_to_cpu(hdr->id));
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2018-02-07 13:51:23 +00:00
|
|
|
/* jump over the padding */
|
|
|
|
ie_len = ALIGN(ie_len, 4);
|
|
|
|
|
2013-09-27 16:55:07 +00:00
|
|
|
len -= ie_len;
|
|
|
|
data += ie_len;
|
2013-10-08 18:48:15 +00:00
|
|
|
}
|
2013-09-27 16:55:07 +00:00
|
|
|
|
2017-12-21 16:16:49 +00:00
|
|
|
if (!test_bit(ATH10K_FW_FEATURE_NON_BMI, fw_file->fw_features) &&
|
|
|
|
(!fw_file->firmware_data || !fw_file->firmware_len)) {
|
2014-08-25 10:09:38 +00:00
|
|
|
ath10k_warn(ar, "No ATH10K_FW_IE_FW_IMAGE found from '%s/%s', skipping\n",
|
2014-03-24 19:20:41 +00:00
|
|
|
ar->hw_params.fw.dir, name);
|
2013-09-27 16:55:07 +00:00
|
|
|
ret = -ENOMEDIUM;
|
|
|
|
goto err;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
err:
|
|
|
|
ath10k_core_free_firmware_files(ar);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2017-02-13 10:38:40 +00:00
|
|
|
static void ath10k_core_get_fw_name(struct ath10k *ar, char *fw_name,
|
|
|
|
size_t fw_name_len, int fw_api)
|
|
|
|
{
|
2017-04-26 09:17:59 +00:00
|
|
|
switch (ar->hif.bus) {
|
|
|
|
case ATH10K_BUS_SDIO:
|
2017-07-28 12:15:37 +00:00
|
|
|
case ATH10K_BUS_USB:
|
2017-04-26 09:17:59 +00:00
|
|
|
scnprintf(fw_name, fw_name_len, "%s-%s-%d.bin",
|
|
|
|
ATH10K_FW_FILE_BASE, ath10k_bus_str(ar->hif.bus),
|
|
|
|
fw_api);
|
|
|
|
break;
|
|
|
|
case ATH10K_BUS_PCI:
|
|
|
|
case ATH10K_BUS_AHB:
|
2017-12-21 16:05:20 +00:00
|
|
|
case ATH10K_BUS_SNOC:
|
2017-04-26 09:17:59 +00:00
|
|
|
scnprintf(fw_name, fw_name_len, "%s-%d.bin",
|
|
|
|
ATH10K_FW_FILE_BASE, fw_api);
|
|
|
|
break;
|
|
|
|
}
|
2017-02-13 10:38:40 +00:00
|
|
|
}
|
|
|
|
|
2013-09-27 16:55:07 +00:00
|
|
|
static int ath10k_core_fetch_firmware_files(struct ath10k *ar)
|
|
|
|
{
|
2017-02-13 10:38:40 +00:00
|
|
|
int ret, i;
|
|
|
|
char fw_name[100];
|
2013-09-27 16:55:07 +00:00
|
|
|
|
2014-10-13 06:40:59 +00:00
|
|
|
/* calibration file is optional, don't check for any errors */
|
|
|
|
ath10k_fetch_cal_file(ar);
|
|
|
|
|
2017-02-13 10:38:40 +00:00
|
|
|
for (i = ATH10K_FW_API_MAX; i >= ATH10K_FW_API_MIN; i--) {
|
|
|
|
ar->fw_api = i;
|
|
|
|
ath10k_dbg(ar, ATH10K_DBG_BOOT, "trying fw api %d\n",
|
|
|
|
ar->fw_api);
|
2015-03-25 11:12:42 +00:00
|
|
|
|
2017-02-13 10:38:40 +00:00
|
|
|
ath10k_core_get_fw_name(ar, fw_name, sizeof(fw_name), ar->fw_api);
|
|
|
|
ret = ath10k_core_fetch_firmware_api_n(ar, fw_name,
|
|
|
|
&ar->normal_mode_fw.fw_file);
|
|
|
|
if (!ret)
|
|
|
|
goto success;
|
|
|
|
}
|
2014-07-25 11:32:17 +00:00
|
|
|
|
2017-02-13 10:38:40 +00:00
|
|
|
/* we end up here if we couldn't fetch any firmware */
|
2014-07-25 11:32:17 +00:00
|
|
|
|
2017-02-13 10:38:40 +00:00
|
|
|
ath10k_err(ar, "Failed to find firmware-N.bin (N between %d and %d) from %s: %d",
|
|
|
|
ATH10K_FW_API_MIN, ATH10K_FW_API_MAX, ar->hw_params.fw.dir,
|
|
|
|
ret);
|
2014-03-24 19:20:41 +00:00
|
|
|
|
2017-02-13 10:38:40 +00:00
|
|
|
return ret;
|
2013-09-27 16:55:07 +00:00
|
|
|
|
2014-03-24 19:20:41 +00:00
|
|
|
success:
|
2014-08-25 10:09:38 +00:00
|
|
|
ath10k_dbg(ar, ATH10K_DBG_BOOT, "using fw api %d\n", ar->fw_api);
|
2013-09-27 16:55:07 +00:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2016-03-18 09:44:22 +00:00
|
|
|
static int ath10k_core_pre_cal_download(struct ath10k *ar)
|
|
|
|
{
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
ret = ath10k_download_cal_file(ar, ar->pre_cal_file);
|
|
|
|
if (ret == 0) {
|
|
|
|
ar->cal_mode = ATH10K_PRE_CAL_MODE_FILE;
|
|
|
|
goto success;
|
|
|
|
}
|
|
|
|
|
|
|
|
ath10k_dbg(ar, ATH10K_DBG_BOOT,
|
|
|
|
"boot did not find a pre calibration file, try DT next: %d\n",
|
|
|
|
ret);
|
|
|
|
|
|
|
|
ret = ath10k_download_cal_dt(ar, "qcom,ath10k-pre-calibration-data");
|
|
|
|
if (ret) {
|
|
|
|
ath10k_dbg(ar, ATH10K_DBG_BOOT,
|
|
|
|
"unable to load pre cal data from DT: %d\n", ret);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
ar->cal_mode = ATH10K_PRE_CAL_MODE_DT;
|
|
|
|
|
|
|
|
success:
|
|
|
|
ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot using calibration mode %s\n",
|
|
|
|
ath10k_cal_mode_str(ar->cal_mode));
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int ath10k_core_pre_cal_config(struct ath10k *ar)
|
|
|
|
{
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
ret = ath10k_core_pre_cal_download(ar);
|
|
|
|
if (ret) {
|
|
|
|
ath10k_dbg(ar, ATH10K_DBG_BOOT,
|
|
|
|
"failed to load pre cal data: %d\n", ret);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
ret = ath10k_core_get_board_id_from_otp(ar);
|
|
|
|
if (ret) {
|
|
|
|
ath10k_err(ar, "failed to get board id: %d\n", ret);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
ret = ath10k_download_and_run_otp(ar);
|
|
|
|
if (ret) {
|
|
|
|
ath10k_err(ar, "failed to run otp: %d\n", ret);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
ath10k_dbg(ar, ATH10K_DBG_BOOT,
|
|
|
|
"pre cal configuration done successfully\n");
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2014-10-13 06:40:53 +00:00
|
|
|
static int ath10k_download_cal_data(struct ath10k *ar)
|
2013-06-12 17:52:10 +00:00
|
|
|
{
|
|
|
|
int ret;
|
|
|
|
|
2016-03-18 09:44:22 +00:00
|
|
|
ret = ath10k_core_pre_cal_config(ar);
|
|
|
|
if (ret == 0)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
ath10k_dbg(ar, ATH10K_DBG_BOOT,
|
|
|
|
"pre cal download procedure failed, try cal file: %d\n",
|
|
|
|
ret);
|
|
|
|
|
2016-03-18 09:44:21 +00:00
|
|
|
ret = ath10k_download_cal_file(ar, ar->cal_file);
|
2014-10-13 06:40:59 +00:00
|
|
|
if (ret == 0) {
|
|
|
|
ar->cal_mode = ATH10K_CAL_MODE_FILE;
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
|
|
|
|
ath10k_dbg(ar, ATH10K_DBG_BOOT,
|
2014-12-02 08:55:54 +00:00
|
|
|
"boot did not find a calibration file, try DT next: %d\n",
|
|
|
|
ret);
|
|
|
|
|
2016-03-18 09:44:21 +00:00
|
|
|
ret = ath10k_download_cal_dt(ar, "qcom,ath10k-calibration-data");
|
2014-12-02 08:55:54 +00:00
|
|
|
if (ret == 0) {
|
|
|
|
ar->cal_mode = ATH10K_CAL_MODE_DT;
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
|
|
|
|
ath10k_dbg(ar, ATH10K_DBG_BOOT,
|
2016-06-02 14:59:50 +00:00
|
|
|
"boot did not find DT entry, try target EEPROM next: %d\n",
|
|
|
|
ret);
|
|
|
|
|
|
|
|
ret = ath10k_download_cal_eeprom(ar);
|
|
|
|
if (ret == 0) {
|
|
|
|
ar->cal_mode = ATH10K_CAL_MODE_EEPROM;
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
|
|
|
|
ath10k_dbg(ar, ATH10K_DBG_BOOT,
|
|
|
|
"boot did not find target EEPROM entry, try OTP next: %d\n",
|
2014-10-13 06:40:59 +00:00
|
|
|
ret);
|
|
|
|
|
2013-06-12 17:52:10 +00:00
|
|
|
ret = ath10k_download_and_run_otp(ar);
|
2014-03-24 19:20:42 +00:00
|
|
|
if (ret) {
|
2014-08-25 10:09:38 +00:00
|
|
|
ath10k_err(ar, "failed to run otp: %d\n", ret);
|
2013-06-12 17:52:10 +00:00
|
|
|
return ret;
|
2014-03-24 19:20:42 +00:00
|
|
|
}
|
2013-06-12 17:52:10 +00:00
|
|
|
|
2014-10-13 06:40:59 +00:00
|
|
|
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;
|
2013-06-12 17:52:10 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static int ath10k_init_uart(struct ath10k *ar)
|
|
|
|
{
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Explicitly setting UART prints to zero as target turns it on
|
|
|
|
* based on scratch registers.
|
|
|
|
*/
|
|
|
|
ret = ath10k_bmi_write32(ar, hi_serial_enable, 0);
|
|
|
|
if (ret) {
|
2014-08-25 10:09:38 +00:00
|
|
|
ath10k_warn(ar, "could not disable UART prints (%d)\n", ret);
|
2013-06-12 17:52:10 +00:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2013-11-20 08:00:41 +00:00
|
|
|
if (!uart_print)
|
2013-06-12 17:52:10 +00:00
|
|
|
return 0;
|
|
|
|
|
2014-12-02 08:55:55 +00:00
|
|
|
ret = ath10k_bmi_write32(ar, hi_dbg_uart_txpin, ar->hw_params.uart_pin);
|
2013-06-12 17:52:10 +00:00
|
|
|
if (ret) {
|
2014-08-25 10:09:38 +00:00
|
|
|
ath10k_warn(ar, "could not enable UART prints (%d)\n", ret);
|
2013-06-12 17:52:10 +00:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
ret = ath10k_bmi_write32(ar, hi_serial_enable, 1);
|
|
|
|
if (ret) {
|
2014-08-25 10:09:38 +00:00
|
|
|
ath10k_warn(ar, "could not enable UART prints (%d)\n", ret);
|
2013-06-12 17:52:10 +00:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2013-09-03 12:24:02 +00:00
|
|
|
/* Set the UART baud rate to 19200. */
|
|
|
|
ret = ath10k_bmi_write32(ar, hi_desired_baud_rate, 19200);
|
|
|
|
if (ret) {
|
2014-08-25 10:09:38 +00:00
|
|
|
ath10k_warn(ar, "could not set the baud rate (%d)\n", ret);
|
2013-09-03 12:24:02 +00:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2014-08-25 10:09:38 +00:00
|
|
|
ath10k_info(ar, "UART prints enabled\n");
|
2013-06-12 17:52:10 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int ath10k_init_hw_params(struct ath10k *ar)
|
|
|
|
{
|
|
|
|
const struct ath10k_hw_params *uninitialized_var(hw_params);
|
|
|
|
int i;
|
|
|
|
|
|
|
|
for (i = 0; i < ARRAY_SIZE(ath10k_hw_params_list); i++) {
|
|
|
|
hw_params = &ath10k_hw_params_list[i];
|
|
|
|
|
2015-11-05 08:50:42 +00:00
|
|
|
if (hw_params->id == ar->target_version &&
|
|
|
|
hw_params->dev_id == ar->dev_id)
|
2013-06-12 17:52:10 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (i == ARRAY_SIZE(ath10k_hw_params_list)) {
|
2014-08-25 10:09:38 +00:00
|
|
|
ath10k_err(ar, "Unsupported hardware version: 0x%x\n",
|
2013-06-12 17:52:10 +00:00
|
|
|
ar->target_version);
|
|
|
|
return -EINVAL;
|
|
|
|
}
|
|
|
|
|
|
|
|
ar->hw_params = *hw_params;
|
|
|
|
|
2014-08-25 10:09:38 +00:00
|
|
|
ath10k_dbg(ar, ATH10K_DBG_BOOT, "Hardware name %s version 0x%x\n",
|
2013-11-20 08:00:41 +00:00
|
|
|
ar->hw_params.name, ar->target_version);
|
2013-06-12 17:52:10 +00:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2013-07-16 07:54:35 +00:00
|
|
|
static void ath10k_core_restart(struct work_struct *work)
|
|
|
|
{
|
|
|
|
struct ath10k *ar = container_of(work, struct ath10k, restart_work);
|
2016-12-21 12:19:21 +00:00
|
|
|
int ret;
|
2013-07-16 07:54:35 +00:00
|
|
|
|
2014-10-28 09:34:38 +00:00
|
|
|
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);
|
2016-08-18 13:12:06 +00:00
|
|
|
complete(&ar->scan.started);
|
|
|
|
complete(&ar->scan.completed);
|
|
|
|
complete(&ar->scan.on_channel);
|
|
|
|
complete(&ar->offchan_tx_completed);
|
|
|
|
complete(&ar->install_key_done);
|
|
|
|
complete(&ar->vdev_setup_done);
|
|
|
|
complete(&ar->thermal.wmi_sync);
|
|
|
|
complete(&ar->bss_survey_done);
|
2014-10-28 09:34:38 +00:00
|
|
|
wake_up(&ar->htt.empty_tx_wq);
|
|
|
|
wake_up(&ar->wmi.tx_credits_wq);
|
|
|
|
wake_up(&ar->peer_mapping_wq);
|
|
|
|
|
2017-03-31 11:58:41 +00:00
|
|
|
/* TODO: We can have one instance of cancelling coverage_class_work by
|
|
|
|
* moving it to ath10k_halt(), so that both stop() and restart() would
|
|
|
|
* call that but it takes conf_mutex() and if we call cancel_work_sync()
|
|
|
|
* with conf_mutex it will deadlock.
|
|
|
|
*/
|
|
|
|
cancel_work_sync(&ar->set_coverage_class_work);
|
|
|
|
|
2013-07-16 07:54:35 +00:00
|
|
|
mutex_lock(&ar->conf_mutex);
|
|
|
|
|
|
|
|
switch (ar->state) {
|
|
|
|
case ATH10K_STATE_ON:
|
|
|
|
ar->state = ATH10K_STATE_RESTARTING;
|
2016-11-30 05:29:29 +00:00
|
|
|
ath10k_halt(ar);
|
2014-08-05 12:54:44 +00:00
|
|
|
ath10k_scan_finish(ar);
|
2013-07-16 07:54:35 +00:00
|
|
|
ieee80211_restart_hw(ar->hw);
|
|
|
|
break;
|
|
|
|
case ATH10K_STATE_OFF:
|
2013-10-16 13:46:05 +00:00
|
|
|
/* this can happen if driver is being unloaded
|
2017-02-20 13:39:57 +00:00
|
|
|
* or if the crash happens during FW probing
|
|
|
|
*/
|
2014-08-25 10:09:38 +00:00
|
|
|
ath10k_warn(ar, "cannot restart a device that hasn't been started\n");
|
2013-07-16 07:54:35 +00:00
|
|
|
break;
|
|
|
|
case ATH10K_STATE_RESTARTING:
|
2014-05-26 09:46:03 +00:00
|
|
|
/* hw restart might be requested from multiple places */
|
|
|
|
break;
|
2013-07-16 07:54:35 +00:00
|
|
|
case ATH10K_STATE_RESTARTED:
|
|
|
|
ar->state = ATH10K_STATE_WEDGED;
|
|
|
|
/* fall through */
|
|
|
|
case ATH10K_STATE_WEDGED:
|
2014-08-25 10:09:38 +00:00
|
|
|
ath10k_warn(ar, "device is wedged, will not restart\n");
|
2013-07-16 07:54:35 +00:00
|
|
|
break;
|
2014-09-10 15:23:30 +00:00
|
|
|
case ATH10K_STATE_UTF:
|
|
|
|
ath10k_warn(ar, "firmware restart in UTF mode not supported\n");
|
|
|
|
break;
|
2013-07-16 07:54:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
mutex_unlock(&ar->conf_mutex);
|
2016-12-21 12:19:21 +00:00
|
|
|
|
2017-12-22 13:38:43 +00:00
|
|
|
ret = ath10k_coredump_submit(ar);
|
2016-12-21 12:19:21 +00:00
|
|
|
if (ret)
|
|
|
|
ath10k_warn(ar, "failed to send firmware crash dump via devcoredump: %d",
|
|
|
|
ret);
|
2013-07-16 07:54:35 +00:00
|
|
|
}
|
|
|
|
|
2016-09-28 12:11:58 +00:00
|
|
|
static void ath10k_core_set_coverage_class_work(struct work_struct *work)
|
|
|
|
{
|
|
|
|
struct ath10k *ar = container_of(work, struct ath10k,
|
|
|
|
set_coverage_class_work);
|
|
|
|
|
|
|
|
if (ar->hw_params.hw_ops->set_coverage_class)
|
|
|
|
ar->hw_params.hw_ops->set_coverage_class(ar, -1);
|
|
|
|
}
|
|
|
|
|
2014-12-03 08:09:59 +00:00
|
|
|
static int ath10k_core_init_firmware_features(struct ath10k *ar)
|
2014-11-25 14:16:05 +00:00
|
|
|
{
|
2016-04-20 16:45:18 +00:00
|
|
|
struct ath10k_fw_file *fw_file = &ar->normal_mode_fw.fw_file;
|
|
|
|
|
|
|
|
if (test_bit(ATH10K_FW_FEATURE_WMI_10_2, fw_file->fw_features) &&
|
|
|
|
!test_bit(ATH10K_FW_FEATURE_WMI_10X, fw_file->fw_features)) {
|
2014-12-03 08:09:59 +00:00
|
|
|
ath10k_err(ar, "feature bits corrupted: 10.2 feature requires 10.x feature to be set as well");
|
|
|
|
return -EINVAL;
|
|
|
|
}
|
|
|
|
|
2016-04-20 16:45:33 +00:00
|
|
|
if (fw_file->wmi_op_version >= ATH10K_FW_WMI_OP_VERSION_MAX) {
|
2014-12-03 08:10:08 +00:00
|
|
|
ath10k_err(ar, "unsupported WMI OP version (max %d): %d\n",
|
2016-04-20 16:45:33 +00:00
|
|
|
ATH10K_FW_WMI_OP_VERSION_MAX, fw_file->wmi_op_version);
|
2014-12-03 08:10:08 +00:00
|
|
|
return -EINVAL;
|
|
|
|
}
|
|
|
|
|
ath10k: enable raw encap mode and software crypto engine
This patch enables raw Rx/Tx encap mode to support software based
crypto engine. This patch introduces a new module param 'cryptmode'.
cryptmode:
0: Use hardware crypto engine globally with native Wi-Fi mode TX/RX
encapsulation to the firmware. This is the default mode.
1: Use sofware crypto engine globally with raw mode TX/RX
encapsulation to the firmware.
Known limitation:
A-MSDU must be disabled for RAW Tx encap mode to perform well when
heavy traffic is applied.
Testing: (by Michal Kazior <michal.kazior@tieto.com>)
a) Performance Testing
cryptmode=1
ap=qca988x sta=killer1525
killer1525 -> qca988x 194.496 mbps [tcp1 ip4]
killer1525 -> qca988x 238.309 mbps [tcp5 ip4]
killer1525 -> qca988x 266.958 mbps [udp1 ip4]
killer1525 -> qca988x 477.468 mbps [udp5 ip4]
qca988x -> killer1525 301.378 mbps [tcp1 ip4]
qca988x -> killer1525 297.949 mbps [tcp5 ip4]
qca988x -> killer1525 331.351 mbps [udp1 ip4]
qca988x -> killer1525 371.528 mbps [udp5 ip4]
ap=killer1525 sta=qca988x
qca988x -> killer1525 331.447 mbps [tcp1 ip4]
qca988x -> killer1525 328.783 mbps [tcp5 ip4]
qca988x -> killer1525 375.309 mbps [udp1 ip4]
qca988x -> killer1525 403.379 mbps [udp5 ip4]
killer1525 -> qca988x 203.689 mbps [tcp1 ip4]
killer1525 -> qca988x 222.339 mbps [tcp5 ip4]
killer1525 -> qca988x 264.199 mbps [udp1 ip4]
killer1525 -> qca988x 479.371 mbps [udp5 ip4]
Note:
- only open network tested for RAW vs nwifi performance comparison
- killer1525 (qca6174 hw2.2) is 2x2 device (hence max 866mbps)
- used iperf
- OTA, devices a few cm apart from each other, no shielding
- tcpX/udpX, X - means number of threads used
Overview:
- relative Tx performance drop is seen but is within reasonable and
expected threshold (A-MSDU must be disabled with RAW Tx)
b) Connectivity Testing
cryptmode=1
ap=iwl6205 sta1=qca988x crypto=open topology-1ap1sta OK
ap=iwl6205 sta1=qca988x crypto=wep1 topology-1ap1sta OK
ap=iwl6205 sta1=qca988x crypto=wpa topology-1ap1sta OK
ap=iwl6205 sta1=qca988x crypto=wpa-ccmp topology-1ap1sta OK
ap=qca988x sta1=iwl6205 crypto=open topology-1ap1sta OK
ap=qca988x sta1=iwl6205 crypto=wep1 topology-1ap1sta OK
ap=qca988x sta1=iwl6205 crypto=wpa topology-1ap1sta OK
ap=qca988x sta1=iwl6205 crypto=wpa-ccmp topology-1ap1sta OK
ap=iwl6205 sta1=qca988x crypto=open topology-1ap1sta2br OK
ap=iwl6205 sta1=qca988x crypto=wep1 topology-1ap1sta2br OK
ap=iwl6205 sta1=qca988x crypto=wpa topology-1ap1sta2br OK
ap=iwl6205 sta1=qca988x crypto=wpa-ccmp topology-1ap1sta2br OK
ap=qca988x sta1=iwl6205 crypto=open topology-1ap1sta2br OK
ap=qca988x sta1=iwl6205 crypto=wep1 topology-1ap1sta2br OK
ap=qca988x sta1=iwl6205 crypto=wpa topology-1ap1sta2br OK
ap=qca988x sta1=iwl6205 crypto=wpa-ccmp topology-1ap1sta2br OK
ap=iwl6205 sta1=qca988x crypto=open topology-1ap1sta2br1vlan OK
ap=iwl6205 sta1=qca988x crypto=wep1 topology-1ap1sta2br1vlan OK
ap=iwl6205 sta1=qca988x crypto=wpa topology-1ap1sta2br1vlan OK
ap=iwl6205 sta1=qca988x crypto=wpa-ccmp topology-1ap1sta2br1vlan OK
ap=qca988x sta1=iwl6205 crypto=open topology-1ap1sta2br1vlan OK
ap=qca988x sta1=iwl6205 crypto=wep1 topology-1ap1sta2br1vlan OK
ap=qca988x sta1=iwl6205 crypto=wpa topology-1ap1sta2br1vlan OK
ap=qca988x sta1=iwl6205 crypto=wpa-ccmp topology-1ap1sta2br1vlan OK
Note:
- each test takes all possible endpoint pairs and pings
- each pair-ping flushes arp table
- ip6 is used
c) Testbed Topology:
1ap1sta:
[ap] ---- [sta]
endpoints: ap, sta
1ap1sta2br:
[veth0] [ap] ---- [sta] [veth2]
| | | |
[veth1] | \ [veth3]
\ / \ /
[br0] [br1]
endpoints: veth0, veth2, br0, br1
note: STA works in 4addr mode, AP has wds_sta=1
1ap1sta2br1vlan:
[veth0] [ap] ---- [sta] [veth2]
| | | |
[veth1] | \ [veth3]
\ / \ /
[br0] [br1]
| |
[vlan0_id2] [vlan1_id2]
endpoints: vlan0_id2, vlan1_id2
note: STA works in 4addr mode, AP has wds_sta=1
Credits:
Thanks to Michal Kazior <michal.kazior@tieto.com> who helped find the
amsdu issue, contributed a workaround (already squashed into this
patch), and contributed the throughput and connectivity tests results.
Signed-off-by: David Liu <cfliu.tw@gmail.com>
Signed-off-by: Michal Kazior <michal.kazior@tieto.com>
Tested-by: Michal Kazior <michal.kazior@tieto.com>
Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
2015-07-24 17:25:32 +00:00
|
|
|
ar->wmi.rx_decap_mode = ATH10K_HW_TXRX_NATIVE_WIFI;
|
|
|
|
switch (ath10k_cryptmode_param) {
|
|
|
|
case ATH10K_CRYPT_MODE_HW:
|
|
|
|
clear_bit(ATH10K_FLAG_RAW_MODE, &ar->dev_flags);
|
|
|
|
clear_bit(ATH10K_FLAG_HW_CRYPTO_DISABLED, &ar->dev_flags);
|
|
|
|
break;
|
|
|
|
case ATH10K_CRYPT_MODE_SW:
|
|
|
|
if (!test_bit(ATH10K_FW_FEATURE_RAW_MODE_SUPPORT,
|
2016-04-20 16:45:18 +00:00
|
|
|
fw_file->fw_features)) {
|
ath10k: enable raw encap mode and software crypto engine
This patch enables raw Rx/Tx encap mode to support software based
crypto engine. This patch introduces a new module param 'cryptmode'.
cryptmode:
0: Use hardware crypto engine globally with native Wi-Fi mode TX/RX
encapsulation to the firmware. This is the default mode.
1: Use sofware crypto engine globally with raw mode TX/RX
encapsulation to the firmware.
Known limitation:
A-MSDU must be disabled for RAW Tx encap mode to perform well when
heavy traffic is applied.
Testing: (by Michal Kazior <michal.kazior@tieto.com>)
a) Performance Testing
cryptmode=1
ap=qca988x sta=killer1525
killer1525 -> qca988x 194.496 mbps [tcp1 ip4]
killer1525 -> qca988x 238.309 mbps [tcp5 ip4]
killer1525 -> qca988x 266.958 mbps [udp1 ip4]
killer1525 -> qca988x 477.468 mbps [udp5 ip4]
qca988x -> killer1525 301.378 mbps [tcp1 ip4]
qca988x -> killer1525 297.949 mbps [tcp5 ip4]
qca988x -> killer1525 331.351 mbps [udp1 ip4]
qca988x -> killer1525 371.528 mbps [udp5 ip4]
ap=killer1525 sta=qca988x
qca988x -> killer1525 331.447 mbps [tcp1 ip4]
qca988x -> killer1525 328.783 mbps [tcp5 ip4]
qca988x -> killer1525 375.309 mbps [udp1 ip4]
qca988x -> killer1525 403.379 mbps [udp5 ip4]
killer1525 -> qca988x 203.689 mbps [tcp1 ip4]
killer1525 -> qca988x 222.339 mbps [tcp5 ip4]
killer1525 -> qca988x 264.199 mbps [udp1 ip4]
killer1525 -> qca988x 479.371 mbps [udp5 ip4]
Note:
- only open network tested for RAW vs nwifi performance comparison
- killer1525 (qca6174 hw2.2) is 2x2 device (hence max 866mbps)
- used iperf
- OTA, devices a few cm apart from each other, no shielding
- tcpX/udpX, X - means number of threads used
Overview:
- relative Tx performance drop is seen but is within reasonable and
expected threshold (A-MSDU must be disabled with RAW Tx)
b) Connectivity Testing
cryptmode=1
ap=iwl6205 sta1=qca988x crypto=open topology-1ap1sta OK
ap=iwl6205 sta1=qca988x crypto=wep1 topology-1ap1sta OK
ap=iwl6205 sta1=qca988x crypto=wpa topology-1ap1sta OK
ap=iwl6205 sta1=qca988x crypto=wpa-ccmp topology-1ap1sta OK
ap=qca988x sta1=iwl6205 crypto=open topology-1ap1sta OK
ap=qca988x sta1=iwl6205 crypto=wep1 topology-1ap1sta OK
ap=qca988x sta1=iwl6205 crypto=wpa topology-1ap1sta OK
ap=qca988x sta1=iwl6205 crypto=wpa-ccmp topology-1ap1sta OK
ap=iwl6205 sta1=qca988x crypto=open topology-1ap1sta2br OK
ap=iwl6205 sta1=qca988x crypto=wep1 topology-1ap1sta2br OK
ap=iwl6205 sta1=qca988x crypto=wpa topology-1ap1sta2br OK
ap=iwl6205 sta1=qca988x crypto=wpa-ccmp topology-1ap1sta2br OK
ap=qca988x sta1=iwl6205 crypto=open topology-1ap1sta2br OK
ap=qca988x sta1=iwl6205 crypto=wep1 topology-1ap1sta2br OK
ap=qca988x sta1=iwl6205 crypto=wpa topology-1ap1sta2br OK
ap=qca988x sta1=iwl6205 crypto=wpa-ccmp topology-1ap1sta2br OK
ap=iwl6205 sta1=qca988x crypto=open topology-1ap1sta2br1vlan OK
ap=iwl6205 sta1=qca988x crypto=wep1 topology-1ap1sta2br1vlan OK
ap=iwl6205 sta1=qca988x crypto=wpa topology-1ap1sta2br1vlan OK
ap=iwl6205 sta1=qca988x crypto=wpa-ccmp topology-1ap1sta2br1vlan OK
ap=qca988x sta1=iwl6205 crypto=open topology-1ap1sta2br1vlan OK
ap=qca988x sta1=iwl6205 crypto=wep1 topology-1ap1sta2br1vlan OK
ap=qca988x sta1=iwl6205 crypto=wpa topology-1ap1sta2br1vlan OK
ap=qca988x sta1=iwl6205 crypto=wpa-ccmp topology-1ap1sta2br1vlan OK
Note:
- each test takes all possible endpoint pairs and pings
- each pair-ping flushes arp table
- ip6 is used
c) Testbed Topology:
1ap1sta:
[ap] ---- [sta]
endpoints: ap, sta
1ap1sta2br:
[veth0] [ap] ---- [sta] [veth2]
| | | |
[veth1] | \ [veth3]
\ / \ /
[br0] [br1]
endpoints: veth0, veth2, br0, br1
note: STA works in 4addr mode, AP has wds_sta=1
1ap1sta2br1vlan:
[veth0] [ap] ---- [sta] [veth2]
| | | |
[veth1] | \ [veth3]
\ / \ /
[br0] [br1]
| |
[vlan0_id2] [vlan1_id2]
endpoints: vlan0_id2, vlan1_id2
note: STA works in 4addr mode, AP has wds_sta=1
Credits:
Thanks to Michal Kazior <michal.kazior@tieto.com> who helped find the
amsdu issue, contributed a workaround (already squashed into this
patch), and contributed the throughput and connectivity tests results.
Signed-off-by: David Liu <cfliu.tw@gmail.com>
Signed-off-by: Michal Kazior <michal.kazior@tieto.com>
Tested-by: Michal Kazior <michal.kazior@tieto.com>
Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
2015-07-24 17:25:32 +00:00
|
|
|
ath10k_err(ar, "cryptmode > 0 requires raw mode support from firmware");
|
|
|
|
return -EINVAL;
|
|
|
|
}
|
|
|
|
|
|
|
|
set_bit(ATH10K_FLAG_RAW_MODE, &ar->dev_flags);
|
|
|
|
set_bit(ATH10K_FLAG_HW_CRYPTO_DISABLED, &ar->dev_flags);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
ath10k_info(ar, "invalid cryptmode: %d\n",
|
|
|
|
ath10k_cryptmode_param);
|
|
|
|
return -EINVAL;
|
|
|
|
}
|
|
|
|
|
|
|
|
ar->htt.max_num_amsdu = ATH10K_HTT_MAX_NUM_AMSDU_DEFAULT;
|
|
|
|
ar->htt.max_num_ampdu = ATH10K_HTT_MAX_NUM_AMPDU_DEFAULT;
|
|
|
|
|
2015-09-09 16:47:36 +00:00
|
|
|
if (rawmode) {
|
|
|
|
if (!test_bit(ATH10K_FW_FEATURE_RAW_MODE_SUPPORT,
|
2016-04-20 16:45:18 +00:00
|
|
|
fw_file->fw_features)) {
|
2015-09-09 16:47:36 +00:00
|
|
|
ath10k_err(ar, "rawmode = 1 requires support from firmware");
|
|
|
|
return -EINVAL;
|
|
|
|
}
|
|
|
|
set_bit(ATH10K_FLAG_RAW_MODE, &ar->dev_flags);
|
|
|
|
}
|
|
|
|
|
ath10k: enable raw encap mode and software crypto engine
This patch enables raw Rx/Tx encap mode to support software based
crypto engine. This patch introduces a new module param 'cryptmode'.
cryptmode:
0: Use hardware crypto engine globally with native Wi-Fi mode TX/RX
encapsulation to the firmware. This is the default mode.
1: Use sofware crypto engine globally with raw mode TX/RX
encapsulation to the firmware.
Known limitation:
A-MSDU must be disabled for RAW Tx encap mode to perform well when
heavy traffic is applied.
Testing: (by Michal Kazior <michal.kazior@tieto.com>)
a) Performance Testing
cryptmode=1
ap=qca988x sta=killer1525
killer1525 -> qca988x 194.496 mbps [tcp1 ip4]
killer1525 -> qca988x 238.309 mbps [tcp5 ip4]
killer1525 -> qca988x 266.958 mbps [udp1 ip4]
killer1525 -> qca988x 477.468 mbps [udp5 ip4]
qca988x -> killer1525 301.378 mbps [tcp1 ip4]
qca988x -> killer1525 297.949 mbps [tcp5 ip4]
qca988x -> killer1525 331.351 mbps [udp1 ip4]
qca988x -> killer1525 371.528 mbps [udp5 ip4]
ap=killer1525 sta=qca988x
qca988x -> killer1525 331.447 mbps [tcp1 ip4]
qca988x -> killer1525 328.783 mbps [tcp5 ip4]
qca988x -> killer1525 375.309 mbps [udp1 ip4]
qca988x -> killer1525 403.379 mbps [udp5 ip4]
killer1525 -> qca988x 203.689 mbps [tcp1 ip4]
killer1525 -> qca988x 222.339 mbps [tcp5 ip4]
killer1525 -> qca988x 264.199 mbps [udp1 ip4]
killer1525 -> qca988x 479.371 mbps [udp5 ip4]
Note:
- only open network tested for RAW vs nwifi performance comparison
- killer1525 (qca6174 hw2.2) is 2x2 device (hence max 866mbps)
- used iperf
- OTA, devices a few cm apart from each other, no shielding
- tcpX/udpX, X - means number of threads used
Overview:
- relative Tx performance drop is seen but is within reasonable and
expected threshold (A-MSDU must be disabled with RAW Tx)
b) Connectivity Testing
cryptmode=1
ap=iwl6205 sta1=qca988x crypto=open topology-1ap1sta OK
ap=iwl6205 sta1=qca988x crypto=wep1 topology-1ap1sta OK
ap=iwl6205 sta1=qca988x crypto=wpa topology-1ap1sta OK
ap=iwl6205 sta1=qca988x crypto=wpa-ccmp topology-1ap1sta OK
ap=qca988x sta1=iwl6205 crypto=open topology-1ap1sta OK
ap=qca988x sta1=iwl6205 crypto=wep1 topology-1ap1sta OK
ap=qca988x sta1=iwl6205 crypto=wpa topology-1ap1sta OK
ap=qca988x sta1=iwl6205 crypto=wpa-ccmp topology-1ap1sta OK
ap=iwl6205 sta1=qca988x crypto=open topology-1ap1sta2br OK
ap=iwl6205 sta1=qca988x crypto=wep1 topology-1ap1sta2br OK
ap=iwl6205 sta1=qca988x crypto=wpa topology-1ap1sta2br OK
ap=iwl6205 sta1=qca988x crypto=wpa-ccmp topology-1ap1sta2br OK
ap=qca988x sta1=iwl6205 crypto=open topology-1ap1sta2br OK
ap=qca988x sta1=iwl6205 crypto=wep1 topology-1ap1sta2br OK
ap=qca988x sta1=iwl6205 crypto=wpa topology-1ap1sta2br OK
ap=qca988x sta1=iwl6205 crypto=wpa-ccmp topology-1ap1sta2br OK
ap=iwl6205 sta1=qca988x crypto=open topology-1ap1sta2br1vlan OK
ap=iwl6205 sta1=qca988x crypto=wep1 topology-1ap1sta2br1vlan OK
ap=iwl6205 sta1=qca988x crypto=wpa topology-1ap1sta2br1vlan OK
ap=iwl6205 sta1=qca988x crypto=wpa-ccmp topology-1ap1sta2br1vlan OK
ap=qca988x sta1=iwl6205 crypto=open topology-1ap1sta2br1vlan OK
ap=qca988x sta1=iwl6205 crypto=wep1 topology-1ap1sta2br1vlan OK
ap=qca988x sta1=iwl6205 crypto=wpa topology-1ap1sta2br1vlan OK
ap=qca988x sta1=iwl6205 crypto=wpa-ccmp topology-1ap1sta2br1vlan OK
Note:
- each test takes all possible endpoint pairs and pings
- each pair-ping flushes arp table
- ip6 is used
c) Testbed Topology:
1ap1sta:
[ap] ---- [sta]
endpoints: ap, sta
1ap1sta2br:
[veth0] [ap] ---- [sta] [veth2]
| | | |
[veth1] | \ [veth3]
\ / \ /
[br0] [br1]
endpoints: veth0, veth2, br0, br1
note: STA works in 4addr mode, AP has wds_sta=1
1ap1sta2br1vlan:
[veth0] [ap] ---- [sta] [veth2]
| | | |
[veth1] | \ [veth3]
\ / \ /
[br0] [br1]
| |
[vlan0_id2] [vlan1_id2]
endpoints: vlan0_id2, vlan1_id2
note: STA works in 4addr mode, AP has wds_sta=1
Credits:
Thanks to Michal Kazior <michal.kazior@tieto.com> who helped find the
amsdu issue, contributed a workaround (already squashed into this
patch), and contributed the throughput and connectivity tests results.
Signed-off-by: David Liu <cfliu.tw@gmail.com>
Signed-off-by: Michal Kazior <michal.kazior@tieto.com>
Tested-by: Michal Kazior <michal.kazior@tieto.com>
Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
2015-07-24 17:25:32 +00:00
|
|
|
if (test_bit(ATH10K_FLAG_RAW_MODE, &ar->dev_flags)) {
|
|
|
|
ar->wmi.rx_decap_mode = ATH10K_HW_TXRX_RAW;
|
|
|
|
|
|
|
|
/* Workaround:
|
|
|
|
*
|
|
|
|
* Firmware A-MSDU aggregation breaks with RAW Tx encap mode
|
|
|
|
* and causes enormous performance issues (malformed frames,
|
|
|
|
* etc).
|
|
|
|
*
|
|
|
|
* Disabling A-MSDU makes RAW mode stable with heavy traffic
|
|
|
|
* albeit a bit slower compared to regular operation.
|
|
|
|
*/
|
|
|
|
ar->htt.max_num_amsdu = 1;
|
|
|
|
}
|
|
|
|
|
2014-12-03 08:10:08 +00:00
|
|
|
/* Backwards compatibility for firmwares without
|
|
|
|
* ATH10K_FW_IE_WMI_OP_VERSION.
|
|
|
|
*/
|
2016-04-20 16:45:33 +00:00
|
|
|
if (fw_file->wmi_op_version == ATH10K_FW_WMI_OP_VERSION_UNSET) {
|
2016-04-20 16:45:18 +00:00
|
|
|
if (test_bit(ATH10K_FW_FEATURE_WMI_10X, fw_file->fw_features)) {
|
2014-12-17 10:21:12 +00:00
|
|
|
if (test_bit(ATH10K_FW_FEATURE_WMI_10_2,
|
2016-04-20 16:45:18 +00:00
|
|
|
fw_file->fw_features))
|
2016-04-20 16:45:33 +00:00
|
|
|
fw_file->wmi_op_version = ATH10K_FW_WMI_OP_VERSION_10_2;
|
2014-12-03 08:10:08 +00:00
|
|
|
else
|
2016-04-20 16:45:33 +00:00
|
|
|
fw_file->wmi_op_version = ATH10K_FW_WMI_OP_VERSION_10_1;
|
2014-12-03 08:10:08 +00:00
|
|
|
} else {
|
2016-04-20 16:45:33 +00:00
|
|
|
fw_file->wmi_op_version = ATH10K_FW_WMI_OP_VERSION_MAIN;
|
2014-12-03 08:10:08 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-04-20 16:45:33 +00:00
|
|
|
switch (fw_file->wmi_op_version) {
|
2014-12-03 08:10:08 +00:00
|
|
|
case ATH10K_FW_WMI_OP_VERSION_MAIN:
|
2014-11-25 14:16:05 +00:00
|
|
|
ar->max_num_peers = TARGET_NUM_PEERS;
|
|
|
|
ar->max_num_stations = TARGET_NUM_STATIONS;
|
2014-12-17 10:20:45 +00:00
|
|
|
ar->max_num_vdevs = TARGET_NUM_VDEVS;
|
2014-12-03 08:10:17 +00:00
|
|
|
ar->htt.max_num_pending_tx = TARGET_NUM_MSDU_DESC;
|
2015-04-01 19:53:21 +00:00
|
|
|
ar->fw_stats_req_mask = WMI_STAT_PDEV | WMI_STAT_VDEV |
|
|
|
|
WMI_STAT_PEER;
|
2015-06-22 14:52:26 +00:00
|
|
|
ar->max_spatial_stream = WMI_MAX_SPATIAL_STREAM;
|
2014-12-03 08:10:08 +00:00
|
|
|
break;
|
|
|
|
case ATH10K_FW_WMI_OP_VERSION_10_1:
|
|
|
|
case ATH10K_FW_WMI_OP_VERSION_10_2:
|
2014-12-17 10:21:12 +00:00
|
|
|
case ATH10K_FW_WMI_OP_VERSION_10_2_4:
|
2016-03-16 12:43:32 +00:00
|
|
|
if (ath10k_peer_stats_enabled(ar)) {
|
2016-02-23 06:49:57 +00:00
|
|
|
ar->max_num_peers = TARGET_10X_TX_STATS_NUM_PEERS;
|
|
|
|
ar->max_num_stations = TARGET_10X_TX_STATS_NUM_STATIONS;
|
|
|
|
} else {
|
|
|
|
ar->max_num_peers = TARGET_10X_NUM_PEERS;
|
|
|
|
ar->max_num_stations = TARGET_10X_NUM_STATIONS;
|
|
|
|
}
|
2014-12-17 10:20:45 +00:00
|
|
|
ar->max_num_vdevs = TARGET_10X_NUM_VDEVS;
|
2014-12-03 08:10:17 +00:00
|
|
|
ar->htt.max_num_pending_tx = TARGET_10X_NUM_MSDU_DESC;
|
2015-04-01 19:53:21 +00:00
|
|
|
ar->fw_stats_req_mask = WMI_STAT_PEER;
|
2015-06-22 14:52:26 +00:00
|
|
|
ar->max_spatial_stream = WMI_MAX_SPATIAL_STREAM;
|
2014-12-03 08:10:08 +00:00
|
|
|
break;
|
2014-12-03 08:11:32 +00:00
|
|
|
case ATH10K_FW_WMI_OP_VERSION_TLV:
|
|
|
|
ar->max_num_peers = TARGET_TLV_NUM_PEERS;
|
|
|
|
ar->max_num_stations = TARGET_TLV_NUM_STATIONS;
|
2015-01-08 10:36:56 +00:00
|
|
|
ar->max_num_vdevs = TARGET_TLV_NUM_VDEVS;
|
2015-03-30 06:51:52 +00:00
|
|
|
ar->max_num_tdls_vdevs = TARGET_TLV_NUM_TDLS_VDEVS;
|
2014-12-03 08:11:32 +00:00
|
|
|
ar->htt.max_num_pending_tx = TARGET_TLV_NUM_MSDU_DESC;
|
2015-03-23 15:32:54 +00:00
|
|
|
ar->wow.max_num_patterns = TARGET_TLV_NUM_WOW_PATTERNS;
|
2015-04-01 19:53:21 +00:00
|
|
|
ar->fw_stats_req_mask = WMI_STAT_PDEV | WMI_STAT_VDEV |
|
|
|
|
WMI_STAT_PEER;
|
2015-06-22 14:52:26 +00:00
|
|
|
ar->max_spatial_stream = WMI_MAX_SPATIAL_STREAM;
|
2014-12-03 08:11:32 +00:00
|
|
|
break;
|
2015-06-22 14:40:09 +00:00
|
|
|
case ATH10K_FW_WMI_OP_VERSION_10_4:
|
2015-06-22 14:40:15 +00:00
|
|
|
ar->max_num_peers = TARGET_10_4_NUM_PEERS;
|
|
|
|
ar->max_num_stations = TARGET_10_4_NUM_STATIONS;
|
|
|
|
ar->num_active_peers = TARGET_10_4_ACTIVE_PEERS;
|
|
|
|
ar->max_num_vdevs = TARGET_10_4_NUM_VDEVS;
|
|
|
|
ar->num_tids = TARGET_10_4_TGT_NUM_TIDS;
|
2016-03-16 12:43:34 +00:00
|
|
|
ar->fw_stats_req_mask = WMI_10_4_STAT_PEER |
|
2018-03-28 09:40:24 +00:00
|
|
|
WMI_10_4_STAT_PEER_EXTD |
|
|
|
|
WMI_10_4_STAT_VDEV_EXTD;
|
2016-01-29 11:05:12 +00:00
|
|
|
ar->max_spatial_stream = ar->hw_params.max_spatial_stream;
|
2017-07-28 12:15:42 +00:00
|
|
|
ar->max_num_tdls_vdevs = TARGET_10_4_NUM_TDLS_VDEVS;
|
2016-03-01 12:16:11 +00:00
|
|
|
|
|
|
|
if (test_bit(ATH10K_FW_FEATURE_PEER_FLOW_CONTROL,
|
2016-04-20 16:45:18 +00:00
|
|
|
fw_file->fw_features))
|
2016-03-01 12:16:11 +00:00
|
|
|
ar->htt.max_num_pending_tx = TARGET_10_4_NUM_MSDU_DESC_PFC;
|
|
|
|
else
|
|
|
|
ar->htt.max_num_pending_tx = TARGET_10_4_NUM_MSDU_DESC;
|
2015-06-22 14:40:15 +00:00
|
|
|
break;
|
2014-12-03 08:10:08 +00:00
|
|
|
case ATH10K_FW_WMI_OP_VERSION_UNSET:
|
|
|
|
case ATH10K_FW_WMI_OP_VERSION_MAX:
|
|
|
|
WARN_ON(1);
|
|
|
|
return -EINVAL;
|
2014-11-25 14:16:05 +00:00
|
|
|
}
|
2014-12-03 08:09:59 +00:00
|
|
|
|
2015-03-30 11:14:28 +00:00
|
|
|
/* Backwards compatibility for firmwares without
|
|
|
|
* ATH10K_FW_IE_HTT_OP_VERSION.
|
|
|
|
*/
|
2016-04-20 16:45:47 +00:00
|
|
|
if (fw_file->htt_op_version == ATH10K_FW_HTT_OP_VERSION_UNSET) {
|
2016-04-20 16:45:33 +00:00
|
|
|
switch (fw_file->wmi_op_version) {
|
2015-03-30 11:14:28 +00:00
|
|
|
case ATH10K_FW_WMI_OP_VERSION_MAIN:
|
2016-04-20 16:45:47 +00:00
|
|
|
fw_file->htt_op_version = ATH10K_FW_HTT_OP_VERSION_MAIN;
|
2015-03-30 11:14:28 +00:00
|
|
|
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:
|
2016-04-20 16:45:47 +00:00
|
|
|
fw_file->htt_op_version = ATH10K_FW_HTT_OP_VERSION_10_1;
|
2015-03-30 11:14:28 +00:00
|
|
|
break;
|
|
|
|
case ATH10K_FW_WMI_OP_VERSION_TLV:
|
2016-04-20 16:45:47 +00:00
|
|
|
fw_file->htt_op_version = ATH10K_FW_HTT_OP_VERSION_TLV;
|
2015-03-30 11:14:28 +00:00
|
|
|
break;
|
2015-06-22 14:40:09 +00:00
|
|
|
case ATH10K_FW_WMI_OP_VERSION_10_4:
|
2015-03-30 11:14:28 +00:00
|
|
|
case ATH10K_FW_WMI_OP_VERSION_UNSET:
|
|
|
|
case ATH10K_FW_WMI_OP_VERSION_MAX:
|
2016-06-30 12:24:01 +00:00
|
|
|
ath10k_err(ar, "htt op version not found from fw meta data");
|
2015-03-30 11:14:28 +00:00
|
|
|
return -EINVAL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-12-03 08:09:59 +00:00
|
|
|
return 0;
|
2014-11-25 14:16:05 +00:00
|
|
|
}
|
|
|
|
|
2016-08-19 10:37:43 +00:00
|
|
|
static int ath10k_core_reset_rx_filter(struct ath10k *ar)
|
|
|
|
{
|
|
|
|
int ret;
|
|
|
|
int vdev_id;
|
|
|
|
int vdev_type;
|
|
|
|
int vdev_subtype;
|
|
|
|
const u8 *vdev_addr;
|
|
|
|
|
|
|
|
vdev_id = 0;
|
|
|
|
vdev_type = WMI_VDEV_TYPE_STA;
|
|
|
|
vdev_subtype = ath10k_wmi_get_vdev_subtype(ar, WMI_VDEV_SUBTYPE_NONE);
|
|
|
|
vdev_addr = ar->mac_addr;
|
|
|
|
|
|
|
|
ret = ath10k_wmi_vdev_create(ar, vdev_id, vdev_type, vdev_subtype,
|
|
|
|
vdev_addr);
|
|
|
|
if (ret) {
|
|
|
|
ath10k_err(ar, "failed to create dummy vdev: %d\n", ret);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
ret = ath10k_wmi_vdev_delete(ar, vdev_id);
|
|
|
|
if (ret) {
|
|
|
|
ath10k_err(ar, "failed to delete dummy vdev: %d\n", ret);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* WMI and HTT may use separate HIF pipes and are not guaranteed to be
|
|
|
|
* serialized properly implicitly.
|
|
|
|
*
|
|
|
|
* Moreover (most) WMI commands have no explicit acknowledges. It is
|
|
|
|
* possible to infer it implicitly by poking firmware with echo
|
|
|
|
* command - getting a reply means all preceding comments have been
|
|
|
|
* (mostly) processed.
|
|
|
|
*
|
|
|
|
* In case of vdev create/delete this is sufficient.
|
|
|
|
*
|
|
|
|
* Without this it's possible to end up with a race when HTT Rx ring is
|
|
|
|
* started before vdev create/delete hack is complete allowing a short
|
|
|
|
* window of opportunity to receive (and Tx ACK) a bunch of frames.
|
|
|
|
*/
|
|
|
|
ret = ath10k_wmi_barrier(ar);
|
|
|
|
if (ret) {
|
|
|
|
ath10k_err(ar, "failed to ping firmware: %d\n", ret);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2016-04-20 16:44:51 +00:00
|
|
|
int ath10k_core_start(struct ath10k *ar, enum ath10k_firmware_mode mode,
|
|
|
|
const struct ath10k_fw_components *fw)
|
2013-06-12 17:52:10 +00:00
|
|
|
{
|
|
|
|
int status;
|
2016-03-16 12:43:34 +00:00
|
|
|
u32 val;
|
2013-06-12 17:52:10 +00:00
|
|
|
|
2013-10-08 18:45:25 +00:00
|
|
|
lockdep_assert_held(&ar->conf_mutex);
|
|
|
|
|
2014-10-28 09:34:38 +00:00
|
|
|
clear_bit(ATH10K_FLAG_CRASH_FLUSH, &ar->dev_flags);
|
|
|
|
|
2016-04-20 16:44:51 +00:00
|
|
|
ar->running_fw = fw;
|
|
|
|
|
2017-12-21 16:16:49 +00:00
|
|
|
if (!test_bit(ATH10K_FW_FEATURE_NON_BMI,
|
|
|
|
ar->running_fw->fw_file.fw_features)) {
|
|
|
|
ath10k_bmi_start(ar);
|
2013-07-16 07:38:53 +00:00
|
|
|
|
2017-12-21 16:16:49 +00:00
|
|
|
if (ath10k_init_configure_target(ar)) {
|
|
|
|
status = -EINVAL;
|
|
|
|
goto err;
|
|
|
|
}
|
2014-10-13 06:40:53 +00:00
|
|
|
|
2017-12-21 16:16:49 +00:00
|
|
|
status = ath10k_download_cal_data(ar);
|
|
|
|
if (status)
|
2015-05-29 14:51:53 +00:00
|
|
|
goto err;
|
2017-12-21 16:16:49 +00:00
|
|
|
|
|
|
|
/* Some of of qca988x solutions are having global reset issue
|
|
|
|
* during target initialization. Bypassing PLL setting before
|
|
|
|
* downloading firmware and letting the SoC run on REF_CLK is
|
|
|
|
* fixing the problem. Corresponding firmware change is also
|
|
|
|
* needed to set the clock source once the target is
|
|
|
|
* initialized.
|
|
|
|
*/
|
|
|
|
if (test_bit(ATH10K_FW_FEATURE_SUPPORTS_SKIP_CLOCK_INIT,
|
|
|
|
ar->running_fw->fw_file.fw_features)) {
|
|
|
|
status = ath10k_bmi_write32(ar, hi_skip_clock_init, 1);
|
|
|
|
if (status) {
|
|
|
|
ath10k_err(ar, "could not write to skip_clock_init: %d\n",
|
|
|
|
status);
|
|
|
|
goto err;
|
|
|
|
}
|
2015-05-29 14:51:53 +00:00
|
|
|
}
|
|
|
|
|
2017-12-21 16:16:49 +00:00
|
|
|
status = ath10k_download_fw(ar);
|
|
|
|
if (status)
|
|
|
|
goto err;
|
2013-06-12 17:52:10 +00:00
|
|
|
|
2017-12-21 16:16:49 +00:00
|
|
|
status = ath10k_init_uart(ar);
|
|
|
|
if (status)
|
|
|
|
goto err;
|
2013-06-12 17:52:10 +00:00
|
|
|
|
2017-12-21 16:16:49 +00:00
|
|
|
if (ar->hif.bus == ATH10K_BUS_SDIO)
|
|
|
|
ath10k_init_sdio(ar);
|
|
|
|
}
|
2017-04-26 09:17:56 +00:00
|
|
|
|
2013-07-05 13:15:13 +00:00
|
|
|
ar->htc.htc_ops.target_send_suspend_complete =
|
|
|
|
ath10k_send_suspend_complete;
|
2013-06-12 17:52:10 +00:00
|
|
|
|
2013-07-05 13:15:13 +00:00
|
|
|
status = ath10k_htc_init(ar);
|
|
|
|
if (status) {
|
2014-08-25 10:09:38 +00:00
|
|
|
ath10k_err(ar, "could not init HTC (%d)\n", status);
|
2013-06-12 17:52:10 +00:00
|
|
|
goto err;
|
|
|
|
}
|
|
|
|
|
2017-12-21 16:16:49 +00:00
|
|
|
if (!test_bit(ATH10K_FW_FEATURE_NON_BMI,
|
|
|
|
ar->running_fw->fw_file.fw_features)) {
|
|
|
|
status = ath10k_bmi_done(ar);
|
|
|
|
if (status)
|
|
|
|
goto err;
|
|
|
|
}
|
2013-06-12 17:52:10 +00:00
|
|
|
|
|
|
|
status = ath10k_wmi_attach(ar);
|
|
|
|
if (status) {
|
2014-08-25 10:09:38 +00:00
|
|
|
ath10k_err(ar, "WMI attach failed: %d\n", status);
|
2013-07-05 13:15:13 +00:00
|
|
|
goto err;
|
2013-06-12 17:52:10 +00:00
|
|
|
}
|
|
|
|
|
2014-05-16 14:15:39 +00:00
|
|
|
status = ath10k_htt_init(ar);
|
|
|
|
if (status) {
|
2014-08-25 10:09:38 +00:00
|
|
|
ath10k_err(ar, "failed to init htt: %d\n", status);
|
2014-05-16 14:15:39 +00:00
|
|
|
goto err_wmi_detach;
|
|
|
|
}
|
|
|
|
|
2016-11-30 09:50:14 +00:00
|
|
|
status = ath10k_htt_tx_start(&ar->htt);
|
2014-05-16 14:15:39 +00:00
|
|
|
if (status) {
|
2014-08-25 10:09:38 +00:00
|
|
|
ath10k_err(ar, "failed to alloc htt tx: %d\n", status);
|
2014-05-16 14:15:39 +00:00
|
|
|
goto err_wmi_detach;
|
|
|
|
}
|
|
|
|
|
2017-08-02 10:33:37 +00:00
|
|
|
/* 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));
|
|
|
|
|
2014-05-16 14:15:39 +00:00
|
|
|
status = ath10k_htt_rx_alloc(&ar->htt);
|
|
|
|
if (status) {
|
2014-08-25 10:09:38 +00:00
|
|
|
ath10k_err(ar, "failed to alloc htt rx: %d\n", status);
|
2014-05-16 14:15:39 +00:00
|
|
|
goto err_htt_tx_detach;
|
|
|
|
}
|
|
|
|
|
2013-11-08 07:05:18 +00:00
|
|
|
status = ath10k_hif_start(ar);
|
|
|
|
if (status) {
|
2014-08-25 10:09:38 +00:00
|
|
|
ath10k_err(ar, "could not start HIF: %d\n", status);
|
2014-05-16 14:15:39 +00:00
|
|
|
goto err_htt_rx_detach;
|
2013-11-08 07:05:18 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
status = ath10k_htc_wait_target(&ar->htc);
|
|
|
|
if (status) {
|
2014-08-25 10:09:38 +00:00
|
|
|
ath10k_err(ar, "failed to connect to HTC: %d\n", status);
|
2013-11-08 07:05:18 +00:00
|
|
|
goto err_hif_stop;
|
|
|
|
}
|
2013-06-12 17:52:10 +00:00
|
|
|
|
2014-09-10 15:23:30 +00:00
|
|
|
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;
|
|
|
|
}
|
2013-06-12 17:52:10 +00:00
|
|
|
}
|
|
|
|
|
2014-05-16 14:15:39 +00:00
|
|
|
status = ath10k_wmi_connect(ar);
|
|
|
|
if (status) {
|
2014-08-25 10:09:38 +00:00
|
|
|
ath10k_err(ar, "could not connect wmi: %d\n", status);
|
2014-05-16 14:15:39 +00:00
|
|
|
goto err_hif_stop;
|
|
|
|
}
|
|
|
|
|
|
|
|
status = ath10k_htc_start(&ar->htc);
|
|
|
|
if (status) {
|
2014-08-25 10:09:38 +00:00
|
|
|
ath10k_err(ar, "failed to start htc: %d\n", status);
|
2014-05-16 14:15:39 +00:00
|
|
|
goto err_hif_stop;
|
|
|
|
}
|
|
|
|
|
2014-09-10 15:23:30 +00:00
|
|
|
if (mode == ATH10K_FIRMWARE_MODE_NORMAL) {
|
|
|
|
status = ath10k_wmi_wait_for_service_ready(ar);
|
2015-03-30 12:39:21 +00:00
|
|
|
if (status) {
|
2014-09-10 15:23:30 +00:00
|
|
|
ath10k_warn(ar, "wmi service ready event not received");
|
|
|
|
goto err_hif_stop;
|
|
|
|
}
|
2014-05-16 14:15:39 +00:00
|
|
|
}
|
2013-06-12 17:52:10 +00:00
|
|
|
|
2014-08-25 10:09:38 +00:00
|
|
|
ath10k_dbg(ar, ATH10K_DBG_BOOT, "firmware %s booted\n",
|
2013-11-20 08:00:41 +00:00
|
|
|
ar->hw->wiphy->fw_version);
|
2013-06-12 17:52:10 +00:00
|
|
|
|
2017-02-02 06:32:18 +00:00
|
|
|
if (test_bit(WMI_SERVICE_EXT_RES_CFG_SUPPORT, ar->wmi.svc_map) &&
|
|
|
|
mode == ATH10K_FIRMWARE_MODE_NORMAL) {
|
2016-03-16 12:43:34 +00:00
|
|
|
val = 0;
|
|
|
|
if (ath10k_peer_stats_enabled(ar))
|
|
|
|
val = WMI_10_4_PEER_STATS;
|
|
|
|
|
2018-03-28 09:40:24 +00:00
|
|
|
/* Enable vdev stats by default */
|
|
|
|
val |= WMI_10_4_VDEV_STATS;
|
|
|
|
|
2016-04-27 10:53:22 +00:00
|
|
|
if (test_bit(WMI_SERVICE_BSS_CHANNEL_INFO_64, ar->wmi.svc_map))
|
|
|
|
val |= WMI_10_4_BSS_CHANNEL_INFO_64;
|
|
|
|
|
2016-05-27 14:45:59 +00:00
|
|
|
/* 10.4 firmware supports BT-Coex without reloading firmware
|
|
|
|
* via pdev param. To support Bluetooth coexistence pdev param,
|
|
|
|
* WMI_COEX_GPIO_SUPPORT of extended resource config should be
|
|
|
|
* enabled always.
|
|
|
|
*/
|
|
|
|
if (test_bit(WMI_SERVICE_COEX_GPIO, ar->wmi.svc_map) &&
|
|
|
|
test_bit(ATH10K_FW_FEATURE_BTCOEX_PARAM,
|
|
|
|
ar->running_fw->fw_file.fw_features))
|
|
|
|
val |= WMI_10_4_COEX_GPIO_SUPPORT;
|
|
|
|
|
2017-07-28 12:15:42 +00:00
|
|
|
if (test_bit(WMI_SERVICE_TDLS_EXPLICIT_MODE_ONLY,
|
|
|
|
ar->wmi.svc_map))
|
|
|
|
val |= WMI_10_4_TDLS_EXPLICIT_MODE_ONLY;
|
|
|
|
|
|
|
|
if (test_bit(WMI_SERVICE_TDLS_UAPSD_BUFFER_STA,
|
|
|
|
ar->wmi.svc_map))
|
|
|
|
val |= WMI_10_4_TDLS_UAPSD_BUFFER_STA;
|
|
|
|
|
2016-04-12 14:45:53 +00:00
|
|
|
status = ath10k_mac_ext_resource_config(ar, val);
|
2016-03-16 12:43:34 +00:00
|
|
|
if (status) {
|
|
|
|
ath10k_err(ar,
|
|
|
|
"failed to send ext resource cfg command : %d\n",
|
|
|
|
status);
|
|
|
|
goto err_hif_stop;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-06-12 17:52:10 +00:00
|
|
|
status = ath10k_wmi_cmd_init(ar);
|
|
|
|
if (status) {
|
2014-08-25 10:09:38 +00:00
|
|
|
ath10k_err(ar, "could not send WMI init command (%d)\n",
|
|
|
|
status);
|
2014-08-07 09:03:31 +00:00
|
|
|
goto err_hif_stop;
|
2013-06-12 17:52:10 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
status = ath10k_wmi_wait_for_unified_ready(ar);
|
2015-03-30 12:39:21 +00:00
|
|
|
if (status) {
|
2014-08-25 10:09:38 +00:00
|
|
|
ath10k_err(ar, "wmi unified ready event not received\n");
|
2014-08-07 09:03:31 +00:00
|
|
|
goto err_hif_stop;
|
2013-06-12 17:52:10 +00:00
|
|
|
}
|
|
|
|
|
2016-08-19 10:37:43 +00:00
|
|
|
/* Some firmware revisions do not properly set up hardware rx filter
|
|
|
|
* registers.
|
|
|
|
*
|
|
|
|
* A known example from QCA9880 and 10.2.4 is that MAC_PCU_ADDR1_MASK
|
|
|
|
* is filled with 0s instead of 1s allowing HW to respond with ACKs to
|
|
|
|
* any frames that matches MAC_PCU_RX_FILTER which is also
|
|
|
|
* misconfigured to accept anything.
|
|
|
|
*
|
|
|
|
* The ADDR1 is programmed using internal firmware structure field and
|
|
|
|
* can't be (easily/sanely) reached from the driver explicitly. It is
|
|
|
|
* possible to implicitly make it correct by creating a dummy vdev and
|
|
|
|
* then deleting it.
|
|
|
|
*/
|
2017-02-02 06:32:18 +00:00
|
|
|
if (mode == ATH10K_FIRMWARE_MODE_NORMAL) {
|
|
|
|
status = ath10k_core_reset_rx_filter(ar);
|
|
|
|
if (status) {
|
|
|
|
ath10k_err(ar,
|
|
|
|
"failed to reset rx filter: %d\n", status);
|
|
|
|
goto err_hif_stop;
|
|
|
|
}
|
2016-08-19 10:37:43 +00:00
|
|
|
}
|
|
|
|
|
2015-01-24 10:14:48 +00:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2016-09-26 18:56:26 +00:00
|
|
|
if (ar->max_num_vdevs >= 64)
|
|
|
|
ar->free_vdev_map = 0xFFFFFFFFFFFFFFFFLL;
|
|
|
|
else
|
|
|
|
ar->free_vdev_map = (1LL << ar->max_num_vdevs) - 1;
|
2016-04-26 16:05:48 +00:00
|
|
|
|
|
|
|
INIT_LIST_HEAD(&ar->arvifs);
|
|
|
|
|
2014-09-10 15:23:30 +00:00
|
|
|
/* 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;
|
|
|
|
}
|
2014-05-16 14:15:39 +00:00
|
|
|
}
|
2013-06-12 17:52:10 +00:00
|
|
|
|
2013-09-03 08:44:03 +00:00
|
|
|
status = ath10k_debug_start(ar);
|
|
|
|
if (status)
|
2014-08-07 09:03:31 +00:00
|
|
|
goto err_hif_stop;
|
2013-09-03 08:44:03 +00:00
|
|
|
|
2013-07-16 07:38:51 +00:00
|
|
|
return 0;
|
|
|
|
|
2013-11-08 07:05:18 +00:00
|
|
|
err_hif_stop:
|
|
|
|
ath10k_hif_stop(ar);
|
2014-05-16 14:15:39 +00:00
|
|
|
err_htt_rx_detach:
|
|
|
|
ath10k_htt_rx_free(&ar->htt);
|
|
|
|
err_htt_tx_detach:
|
|
|
|
ath10k_htt_tx_free(&ar->htt);
|
2013-07-16 07:38:51 +00:00
|
|
|
err_wmi_detach:
|
|
|
|
ath10k_wmi_detach(ar);
|
|
|
|
err:
|
|
|
|
return status;
|
|
|
|
}
|
2013-07-16 07:38:57 +00:00
|
|
|
EXPORT_SYMBOL(ath10k_core_start);
|
2013-07-16 07:38:51 +00:00
|
|
|
|
2014-02-10 16:14:24 +00:00
|
|
|
int ath10k_wait_for_suspend(struct ath10k *ar, u32 suspend_opt)
|
|
|
|
{
|
|
|
|
int ret;
|
2015-03-30 12:39:21 +00:00
|
|
|
unsigned long time_left;
|
2014-02-10 16:14:24 +00:00
|
|
|
|
|
|
|
reinit_completion(&ar->target_suspend);
|
|
|
|
|
|
|
|
ret = ath10k_wmi_pdev_suspend_target(ar, suspend_opt);
|
|
|
|
if (ret) {
|
2014-08-25 10:09:38 +00:00
|
|
|
ath10k_warn(ar, "could not suspend target (%d)\n", ret);
|
2014-02-10 16:14:24 +00:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2015-03-30 12:39:21 +00:00
|
|
|
time_left = wait_for_completion_timeout(&ar->target_suspend, 1 * HZ);
|
2014-02-10 16:14:24 +00:00
|
|
|
|
2015-03-30 12:39:21 +00:00
|
|
|
if (!time_left) {
|
2014-08-25 10:09:38 +00:00
|
|
|
ath10k_warn(ar, "suspend timed out - target pause event never came\n");
|
2014-02-10 16:14:24 +00:00
|
|
|
return -ETIMEDOUT;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2013-07-16 07:38:51 +00:00
|
|
|
void ath10k_core_stop(struct ath10k *ar)
|
|
|
|
{
|
2013-10-08 18:45:25 +00:00
|
|
|
lockdep_assert_held(&ar->conf_mutex);
|
2015-07-09 08:49:42 +00:00
|
|
|
ath10k_debug_stop(ar);
|
2013-10-08 18:45:25 +00:00
|
|
|
|
2014-02-10 16:14:24 +00:00
|
|
|
/* try to suspend target */
|
2014-09-10 15:23:30 +00:00
|
|
|
if (ar->state != ATH10K_STATE_RESTARTING &&
|
|
|
|
ar->state != ATH10K_STATE_UTF)
|
2014-04-23 16:30:04 +00:00
|
|
|
ath10k_wait_for_suspend(ar, WMI_PDEV_SUSPEND_AND_DISABLE_INTR);
|
|
|
|
|
2014-05-16 14:15:39 +00:00
|
|
|
ath10k_hif_stop(ar);
|
2016-11-30 09:50:14 +00:00
|
|
|
ath10k_htt_tx_stop(&ar->htt);
|
2014-05-16 14:15:39 +00:00
|
|
|
ath10k_htt_rx_free(&ar->htt);
|
2013-07-16 07:38:51 +00:00
|
|
|
ath10k_wmi_detach(ar);
|
|
|
|
}
|
2013-07-16 07:38:57 +00:00
|
|
|
EXPORT_SYMBOL(ath10k_core_stop);
|
|
|
|
|
|
|
|
/* mac80211 manages fw/hw initialization through start/stop hooks. However in
|
|
|
|
* order to know what hw capabilities should be advertised to mac80211 it is
|
|
|
|
* necessary to load the firmware (and tear it down immediately since start
|
2017-02-20 13:39:57 +00:00
|
|
|
* hook will try to init it again) before registering
|
|
|
|
*/
|
2013-07-16 07:38:57 +00:00
|
|
|
static int ath10k_core_probe_fw(struct ath10k *ar)
|
|
|
|
{
|
2013-07-16 07:38:58 +00:00
|
|
|
struct bmi_target_info target_info;
|
|
|
|
int ret = 0;
|
2013-07-16 07:38:57 +00:00
|
|
|
|
|
|
|
ret = ath10k_hif_power_up(ar);
|
|
|
|
if (ret) {
|
2018-02-05 04:11:34 +00:00
|
|
|
ath10k_err(ar, "could not power on hif bus (%d)\n", ret);
|
2013-07-16 07:38:57 +00:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2017-12-21 16:16:49 +00:00
|
|
|
switch (ar->hif.bus) {
|
|
|
|
case ATH10K_BUS_SDIO:
|
|
|
|
memset(&target_info, 0, sizeof(target_info));
|
2017-04-26 09:17:57 +00:00
|
|
|
ret = ath10k_bmi_get_target_info_sdio(ar, &target_info);
|
2017-12-21 16:16:49 +00:00
|
|
|
if (ret) {
|
|
|
|
ath10k_err(ar, "could not get target info (%d)\n", ret);
|
|
|
|
goto err_power_down;
|
|
|
|
}
|
|
|
|
ar->target_version = target_info.version;
|
|
|
|
ar->hw->wiphy->hw_version = target_info.version;
|
|
|
|
break;
|
|
|
|
case ATH10K_BUS_PCI:
|
|
|
|
case ATH10K_BUS_AHB:
|
2017-12-28 19:06:45 +00:00
|
|
|
case ATH10K_BUS_USB:
|
2017-12-21 16:16:49 +00:00
|
|
|
memset(&target_info, 0, sizeof(target_info));
|
2017-04-26 09:17:57 +00:00
|
|
|
ret = ath10k_bmi_get_target_info(ar, &target_info);
|
2017-12-21 16:16:49 +00:00
|
|
|
if (ret) {
|
|
|
|
ath10k_err(ar, "could not get target info (%d)\n", ret);
|
|
|
|
goto err_power_down;
|
|
|
|
}
|
|
|
|
ar->target_version = target_info.version;
|
|
|
|
ar->hw->wiphy->hw_version = target_info.version;
|
|
|
|
break;
|
|
|
|
case ATH10K_BUS_SNOC:
|
2018-04-10 15:01:29 +00:00
|
|
|
memset(&target_info, 0, sizeof(target_info));
|
|
|
|
ret = ath10k_hif_get_target_info(ar, &target_info);
|
|
|
|
if (ret) {
|
|
|
|
ath10k_err(ar, "could not get target info (%d)\n", ret);
|
|
|
|
goto err_power_down;
|
|
|
|
}
|
|
|
|
ar->target_version = target_info.version;
|
|
|
|
ar->hw->wiphy->hw_version = target_info.version;
|
2017-12-21 16:16:49 +00:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
ath10k_err(ar, "incorrect hif bus type: %d\n", ar->hif.bus);
|
2013-07-16 07:38:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
ret = ath10k_init_hw_params(ar);
|
|
|
|
if (ret) {
|
2014-08-25 10:09:38 +00:00
|
|
|
ath10k_err(ar, "could not get hw params (%d)\n", ret);
|
2014-12-03 08:09:31 +00:00
|
|
|
goto err_power_down;
|
2013-07-16 07:38:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
ret = ath10k_core_fetch_firmware_files(ar);
|
|
|
|
if (ret) {
|
2014-08-25 10:09:38 +00:00
|
|
|
ath10k_err(ar, "could not fetch firmware files (%d)\n", ret);
|
2014-12-03 08:09:31 +00:00
|
|
|
goto err_power_down;
|
2013-07-16 07:38:58 +00:00
|
|
|
}
|
|
|
|
|
2016-04-20 16:45:05 +00:00
|
|
|
BUILD_BUG_ON(sizeof(ar->hw->wiphy->fw_version) !=
|
|
|
|
sizeof(ar->normal_mode_fw.fw_file.fw_version));
|
|
|
|
memcpy(ar->hw->wiphy->fw_version, ar->normal_mode_fw.fw_file.fw_version,
|
|
|
|
sizeof(ar->hw->wiphy->fw_version));
|
|
|
|
|
2015-11-25 13:38:27 +00:00
|
|
|
ath10k_debug_print_hwfw_info(ar);
|
|
|
|
|
2017-12-21 16:16:49 +00:00
|
|
|
if (!test_bit(ATH10K_FW_FEATURE_NON_BMI,
|
|
|
|
ar->normal_mode_fw.fw_file.fw_features)) {
|
|
|
|
ret = ath10k_core_pre_cal_download(ar);
|
|
|
|
if (ret) {
|
|
|
|
/* pre calibration data download is not necessary
|
|
|
|
* for all the chipsets. Ignore failures and continue.
|
|
|
|
*/
|
|
|
|
ath10k_dbg(ar, ATH10K_DBG_BOOT,
|
|
|
|
"could not load pre cal data: %d\n", ret);
|
|
|
|
}
|
2016-03-18 09:44:22 +00:00
|
|
|
|
2017-12-21 16:16:49 +00:00
|
|
|
ret = ath10k_core_get_board_id_from_otp(ar);
|
|
|
|
if (ret && ret != -EOPNOTSUPP) {
|
|
|
|
ath10k_err(ar, "failed to get board id from otp: %d\n",
|
|
|
|
ret);
|
|
|
|
goto err_free_firmware_files;
|
|
|
|
}
|
2015-10-09 08:55:59 +00:00
|
|
|
|
2017-12-21 16:16:49 +00:00
|
|
|
ret = ath10k_core_check_smbios(ar);
|
|
|
|
if (ret)
|
|
|
|
ath10k_dbg(ar, ATH10K_DBG_BOOT, "SMBIOS bdf variant name not set.\n");
|
ath10k: search DT for qcom,ath10k-calibration-variant
Board Data File (BDF) is loaded upon driver boot-up procedure. The right
board data file is identified on QCA4019 using bus, bmi-chip-id and
bmi-board-id.
The problem, however, can occur when the (default) board data file cannot
fulfill with the vendor requirements and it is necessary to use a different
board data file.
This problem was solved for SMBIOS by adding a special SMBIOS type 0xF8.
Something similar has to be provided for systems without SMBIOS but with
device trees. No solution was specified by QCA and therefore a new one has
to be found for ath10k.
The device tree requires addition strings to define the variant name
wifi@a000000 {
status = "okay";
qcom,ath10k-calibration-variant = "RT-AC58U";
};
wifi@a800000 {
status = "okay";
qcom,ath10k-calibration-variant = "RT-AC58U";
};
This would create the boarddata identifiers for the board-2.bin search
* bus=ahb,bmi-chip-id=0,bmi-board-id=16,variant=RT-AC58U
* bus=ahb,bmi-chip-id=0,bmi-board-id=17,variant=RT-AC58U
Signed-off-by: Sven Eckelmann <sven.eckelmann@openmesh.com>
Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
2017-12-08 10:37:42 +00:00
|
|
|
|
2017-12-21 16:16:49 +00:00
|
|
|
ret = ath10k_core_check_dt(ar);
|
|
|
|
if (ret)
|
|
|
|
ath10k_dbg(ar, ATH10K_DBG_BOOT, "DT bdf variant name not set.\n");
|
ath10k: search SMBIOS for OEM board file extension
Board Data File (BDF) is loaded upon driver boot-up procedure. The right
board data file is identified, among others, by device and sybsystem ids.
The problem, however, can occur when the (default) board data file cannot
fulfill with the vendor requirements and it is necessary to use a different
board data file.
To solve the issue QCA uses SMBIOS type 0xF8 to store Board Data File Name
Extension to specify the extension/variant name. The driver will take the
extension suffix into consideration and will load the right (non-default)
board data file if necessary.
If it is unnecessary to use extension board data file, please leave the
SMBIOS field blank and default configuration will be used.
Example:
If a default board data file for a specific board is identified by a string
"bus=pci,vendor=168c,device=003e,subsystem-vendor=1028,
subsystem-device=0310"
then the OEM specific data file, if used, could be identified by variant
suffix:
"bus=pci,vendor=168c,device=003e,subsystem-vendor=1028,
subsystem-device=0310,variant=DE_1AB"
If board data file name extension is set but board-2.bin does not contain
board data file for the variant, the driver will fallback to the default
board data file not to break backward compatibility.
This was first applied in commit f2593cb1b291 ("ath10k: Search SMBIOS for OEM
board file extension") but later reverted in commit 005c3490e9db ("Revert
"ath10k: Search SMBIOS for OEM board file extension"". This patch is now
otherwise the same as commit f2593cb1b291 except the regression fixed.
Signed-off-by: Waldemar Rymarkiewicz <ext.waldemar.rymarkiewicz@tieto.com>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
2017-02-24 22:30:03 +00:00
|
|
|
|
2017-12-21 16:16:49 +00:00
|
|
|
ret = ath10k_core_fetch_board_file(ar);
|
|
|
|
if (ret) {
|
|
|
|
ath10k_err(ar, "failed to fetch board file: %d\n", ret);
|
|
|
|
goto err_free_firmware_files;
|
|
|
|
}
|
2015-10-09 08:55:59 +00:00
|
|
|
|
2017-12-21 16:16:49 +00:00
|
|
|
ath10k_debug_print_board_info(ar);
|
|
|
|
}
|
2015-11-25 13:38:27 +00:00
|
|
|
|
2014-12-03 08:09:59 +00:00
|
|
|
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;
|
|
|
|
}
|
2014-11-25 14:16:05 +00:00
|
|
|
|
2017-12-21 16:16:49 +00:00
|
|
|
if (!test_bit(ATH10K_FW_FEATURE_NON_BMI,
|
|
|
|
ar->normal_mode_fw.fw_file.fw_features)) {
|
|
|
|
ret = ath10k_swap_code_seg_init(ar,
|
|
|
|
&ar->normal_mode_fw.fw_file);
|
|
|
|
if (ret) {
|
|
|
|
ath10k_err(ar, "failed to initialize code swap segment: %d\n",
|
|
|
|
ret);
|
|
|
|
goto err_free_firmware_files;
|
|
|
|
}
|
2015-06-18 07:01:09 +00:00
|
|
|
}
|
|
|
|
|
2013-10-08 18:45:25 +00:00
|
|
|
mutex_lock(&ar->conf_mutex);
|
|
|
|
|
2016-04-20 16:44:51 +00:00
|
|
|
ret = ath10k_core_start(ar, ATH10K_FIRMWARE_MODE_NORMAL,
|
|
|
|
&ar->normal_mode_fw);
|
2013-07-16 07:38:57 +00:00
|
|
|
if (ret) {
|
2014-08-25 10:09:38 +00:00
|
|
|
ath10k_err(ar, "could not init core (%d)\n", ret);
|
2014-12-03 08:09:31 +00:00
|
|
|
goto err_unlock;
|
2013-07-16 07:38:57 +00:00
|
|
|
}
|
|
|
|
|
2015-11-25 13:38:27 +00:00
|
|
|
ath10k_debug_print_boot_info(ar);
|
2013-07-16 07:38:57 +00:00
|
|
|
ath10k_core_stop(ar);
|
2013-10-08 18:45:25 +00:00
|
|
|
|
|
|
|
mutex_unlock(&ar->conf_mutex);
|
|
|
|
|
2013-07-16 07:38:57 +00:00
|
|
|
ath10k_hif_power_down(ar);
|
|
|
|
return 0;
|
2014-12-03 08:09:31 +00:00
|
|
|
|
|
|
|
err_unlock:
|
|
|
|
mutex_unlock(&ar->conf_mutex);
|
|
|
|
|
2014-12-03 08:09:59 +00:00
|
|
|
err_free_firmware_files:
|
2014-12-03 08:09:31 +00:00
|
|
|
ath10k_core_free_firmware_files(ar);
|
|
|
|
|
|
|
|
err_power_down:
|
|
|
|
ath10k_hif_power_down(ar);
|
|
|
|
|
|
|
|
return ret;
|
2013-07-16 07:38:57 +00:00
|
|
|
}
|
2013-07-16 07:38:51 +00:00
|
|
|
|
2014-05-23 10:28:47 +00:00
|
|
|
static void ath10k_core_register_work(struct work_struct *work)
|
2013-07-16 07:38:51 +00:00
|
|
|
{
|
2014-05-23 10:28:47 +00:00
|
|
|
struct ath10k *ar = container_of(work, struct ath10k, register_work);
|
2013-07-16 07:38:51 +00:00
|
|
|
int status;
|
|
|
|
|
2016-09-06 19:05:28 +00:00
|
|
|
/* peer stats are enabled by default */
|
|
|
|
set_bit(ATH10K_FLAG_PEER_STATS, &ar->dev_flags);
|
|
|
|
|
2013-07-16 07:38:57 +00:00
|
|
|
status = ath10k_core_probe_fw(ar);
|
|
|
|
if (status) {
|
2014-08-25 10:09:38 +00:00
|
|
|
ath10k_err(ar, "could not probe fw (%d)\n", status);
|
2014-05-23 10:28:47 +00:00
|
|
|
goto err;
|
2013-07-16 07:38:57 +00:00
|
|
|
}
|
2013-07-16 07:38:51 +00:00
|
|
|
|
2013-06-12 17:52:10 +00:00
|
|
|
status = ath10k_mac_register(ar);
|
2013-07-16 07:38:57 +00:00
|
|
|
if (status) {
|
2014-08-25 10:09:38 +00:00
|
|
|
ath10k_err(ar, "could not register to mac80211 (%d)\n", status);
|
2013-07-16 07:38:58 +00:00
|
|
|
goto err_release_fw;
|
2013-07-16 07:38:57 +00:00
|
|
|
}
|
2013-06-12 17:52:10 +00:00
|
|
|
|
2017-12-22 13:39:32 +00:00
|
|
|
status = ath10k_coredump_register(ar);
|
|
|
|
if (status) {
|
|
|
|
ath10k_err(ar, "unable to register coredump\n");
|
|
|
|
goto err_unregister_mac;
|
|
|
|
}
|
|
|
|
|
2014-09-04 07:13:08 +00:00
|
|
|
status = ath10k_debug_register(ar);
|
2013-06-12 17:52:10 +00:00
|
|
|
if (status) {
|
2014-08-25 10:09:38 +00:00
|
|
|
ath10k_err(ar, "unable to initialize debugfs\n");
|
2017-12-22 13:39:32 +00:00
|
|
|
goto err_unregister_coredump;
|
2013-06-12 17:52:10 +00:00
|
|
|
}
|
|
|
|
|
2014-08-02 06:12:54 +00:00
|
|
|
status = ath10k_spectral_create(ar);
|
|
|
|
if (status) {
|
2014-08-25 10:09:38 +00:00
|
|
|
ath10k_err(ar, "failed to initialize spectral\n");
|
2014-08-02 06:12:54 +00:00
|
|
|
goto err_debug_destroy;
|
|
|
|
}
|
|
|
|
|
2014-12-17 10:22:07 +00:00
|
|
|
status = ath10k_thermal_register(ar);
|
|
|
|
if (status) {
|
|
|
|
ath10k_err(ar, "could not register thermal device: %d\n",
|
|
|
|
status);
|
|
|
|
goto err_spectral_destroy;
|
|
|
|
}
|
|
|
|
|
2014-05-23 10:28:47 +00:00
|
|
|
set_bit(ATH10K_FLAG_CORE_REGISTERED, &ar->dev_flags);
|
|
|
|
return;
|
2013-06-12 17:52:10 +00:00
|
|
|
|
2014-12-17 10:22:07 +00:00
|
|
|
err_spectral_destroy:
|
|
|
|
ath10k_spectral_destroy(ar);
|
2014-08-02 06:12:54 +00:00
|
|
|
err_debug_destroy:
|
|
|
|
ath10k_debug_destroy(ar);
|
2017-12-22 13:39:32 +00:00
|
|
|
err_unregister_coredump:
|
|
|
|
ath10k_coredump_unregister(ar);
|
2013-06-12 17:52:10 +00:00
|
|
|
err_unregister_mac:
|
|
|
|
ath10k_mac_unregister(ar);
|
2013-07-16 07:38:58 +00:00
|
|
|
err_release_fw:
|
|
|
|
ath10k_core_free_firmware_files(ar);
|
2014-05-23 10:28:47 +00:00
|
|
|
err:
|
2014-07-14 13:07:29 +00:00
|
|
|
/* TODO: It's probably a good idea to release device from the driver
|
|
|
|
* but calling device_release_driver() here will cause a deadlock.
|
|
|
|
*/
|
2014-05-23 10:28:47 +00:00
|
|
|
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;
|
2013-06-12 17:52:10 +00:00
|
|
|
}
|
|
|
|
EXPORT_SYMBOL(ath10k_core_register);
|
|
|
|
|
|
|
|
void ath10k_core_unregister(struct ath10k *ar)
|
|
|
|
{
|
2014-05-23 10:28:47 +00:00
|
|
|
cancel_work_sync(&ar->register_work);
|
|
|
|
|
|
|
|
if (!test_bit(ATH10K_FLAG_CORE_REGISTERED, &ar->dev_flags))
|
|
|
|
return;
|
|
|
|
|
2014-12-17 10:22:07 +00:00
|
|
|
ath10k_thermal_unregister(ar);
|
2014-08-12 15:12:17 +00:00
|
|
|
/* 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);
|
|
|
|
|
2013-06-12 17:52:10 +00:00
|
|
|
/* We must unregister from mac80211 before we stop HTC and HIF.
|
|
|
|
* Otherwise we will fail to submit commands to FW and mac80211 will be
|
2017-02-20 13:39:57 +00:00
|
|
|
* unhappy about callback failures.
|
|
|
|
*/
|
2013-06-12 17:52:10 +00:00
|
|
|
ath10k_mac_unregister(ar);
|
2013-09-03 08:44:03 +00:00
|
|
|
|
2014-09-10 15:23:30 +00:00
|
|
|
ath10k_testmode_destroy(ar);
|
|
|
|
|
2013-07-16 07:38:58 +00:00
|
|
|
ath10k_core_free_firmware_files(ar);
|
2015-10-09 08:55:58 +00:00
|
|
|
ath10k_core_free_board_files(ar);
|
2013-11-04 17:18:16 +00:00
|
|
|
|
2014-09-04 07:13:08 +00:00
|
|
|
ath10k_debug_unregister(ar);
|
2013-06-12 17:52:10 +00:00
|
|
|
}
|
|
|
|
EXPORT_SYMBOL(ath10k_core_unregister);
|
|
|
|
|
2014-08-07 09:03:27 +00:00
|
|
|
struct ath10k *ath10k_core_create(size_t priv_size, struct device *dev,
|
2014-10-13 06:40:47 +00:00
|
|
|
enum ath10k_bus bus,
|
2015-01-24 10:14:49 +00:00
|
|
|
enum ath10k_hw_rev hw_rev,
|
2014-05-23 10:28:45 +00:00
|
|
|
const struct ath10k_hif_ops *hif_ops)
|
|
|
|
{
|
|
|
|
struct ath10k *ar;
|
2014-09-04 07:13:08 +00:00
|
|
|
int ret;
|
2014-05-23 10:28:45 +00:00
|
|
|
|
2014-08-07 09:03:27 +00:00
|
|
|
ar = ath10k_mac_create(priv_size);
|
2014-05-23 10:28:45 +00:00
|
|
|
if (!ar)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
ar->ath_common.priv = ar;
|
|
|
|
ar->ath_common.hw = ar->hw;
|
|
|
|
ar->dev = dev;
|
2015-01-24 10:14:49 +00:00
|
|
|
ar->hw_rev = hw_rev;
|
2014-05-23 10:28:45 +00:00
|
|
|
ar->hif.ops = hif_ops;
|
2014-10-13 06:40:47 +00:00
|
|
|
ar->hif.bus = bus;
|
2014-05-23 10:28:45 +00:00
|
|
|
|
2015-01-24 10:14:49 +00:00
|
|
|
switch (hw_rev) {
|
|
|
|
case ATH10K_HW_QCA988X:
|
2016-06-02 14:59:49 +00:00
|
|
|
case ATH10K_HW_QCA9887:
|
2015-01-24 10:14:49 +00:00
|
|
|
ar->regs = &qca988x_regs;
|
2017-06-06 09:05:41 +00:00
|
|
|
ar->hw_ce_regs = &qcax_ce_regs;
|
2015-06-18 07:01:01 +00:00
|
|
|
ar->hw_values = &qca988x_values;
|
2015-01-24 10:14:49 +00:00
|
|
|
break;
|
|
|
|
case ATH10K_HW_QCA6174:
|
2015-10-28 14:09:53 +00:00
|
|
|
case ATH10K_HW_QCA9377:
|
2015-01-24 10:14:49 +00:00
|
|
|
ar->regs = &qca6174_regs;
|
2017-06-06 09:05:41 +00:00
|
|
|
ar->hw_ce_regs = &qcax_ce_regs;
|
2015-06-18 07:01:01 +00:00
|
|
|
ar->hw_values = &qca6174_values;
|
2015-01-24 10:14:49 +00:00
|
|
|
break;
|
2015-06-18 07:01:03 +00:00
|
|
|
case ATH10K_HW_QCA99X0:
|
2016-05-23 20:12:45 +00:00
|
|
|
case ATH10K_HW_QCA9984:
|
2015-06-18 07:01:03 +00:00
|
|
|
ar->regs = &qca99x0_regs;
|
2017-06-06 09:05:41 +00:00
|
|
|
ar->hw_ce_regs = &qcax_ce_regs;
|
2015-06-18 07:01:03 +00:00
|
|
|
ar->hw_values = &qca99x0_values;
|
|
|
|
break;
|
2016-06-30 12:24:00 +00:00
|
|
|
case ATH10K_HW_QCA9888:
|
|
|
|
ar->regs = &qca99x0_regs;
|
2017-06-06 09:05:41 +00:00
|
|
|
ar->hw_ce_regs = &qcax_ce_regs;
|
2016-06-30 12:24:00 +00:00
|
|
|
ar->hw_values = &qca9888_values;
|
|
|
|
break;
|
2016-01-27 09:54:26 +00:00
|
|
|
case ATH10K_HW_QCA4019:
|
|
|
|
ar->regs = &qca4019_regs;
|
2017-06-06 09:05:41 +00:00
|
|
|
ar->hw_ce_regs = &qcax_ce_regs;
|
2016-01-27 09:54:26 +00:00
|
|
|
ar->hw_values = &qca4019_values;
|
|
|
|
break;
|
2017-06-28 04:48:36 +00:00
|
|
|
case ATH10K_HW_WCN3990:
|
|
|
|
ar->regs = &wcn3990_regs;
|
|
|
|
ar->hw_ce_regs = &wcn3990_ce_regs;
|
|
|
|
ar->hw_values = &wcn3990_values;
|
|
|
|
break;
|
2015-01-24 10:14:49 +00:00
|
|
|
default:
|
|
|
|
ath10k_err(ar, "unsupported core hardware revision %d\n",
|
|
|
|
hw_rev);
|
|
|
|
ret = -ENOTSUPP;
|
|
|
|
goto err_free_mac;
|
|
|
|
}
|
|
|
|
|
2014-05-23 10:28:45 +00:00
|
|
|
init_completion(&ar->scan.started);
|
|
|
|
init_completion(&ar->scan.completed);
|
|
|
|
init_completion(&ar->scan.on_channel);
|
|
|
|
init_completion(&ar->target_suspend);
|
2015-03-23 15:32:53 +00:00
|
|
|
init_completion(&ar->wow.wakeup_completed);
|
2014-05-23 10:28:45 +00:00
|
|
|
|
|
|
|
init_completion(&ar->install_key_done);
|
|
|
|
init_completion(&ar->vdev_setup_done);
|
2014-12-17 10:22:26 +00:00
|
|
|
init_completion(&ar->thermal.wmi_sync);
|
2016-04-27 10:53:22 +00:00
|
|
|
init_completion(&ar->bss_survey_done);
|
2014-05-23 10:28:45 +00:00
|
|
|
|
2014-08-05 12:54:44 +00:00
|
|
|
INIT_DELAYED_WORK(&ar->scan.timeout, ath10k_scan_timeout_work);
|
2014-05-23 10:28:45 +00:00
|
|
|
|
|
|
|
ar->workqueue = create_singlethread_workqueue("ath10k_wq");
|
|
|
|
if (!ar->workqueue)
|
2014-09-04 07:13:08 +00:00
|
|
|
goto err_free_mac;
|
2014-05-23 10:28:45 +00:00
|
|
|
|
2015-07-29 08:40:38 +00:00
|
|
|
ar->workqueue_aux = create_singlethread_workqueue("ath10k_aux_wq");
|
|
|
|
if (!ar->workqueue_aux)
|
|
|
|
goto err_free_wq;
|
|
|
|
|
2014-05-23 10:28:45 +00:00
|
|
|
mutex_init(&ar->conf_mutex);
|
|
|
|
spin_lock_init(&ar->data_lock);
|
2016-03-06 14:14:34 +00:00
|
|
|
spin_lock_init(&ar->txqs_lock);
|
2014-05-23 10:28:45 +00:00
|
|
|
|
2016-03-06 14:14:34 +00:00
|
|
|
INIT_LIST_HEAD(&ar->txqs);
|
2014-05-23 10:28:45 +00:00
|
|
|
INIT_LIST_HEAD(&ar->peers);
|
|
|
|
init_waitqueue_head(&ar->peer_mapping_wq);
|
2014-10-28 09:34:38 +00:00
|
|
|
init_waitqueue_head(&ar->htt.empty_tx_wq);
|
|
|
|
init_waitqueue_head(&ar->wmi.tx_credits_wq);
|
2014-05-23 10:28:45 +00:00
|
|
|
|
|
|
|
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);
|
|
|
|
|
2014-05-23 10:28:47 +00:00
|
|
|
INIT_WORK(&ar->register_work, ath10k_core_register_work);
|
2014-05-23 10:28:45 +00:00
|
|
|
INIT_WORK(&ar->restart_work, ath10k_core_restart);
|
2016-09-28 12:11:58 +00:00
|
|
|
INIT_WORK(&ar->set_coverage_class_work,
|
|
|
|
ath10k_core_set_coverage_class_work);
|
2014-05-23 10:28:45 +00:00
|
|
|
|
2016-09-02 16:46:09 +00:00
|
|
|
init_dummy_netdev(&ar->napi_dev);
|
|
|
|
|
2017-12-22 13:38:59 +00:00
|
|
|
ret = ath10k_coredump_create(ar);
|
2014-09-04 07:13:08 +00:00
|
|
|
if (ret)
|
2015-07-29 08:40:38 +00:00
|
|
|
goto err_free_aux_wq;
|
2014-09-04 07:13:08 +00:00
|
|
|
|
2017-12-22 13:38:59 +00:00
|
|
|
ret = ath10k_debug_create(ar);
|
|
|
|
if (ret)
|
|
|
|
goto err_free_coredump;
|
|
|
|
|
2014-05-23 10:28:45 +00:00
|
|
|
return ar;
|
|
|
|
|
2017-12-22 13:38:59 +00:00
|
|
|
err_free_coredump:
|
|
|
|
ath10k_coredump_destroy(ar);
|
|
|
|
|
2015-07-29 08:40:38 +00:00
|
|
|
err_free_aux_wq:
|
|
|
|
destroy_workqueue(ar->workqueue_aux);
|
2014-09-04 07:13:08 +00:00
|
|
|
err_free_wq:
|
|
|
|
destroy_workqueue(ar->workqueue);
|
|
|
|
|
|
|
|
err_free_mac:
|
2014-05-23 10:28:45 +00:00
|
|
|
ath10k_mac_destroy(ar);
|
2014-09-04 07:13:08 +00:00
|
|
|
|
2014-05-23 10:28:45 +00:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
EXPORT_SYMBOL(ath10k_core_create);
|
|
|
|
|
|
|
|
void ath10k_core_destroy(struct ath10k *ar)
|
|
|
|
{
|
|
|
|
flush_workqueue(ar->workqueue);
|
|
|
|
destroy_workqueue(ar->workqueue);
|
|
|
|
|
2015-07-29 08:40:38 +00:00
|
|
|
flush_workqueue(ar->workqueue_aux);
|
|
|
|
destroy_workqueue(ar->workqueue_aux);
|
|
|
|
|
2014-09-04 07:13:08 +00:00
|
|
|
ath10k_debug_destroy(ar);
|
2017-12-22 13:38:59 +00:00
|
|
|
ath10k_coredump_destroy(ar);
|
2016-11-30 09:50:14 +00:00
|
|
|
ath10k_htt_tx_destroy(&ar->htt);
|
2015-08-28 11:51:34 +00:00
|
|
|
ath10k_wmi_free_host_mem(ar);
|
2014-05-23 10:28:45 +00:00
|
|
|
ath10k_mac_destroy(ar);
|
|
|
|
}
|
|
|
|
EXPORT_SYMBOL(ath10k_core_destroy);
|
|
|
|
|
2013-06-12 17:52:10 +00:00
|
|
|
MODULE_AUTHOR("Qualcomm Atheros");
|
2016-05-27 14:45:57 +00:00
|
|
|
MODULE_DESCRIPTION("Core module for Qualcomm Atheros 802.11ac wireless LAN cards.");
|
2013-06-12 17:52:10 +00:00
|
|
|
MODULE_LICENSE("Dual BSD/GPL");
|