1316 lines
44 KiB
Diff
1316 lines
44 KiB
Diff
From 08eadf05f847b1b2472f8d5a0afcab03f832923f Mon Sep 17 00:00:00 2001
|
|
From: Patrick Walther <patrick.walther@netmodule.com>
|
|
Date: Wed, 14 Sep 2022 14:30:15 +0200
|
|
Subject: [PATCH] backport of ath10k patches from openwrt
|
|
|
|
---
|
|
drivers/net/wireless/ath/ath10k/Kconfig | 16 +++
|
|
drivers/net/wireless/ath/ath10k/Makefile | 3 +-
|
|
drivers/net/wireless/ath/ath10k/core.c | 122 ++++++++++++++++++--
|
|
drivers/net/wireless/ath/ath10k/core.h | 19 ++++
|
|
drivers/net/wireless/ath/ath10k/htt.h | 4 +
|
|
drivers/net/wireless/ath/ath10k/htt_tx.c | 61 +++++-----
|
|
drivers/net/wireless/ath/ath10k/hw.h | 1 +
|
|
drivers/net/wireless/ath/ath10k/leds.c | 101 +++++++++++++++++
|
|
drivers/net/wireless/ath/ath10k/leds.h | 41 +++++++
|
|
drivers/net/wireless/ath/ath10k/mac.c | 132 +++++++++++++++++++---
|
|
drivers/net/wireless/ath/ath10k/pci.c | 16 +++
|
|
drivers/net/wireless/ath/ath10k/thermal.h | 2 +-
|
|
drivers/net/wireless/ath/ath10k/txrx.c | 15 ++-
|
|
drivers/net/wireless/ath/ath10k/wmi-ops.h | 32 ++++++
|
|
drivers/net/wireless/ath/ath10k/wmi-tlv.c | 2 +
|
|
drivers/net/wireless/ath/ath10k/wmi.c | 54 +++++++++
|
|
drivers/net/wireless/ath/ath10k/wmi.h | 35 ++++++
|
|
local-symbols | 2 +
|
|
18 files changed, 606 insertions(+), 52 deletions(-)
|
|
create mode 100644 drivers/net/wireless/ath/ath10k/leds.c
|
|
create mode 100644 drivers/net/wireless/ath/ath10k/leds.h
|
|
|
|
diff --git a/drivers/net/wireless/ath/ath10k/Kconfig b/drivers/net/wireless/ath/ath10k/Kconfig
|
|
index 49373f9..5d53bc3 100644
|
|
--- a/drivers/net/wireless/ath/ath10k/Kconfig
|
|
+++ b/drivers/net/wireless/ath/ath10k/Kconfig
|
|
@@ -71,6 +71,16 @@ config ATH10K_DEBUGFS
|
|
|
|
If unsure, say Y to make it easier to debug problems.
|
|
|
|
+config ATH10K_LEDS
|
|
+ bool "Atheros ath10k LED support"
|
|
+ depends on ATH10K
|
|
+ select MAC80211_LEDS
|
|
+ select LEDS_CLASS
|
|
+ select NEW_LEDS
|
|
+ default y
|
|
+ ---help---
|
|
+ This option is necessary, if you want LED support for chipset connected led pins. If unsure, say N.
|
|
+
|
|
config ATH10K_SPECTRAL
|
|
bool "Atheros ath10k spectral scan support"
|
|
depends on ATH10K_DEBUGFS
|
|
@@ -86,6 +96,12 @@ config ATH10K_TRACING
|
|
help
|
|
Select this to ath10k use tracing infrastructure.
|
|
|
|
+config ATH10K_THERMAL
|
|
+ bool "Atheros ath10k thermal monitoring support"
|
|
+ depends on THERMAL
|
|
+ ---help---
|
|
+ Select this to ath10k use hwmon for thermal measurement.
|
|
+
|
|
config ATH10K_DFS_CERTIFIED
|
|
bool "Atheros DFS support for certified platforms"
|
|
depends on ATH10K && CFG80211_CERTIFICATION_ONUS
|
|
diff --git a/drivers/net/wireless/ath/ath10k/Makefile b/drivers/net/wireless/ath/ath10k/Makefile
|
|
index 24d846a..e040d84 100644
|
|
--- a/drivers/net/wireless/ath/ath10k/Makefile
|
|
+++ b/drivers/net/wireless/ath/ath10k/Makefile
|
|
@@ -18,7 +18,8 @@ ath10k_core-y += mac.o \
|
|
ath10k_core-$(CPTCFG_ATH10K_SPECTRAL) += spectral.o
|
|
ath10k_core-$(CPTCFG_NL80211_TESTMODE) += testmode.o
|
|
ath10k_core-$(CPTCFG_ATH10K_TRACING) += trace.o
|
|
-ath10k_core-$(CONFIG_THERMAL) += thermal.o
|
|
+ath10k_core-$(CPTCFG_ATH10K_THERMAL) += thermal.o
|
|
+ath10k_core-$(CPTCFG_ATH10K_LEDS) += leds.o
|
|
ath10k_core-$(CPTCFG_MAC80211_DEBUGFS) += debugfs_sta.o
|
|
ath10k_core-$(CONFIG_PM) += wow.o
|
|
ath10k_core-$(CONFIG_DEV_COREDUMP) += coredump.o
|
|
diff --git a/drivers/net/wireless/ath/ath10k/core.c b/drivers/net/wireless/ath/ath10k/core.c
|
|
index 58e86e6..3b34c59 100644
|
|
--- a/drivers/net/wireless/ath/ath10k/core.c
|
|
+++ b/drivers/net/wireless/ath/ath10k/core.c
|
|
@@ -8,10 +8,12 @@
|
|
#include <linux/module.h>
|
|
#include <linux/firmware.h>
|
|
#include <linux/of.h>
|
|
+#include <linux/of_net.h>
|
|
#include <linux/property.h>
|
|
#include <linux/dmi.h>
|
|
#include <linux/ctype.h>
|
|
#include <linux/pm_qos.h>
|
|
+#include <linux/nvmem-consumer.h>
|
|
#include <asm/byteorder.h>
|
|
|
|
#include "core.h"
|
|
@@ -25,6 +27,7 @@
|
|
#include "testmode.h"
|
|
#include "wmi-ops.h"
|
|
#include "coredump.h"
|
|
+#include "leds.h"
|
|
|
|
unsigned int ath10k_debug_mask;
|
|
EXPORT_SYMBOL(ath10k_debug_mask);
|
|
@@ -32,9 +35,11 @@ EXPORT_SYMBOL(ath10k_debug_mask);
|
|
static unsigned int ath10k_cryptmode_param;
|
|
static bool uart_print;
|
|
static bool skip_otp;
|
|
-static bool rawmode;
|
|
static bool fw_diag_log;
|
|
|
|
+/* frame mode values are mapped as per enum ath10k_hw_txrx_mode */
|
|
+unsigned int ath10k_frame_mode = ATH10K_HW_TXRX_NATIVE_WIFI;
|
|
+
|
|
unsigned long ath10k_coredump_mask = BIT(ATH10K_FW_CRASH_DUMP_REGISTERS) |
|
|
BIT(ATH10K_FW_CRASH_DUMP_CE_DATA);
|
|
|
|
@@ -43,15 +48,16 @@ module_param_named(debug_mask, ath10k_debug_mask, uint, 0644);
|
|
module_param_named(cryptmode, ath10k_cryptmode_param, uint, 0644);
|
|
module_param(uart_print, bool, 0644);
|
|
module_param(skip_otp, bool, 0644);
|
|
-module_param(rawmode, bool, 0644);
|
|
module_param(fw_diag_log, bool, 0644);
|
|
+module_param_named(frame_mode, ath10k_frame_mode, uint, 0644);
|
|
module_param_named(coredump_mask, ath10k_coredump_mask, ulong, 0444);
|
|
|
|
MODULE_PARM_DESC(debug_mask, "Debugging mask");
|
|
MODULE_PARM_DESC(uart_print, "Uart target debugging");
|
|
MODULE_PARM_DESC(skip_otp, "Skip otp failure for calibration in testmode");
|
|
MODULE_PARM_DESC(cryptmode, "Crypto mode: 0-hardware, 1-software");
|
|
-MODULE_PARM_DESC(rawmode, "Use raw 802.11 frame datapath");
|
|
+MODULE_PARM_DESC(frame_mode,
|
|
+ "Datapath frame mode (0: raw, 1: native wifi (default), 2: ethernet)");
|
|
MODULE_PARM_DESC(coredump_mask, "Bitfield of what to include in firmware crash file");
|
|
MODULE_PARM_DESC(fw_diag_log, "Diag based fw log debugging");
|
|
|
|
@@ -61,6 +67,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
|
|
.dev_id = QCA988X_2_0_DEVICE_ID,
|
|
.bus = ATH10K_BUS_PCI,
|
|
.name = "qca988x hw2.0",
|
|
+ .led_pin = 1,
|
|
.patch_load_addr = QCA988X_HW_2_0_PATCH_LOAD_ADDR,
|
|
.uart_pin = 7,
|
|
.cc_wraparound_type = ATH10K_HW_CC_WRAP_SHIFTED_ALL,
|
|
@@ -134,6 +141,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
|
|
.dev_id = QCA9887_1_0_DEVICE_ID,
|
|
.bus = ATH10K_BUS_PCI,
|
|
.name = "qca9887 hw1.0",
|
|
+ .led_pin = 1,
|
|
.patch_load_addr = QCA9887_HW_1_0_PATCH_LOAD_ADDR,
|
|
.uart_pin = 7,
|
|
.cc_wraparound_type = ATH10K_HW_CC_WRAP_SHIFTED_ALL,
|
|
@@ -351,6 +359,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
|
|
.dev_id = QCA99X0_2_0_DEVICE_ID,
|
|
.bus = ATH10K_BUS_PCI,
|
|
.name = "qca99x0 hw2.0",
|
|
+ .led_pin = 17,
|
|
.patch_load_addr = QCA99X0_HW_2_0_PATCH_LOAD_ADDR,
|
|
.uart_pin = 7,
|
|
.otp_exe_param = 0x00000700,
|
|
@@ -393,6 +402,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
|
|
.dev_id = QCA9984_1_0_DEVICE_ID,
|
|
.bus = ATH10K_BUS_PCI,
|
|
.name = "qca9984/qca9994 hw1.0",
|
|
+ .led_pin = 17,
|
|
.patch_load_addr = QCA9984_HW_1_0_PATCH_LOAD_ADDR,
|
|
.uart_pin = 7,
|
|
.cc_wraparound_type = ATH10K_HW_CC_WRAP_SHIFTED_EACH,
|
|
@@ -442,6 +452,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
|
|
.dev_id = QCA9888_2_0_DEVICE_ID,
|
|
.bus = ATH10K_BUS_PCI,
|
|
.name = "qca9888 hw2.0",
|
|
+ .led_pin = 17,
|
|
.patch_load_addr = QCA9888_HW_2_0_PATCH_LOAD_ADDR,
|
|
.uart_pin = 7,
|
|
.cc_wraparound_type = ATH10K_HW_CC_WRAP_SHIFTED_EACH,
|
|
@@ -952,7 +963,8 @@ static int ath10k_core_get_board_id_from_otp(struct ath10k *ar)
|
|
}
|
|
|
|
if (ar->cal_mode == ATH10K_PRE_CAL_MODE_DT ||
|
|
- ar->cal_mode == ATH10K_PRE_CAL_MODE_FILE)
|
|
+ ar->cal_mode == ATH10K_PRE_CAL_MODE_FILE ||
|
|
+ ar->cal_mode == ATH10K_PRE_CAL_MODE_NVMEM)
|
|
bmi_board_id_param = BMI_PARAM_GET_FLASH_BOARD_ID;
|
|
else
|
|
bmi_board_id_param = BMI_PARAM_GET_EEPROM_BOARD_ID;
|
|
@@ -1199,6 +1211,7 @@ success:
|
|
static int ath10k_core_fetch_board_data_api_1(struct ath10k *ar, int bd_ie_type)
|
|
{
|
|
const struct firmware *fw;
|
|
+ char boardname[100];
|
|
|
|
if (bd_ie_type == ATH10K_BD_IE_BOARD) {
|
|
if (!ar->hw_params.fw.board) {
|
|
@@ -1206,9 +1219,19 @@ static int ath10k_core_fetch_board_data_api_1(struct ath10k *ar, int bd_ie_type)
|
|
return -EINVAL;
|
|
}
|
|
|
|
+ scnprintf(boardname, sizeof(boardname), "board-%s-%s.bin",
|
|
+ ath10k_bus_str(ar->hif.bus), dev_name(ar->dev));
|
|
+
|
|
ar->normal_mode_fw.board = ath10k_fetch_fw_file(ar,
|
|
ar->hw_params.fw.dir,
|
|
- ar->hw_params.fw.board);
|
|
+ boardname);
|
|
+ if (IS_ERR(ar->normal_mode_fw.board)) {
|
|
+ fw = ath10k_fetch_fw_file(ar,
|
|
+ ar->hw_params.fw.dir,
|
|
+ ar->hw_params.fw.board);
|
|
+ ar->normal_mode_fw.board = fw;
|
|
+ }
|
|
+
|
|
if (IS_ERR(ar->normal_mode_fw.board))
|
|
return PTR_ERR(ar->normal_mode_fw.board);
|
|
|
|
@@ -1743,7 +1766,8 @@ static int ath10k_download_and_run_otp(struct ath10k *ar)
|
|
|
|
/* 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)
|
|
+ ar->cal_mode == ATH10K_PRE_CAL_MODE_FILE ||
|
|
+ ar->cal_mode == ATH10K_PRE_CAL_MODE_NVMEM)
|
|
bmi_otp_exe_param = BMI_PARAM_FLASH_SECTION_ALL;
|
|
|
|
ret = ath10k_bmi_execute(ar, address, bmi_otp_exe_param, &result);
|
|
@@ -1870,6 +1894,39 @@ out_free:
|
|
return ret;
|
|
}
|
|
|
|
+static int ath10k_download_cal_nvmem(struct ath10k *ar, const char *cell_name)
|
|
+{
|
|
+ struct nvmem_cell *cell;
|
|
+ void *buf;
|
|
+ size_t len;
|
|
+ int ret;
|
|
+
|
|
+ cell = devm_nvmem_cell_get(ar->dev, cell_name);
|
|
+ if (IS_ERR(cell)) {
|
|
+ ret = PTR_ERR(cell);
|
|
+ return ret;
|
|
+ }
|
|
+
|
|
+ buf = nvmem_cell_read(cell, &len);
|
|
+ if (IS_ERR(buf))
|
|
+ return PTR_ERR(buf);
|
|
+
|
|
+ if (ar->hw_params.cal_data_len != len) {
|
|
+ kfree(buf);
|
|
+ ath10k_warn(ar, "invalid calibration data length in nvmem-cell '%s': %zu != %u\n",
|
|
+ cell_name, len, ar->hw_params.cal_data_len);
|
|
+ return -EMSGSIZE;
|
|
+ }
|
|
+
|
|
+ ret = ath10k_download_board_data(ar, buf, len);
|
|
+ kfree(buf);
|
|
+ if (ret)
|
|
+ ath10k_warn(ar, "failed to download calibration data from nvmem-cell '%s': %d\n",
|
|
+ cell_name, ret);
|
|
+
|
|
+ return ret;
|
|
+}
|
|
+
|
|
int ath10k_core_fetch_firmware_api_n(struct ath10k *ar, const char *name,
|
|
struct ath10k_fw_file *fw_file)
|
|
{
|
|
@@ -2104,6 +2161,18 @@ static int ath10k_core_pre_cal_download(struct ath10k *ar)
|
|
{
|
|
int ret;
|
|
|
|
+ ret = ath10k_download_cal_nvmem(ar, "pre-calibration");
|
|
+ if (ret == 0) {
|
|
+ ar->cal_mode = ATH10K_PRE_CAL_MODE_NVMEM;
|
|
+ goto success;
|
|
+ } else if (ret == -EPROBE_DEFER) {
|
|
+ return ret;
|
|
+ }
|
|
+
|
|
+ ath10k_dbg(ar, ATH10K_DBG_BOOT,
|
|
+ "boot did not find a pre-calibration nvmem-cell, try file next: %d\n",
|
|
+ ret);
|
|
+
|
|
ret = ath10k_download_cal_file(ar, ar->pre_cal_file);
|
|
if (ret == 0) {
|
|
ar->cal_mode = ATH10K_PRE_CAL_MODE_FILE;
|
|
@@ -2170,6 +2239,18 @@ static int ath10k_download_cal_data(struct ath10k *ar)
|
|
"pre cal download procedure failed, try cal file: %d\n",
|
|
ret);
|
|
|
|
+ ret = ath10k_download_cal_nvmem(ar, "calibration");
|
|
+ if (ret == 0) {
|
|
+ ar->cal_mode = ATH10K_CAL_MODE_NVMEM;
|
|
+ goto done;
|
|
+ } else if (ret == -EPROBE_DEFER) {
|
|
+ return ret;
|
|
+ }
|
|
+
|
|
+ ath10k_dbg(ar, ATH10K_DBG_BOOT,
|
|
+ "boot did not find a calibration nvmem-cell, try file next: %d\n",
|
|
+ ret);
|
|
+
|
|
ret = ath10k_download_cal_file(ar, ar->cal_file);
|
|
if (ret == 0) {
|
|
ar->cal_mode = ATH10K_CAL_MODE_FILE;
|
|
@@ -2487,7 +2568,7 @@ static int ath10k_core_init_firmware_features(struct ath10k *ar)
|
|
ar->htt.max_num_amsdu = ATH10K_HTT_MAX_NUM_AMSDU_DEFAULT;
|
|
ar->htt.max_num_ampdu = ATH10K_HTT_MAX_NUM_AMPDU_DEFAULT;
|
|
|
|
- if (rawmode) {
|
|
+ if (ath10k_frame_mode == ATH10K_HW_TXRX_RAW) {
|
|
if (!test_bit(ATH10K_FW_FEATURE_RAW_MODE_SUPPORT,
|
|
fw_file->fw_features)) {
|
|
ath10k_err(ar, "rawmode = 1 requires support from firmware");
|
|
@@ -3084,6 +3165,10 @@ int ath10k_core_start(struct ath10k *ar, enum ath10k_firmware_mode mode,
|
|
goto err_hif_stop;
|
|
}
|
|
|
|
+ status = ath10k_leds_start(ar);
|
|
+ if (status)
|
|
+ goto err_hif_stop;
|
|
+
|
|
return 0;
|
|
|
|
err_hif_stop:
|
|
@@ -3250,6 +3335,8 @@ static int ath10k_core_probe_fw(struct ath10k *ar)
|
|
|
|
device_get_mac_address(ar->dev, ar->mac_addr, sizeof(ar->mac_addr));
|
|
|
|
+ of_get_mac_address(ar->dev->of_node, ar->mac_addr);
|
|
+
|
|
ret = ath10k_core_init_firmware_features(ar);
|
|
if (ret) {
|
|
ath10k_err(ar, "fatal problem with firmware features: %d\n",
|
|
@@ -3342,9 +3429,18 @@ static void ath10k_core_register_work(struct work_struct *work)
|
|
goto err_spectral_destroy;
|
|
}
|
|
|
|
+ status = ath10k_leds_register(ar);
|
|
+ if (status) {
|
|
+ ath10k_err(ar, "could not register leds: %d\n",
|
|
+ status);
|
|
+ goto err_thermal_unregister;
|
|
+ }
|
|
+
|
|
set_bit(ATH10K_FLAG_CORE_REGISTERED, &ar->dev_flags);
|
|
return;
|
|
|
|
+err_thermal_unregister:
|
|
+ ath10k_thermal_unregister(ar);
|
|
err_spectral_destroy:
|
|
ath10k_spectral_destroy(ar);
|
|
err_debug_destroy:
|
|
@@ -3369,6 +3465,16 @@ int ath10k_core_register(struct ath10k *ar,
|
|
|
|
queue_work(ar->workqueue, &ar->register_work);
|
|
|
|
+ /* OpenWrt requires all PHYs to be initialized to create the
|
|
+ * configuration files during bootup. ath10k violates this
|
|
+ * because it delays the creation of the PHY to a not well defined
|
|
+ * point in the future.
|
|
+ *
|
|
+ * Forcing the work to be done immediately works around this problem
|
|
+ * but may also delay the boot when firmware images cannot be found.
|
|
+ */
|
|
+ flush_workqueue(ar->workqueue);
|
|
+
|
|
return 0;
|
|
}
|
|
EXPORT_SYMBOL(ath10k_core_register);
|
|
@@ -3380,6 +3486,8 @@ void ath10k_core_unregister(struct ath10k *ar)
|
|
if (!test_bit(ATH10K_FLAG_CORE_REGISTERED, &ar->dev_flags))
|
|
return;
|
|
|
|
+ ath10k_leds_unregister(ar);
|
|
+
|
|
ath10k_thermal_unregister(ar);
|
|
/* Stop spectral before unregistering from mac80211 to remove the
|
|
* relayfs debugfs file cleanly. Otherwise the parent debugfs tree
|
|
diff --git a/drivers/net/wireless/ath/ath10k/core.h b/drivers/net/wireless/ath/ath10k/core.h
|
|
index 4f5ca94..dfe7b0e 100644
|
|
--- a/drivers/net/wireless/ath/ath10k/core.h
|
|
+++ b/drivers/net/wireless/ath/ath10k/core.h
|
|
@@ -14,6 +14,7 @@
|
|
#include <linux/pci.h>
|
|
#include <linux/uuid.h>
|
|
#include <linux/time.h>
|
|
+#include <linux/leds.h>
|
|
|
|
#include "htt.h"
|
|
#include "htc.h"
|
|
@@ -877,8 +878,10 @@ enum ath10k_cal_mode {
|
|
ATH10K_CAL_MODE_FILE,
|
|
ATH10K_CAL_MODE_OTP,
|
|
ATH10K_CAL_MODE_DT,
|
|
+ ATH10K_CAL_MODE_NVMEM,
|
|
ATH10K_PRE_CAL_MODE_FILE,
|
|
ATH10K_PRE_CAL_MODE_DT,
|
|
+ ATH10K_PRE_CAL_MODE_NVMEM,
|
|
ATH10K_CAL_MODE_EEPROM,
|
|
};
|
|
|
|
@@ -898,10 +901,14 @@ static inline const char *ath10k_cal_mode_str(enum ath10k_cal_mode mode)
|
|
return "otp";
|
|
case ATH10K_CAL_MODE_DT:
|
|
return "dt";
|
|
+ case ATH10K_CAL_MODE_NVMEM:
|
|
+ return "nvmem";
|
|
case ATH10K_PRE_CAL_MODE_FILE:
|
|
return "pre-cal-file";
|
|
case ATH10K_PRE_CAL_MODE_DT:
|
|
return "pre-cal-dt";
|
|
+ case ATH10K_PRE_CAL_MODE_NVMEM:
|
|
+ return "pre-cal-nvmem";
|
|
case ATH10K_CAL_MODE_EEPROM:
|
|
return "eeprom";
|
|
}
|
|
@@ -1249,6 +1256,13 @@ struct ath10k {
|
|
bool utf_monitor;
|
|
} testmode;
|
|
|
|
+ struct {
|
|
+ struct gpio_led wifi_led;
|
|
+ struct led_classdev cdev;
|
|
+ char label[48];
|
|
+ u32 gpio_state_pin;
|
|
+ } leds;
|
|
+
|
|
struct {
|
|
/* protected by data_lock */
|
|
u32 rx_crc_err_drop;
|
|
@@ -1298,6 +1312,10 @@ struct ath10k {
|
|
s32 tx_power_2g_limit;
|
|
s32 tx_power_5g_limit;
|
|
|
|
+#ifdef CPTCFG_MAC80211_LEDS
|
|
+ const char *led_default_trigger;
|
|
+#endif
|
|
+
|
|
/* must be last */
|
|
u8 drv_priv[] __aligned(sizeof(void *));
|
|
};
|
|
@@ -1311,6 +1329,7 @@ static inline bool ath10k_peer_stats_enabled(struct ath10k *ar)
|
|
return false;
|
|
}
|
|
|
|
+extern unsigned int ath10k_frame_mode;
|
|
extern unsigned long ath10k_coredump_mask;
|
|
|
|
void ath10k_core_napi_sync_disable(struct ath10k *ar);
|
|
diff --git a/drivers/net/wireless/ath/ath10k/htt.h b/drivers/net/wireless/ath/ath10k/htt.h
|
|
index ec689e3..4c70917 100644
|
|
--- a/drivers/net/wireless/ath/ath10k/htt.h
|
|
+++ b/drivers/net/wireless/ath/ath10k/htt.h
|
|
@@ -235,7 +235,11 @@ enum htt_rx_ring_flags {
|
|
};
|
|
|
|
#define HTT_RX_RING_SIZE_MIN 128
|
|
+#ifndef CONFIG_ATH10K_SMALLBUFFERS
|
|
#define HTT_RX_RING_SIZE_MAX 2048
|
|
+#else
|
|
+#define HTT_RX_RING_SIZE_MAX 512
|
|
+#endif
|
|
#define HTT_RX_RING_SIZE HTT_RX_RING_SIZE_MAX
|
|
#define HTT_RX_RING_FILL_LEVEL (((HTT_RX_RING_SIZE) / 2) - 1)
|
|
#define HTT_RX_RING_FILL_LEVEL_DUAL_MAC (HTT_RX_RING_SIZE - 1)
|
|
diff --git a/drivers/net/wireless/ath/ath10k/htt_tx.c b/drivers/net/wireless/ath/ath10k/htt_tx.c
|
|
index b793eac..9863343 100644
|
|
--- a/drivers/net/wireless/ath/ath10k/htt_tx.c
|
|
+++ b/drivers/net/wireless/ath/ath10k/htt_tx.c
|
|
@@ -1295,7 +1295,6 @@ static int ath10k_htt_tx_hl(struct ath10k_htt *htt, enum ath10k_hw_txrx_mode txm
|
|
struct ath10k *ar = htt->ar;
|
|
int res, data_len;
|
|
struct htt_cmd_hdr *cmd_hdr;
|
|
- struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)msdu->data;
|
|
struct htt_data_tx_desc *tx_desc;
|
|
struct ath10k_skb_cb *skb_cb = ATH10K_SKB_CB(msdu);
|
|
struct sk_buff *tmp_skb;
|
|
@@ -1306,11 +1305,15 @@ static int ath10k_htt_tx_hl(struct ath10k_htt *htt, enum ath10k_hw_txrx_mode txm
|
|
u16 flags1 = 0;
|
|
u16 msdu_id = 0;
|
|
|
|
- if ((ieee80211_is_action(hdr->frame_control) ||
|
|
- ieee80211_is_deauth(hdr->frame_control) ||
|
|
- ieee80211_is_disassoc(hdr->frame_control)) &&
|
|
- ieee80211_has_protected(hdr->frame_control)) {
|
|
- skb_put(msdu, IEEE80211_CCMP_MIC_LEN);
|
|
+ if (!is_eth) {
|
|
+ struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)msdu->data;
|
|
+
|
|
+ if ((ieee80211_is_action(hdr->frame_control) ||
|
|
+ ieee80211_is_deauth(hdr->frame_control) ||
|
|
+ ieee80211_is_disassoc(hdr->frame_control)) &&
|
|
+ ieee80211_has_protected(hdr->frame_control)) {
|
|
+ skb_put(msdu, IEEE80211_CCMP_MIC_LEN);
|
|
+ }
|
|
}
|
|
|
|
data_len = msdu->len;
|
|
@@ -1407,7 +1410,6 @@ static int ath10k_htt_tx_32(struct ath10k_htt *htt,
|
|
{
|
|
struct ath10k *ar = htt->ar;
|
|
struct device *dev = ar->dev;
|
|
- struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)msdu->data;
|
|
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(msdu);
|
|
struct ath10k_skb_cb *skb_cb = ATH10K_SKB_CB(msdu);
|
|
struct ath10k_hif_sg_item sg_items[2];
|
|
@@ -1439,15 +1441,19 @@ static int ath10k_htt_tx_32(struct ath10k_htt *htt,
|
|
txbuf_paddr = htt->txbuf.paddr +
|
|
(sizeof(struct ath10k_htt_txbuf_32) * msdu_id);
|
|
|
|
- if ((ieee80211_is_action(hdr->frame_control) ||
|
|
- ieee80211_is_deauth(hdr->frame_control) ||
|
|
- ieee80211_is_disassoc(hdr->frame_control)) &&
|
|
- ieee80211_has_protected(hdr->frame_control)) {
|
|
- skb_put(msdu, IEEE80211_CCMP_MIC_LEN);
|
|
- } else if (!(skb_cb->flags & ATH10K_SKB_F_NO_HWCRYPT) &&
|
|
- txmode == ATH10K_HW_TXRX_RAW &&
|
|
- ieee80211_has_protected(hdr->frame_control)) {
|
|
- skb_put(msdu, IEEE80211_CCMP_MIC_LEN);
|
|
+ if (!is_eth) {
|
|
+ struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)msdu->data;
|
|
+
|
|
+ if ((ieee80211_is_action(hdr->frame_control) ||
|
|
+ ieee80211_is_deauth(hdr->frame_control) ||
|
|
+ ieee80211_is_disassoc(hdr->frame_control)) &&
|
|
+ ieee80211_has_protected(hdr->frame_control)) {
|
|
+ skb_put(msdu, IEEE80211_CCMP_MIC_LEN);
|
|
+ } else if (!(skb_cb->flags & ATH10K_SKB_F_NO_HWCRYPT) &&
|
|
+ txmode == ATH10K_HW_TXRX_RAW &&
|
|
+ ieee80211_has_protected(hdr->frame_control)) {
|
|
+ skb_put(msdu, IEEE80211_CCMP_MIC_LEN);
|
|
+ }
|
|
}
|
|
|
|
skb_cb->paddr = dma_map_single(dev, msdu->data, msdu->len,
|
|
@@ -1609,7 +1615,6 @@ static int ath10k_htt_tx_64(struct ath10k_htt *htt,
|
|
{
|
|
struct ath10k *ar = htt->ar;
|
|
struct device *dev = ar->dev;
|
|
- struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)msdu->data;
|
|
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(msdu);
|
|
struct ath10k_skb_cb *skb_cb = ATH10K_SKB_CB(msdu);
|
|
struct ath10k_hif_sg_item sg_items[2];
|
|
@@ -1641,15 +1646,19 @@ static int ath10k_htt_tx_64(struct ath10k_htt *htt,
|
|
txbuf_paddr = htt->txbuf.paddr +
|
|
(sizeof(struct ath10k_htt_txbuf_64) * msdu_id);
|
|
|
|
- if ((ieee80211_is_action(hdr->frame_control) ||
|
|
- ieee80211_is_deauth(hdr->frame_control) ||
|
|
- ieee80211_is_disassoc(hdr->frame_control)) &&
|
|
- ieee80211_has_protected(hdr->frame_control)) {
|
|
- skb_put(msdu, IEEE80211_CCMP_MIC_LEN);
|
|
- } else if (!(skb_cb->flags & ATH10K_SKB_F_NO_HWCRYPT) &&
|
|
- txmode == ATH10K_HW_TXRX_RAW &&
|
|
- ieee80211_has_protected(hdr->frame_control)) {
|
|
- skb_put(msdu, IEEE80211_CCMP_MIC_LEN);
|
|
+ if (!is_eth) {
|
|
+ struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)msdu->data;
|
|
+
|
|
+ if ((ieee80211_is_action(hdr->frame_control) ||
|
|
+ ieee80211_is_deauth(hdr->frame_control) ||
|
|
+ ieee80211_is_disassoc(hdr->frame_control)) &&
|
|
+ ieee80211_has_protected(hdr->frame_control)) {
|
|
+ skb_put(msdu, IEEE80211_CCMP_MIC_LEN);
|
|
+ } else if (!(skb_cb->flags & ATH10K_SKB_F_NO_HWCRYPT) &&
|
|
+ txmode == ATH10K_HW_TXRX_RAW &&
|
|
+ ieee80211_has_protected(hdr->frame_control)) {
|
|
+ skb_put(msdu, IEEE80211_CCMP_MIC_LEN);
|
|
+ }
|
|
}
|
|
|
|
skb_cb->paddr = dma_map_single(dev, msdu->data, msdu->len,
|
|
diff --git a/drivers/net/wireless/ath/ath10k/hw.h b/drivers/net/wireless/ath/ath10k/hw.h
|
|
index 79ae9e4..9d65f3e 100644
|
|
--- a/drivers/net/wireless/ath/ath10k/hw.h
|
|
+++ b/drivers/net/wireless/ath/ath10k/hw.h
|
|
@@ -517,6 +517,7 @@ struct ath10k_hw_params {
|
|
const char *name;
|
|
u32 patch_load_addr;
|
|
int uart_pin;
|
|
+ int led_pin;
|
|
u32 otp_exe_param;
|
|
|
|
/* Type of hw cycle counter wraparound logic, for more info
|
|
diff --git a/drivers/net/wireless/ath/ath10k/leds.c b/drivers/net/wireless/ath/ath10k/leds.c
|
|
new file mode 100644
|
|
index 0000000..be8f255
|
|
--- /dev/null
|
|
+++ b/drivers/net/wireless/ath/ath10k/leds.c
|
|
@@ -0,0 +1,101 @@
|
|
+/*
|
|
+ * Copyright (c) 2005-2011 Atheros Communications Inc.
|
|
+ * Copyright (c) 2011-2017 Qualcomm Atheros, Inc.
|
|
+ * Copyright (c) 2018 Sebastian Gottschall <s.gottschall@dd-wrt.com>
|
|
+ * Copyright (c) 2018, The Linux Foundation. All rights reserved.
|
|
+ *
|
|
+ * 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/leds.h>
|
|
+
|
|
+#include "core.h"
|
|
+#include "wmi.h"
|
|
+#include "wmi-ops.h"
|
|
+
|
|
+#include "leds.h"
|
|
+
|
|
+static int ath10k_leds_set_brightness_blocking(struct led_classdev *led_cdev,
|
|
+ enum led_brightness brightness)
|
|
+{
|
|
+ struct ath10k *ar = container_of(led_cdev, struct ath10k,
|
|
+ leds.cdev);
|
|
+ struct gpio_led *led = &ar->leds.wifi_led;
|
|
+
|
|
+ mutex_lock(&ar->conf_mutex);
|
|
+
|
|
+ if (ar->state != ATH10K_STATE_ON)
|
|
+ goto out;
|
|
+
|
|
+ ar->leds.gpio_state_pin = (brightness != LED_OFF) ^ led->active_low;
|
|
+ ath10k_wmi_gpio_output(ar, led->gpio, ar->leds.gpio_state_pin);
|
|
+
|
|
+out:
|
|
+ mutex_unlock(&ar->conf_mutex);
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+int ath10k_leds_start(struct ath10k *ar)
|
|
+{
|
|
+ if (ar->hw_params.led_pin == 0)
|
|
+ /* leds not supported */
|
|
+ return 0;
|
|
+
|
|
+ /* under some circumstances, the gpio pin gets reconfigured
|
|
+ * to default state by the firmware, so we need to
|
|
+ * reconfigure it this behaviour has only ben seen on
|
|
+ * QCA9984 and QCA99XX devices so far
|
|
+ */
|
|
+ ath10k_wmi_gpio_config(ar, ar->hw_params.led_pin, 0,
|
|
+ WMI_GPIO_PULL_NONE, WMI_GPIO_INTTYPE_DISABLE);
|
|
+ ath10k_wmi_gpio_output(ar, ar->hw_params.led_pin, 1);
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+int ath10k_leds_register(struct ath10k *ar)
|
|
+{
|
|
+ int ret;
|
|
+
|
|
+ if (ar->hw_params.led_pin == 0)
|
|
+ /* leds not supported */
|
|
+ return 0;
|
|
+
|
|
+ snprintf(ar->leds.label, sizeof(ar->leds.label), "ath10k-%s",
|
|
+ wiphy_name(ar->hw->wiphy));
|
|
+ ar->leds.wifi_led.active_low = 1;
|
|
+ ar->leds.wifi_led.gpio = ar->hw_params.led_pin;
|
|
+ ar->leds.wifi_led.name = ar->leds.label;
|
|
+ ar->leds.wifi_led.default_state = LEDS_GPIO_DEFSTATE_KEEP;
|
|
+
|
|
+ ar->leds.cdev.name = ar->leds.label;
|
|
+ ar->leds.cdev.brightness_set_blocking = ath10k_leds_set_brightness_blocking;
|
|
+ ar->leds.cdev.default_trigger = ar->led_default_trigger;
|
|
+
|
|
+ ret = led_classdev_register(wiphy_dev(ar->hw->wiphy), &ar->leds.cdev);
|
|
+ if (ret)
|
|
+ return ret;
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+void ath10k_leds_unregister(struct ath10k *ar)
|
|
+{
|
|
+ if (ar->hw_params.led_pin == 0)
|
|
+ /* leds not supported */
|
|
+ return;
|
|
+
|
|
+ led_classdev_unregister(&ar->leds.cdev);
|
|
+}
|
|
+
|
|
diff --git a/drivers/net/wireless/ath/ath10k/leds.h b/drivers/net/wireless/ath/ath10k/leds.h
|
|
new file mode 100644
|
|
index 0000000..a0f5c84
|
|
--- /dev/null
|
|
+++ b/drivers/net/wireless/ath/ath10k/leds.h
|
|
@@ -0,0 +1,41 @@
|
|
+/*
|
|
+ * Copyright (c) 2018, The Linux Foundation. All rights reserved.
|
|
+ *
|
|
+ * Permission to use, copy, modify, and/or distribute this software for any
|
|
+ * purpose with or without fee is hereby granted, provided that the above
|
|
+ * copyright notice and this permission notice appear in all copies.
|
|
+ *
|
|
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
+ */
|
|
+#ifndef _LEDS_H_
|
|
+#define _LEDS_H_
|
|
+
|
|
+#include "core.h"
|
|
+
|
|
+#ifdef CPTCFG_ATH10K_LEDS
|
|
+void ath10k_leds_unregister(struct ath10k *ar);
|
|
+int ath10k_leds_start(struct ath10k *ar);
|
|
+int ath10k_leds_register(struct ath10k *ar);
|
|
+#else
|
|
+static inline void ath10k_leds_unregister(struct ath10k *ar)
|
|
+{
|
|
+}
|
|
+
|
|
+static inline int ath10k_leds_start(struct ath10k *ar)
|
|
+{
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+static inline int ath10k_leds_register(struct ath10k *ar)
|
|
+{
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+#endif
|
|
+#endif /* _LEDS_H_ */
|
|
diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c
|
|
index 266ba48..7a5311b 100644
|
|
--- a/drivers/net/wireless/ath/ath10k/mac.c
|
|
+++ b/drivers/net/wireless/ath/ath10k/mac.c
|
|
@@ -24,6 +24,7 @@
|
|
#include "wmi-tlv.h"
|
|
#include "wmi-ops.h"
|
|
#include "wow.h"
|
|
+#include "leds.h"
|
|
|
|
/*********/
|
|
/* Rates */
|
|
@@ -1020,6 +1021,40 @@ static inline int ath10k_vdev_setup_sync(struct ath10k *ar)
|
|
return ar->last_wmi_vdev_start_status;
|
|
}
|
|
|
|
+static u32 ath10k_get_max_antenna_gain(struct ath10k *ar,
|
|
+ u32 ch_max_antenna_gain)
|
|
+{
|
|
+ u32 max_antenna_gain;
|
|
+
|
|
+ if (ar->dfs_detector && ar->dfs_detector->region == NL80211_DFS_FCC) {
|
|
+ /* FCC allows maximum antenna gain of 6 dBi. 15.247(b)(4):
|
|
+ *
|
|
+ * > (4) The conducted output power limit
|
|
+ * > specified in paragraph (b) of this section
|
|
+ * > is based on the use of antennas
|
|
+ * > with directional gains that do not exceed
|
|
+ * > 6 dBi. Except as shown in paragraph
|
|
+ * > (c) of this section, if transmitting
|
|
+ * > antennas of directional gain greater
|
|
+ * > than 6 dBi are used, the conducted
|
|
+ * > output power from the intentional radiator
|
|
+ * > shall be reduced below the stated
|
|
+ * > values in paragraphs (b)(1), (b)(2),
|
|
+ * > and (b)(3) of this section, as appropriate,
|
|
+ * > by the amount in dB that the
|
|
+ * > directional gain of the antenna exceeds
|
|
+ * > 6 dBi.
|
|
+ *
|
|
+ * https://www.gpo.gov/fdsys/pkg/CFR-2013-title47-vol1/pdf/CFR-2013-title47-vol1-sec15-247.pdf
|
|
+ */
|
|
+ max_antenna_gain = 6;
|
|
+ } else {
|
|
+ max_antenna_gain = 0;
|
|
+ }
|
|
+
|
|
+ return max(ch_max_antenna_gain, max_antenna_gain);
|
|
+}
|
|
+
|
|
static int ath10k_monitor_vdev_start(struct ath10k *ar, int vdev_id)
|
|
{
|
|
struct cfg80211_chan_def *chandef = NULL;
|
|
@@ -1052,7 +1087,8 @@ static int ath10k_monitor_vdev_start(struct ath10k *ar, int vdev_id)
|
|
arg.channel.min_power = 0;
|
|
arg.channel.max_power = channel->max_power * 2;
|
|
arg.channel.max_reg_power = channel->max_reg_power * 2;
|
|
- arg.channel.max_antenna_gain = channel->max_antenna_gain;
|
|
+ arg.channel.max_antenna_gain = ath10k_get_max_antenna_gain(ar,
|
|
+ channel->max_antenna_gain);
|
|
|
|
reinit_completion(&ar->vdev_setup_done);
|
|
reinit_completion(&ar->vdev_delete_done);
|
|
@@ -1498,7 +1534,8 @@ static int ath10k_vdev_start_restart(struct ath10k_vif *arvif,
|
|
arg.channel.min_power = 0;
|
|
arg.channel.max_power = chandef->chan->max_power * 2;
|
|
arg.channel.max_reg_power = chandef->chan->max_reg_power * 2;
|
|
- arg.channel.max_antenna_gain = chandef->chan->max_antenna_gain;
|
|
+ arg.channel.max_antenna_gain = ath10k_get_max_antenna_gain(ar,
|
|
+ chandef->chan->max_antenna_gain);
|
|
|
|
if (arvif->vdev_type == WMI_VDEV_TYPE_AP) {
|
|
arg.ssid = arvif->u.ap.ssid;
|
|
@@ -3426,7 +3463,8 @@ static int ath10k_update_channel_list(struct ath10k *ar)
|
|
ch->min_power = 0;
|
|
ch->max_power = channel->max_power * 2;
|
|
ch->max_reg_power = channel->max_reg_power * 2;
|
|
- ch->max_antenna_gain = channel->max_antenna_gain;
|
|
+ ch->max_antenna_gain = ath10k_get_max_antenna_gain(ar,
|
|
+ channel->max_antenna_gain);
|
|
ch->reg_class_id = 0; /* FIXME */
|
|
|
|
/* FIXME: why use only legacy modes, why not any
|
|
@@ -3710,6 +3748,9 @@ ath10k_mac_tx_h_get_txmode(struct ath10k *ar,
|
|
const struct ath10k_skb_cb *skb_cb = ATH10K_SKB_CB(skb);
|
|
__le16 fc = hdr->frame_control;
|
|
|
|
+ if (IEEE80211_SKB_CB(skb)->flags & IEEE80211_TX_CTL_HW_80211_ENCAP)
|
|
+ return ATH10K_HW_TXRX_ETHERNET;
|
|
+
|
|
if (!vif || vif->type == NL80211_IFTYPE_MONITOR)
|
|
return ATH10K_HW_TXRX_RAW;
|
|
|
|
@@ -3870,6 +3911,12 @@ static void ath10k_mac_tx_h_fill_cb(struct ath10k *ar,
|
|
bool noack = false;
|
|
|
|
cb->flags = 0;
|
|
+
|
|
+ if (info->flags & IEEE80211_TX_CTL_HW_80211_ENCAP) {
|
|
+ cb->flags |= ATH10K_SKB_F_QOS; /* Assume data frames are QoS */
|
|
+ goto finish_cb_fill;
|
|
+ }
|
|
+
|
|
if (!ath10k_tx_h_use_hwcrypto(vif, skb))
|
|
cb->flags |= ATH10K_SKB_F_NO_HWCRYPT;
|
|
|
|
@@ -3908,6 +3955,7 @@ static void ath10k_mac_tx_h_fill_cb(struct ath10k *ar,
|
|
cb->flags |= ATH10K_SKB_F_RAW_TX;
|
|
}
|
|
|
|
+finish_cb_fill:
|
|
cb->vif = vif;
|
|
cb->txq = txq;
|
|
cb->airtime_est = airtime;
|
|
@@ -4031,7 +4079,11 @@ static int ath10k_mac_tx(struct ath10k *ar,
|
|
ath10k_tx_h_seq_no(vif, skb);
|
|
break;
|
|
case ATH10K_HW_TXRX_ETHERNET:
|
|
- ath10k_tx_h_8023(skb);
|
|
+ /* Convert 802.11->802.3 header only if the frame was erlier
|
|
+ * encapsulated to 802.11 by mac80211. Otherwise pass it as is.
|
|
+ */
|
|
+ if (!(info->flags & IEEE80211_TX_CTL_HW_80211_ENCAP))
|
|
+ ath10k_tx_h_8023(skb);
|
|
break;
|
|
case ATH10K_HW_TXRX_RAW:
|
|
if (!test_bit(ATH10K_FLAG_RAW_MODE, &ar->dev_flags) &&
|
|
@@ -4643,12 +4695,10 @@ static void ath10k_mac_op_tx(struct ieee80211_hw *hw,
|
|
struct ieee80211_vif *vif = info->control.vif;
|
|
struct ieee80211_sta *sta = control->sta;
|
|
struct ieee80211_txq *txq = NULL;
|
|
- struct ieee80211_hdr *hdr = (void *)skb->data;
|
|
enum ath10k_hw_txrx_mode txmode;
|
|
enum ath10k_mac_tx_path txpath;
|
|
bool is_htt;
|
|
bool is_mgmt;
|
|
- bool is_presp;
|
|
int ret;
|
|
u16 airtime;
|
|
|
|
@@ -4662,8 +4712,14 @@ static void ath10k_mac_op_tx(struct ieee80211_hw *hw,
|
|
is_mgmt = (txpath == ATH10K_MAC_TX_HTT_MGMT);
|
|
|
|
if (is_htt) {
|
|
+ bool is_presp = false;
|
|
+
|
|
spin_lock_bh(&ar->htt.tx_lock);
|
|
- is_presp = ieee80211_is_probe_resp(hdr->frame_control);
|
|
+ if (!(info->flags & IEEE80211_TX_CTL_HW_80211_ENCAP)) {
|
|
+ struct ieee80211_hdr *hdr = (void *)skb->data;
|
|
+
|
|
+ is_presp = ieee80211_is_probe_resp(hdr->frame_control);
|
|
+ }
|
|
|
|
ret = ath10k_htt_tx_inc_pending(htt);
|
|
if (ret) {
|
|
@@ -5463,6 +5519,30 @@ static int ath10k_mac_set_txbf_conf(struct ath10k_vif *arvif)
|
|
ar->wmi.vdev_param->txbf, value);
|
|
}
|
|
|
|
+static void ath10k_update_vif_offload(struct ieee80211_hw *hw,
|
|
+ struct ieee80211_vif *vif)
|
|
+{
|
|
+ struct ath10k_vif *arvif = (void *)vif->drv_priv;
|
|
+ struct ath10k *ar = hw->priv;
|
|
+ u32 vdev_param;
|
|
+ int ret;
|
|
+
|
|
+ if (ath10k_frame_mode != ATH10K_HW_TXRX_ETHERNET ||
|
|
+ ar->wmi.vdev_param->tx_encap_type == WMI_VDEV_PARAM_UNSUPPORTED ||
|
|
+ (vif->type != NL80211_IFTYPE_STATION &&
|
|
+ vif->type != NL80211_IFTYPE_AP))
|
|
+ vif->offload_flags &= ~IEEE80211_OFFLOAD_ENCAP_ENABLED;
|
|
+
|
|
+ vdev_param = ar->wmi.vdev_param->tx_encap_type;
|
|
+ ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
|
|
+ ATH10K_HW_TXRX_NATIVE_WIFI);
|
|
+ /* 10.X firmware does not support this VDEV parameter. Do not warn */
|
|
+ if (ret && ret != -EOPNOTSUPP) {
|
|
+ ath10k_warn(ar, "failed to set vdev %i TX encapsulation: %d\n",
|
|
+ arvif->vdev_id, ret);
|
|
+ }
|
|
+}
|
|
+
|
|
/*
|
|
* TODO:
|
|
* Figure out how to handle WMI_VDEV_SUBTYPE_P2P_DEVICE,
|
|
@@ -5672,15 +5752,7 @@ static int ath10k_add_interface(struct ieee80211_hw *hw,
|
|
|
|
arvif->def_wep_key_idx = -1;
|
|
|
|
- vdev_param = ar->wmi.vdev_param->tx_encap_type;
|
|
- ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
|
|
- ATH10K_HW_TXRX_NATIVE_WIFI);
|
|
- /* 10.X firmware does not support this VDEV parameter. Do not warn */
|
|
- if (ret && ret != -EOPNOTSUPP) {
|
|
- ath10k_warn(ar, "failed to set vdev %i TX encapsulation: %d\n",
|
|
- arvif->vdev_id, ret);
|
|
- goto err_vdev_delete;
|
|
- }
|
|
+ ath10k_update_vif_offload(hw, vif);
|
|
|
|
/* Configuring number of spatial stream for monitor interface is causing
|
|
* target assert in qca9888 and qca6174.
|
|
@@ -9368,6 +9440,7 @@ static const struct ieee80211_ops ath10k_ops = {
|
|
.stop = ath10k_stop,
|
|
.config = ath10k_config,
|
|
.add_interface = ath10k_add_interface,
|
|
+ .update_vif_offload = ath10k_update_vif_offload,
|
|
.remove_interface = ath10k_remove_interface,
|
|
.configure_filter = ath10k_configure_filter,
|
|
.bss_info_changed = ath10k_bss_info_changed,
|
|
@@ -9859,6 +9932,21 @@ static int ath10k_mac_init_rd(struct ath10k *ar)
|
|
return 0;
|
|
}
|
|
|
|
+#ifdef CPTCFG_MAC80211_LEDS
|
|
+static const struct ieee80211_tpt_blink ath10k_tpt_blink[] = {
|
|
+ { .throughput = 0 * 1024, .blink_time = 334 },
|
|
+ { .throughput = 1 * 1024, .blink_time = 260 },
|
|
+ { .throughput = 2 * 1024, .blink_time = 220 },
|
|
+ { .throughput = 5 * 1024, .blink_time = 190 },
|
|
+ { .throughput = 10 * 1024, .blink_time = 170 },
|
|
+ { .throughput = 25 * 1024, .blink_time = 150 },
|
|
+ { .throughput = 54 * 1024, .blink_time = 130 },
|
|
+ { .throughput = 120 * 1024, .blink_time = 110 },
|
|
+ { .throughput = 265 * 1024, .blink_time = 80 },
|
|
+ { .throughput = 586 * 1024, .blink_time = 50 },
|
|
+};
|
|
+#endif
|
|
+
|
|
int ath10k_mac_register(struct ath10k *ar)
|
|
{
|
|
static const u32 cipher_suites[] = {
|
|
@@ -10037,6 +10125,12 @@ int ath10k_mac_register(struct ath10k *ar)
|
|
if (test_bit(WMI_SERVICE_TDLS_UAPSD_BUFFER_STA, ar->wmi.svc_map))
|
|
ieee80211_hw_set(ar->hw, SUPPORTS_TDLS_BUFFER_STA);
|
|
|
|
+ if (ath10k_frame_mode == ATH10K_HW_TXRX_ETHERNET) {
|
|
+ if (ar->wmi.vdev_param->tx_encap_type !=
|
|
+ WMI_VDEV_PARAM_UNSUPPORTED)
|
|
+ ieee80211_hw_set(ar->hw, SUPPORTS_TX_ENCAP_OFFLOAD);
|
|
+ }
|
|
+
|
|
ar->hw->wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL;
|
|
ar->hw->wiphy->flags |= WIPHY_FLAG_HAS_CHANNEL_SWITCH;
|
|
ar->hw->wiphy->max_remain_on_channel_duration = 5000;
|
|
@@ -10211,6 +10305,12 @@ int ath10k_mac_register(struct ath10k *ar)
|
|
|
|
ar->hw->weight_multiplier = ATH10K_AIRTIME_WEIGHT_MULTIPLIER;
|
|
|
|
+#ifdef CPTCFG_MAC80211_LEDS
|
|
+ ar->led_default_trigger = ieee80211_create_tpt_led_trigger(ar->hw,
|
|
+ IEEE80211_TPT_LEDTRIG_FL_RADIO, ath10k_tpt_blink,
|
|
+ ARRAY_SIZE(ath10k_tpt_blink));
|
|
+#endif
|
|
+
|
|
ret = ieee80211_register_hw(ar->hw);
|
|
if (ret) {
|
|
ath10k_err(ar, "failed to register ieee80211: %d\n", ret);
|
|
diff --git a/drivers/net/wireless/ath/ath10k/pci.c b/drivers/net/wireless/ath/ath10k/pci.c
|
|
index f6191b5..e9e08b0 100644
|
|
--- a/drivers/net/wireless/ath/ath10k/pci.c
|
|
+++ b/drivers/net/wireless/ath/ath10k/pci.c
|
|
@@ -131,7 +131,11 @@ static const struct ce_attr pci_host_ce_config_wlan[] = {
|
|
.flags = CE_ATTR_FLAGS,
|
|
.src_nentries = 0,
|
|
.src_sz_max = 2048,
|
|
+#ifndef CONFIG_ATH10K_SMALLBUFFERS
|
|
.dest_nentries = 512,
|
|
+#else
|
|
+ .dest_nentries = 128,
|
|
+#endif
|
|
.recv_cb = ath10k_pci_htt_htc_rx_cb,
|
|
},
|
|
|
|
@@ -140,7 +144,11 @@ static const struct ce_attr pci_host_ce_config_wlan[] = {
|
|
.flags = CE_ATTR_FLAGS,
|
|
.src_nentries = 0,
|
|
.src_sz_max = 2048,
|
|
+#ifndef CONFIG_ATH10K_SMALLBUFFERS
|
|
.dest_nentries = 128,
|
|
+#else
|
|
+ .dest_nentries = 64,
|
|
+#endif
|
|
.recv_cb = ath10k_pci_htc_rx_cb,
|
|
},
|
|
|
|
@@ -167,7 +175,11 @@ static const struct ce_attr pci_host_ce_config_wlan[] = {
|
|
.flags = CE_ATTR_FLAGS,
|
|
.src_nentries = 0,
|
|
.src_sz_max = 512,
|
|
+#ifndef CONFIG_ATH10K_SMALLBUFFERS
|
|
.dest_nentries = 512,
|
|
+#else
|
|
+ .dest_nentries = 128,
|
|
+#endif
|
|
.recv_cb = ath10k_pci_htt_rx_cb,
|
|
},
|
|
|
|
@@ -192,7 +204,11 @@ static const struct ce_attr pci_host_ce_config_wlan[] = {
|
|
.flags = CE_ATTR_FLAGS,
|
|
.src_nentries = 0,
|
|
.src_sz_max = 2048,
|
|
+#ifndef CONFIG_ATH10K_SMALLBUFFERS
|
|
.dest_nentries = 128,
|
|
+#else
|
|
+ .dest_nentries = 96,
|
|
+#endif
|
|
.recv_cb = ath10k_pci_pktlog_rx_cb,
|
|
},
|
|
|
|
diff --git a/drivers/net/wireless/ath/ath10k/thermal.h b/drivers/net/wireless/ath/ath10k/thermal.h
|
|
index 5fdb020..d76c307 100644
|
|
--- a/drivers/net/wireless/ath/ath10k/thermal.h
|
|
+++ b/drivers/net/wireless/ath/ath10k/thermal.h
|
|
@@ -25,7 +25,7 @@ struct ath10k_thermal {
|
|
int temperature;
|
|
};
|
|
|
|
-#if IS_REACHABLE(CONFIG_THERMAL)
|
|
+#if IS_REACHABLE(CPTCFG_ATH10K_THERMAL)
|
|
int ath10k_thermal_register(struct ath10k *ar);
|
|
void ath10k_thermal_unregister(struct ath10k *ar);
|
|
void ath10k_thermal_event_temperature(struct ath10k *ar, int temperature);
|
|
diff --git a/drivers/net/wireless/ath/ath10k/txrx.c b/drivers/net/wireless/ath/ath10k/txrx.c
|
|
index 6f8b642..08e079e 100644
|
|
--- a/drivers/net/wireless/ath/ath10k/txrx.c
|
|
+++ b/drivers/net/wireless/ath/ath10k/txrx.c
|
|
@@ -43,6 +43,7 @@ out:
|
|
int ath10k_txrx_tx_unref(struct ath10k_htt *htt,
|
|
const struct htt_tx_done *tx_done)
|
|
{
|
|
+ struct ieee80211_tx_status status;
|
|
struct ath10k *ar = htt->ar;
|
|
struct device *dev = ar->dev;
|
|
struct ieee80211_tx_info *info;
|
|
@@ -128,7 +129,19 @@ int ath10k_txrx_tx_unref(struct ath10k_htt *htt,
|
|
info->status.is_valid_ack_signal = true;
|
|
}
|
|
|
|
- ieee80211_tx_status(htt->ar->hw, msdu);
|
|
+ memset(&status, 0, sizeof(status));
|
|
+ status.skb = msdu;
|
|
+ status.info = info;
|
|
+
|
|
+ rcu_read_lock();
|
|
+
|
|
+ if (txq)
|
|
+ status.sta = txq->sta;
|
|
+
|
|
+ ieee80211_tx_status_ext(htt->ar->hw, &status);
|
|
+
|
|
+ rcu_read_unlock();
|
|
+
|
|
/* we do not own the msdu anymore */
|
|
|
|
return 0;
|
|
diff --git a/drivers/net/wireless/ath/ath10k/wmi-ops.h b/drivers/net/wireless/ath/ath10k/wmi-ops.h
|
|
index aa57d80..f3f6b59 100644
|
|
--- a/drivers/net/wireless/ath/ath10k/wmi-ops.h
|
|
+++ b/drivers/net/wireless/ath/ath10k/wmi-ops.h
|
|
@@ -226,7 +226,10 @@ struct wmi_ops {
|
|
const struct wmi_bb_timing_cfg_arg *arg);
|
|
struct sk_buff *(*gen_per_peer_per_tid_cfg)(struct ath10k *ar,
|
|
const struct wmi_per_peer_per_tid_cfg_arg *arg);
|
|
+ struct sk_buff *(*gen_gpio_config)(struct ath10k *ar, u32 gpio_num,
|
|
+ u32 input, u32 pull_type, u32 intr_mode);
|
|
|
|
+ struct sk_buff *(*gen_gpio_output)(struct ath10k *ar, u32 gpio_num, u32 set);
|
|
};
|
|
|
|
int ath10k_wmi_cmd_send(struct ath10k *ar, struct sk_buff *skb, u32 cmd_id);
|
|
@@ -1122,6 +1125,35 @@ ath10k_wmi_force_fw_hang(struct ath10k *ar,
|
|
return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->force_fw_hang_cmdid);
|
|
}
|
|
|
|
+static inline int ath10k_wmi_gpio_config(struct ath10k *ar, u32 gpio_num,
|
|
+ u32 input, u32 pull_type, u32 intr_mode)
|
|
+{
|
|
+ struct sk_buff *skb;
|
|
+
|
|
+ if (!ar->wmi.ops->gen_gpio_config)
|
|
+ return -EOPNOTSUPP;
|
|
+
|
|
+ skb = ar->wmi.ops->gen_gpio_config(ar, gpio_num, input, pull_type, intr_mode);
|
|
+ if (IS_ERR(skb))
|
|
+ return PTR_ERR(skb);
|
|
+
|
|
+ return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->gpio_config_cmdid);
|
|
+}
|
|
+
|
|
+static inline int ath10k_wmi_gpio_output(struct ath10k *ar, u32 gpio_num, u32 set)
|
|
+{
|
|
+ struct sk_buff *skb;
|
|
+
|
|
+ if (!ar->wmi.ops->gen_gpio_config)
|
|
+ return -EOPNOTSUPP;
|
|
+
|
|
+ skb = ar->wmi.ops->gen_gpio_output(ar, gpio_num, set);
|
|
+ if (IS_ERR(skb))
|
|
+ return PTR_ERR(skb);
|
|
+
|
|
+ return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->gpio_output_cmdid);
|
|
+}
|
|
+
|
|
static inline int
|
|
ath10k_wmi_dbglog_cfg(struct ath10k *ar, u64 module_enable, u32 log_level)
|
|
{
|
|
diff --git a/drivers/net/wireless/ath/ath10k/wmi-tlv.c b/drivers/net/wireless/ath/ath10k/wmi-tlv.c
|
|
index 7efbe03..6a391b2 100644
|
|
--- a/drivers/net/wireless/ath/ath10k/wmi-tlv.c
|
|
+++ b/drivers/net/wireless/ath/ath10k/wmi-tlv.c
|
|
@@ -4594,6 +4594,8 @@ static const struct wmi_ops wmi_tlv_ops = {
|
|
.gen_echo = ath10k_wmi_tlv_op_gen_echo,
|
|
.gen_vdev_spectral_conf = ath10k_wmi_tlv_op_gen_vdev_spectral_conf,
|
|
.gen_vdev_spectral_enable = ath10k_wmi_tlv_op_gen_vdev_spectral_enable,
|
|
+ /* .gen_gpio_config not implemented */
|
|
+ /* .gen_gpio_output not implemented */
|
|
};
|
|
|
|
static const struct wmi_peer_flags_map wmi_tlv_peer_flags_map = {
|
|
diff --git a/drivers/net/wireless/ath/ath10k/wmi.c b/drivers/net/wireless/ath/ath10k/wmi.c
|
|
index 416f2b9..ed57499 100644
|
|
--- a/drivers/net/wireless/ath/ath10k/wmi.c
|
|
+++ b/drivers/net/wireless/ath/ath10k/wmi.c
|
|
@@ -7472,6 +7472,49 @@ ath10k_wmi_op_gen_peer_set_param(struct ath10k *ar, u32 vdev_id,
|
|
return skb;
|
|
}
|
|
|
|
+static struct sk_buff *ath10k_wmi_op_gen_gpio_config(struct ath10k *ar,
|
|
+ u32 gpio_num, u32 input,
|
|
+ u32 pull_type, u32 intr_mode)
|
|
+{
|
|
+ struct wmi_gpio_config_cmd *cmd;
|
|
+ struct sk_buff *skb;
|
|
+
|
|
+ skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd));
|
|
+ if (!skb)
|
|
+ return ERR_PTR(-ENOMEM);
|
|
+
|
|
+ cmd = (struct wmi_gpio_config_cmd *)skb->data;
|
|
+ cmd->pull_type = __cpu_to_le32(pull_type);
|
|
+ cmd->gpio_num = __cpu_to_le32(gpio_num);
|
|
+ cmd->input = __cpu_to_le32(input);
|
|
+ cmd->intr_mode = __cpu_to_le32(intr_mode);
|
|
+
|
|
+ ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi gpio_config gpio_num 0x%08x input 0x%08x pull_type 0x%08x intr_mode 0x%08x\n",
|
|
+ gpio_num, input, pull_type, intr_mode);
|
|
+
|
|
+ return skb;
|
|
+}
|
|
+
|
|
+static struct sk_buff *ath10k_wmi_op_gen_gpio_output(struct ath10k *ar,
|
|
+ u32 gpio_num, u32 set)
|
|
+{
|
|
+ struct wmi_gpio_output_cmd *cmd;
|
|
+ struct sk_buff *skb;
|
|
+
|
|
+ skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd));
|
|
+ if (!skb)
|
|
+ return ERR_PTR(-ENOMEM);
|
|
+
|
|
+ cmd = (struct wmi_gpio_output_cmd *)skb->data;
|
|
+ cmd->gpio_num = __cpu_to_le32(gpio_num);
|
|
+ cmd->set = __cpu_to_le32(set);
|
|
+
|
|
+ ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi gpio_output gpio_num 0x%08x set 0x%08x\n",
|
|
+ gpio_num, set);
|
|
+
|
|
+ return skb;
|
|
+}
|
|
+
|
|
static struct sk_buff *
|
|
ath10k_wmi_op_gen_set_psmode(struct ath10k *ar, u32 vdev_id,
|
|
enum wmi_sta_ps_mode psmode)
|
|
@@ -9160,6 +9203,9 @@ static const struct wmi_ops wmi_ops = {
|
|
.fw_stats_fill = ath10k_wmi_main_op_fw_stats_fill,
|
|
.get_vdev_subtype = ath10k_wmi_op_get_vdev_subtype,
|
|
.gen_echo = ath10k_wmi_op_gen_echo,
|
|
+ .gen_gpio_config = ath10k_wmi_op_gen_gpio_config,
|
|
+ .gen_gpio_output = ath10k_wmi_op_gen_gpio_output,
|
|
+
|
|
/* .gen_bcn_tmpl not implemented */
|
|
/* .gen_prb_tmpl not implemented */
|
|
/* .gen_p2p_go_bcn_ie not implemented */
|
|
@@ -9230,6 +9276,8 @@ static const struct wmi_ops wmi_10_1_ops = {
|
|
.fw_stats_fill = ath10k_wmi_10x_op_fw_stats_fill,
|
|
.get_vdev_subtype = ath10k_wmi_op_get_vdev_subtype,
|
|
.gen_echo = ath10k_wmi_op_gen_echo,
|
|
+ .gen_gpio_config = ath10k_wmi_op_gen_gpio_config,
|
|
+ .gen_gpio_output = ath10k_wmi_op_gen_gpio_output,
|
|
/* .gen_bcn_tmpl not implemented */
|
|
/* .gen_prb_tmpl not implemented */
|
|
/* .gen_p2p_go_bcn_ie not implemented */
|
|
@@ -9302,6 +9350,8 @@ static const struct wmi_ops wmi_10_2_ops = {
|
|
.gen_delba_send = ath10k_wmi_op_gen_delba_send,
|
|
.fw_stats_fill = ath10k_wmi_10x_op_fw_stats_fill,
|
|
.get_vdev_subtype = ath10k_wmi_op_get_vdev_subtype,
|
|
+ .gen_gpio_config = ath10k_wmi_op_gen_gpio_config,
|
|
+ .gen_gpio_output = ath10k_wmi_op_gen_gpio_output,
|
|
/* .gen_pdev_enable_adaptive_cca not implemented */
|
|
};
|
|
|
|
@@ -9373,6 +9423,8 @@ static const struct wmi_ops wmi_10_2_4_ops = {
|
|
ath10k_wmi_op_gen_pdev_enable_adaptive_cca,
|
|
.get_vdev_subtype = ath10k_wmi_10_2_4_op_get_vdev_subtype,
|
|
.gen_bb_timing = ath10k_wmi_10_2_4_op_gen_bb_timing,
|
|
+ .gen_gpio_config = ath10k_wmi_op_gen_gpio_config,
|
|
+ .gen_gpio_output = ath10k_wmi_op_gen_gpio_output,
|
|
/* .gen_bcn_tmpl not implemented */
|
|
/* .gen_prb_tmpl not implemented */
|
|
/* .gen_p2p_go_bcn_ie not implemented */
|
|
@@ -9454,6 +9506,8 @@ static const struct wmi_ops wmi_10_4_ops = {
|
|
.gen_pdev_bss_chan_info_req = ath10k_wmi_10_2_op_gen_pdev_bss_chan_info,
|
|
.gen_echo = ath10k_wmi_op_gen_echo,
|
|
.gen_pdev_get_tpc_config = ath10k_wmi_10_2_4_op_gen_pdev_get_tpc_config,
|
|
+ .gen_gpio_config = ath10k_wmi_op_gen_gpio_config,
|
|
+ .gen_gpio_output = ath10k_wmi_op_gen_gpio_output,
|
|
};
|
|
|
|
int ath10k_wmi_attach(struct ath10k *ar)
|
|
diff --git a/drivers/net/wireless/ath/ath10k/wmi.h b/drivers/net/wireless/ath/ath10k/wmi.h
|
|
index 01bfd09..1a39a9a 100644
|
|
--- a/drivers/net/wireless/ath/ath10k/wmi.h
|
|
+++ b/drivers/net/wireless/ath/ath10k/wmi.h
|
|
@@ -3030,6 +3030,41 @@ enum wmi_10_4_feature_mask {
|
|
|
|
};
|
|
|
|
+/* WMI_GPIO_CONFIG_CMDID */
|
|
+enum {
|
|
+ WMI_GPIO_PULL_NONE,
|
|
+ WMI_GPIO_PULL_UP,
|
|
+ WMI_GPIO_PULL_DOWN,
|
|
+};
|
|
+
|
|
+enum {
|
|
+ WMI_GPIO_INTTYPE_DISABLE,
|
|
+ WMI_GPIO_INTTYPE_RISING_EDGE,
|
|
+ WMI_GPIO_INTTYPE_FALLING_EDGE,
|
|
+ WMI_GPIO_INTTYPE_BOTH_EDGE,
|
|
+ WMI_GPIO_INTTYPE_LEVEL_LOW,
|
|
+ WMI_GPIO_INTTYPE_LEVEL_HIGH
|
|
+};
|
|
+
|
|
+/* WMI_GPIO_CONFIG_CMDID */
|
|
+struct wmi_gpio_config_cmd {
|
|
+ __le32 gpio_num; /* GPIO number to be setup */
|
|
+ __le32 input; /* 0 - Output/ 1 - Input */
|
|
+ __le32 pull_type; /* Pull type defined above */
|
|
+ __le32 intr_mode; /* Interrupt mode defined above (Input) */
|
|
+} __packed;
|
|
+
|
|
+/* WMI_GPIO_OUTPUT_CMDID */
|
|
+struct wmi_gpio_output_cmd {
|
|
+ __le32 gpio_num; /* GPIO number to be setup */
|
|
+ __le32 set; /* Set the GPIO pin*/
|
|
+} __packed;
|
|
+
|
|
+/* WMI_GPIO_INPUT_EVENTID */
|
|
+struct wmi_gpio_input_event {
|
|
+ __le32 gpio_num; /* GPIO number which changed state */
|
|
+} __packed;
|
|
+
|
|
struct wmi_ext_resource_config_10_4_cmd {
|
|
/* contains enum wmi_host_platform_type */
|
|
__le32 host_platform_config;
|
|
diff --git a/local-symbols b/local-symbols
|
|
index 395c284..ee80d12 100644
|
|
--- a/local-symbols
|
|
+++ b/local-symbols
|
|
@@ -165,6 +165,8 @@ ATH10K_SNOC=
|
|
ATH10K_DEBUG=
|
|
ATH10K_DEBUGFS=
|
|
ATH10K_SPECTRAL=
|
|
+ATH10K_THERMAL=
|
|
+ATH10K_LEDS=
|
|
ATH10K_TRACING=
|
|
ATH10K_DFS_CERTIFIED=
|
|
WCN36XX=
|