Merge ath-next from ath.git
Major changes in ath10k: * Device tree support * Major restructuring how to handle different WMI interface versions * Add WMI TLV interface in preparation for new firmware interface support * Support new firmware branch 10.2.4 * Add thermal cooling interface * Add hwmon interface to read temparture from the device And of course lots of small fixes and cleanups.
This commit is contained in:
commit
350b193ebd
|
@ -0,0 +1,30 @@
|
|||
* Qualcomm Atheros ath10k wireless devices
|
||||
|
||||
For ath10k devices the calibration data can be provided through Device
|
||||
Tree. The node is a child node of the PCI controller.
|
||||
|
||||
Required properties:
|
||||
-compatible : Should be "qcom,ath10k"
|
||||
|
||||
Optional properties:
|
||||
- qcom,ath10k-calibration-data : calibration data as an array, the
|
||||
length can vary between hw versions
|
||||
|
||||
|
||||
Example:
|
||||
|
||||
pci {
|
||||
pcie@0 {
|
||||
reg = <0 0 0 0 0>;
|
||||
#interrupt-cells = <1>;
|
||||
#size-cells = <2>;
|
||||
#address-cells = <3>;
|
||||
device_type = "pci";
|
||||
|
||||
ath10k@0,0 {
|
||||
reg = <0 0 0 0 0>;
|
||||
device_type = "pci";
|
||||
qcom,ath10k-calibration-data = [ 01 02 03 ... ];
|
||||
};
|
||||
};
|
||||
};
|
|
@ -8,11 +8,13 @@ ath10k_core-y += mac.o \
|
|||
htt_tx.o \
|
||||
txrx.o \
|
||||
wmi.o \
|
||||
wmi-tlv.o \
|
||||
bmi.o
|
||||
|
||||
ath10k_core-$(CONFIG_ATH10K_DEBUGFS) += spectral.o
|
||||
ath10k_core-$(CONFIG_NL80211_TESTMODE) += testmode.o
|
||||
ath10k_core-$(CONFIG_ATH10K_TRACING) += trace.o
|
||||
ath10k_core-$(CONFIG_THERMAL) += thermal.o
|
||||
|
||||
obj-$(CONFIG_ATH10K_PCI) += ath10k_pci.o
|
||||
ath10k_pci-y += pci.o \
|
||||
|
|
|
@ -1093,6 +1093,8 @@ int ath10k_ce_alloc_pipe(struct ath10k *ar, int ce_id,
|
|||
(CE_HTT_H2T_MSG_SRC_NENTRIES - 1));
|
||||
BUILD_BUG_ON(2*TARGET_10X_NUM_MSDU_DESC >
|
||||
(CE_HTT_H2T_MSG_SRC_NENTRIES - 1));
|
||||
BUILD_BUG_ON(2*TARGET_TLV_NUM_MSDU_DESC >
|
||||
(CE_HTT_H2T_MSG_SRC_NENTRIES - 1));
|
||||
|
||||
ce_state->ar = ar;
|
||||
ce_state->id = ce_id;
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
|
||||
#include <linux/module.h>
|
||||
#include <linux/firmware.h>
|
||||
#include <linux/of.h>
|
||||
|
||||
#include "core.h"
|
||||
#include "mac.h"
|
||||
|
@ -27,20 +28,18 @@
|
|||
#include "debug.h"
|
||||
#include "htt.h"
|
||||
#include "testmode.h"
|
||||
#include "wmi-ops.h"
|
||||
|
||||
unsigned int ath10k_debug_mask;
|
||||
static bool uart_print;
|
||||
static unsigned int ath10k_p2p;
|
||||
static bool skip_otp;
|
||||
|
||||
module_param_named(debug_mask, ath10k_debug_mask, uint, 0644);
|
||||
module_param(uart_print, bool, 0644);
|
||||
module_param_named(p2p, ath10k_p2p, uint, 0644);
|
||||
module_param(skip_otp, bool, 0644);
|
||||
|
||||
MODULE_PARM_DESC(debug_mask, "Debugging mask");
|
||||
MODULE_PARM_DESC(uart_print, "Uart target debugging");
|
||||
MODULE_PARM_DESC(p2p, "Enable ath10k P2P support");
|
||||
MODULE_PARM_DESC(skip_otp, "Skip otp failure for calibration in testmode");
|
||||
|
||||
static const struct ath10k_hw_params ath10k_hw_params_list[] = {
|
||||
|
@ -48,11 +47,14 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
|
|||
.id = QCA988X_HW_2_0_VERSION,
|
||||
.name = "qca988x hw2.0",
|
||||
.patch_load_addr = QCA988X_HW_2_0_PATCH_LOAD_ADDR,
|
||||
.uart_pin = 7,
|
||||
.fw = {
|
||||
.dir = QCA988X_HW_2_0_FW_DIR,
|
||||
.fw = QCA988X_HW_2_0_FW_FILE,
|
||||
.otp = QCA988X_HW_2_0_OTP_FILE,
|
||||
.board = QCA988X_HW_2_0_BOARD_DATA_FILE,
|
||||
.board_size = QCA988X_BOARD_DATA_SZ,
|
||||
.board_ext_size = QCA988X_BOARD_EXT_DATA_SZ,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
@ -146,8 +148,8 @@ static const struct firmware *ath10k_fetch_fw_file(struct ath10k *ar,
|
|||
static int ath10k_push_board_ext_data(struct ath10k *ar, const void *data,
|
||||
size_t data_len)
|
||||
{
|
||||
u32 board_data_size = QCA988X_BOARD_DATA_SZ;
|
||||
u32 board_ext_data_size = QCA988X_BOARD_EXT_DATA_SZ;
|
||||
u32 board_data_size = ar->hw_params.fw.board_size;
|
||||
u32 board_ext_data_size = ar->hw_params.fw.board_ext_size;
|
||||
u32 board_ext_data_addr;
|
||||
int ret;
|
||||
|
||||
|
@ -193,7 +195,7 @@ static int ath10k_push_board_ext_data(struct ath10k *ar, const void *data,
|
|||
static int ath10k_download_board_data(struct ath10k *ar, const void *data,
|
||||
size_t data_len)
|
||||
{
|
||||
u32 board_data_size = QCA988X_BOARD_DATA_SZ;
|
||||
u32 board_data_size = ar->hw_params.fw.board_size;
|
||||
u32 address;
|
||||
int ret;
|
||||
|
||||
|
@ -249,6 +251,63 @@ static int ath10k_download_cal_file(struct ath10k *ar)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int ath10k_download_cal_dt(struct ath10k *ar)
|
||||
{
|
||||
struct device_node *node;
|
||||
int data_len;
|
||||
void *data;
|
||||
int ret;
|
||||
|
||||
node = ar->dev->of_node;
|
||||
if (!node)
|
||||
/* Device Tree is optional, don't print any warnings if
|
||||
* there's no node for ath10k.
|
||||
*/
|
||||
return -ENOENT;
|
||||
|
||||
if (!of_get_property(node, "qcom,ath10k-calibration-data",
|
||||
&data_len)) {
|
||||
/* The calibration data node is optional */
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
if (data_len != QCA988X_CAL_DATA_LEN) {
|
||||
ath10k_warn(ar, "invalid calibration data length in DT: %d\n",
|
||||
data_len);
|
||||
ret = -EMSGSIZE;
|
||||
goto out;
|
||||
}
|
||||
|
||||
data = kmalloc(data_len, GFP_KERNEL);
|
||||
if (!data) {
|
||||
ret = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = of_property_read_u8_array(node, "qcom,ath10k-calibration-data",
|
||||
data, data_len);
|
||||
if (ret) {
|
||||
ath10k_warn(ar, "failed to read calibration data from DT: %d\n",
|
||||
ret);
|
||||
goto out_free;
|
||||
}
|
||||
|
||||
ret = ath10k_download_board_data(ar, data, data_len);
|
||||
if (ret) {
|
||||
ath10k_warn(ar, "failed to download calibration data from Device Tree: %d\n",
|
||||
ret);
|
||||
goto out_free;
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
|
||||
out_free:
|
||||
kfree(data);
|
||||
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int ath10k_download_and_run_otp(struct ath10k *ar)
|
||||
{
|
||||
u32 result, address = ar->hw_params.patch_load_addr;
|
||||
|
@ -447,7 +506,7 @@ static int ath10k_core_fetch_firmware_api_n(struct ath10k *ar, const char *name)
|
|||
int ie_id, i, index, bit, ret;
|
||||
struct ath10k_fw_ie *hdr;
|
||||
const u8 *data;
|
||||
__le32 *timestamp;
|
||||
__le32 *timestamp, *version;
|
||||
|
||||
/* first fetch the firmware file (firmware-*.bin) */
|
||||
ar->firmware = ath10k_fetch_fw_file(ar, ar->hw_params.fw.dir, name);
|
||||
|
@ -562,6 +621,17 @@ static int ath10k_core_fetch_firmware_api_n(struct ath10k *ar, const char *name)
|
|||
ar->otp_len = ie_len;
|
||||
|
||||
break;
|
||||
case ATH10K_FW_IE_WMI_OP_VERSION:
|
||||
if (ie_len != sizeof(u32))
|
||||
break;
|
||||
|
||||
version = (__le32 *)data;
|
||||
|
||||
ar->wmi.op_version = le32_to_cpup(version);
|
||||
|
||||
ath10k_dbg(ar, ATH10K_DBG_BOOT, "found fw ie wmi op version %d\n",
|
||||
ar->wmi.op_version);
|
||||
break;
|
||||
default:
|
||||
ath10k_warn(ar, "Unknown FW IE: %u\n",
|
||||
le32_to_cpu(hdr->id));
|
||||
|
@ -582,13 +652,6 @@ static int ath10k_core_fetch_firmware_api_n(struct ath10k *ar, const char *name)
|
|||
goto err;
|
||||
}
|
||||
|
||||
if (test_bit(ATH10K_FW_FEATURE_WMI_10_2, ar->fw_features) &&
|
||||
!test_bit(ATH10K_FW_FEATURE_WMI_10X, ar->fw_features)) {
|
||||
ath10k_err(ar, "feature bits corrupted: 10.2 feature requires 10.x feature to be set as well");
|
||||
ret = -EINVAL;
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* now fetch the board file */
|
||||
if (ar->hw_params.fw.board == NULL) {
|
||||
ath10k_err(ar, "board data file not defined");
|
||||
|
@ -624,6 +687,13 @@ static int ath10k_core_fetch_firmware_files(struct ath10k *ar)
|
|||
/* calibration file is optional, don't check for any errors */
|
||||
ath10k_fetch_cal_file(ar);
|
||||
|
||||
ar->fw_api = 4;
|
||||
ath10k_dbg(ar, ATH10K_DBG_BOOT, "trying fw api %d\n", ar->fw_api);
|
||||
|
||||
ret = ath10k_core_fetch_firmware_api_n(ar, ATH10K_FW_API4_FILE);
|
||||
if (ret == 0)
|
||||
goto success;
|
||||
|
||||
ar->fw_api = 3;
|
||||
ath10k_dbg(ar, ATH10K_DBG_BOOT, "trying fw api %d\n", ar->fw_api);
|
||||
|
||||
|
@ -662,7 +732,17 @@ static int ath10k_download_cal_data(struct ath10k *ar)
|
|||
}
|
||||
|
||||
ath10k_dbg(ar, ATH10K_DBG_BOOT,
|
||||
"boot did not find a calibration file, try OTP next: %d\n",
|
||||
"boot did not find a calibration file, try DT next: %d\n",
|
||||
ret);
|
||||
|
||||
ret = ath10k_download_cal_dt(ar);
|
||||
if (ret == 0) {
|
||||
ar->cal_mode = ATH10K_CAL_MODE_DT;
|
||||
goto done;
|
||||
}
|
||||
|
||||
ath10k_dbg(ar, ATH10K_DBG_BOOT,
|
||||
"boot did not find DT entry, try OTP next: %d\n",
|
||||
ret);
|
||||
|
||||
ret = ath10k_download_and_run_otp(ar);
|
||||
|
@ -696,7 +776,7 @@ static int ath10k_init_uart(struct ath10k *ar)
|
|||
if (!uart_print)
|
||||
return 0;
|
||||
|
||||
ret = ath10k_bmi_write32(ar, hi_dbg_uart_txpin, 7);
|
||||
ret = ath10k_bmi_write32(ar, hi_dbg_uart_txpin, ar->hw_params.uart_pin);
|
||||
if (ret) {
|
||||
ath10k_warn(ar, "could not enable UART prints (%d)\n", ret);
|
||||
return ret;
|
||||
|
@ -764,6 +844,7 @@ static void ath10k_core_restart(struct work_struct *work)
|
|||
complete_all(&ar->offchan_tx_completed);
|
||||
complete_all(&ar->install_key_done);
|
||||
complete_all(&ar->vdev_setup_done);
|
||||
complete_all(&ar->thermal.wmi_sync);
|
||||
wake_up(&ar->htt.empty_tx_wq);
|
||||
wake_up(&ar->wmi.tx_credits_wq);
|
||||
wake_up(&ar->peer_mapping_wq);
|
||||
|
@ -799,15 +880,62 @@ static void ath10k_core_restart(struct work_struct *work)
|
|||
mutex_unlock(&ar->conf_mutex);
|
||||
}
|
||||
|
||||
static void ath10k_core_init_max_sta_count(struct ath10k *ar)
|
||||
static int ath10k_core_init_firmware_features(struct ath10k *ar)
|
||||
{
|
||||
if (test_bit(ATH10K_FW_FEATURE_WMI_10X, ar->fw_features)) {
|
||||
ar->max_num_peers = TARGET_10X_NUM_PEERS;
|
||||
ar->max_num_stations = TARGET_10X_NUM_STATIONS;
|
||||
} else {
|
||||
if (test_bit(ATH10K_FW_FEATURE_WMI_10_2, ar->fw_features) &&
|
||||
!test_bit(ATH10K_FW_FEATURE_WMI_10X, ar->fw_features)) {
|
||||
ath10k_err(ar, "feature bits corrupted: 10.2 feature requires 10.x feature to be set as well");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (ar->wmi.op_version >= ATH10K_FW_WMI_OP_VERSION_MAX) {
|
||||
ath10k_err(ar, "unsupported WMI OP version (max %d): %d\n",
|
||||
ATH10K_FW_WMI_OP_VERSION_MAX, ar->wmi.op_version);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Backwards compatibility for firmwares without
|
||||
* ATH10K_FW_IE_WMI_OP_VERSION.
|
||||
*/
|
||||
if (ar->wmi.op_version == ATH10K_FW_WMI_OP_VERSION_UNSET) {
|
||||
if (test_bit(ATH10K_FW_FEATURE_WMI_10X, ar->fw_features)) {
|
||||
if (test_bit(ATH10K_FW_FEATURE_WMI_10_2,
|
||||
ar->fw_features))
|
||||
ar->wmi.op_version = ATH10K_FW_WMI_OP_VERSION_10_2;
|
||||
else
|
||||
ar->wmi.op_version = ATH10K_FW_WMI_OP_VERSION_10_1;
|
||||
} else {
|
||||
ar->wmi.op_version = ATH10K_FW_WMI_OP_VERSION_MAIN;
|
||||
}
|
||||
}
|
||||
|
||||
switch (ar->wmi.op_version) {
|
||||
case ATH10K_FW_WMI_OP_VERSION_MAIN:
|
||||
ar->max_num_peers = TARGET_NUM_PEERS;
|
||||
ar->max_num_stations = TARGET_NUM_STATIONS;
|
||||
ar->max_num_vdevs = TARGET_NUM_VDEVS;
|
||||
ar->htt.max_num_pending_tx = TARGET_NUM_MSDU_DESC;
|
||||
break;
|
||||
case ATH10K_FW_WMI_OP_VERSION_10_1:
|
||||
case ATH10K_FW_WMI_OP_VERSION_10_2:
|
||||
case ATH10K_FW_WMI_OP_VERSION_10_2_4:
|
||||
ar->max_num_peers = TARGET_10X_NUM_PEERS;
|
||||
ar->max_num_stations = TARGET_10X_NUM_STATIONS;
|
||||
ar->max_num_vdevs = TARGET_10X_NUM_VDEVS;
|
||||
ar->htt.max_num_pending_tx = TARGET_10X_NUM_MSDU_DESC;
|
||||
break;
|
||||
case ATH10K_FW_WMI_OP_VERSION_TLV:
|
||||
ar->max_num_peers = TARGET_TLV_NUM_PEERS;
|
||||
ar->max_num_stations = TARGET_TLV_NUM_STATIONS;
|
||||
ar->htt.max_num_pending_tx = TARGET_TLV_NUM_MSDU_DESC;
|
||||
break;
|
||||
case ATH10K_FW_WMI_OP_VERSION_UNSET:
|
||||
case ATH10K_FW_WMI_OP_VERSION_MAX:
|
||||
WARN_ON(1);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ath10k_core_start(struct ath10k *ar, enum ath10k_firmware_mode mode)
|
||||
|
@ -945,10 +1073,7 @@ int ath10k_core_start(struct ath10k *ar, enum ath10k_firmware_mode mode)
|
|||
if (status)
|
||||
goto err_hif_stop;
|
||||
|
||||
if (test_bit(ATH10K_FW_FEATURE_WMI_10X, ar->fw_features))
|
||||
ar->free_vdev_map = (1LL << TARGET_10X_NUM_VDEVS) - 1;
|
||||
else
|
||||
ar->free_vdev_map = (1LL << TARGET_NUM_VDEVS) - 1;
|
||||
ar->free_vdev_map = (1LL << ar->max_num_vdevs) - 1;
|
||||
|
||||
INIT_LIST_HEAD(&ar->arvifs);
|
||||
|
||||
|
@ -1025,8 +1150,7 @@ static int ath10k_core_probe_fw(struct ath10k *ar)
|
|||
ret = ath10k_bmi_get_target_info(ar, &target_info);
|
||||
if (ret) {
|
||||
ath10k_err(ar, "could not get target info (%d)\n", ret);
|
||||
ath10k_hif_power_down(ar);
|
||||
return ret;
|
||||
goto err_power_down;
|
||||
}
|
||||
|
||||
ar->target_version = target_info.version;
|
||||
|
@ -1035,28 +1159,28 @@ static int ath10k_core_probe_fw(struct ath10k *ar)
|
|||
ret = ath10k_init_hw_params(ar);
|
||||
if (ret) {
|
||||
ath10k_err(ar, "could not get hw params (%d)\n", ret);
|
||||
ath10k_hif_power_down(ar);
|
||||
return ret;
|
||||
goto err_power_down;
|
||||
}
|
||||
|
||||
ret = ath10k_core_fetch_firmware_files(ar);
|
||||
if (ret) {
|
||||
ath10k_err(ar, "could not fetch firmware files (%d)\n", ret);
|
||||
ath10k_hif_power_down(ar);
|
||||
return ret;
|
||||
goto err_power_down;
|
||||
}
|
||||
|
||||
ath10k_core_init_max_sta_count(ar);
|
||||
ret = ath10k_core_init_firmware_features(ar);
|
||||
if (ret) {
|
||||
ath10k_err(ar, "fatal problem with firmware features: %d\n",
|
||||
ret);
|
||||
goto err_free_firmware_files;
|
||||
}
|
||||
|
||||
mutex_lock(&ar->conf_mutex);
|
||||
|
||||
ret = ath10k_core_start(ar, ATH10K_FIRMWARE_MODE_NORMAL);
|
||||
if (ret) {
|
||||
ath10k_err(ar, "could not init core (%d)\n", ret);
|
||||
ath10k_core_free_firmware_files(ar);
|
||||
ath10k_hif_power_down(ar);
|
||||
mutex_unlock(&ar->conf_mutex);
|
||||
return ret;
|
||||
goto err_unlock;
|
||||
}
|
||||
|
||||
ath10k_print_driver_info(ar);
|
||||
|
@ -1066,34 +1190,17 @@ static int ath10k_core_probe_fw(struct ath10k *ar)
|
|||
|
||||
ath10k_hif_power_down(ar);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ath10k_core_check_chip_id(struct ath10k *ar)
|
||||
{
|
||||
u32 hw_revision = MS(ar->chip_id, SOC_CHIP_ID_REV);
|
||||
err_unlock:
|
||||
mutex_unlock(&ar->conf_mutex);
|
||||
|
||||
ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot chip_id 0x%08x hw_revision 0x%x\n",
|
||||
ar->chip_id, hw_revision);
|
||||
err_free_firmware_files:
|
||||
ath10k_core_free_firmware_files(ar);
|
||||
|
||||
/* Check that we are not using hw1.0 (some of them have same pci id
|
||||
* as hw2.0) before doing anything else as ath10k crashes horribly
|
||||
* due to missing hw1.0 workarounds. */
|
||||
switch (hw_revision) {
|
||||
case QCA988X_HW_1_0_CHIP_ID_REV:
|
||||
ath10k_err(ar, "ERROR: qca988x hw1.0 is not supported\n");
|
||||
return -EOPNOTSUPP;
|
||||
err_power_down:
|
||||
ath10k_hif_power_down(ar);
|
||||
|
||||
case QCA988X_HW_2_0_CHIP_ID_REV:
|
||||
/* known hardware revision, continue normally */
|
||||
return 0;
|
||||
|
||||
default:
|
||||
ath10k_warn(ar, "Warning: hardware revision unknown (0x%x), expect problems\n",
|
||||
ar->chip_id);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void ath10k_core_register_work(struct work_struct *work)
|
||||
|
@ -1125,9 +1232,18 @@ static void ath10k_core_register_work(struct work_struct *work)
|
|||
goto err_debug_destroy;
|
||||
}
|
||||
|
||||
status = ath10k_thermal_register(ar);
|
||||
if (status) {
|
||||
ath10k_err(ar, "could not register thermal device: %d\n",
|
||||
status);
|
||||
goto err_spectral_destroy;
|
||||
}
|
||||
|
||||
set_bit(ATH10K_FLAG_CORE_REGISTERED, &ar->dev_flags);
|
||||
return;
|
||||
|
||||
err_spectral_destroy:
|
||||
ath10k_spectral_destroy(ar);
|
||||
err_debug_destroy:
|
||||
ath10k_debug_destroy(ar);
|
||||
err_unregister_mac:
|
||||
|
@ -1143,16 +1259,7 @@ static void ath10k_core_register_work(struct work_struct *work)
|
|||
|
||||
int ath10k_core_register(struct ath10k *ar, u32 chip_id)
|
||||
{
|
||||
int status;
|
||||
|
||||
ar->chip_id = chip_id;
|
||||
|
||||
status = ath10k_core_check_chip_id(ar);
|
||||
if (status) {
|
||||
ath10k_err(ar, "Unsupported chip id 0x%08x\n", ar->chip_id);
|
||||
return status;
|
||||
}
|
||||
|
||||
queue_work(ar->workqueue, &ar->register_work);
|
||||
|
||||
return 0;
|
||||
|
@ -1166,6 +1273,7 @@ void ath10k_core_unregister(struct ath10k *ar)
|
|||
if (!test_bit(ATH10K_FLAG_CORE_REGISTERED, &ar->dev_flags))
|
||||
return;
|
||||
|
||||
ath10k_thermal_unregister(ar);
|
||||
/* Stop spectral before unregistering from mac80211 to remove the
|
||||
* relayfs debugfs file cleanly. Otherwise the parent debugfs tree
|
||||
* would be already be free'd recursively, leading to a double free.
|
||||
|
@ -1198,10 +1306,7 @@ struct ath10k *ath10k_core_create(size_t priv_size, struct device *dev,
|
|||
|
||||
ar->ath_common.priv = ar;
|
||||
ar->ath_common.hw = ar->hw;
|
||||
|
||||
ar->p2p = !!ath10k_p2p;
|
||||
ar->dev = dev;
|
||||
|
||||
ar->hif.ops = hif_ops;
|
||||
ar->hif.bus = bus;
|
||||
|
||||
|
@ -1212,6 +1317,7 @@ struct ath10k *ath10k_core_create(size_t priv_size, struct device *dev,
|
|||
|
||||
init_completion(&ar->install_key_done);
|
||||
init_completion(&ar->vdev_setup_done);
|
||||
init_completion(&ar->thermal.wmi_sync);
|
||||
|
||||
INIT_DELAYED_WORK(&ar->scan.timeout, ath10k_scan_timeout_work);
|
||||
|
||||
|
|
|
@ -34,6 +34,7 @@
|
|||
#include "../regd.h"
|
||||
#include "../dfs_pattern_detector.h"
|
||||
#include "spectral.h"
|
||||
#include "thermal.h"
|
||||
|
||||
#define MS(_v, _f) (((_v) & _f##_MASK) >> _f##_LSB)
|
||||
#define SM(_v, _f) (((_v) << _f##_LSB) & _f##_MASK)
|
||||
|
@ -120,6 +121,7 @@ struct ath10k_mem_chunk {
|
|||
};
|
||||
|
||||
struct ath10k_wmi {
|
||||
enum ath10k_fw_wmi_op_version op_version;
|
||||
enum ath10k_htc_ep_id eid;
|
||||
struct completion service_ready;
|
||||
struct completion unified_ready;
|
||||
|
@ -128,6 +130,7 @@ struct ath10k_wmi {
|
|||
struct wmi_cmd_map *cmd;
|
||||
struct wmi_vdev_param_map *vdev_param;
|
||||
struct wmi_pdev_param_map *pdev_param;
|
||||
const struct wmi_ops *ops;
|
||||
|
||||
u32 num_mem_chunks;
|
||||
struct ath10k_mem_chunk mem_chunks[WMI_MAX_MEM_REQS];
|
||||
|
@ -325,6 +328,7 @@ struct ath10k_debug {
|
|||
u32 fw_dbglog_mask;
|
||||
u32 pktlog_filter;
|
||||
u32 reg_addr;
|
||||
u32 nf_cal_period;
|
||||
|
||||
u8 htt_max_amsdu;
|
||||
u8 htt_max_ampdu;
|
||||
|
@ -369,7 +373,7 @@ enum ath10k_fw_features {
|
|||
/* wmi_mgmt_rx_hdr contains extra RSSI information */
|
||||
ATH10K_FW_FEATURE_EXT_WMI_MGMT_RX = 0,
|
||||
|
||||
/* firmware from 10X branch */
|
||||
/* Firmware from 10X branch. Deprecated, don't use in new code. */
|
||||
ATH10K_FW_FEATURE_WMI_10X = 1,
|
||||
|
||||
/* firmware support tx frame management over WMI, otherwise it's HTT */
|
||||
|
@ -378,8 +382,9 @@ enum ath10k_fw_features {
|
|||
/* Firmware does not support P2P */
|
||||
ATH10K_FW_FEATURE_NO_P2P = 3,
|
||||
|
||||
/* Firmware 10.2 feature bit. The ATH10K_FW_FEATURE_WMI_10X feature bit
|
||||
* is required to be set as well.
|
||||
/* Firmware 10.2 feature bit. The ATH10K_FW_FEATURE_WMI_10X feature
|
||||
* bit is required to be set as well. Deprecated, don't use in new
|
||||
* code.
|
||||
*/
|
||||
ATH10K_FW_FEATURE_WMI_10_2 = 4,
|
||||
|
||||
|
@ -401,6 +406,7 @@ enum ath10k_dev_flags {
|
|||
enum ath10k_cal_mode {
|
||||
ATH10K_CAL_MODE_FILE,
|
||||
ATH10K_CAL_MODE_OTP,
|
||||
ATH10K_CAL_MODE_DT,
|
||||
};
|
||||
|
||||
static inline const char *ath10k_cal_mode_str(enum ath10k_cal_mode mode)
|
||||
|
@ -410,6 +416,8 @@ static inline const char *ath10k_cal_mode_str(enum ath10k_cal_mode mode)
|
|||
return "file";
|
||||
case ATH10K_CAL_MODE_OTP:
|
||||
return "otp";
|
||||
case ATH10K_CAL_MODE_DT:
|
||||
return "dt";
|
||||
}
|
||||
|
||||
return "unknown";
|
||||
|
@ -480,12 +488,15 @@ struct ath10k {
|
|||
u32 id;
|
||||
const char *name;
|
||||
u32 patch_load_addr;
|
||||
int uart_pin;
|
||||
|
||||
struct ath10k_hw_params_fw {
|
||||
const char *dir;
|
||||
const char *fw;
|
||||
const char *otp;
|
||||
const char *board;
|
||||
size_t board_size;
|
||||
size_t board_ext_size;
|
||||
} fw;
|
||||
} hw_params;
|
||||
|
||||
|
@ -571,6 +582,7 @@ struct ath10k {
|
|||
|
||||
int max_num_peers;
|
||||
int max_num_stations;
|
||||
int max_num_vdevs;
|
||||
|
||||
struct work_struct offchan_tx_work;
|
||||
struct sk_buff_head offchan_tx_queue;
|
||||
|
@ -610,6 +622,7 @@ struct ath10k {
|
|||
/* protected by conf_mutex */
|
||||
const struct firmware *utf;
|
||||
DECLARE_BITMAP(orig_fw_features, ATH10K_FW_FEATURE_COUNT);
|
||||
enum ath10k_fw_wmi_op_version orig_wmi_op_version;
|
||||
|
||||
/* protected by data_lock */
|
||||
bool utf_monitor;
|
||||
|
@ -622,6 +635,8 @@ struct ath10k {
|
|||
u32 fw_cold_reset_counter;
|
||||
} stats;
|
||||
|
||||
struct ath10k_thermal thermal;
|
||||
|
||||
/* must be last */
|
||||
u8 drv_priv[0] __aligned(sizeof(void *));
|
||||
};
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
#include "core.h"
|
||||
#include "debug.h"
|
||||
#include "hif.h"
|
||||
#include "wmi-ops.h"
|
||||
|
||||
/* ms */
|
||||
#define ATH10K_DEBUG_HTT_STATS_INTERVAL 1000
|
||||
|
@ -123,7 +124,7 @@ EXPORT_SYMBOL(ath10k_info);
|
|||
|
||||
void ath10k_print_driver_info(struct ath10k *ar)
|
||||
{
|
||||
ath10k_info(ar, "%s (0x%08x, 0x%08x) fw %s api %d htt %d.%d wmi %d.%d.%d.%d cal %s max_sta %d\n",
|
||||
ath10k_info(ar, "%s (0x%08x, 0x%08x) fw %s api %d htt %d.%d wmi %d cal %s max_sta %d\n",
|
||||
ar->hw_params.name,
|
||||
ar->target_version,
|
||||
ar->chip_id,
|
||||
|
@ -131,10 +132,7 @@ void ath10k_print_driver_info(struct ath10k *ar)
|
|||
ar->fw_api,
|
||||
ar->htt.target_version_major,
|
||||
ar->htt.target_version_minor,
|
||||
ar->fw_version_major,
|
||||
ar->fw_version_minor,
|
||||
ar->fw_version_release,
|
||||
ar->fw_version_build,
|
||||
ar->wmi.op_version,
|
||||
ath10k_cal_mode_str(ar->cal_mode),
|
||||
ar->max_num_stations);
|
||||
ath10k_info(ar, "debug %d debugfs %d tracing %d dfs %d testmode %d\n",
|
||||
|
@ -1607,6 +1605,73 @@ static const struct file_operations fops_cal_data = {
|
|||
.llseek = default_llseek,
|
||||
};
|
||||
|
||||
static ssize_t ath10k_read_nf_cal_period(struct file *file,
|
||||
char __user *user_buf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
struct ath10k *ar = file->private_data;
|
||||
unsigned int len;
|
||||
char buf[32];
|
||||
|
||||
len = scnprintf(buf, sizeof(buf), "%d\n",
|
||||
ar->debug.nf_cal_period);
|
||||
|
||||
return simple_read_from_buffer(user_buf, count, ppos, buf, len);
|
||||
}
|
||||
|
||||
static ssize_t ath10k_write_nf_cal_period(struct file *file,
|
||||
const char __user *user_buf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
struct ath10k *ar = file->private_data;
|
||||
unsigned long period;
|
||||
int ret;
|
||||
|
||||
ret = kstrtoul_from_user(user_buf, count, 0, &period);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (period > WMI_PDEV_PARAM_CAL_PERIOD_MAX)
|
||||
return -EINVAL;
|
||||
|
||||
/* there's no way to switch back to the firmware default */
|
||||
if (period == 0)
|
||||
return -EINVAL;
|
||||
|
||||
mutex_lock(&ar->conf_mutex);
|
||||
|
||||
ar->debug.nf_cal_period = period;
|
||||
|
||||
if (ar->state != ATH10K_STATE_ON) {
|
||||
/* firmware is not running, nothing else to do */
|
||||
ret = count;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
ret = ath10k_wmi_pdev_set_param(ar, ar->wmi.pdev_param->cal_period,
|
||||
ar->debug.nf_cal_period);
|
||||
if (ret) {
|
||||
ath10k_warn(ar, "cal period cfg failed from debugfs: %d\n",
|
||||
ret);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
ret = count;
|
||||
|
||||
exit:
|
||||
mutex_unlock(&ar->conf_mutex);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const struct file_operations fops_nf_cal_period = {
|
||||
.read = ath10k_read_nf_cal_period,
|
||||
.write = ath10k_write_nf_cal_period,
|
||||
.open = simple_open,
|
||||
.owner = THIS_MODULE,
|
||||
.llseek = default_llseek,
|
||||
};
|
||||
|
||||
int ath10k_debug_start(struct ath10k *ar)
|
||||
{
|
||||
int ret;
|
||||
|
@ -1642,6 +1707,16 @@ int ath10k_debug_start(struct ath10k *ar)
|
|||
ath10k_warn(ar, "failed to disable pktlog: %d\n", ret);
|
||||
}
|
||||
|
||||
if (ar->debug.nf_cal_period) {
|
||||
ret = ath10k_wmi_pdev_set_param(ar,
|
||||
ar->wmi.pdev_param->cal_period,
|
||||
ar->debug.nf_cal_period);
|
||||
if (ret)
|
||||
/* not serious */
|
||||
ath10k_warn(ar, "cal period cfg failed from debug start: %d\n",
|
||||
ret);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -1880,6 +1955,9 @@ int ath10k_debug_register(struct ath10k *ar)
|
|||
debugfs_create_file("cal_data", S_IRUSR, ar->debug.debugfs_phy,
|
||||
ar, &fops_cal_data);
|
||||
|
||||
debugfs_create_file("nf_cal_period", S_IRUSR | S_IWUSR,
|
||||
ar->debug.debugfs_phy, ar, &fops_nf_cal_period);
|
||||
|
||||
if (config_enabled(CONFIG_ATH10K_DFS_CERTIFIED)) {
|
||||
debugfs_create_file("dfs_simulate_radar", S_IWUSR,
|
||||
ar->debug.debugfs_phy, ar,
|
||||
|
|
|
@ -93,11 +93,6 @@ int ath10k_htt_tx_alloc(struct ath10k_htt *htt)
|
|||
|
||||
spin_lock_init(&htt->tx_lock);
|
||||
|
||||
if (test_bit(ATH10K_FW_FEATURE_WMI_10X, htt->ar->fw_features))
|
||||
htt->max_num_pending_tx = TARGET_10X_NUM_MSDU_DESC;
|
||||
else
|
||||
htt->max_num_pending_tx = TARGET_NUM_MSDU_DESC;
|
||||
|
||||
ath10k_dbg(ar, ATH10K_DBG_BOOT, "htt tx max num pending tx %d\n",
|
||||
htt->max_num_pending_tx);
|
||||
|
||||
|
|
|
@ -37,6 +37,9 @@
|
|||
#define ATH10K_FW_API2_FILE "firmware-2.bin"
|
||||
#define ATH10K_FW_API3_FILE "firmware-3.bin"
|
||||
|
||||
/* added support for ATH10K_FW_IE_WMI_OP_VERSION */
|
||||
#define ATH10K_FW_API4_FILE "firmware-4.bin"
|
||||
|
||||
#define ATH10K_FW_UTF_FILE "utf.bin"
|
||||
|
||||
/* includes also the null byte */
|
||||
|
@ -58,6 +61,24 @@ enum ath10k_fw_ie_type {
|
|||
ATH10K_FW_IE_FEATURES = 2,
|
||||
ATH10K_FW_IE_FW_IMAGE = 3,
|
||||
ATH10K_FW_IE_OTP_IMAGE = 4,
|
||||
|
||||
/* WMI "operations" interface version, 32 bit value. Supported from
|
||||
* FW API 4 and above.
|
||||
*/
|
||||
ATH10K_FW_IE_WMI_OP_VERSION = 5,
|
||||
};
|
||||
|
||||
enum ath10k_fw_wmi_op_version {
|
||||
ATH10K_FW_WMI_OP_VERSION_UNSET = 0,
|
||||
|
||||
ATH10K_FW_WMI_OP_VERSION_MAIN = 1,
|
||||
ATH10K_FW_WMI_OP_VERSION_10_1 = 2,
|
||||
ATH10K_FW_WMI_OP_VERSION_10_2 = 3,
|
||||
ATH10K_FW_WMI_OP_VERSION_TLV = 4,
|
||||
ATH10K_FW_WMI_OP_VERSION_10_2_4 = 5,
|
||||
|
||||
/* keep last */
|
||||
ATH10K_FW_WMI_OP_VERSION_MAX,
|
||||
};
|
||||
|
||||
/* Known pecularities:
|
||||
|
@ -162,6 +183,15 @@ struct ath10k_pktlog_hdr {
|
|||
#define TARGET_10X_NUM_MSDU_DESC (1024 + 400)
|
||||
#define TARGET_10X_MAX_FRAG_ENTRIES 0
|
||||
|
||||
/* Target specific defines for WMI-TLV firmware */
|
||||
#define TARGET_TLV_NUM_VDEVS 3
|
||||
#define TARGET_TLV_NUM_STATIONS 32
|
||||
#define TARGET_TLV_NUM_PEERS ((TARGET_TLV_NUM_STATIONS) + \
|
||||
(TARGET_TLV_NUM_VDEVS) + \
|
||||
2)
|
||||
#define TARGET_TLV_NUM_TIDS ((TARGET_TLV_NUM_PEERS) * 2)
|
||||
#define TARGET_TLV_NUM_MSDU_DESC (1024 + 32)
|
||||
|
||||
/* Number of Copy Engines supported */
|
||||
#define CE_COUNT 8
|
||||
|
||||
|
|
|
@ -27,6 +27,8 @@
|
|||
#include "htt.h"
|
||||
#include "txrx.h"
|
||||
#include "testmode.h"
|
||||
#include "wmi.h"
|
||||
#include "wmi-ops.h"
|
||||
|
||||
/**********/
|
||||
/* Crypto */
|
||||
|
@ -267,7 +269,10 @@ chan_to_phymode(const struct cfg80211_chan_def *chandef)
|
|||
case IEEE80211_BAND_2GHZ:
|
||||
switch (chandef->width) {
|
||||
case NL80211_CHAN_WIDTH_20_NOHT:
|
||||
phymode = MODE_11G;
|
||||
if (chandef->chan->flags & IEEE80211_CHAN_NO_OFDM)
|
||||
phymode = MODE_11B;
|
||||
else
|
||||
phymode = MODE_11G;
|
||||
break;
|
||||
case NL80211_CHAN_WIDTH_20:
|
||||
phymode = MODE_11NG_HT20;
|
||||
|
@ -1046,28 +1051,85 @@ static void ath10k_control_ibss(struct ath10k_vif *arvif,
|
|||
arvif->vdev_id, ret);
|
||||
}
|
||||
|
||||
/*
|
||||
* Review this when mac80211 gains per-interface powersave support.
|
||||
*/
|
||||
static int ath10k_mac_vif_recalc_ps_wake_threshold(struct ath10k_vif *arvif)
|
||||
{
|
||||
struct ath10k *ar = arvif->ar;
|
||||
u32 param;
|
||||
u32 value;
|
||||
int ret;
|
||||
|
||||
lockdep_assert_held(&arvif->ar->conf_mutex);
|
||||
|
||||
if (arvif->u.sta.uapsd)
|
||||
value = WMI_STA_PS_TX_WAKE_THRESHOLD_NEVER;
|
||||
else
|
||||
value = WMI_STA_PS_TX_WAKE_THRESHOLD_ALWAYS;
|
||||
|
||||
param = WMI_STA_PS_PARAM_TX_WAKE_THRESHOLD;
|
||||
ret = ath10k_wmi_set_sta_ps_param(ar, arvif->vdev_id, param, value);
|
||||
if (ret) {
|
||||
ath10k_warn(ar, "failed to submit ps wake threshold %u on vdev %i: %d\n",
|
||||
value, arvif->vdev_id, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ath10k_mac_vif_recalc_ps_poll_count(struct ath10k_vif *arvif)
|
||||
{
|
||||
struct ath10k *ar = arvif->ar;
|
||||
u32 param;
|
||||
u32 value;
|
||||
int ret;
|
||||
|
||||
lockdep_assert_held(&arvif->ar->conf_mutex);
|
||||
|
||||
if (arvif->u.sta.uapsd)
|
||||
value = WMI_STA_PS_PSPOLL_COUNT_UAPSD;
|
||||
else
|
||||
value = WMI_STA_PS_PSPOLL_COUNT_NO_MAX;
|
||||
|
||||
param = WMI_STA_PS_PARAM_PSPOLL_COUNT;
|
||||
ret = ath10k_wmi_set_sta_ps_param(ar, arvif->vdev_id,
|
||||
param, value);
|
||||
if (ret) {
|
||||
ath10k_warn(ar, "failed to submit ps poll count %u on vdev %i: %d\n",
|
||||
value, arvif->vdev_id, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ath10k_mac_vif_setup_ps(struct ath10k_vif *arvif)
|
||||
{
|
||||
struct ath10k *ar = arvif->ar;
|
||||
struct ieee80211_vif *vif = arvif->vif;
|
||||
struct ieee80211_conf *conf = &ar->hw->conf;
|
||||
enum wmi_sta_powersave_param param;
|
||||
enum wmi_sta_ps_mode psmode;
|
||||
int ret;
|
||||
int ps_timeout;
|
||||
|
||||
lockdep_assert_held(&arvif->ar->conf_mutex);
|
||||
|
||||
if (arvif->vif->type != NL80211_IFTYPE_STATION)
|
||||
return 0;
|
||||
|
||||
if (conf->flags & IEEE80211_CONF_PS) {
|
||||
if (vif->bss_conf.ps) {
|
||||
psmode = WMI_STA_PS_MODE_ENABLED;
|
||||
param = WMI_STA_PS_PARAM_INACTIVITY_TIME;
|
||||
|
||||
ps_timeout = conf->dynamic_ps_timeout;
|
||||
if (ps_timeout == 0) {
|
||||
/* Firmware doesn't like 0 */
|
||||
ps_timeout = ieee80211_tu_to_usec(
|
||||
vif->bss_conf.beacon_int) / 1000;
|
||||
}
|
||||
|
||||
ret = ath10k_wmi_set_sta_ps_param(ar, arvif->vdev_id, param,
|
||||
conf->dynamic_ps_timeout);
|
||||
ps_timeout);
|
||||
if (ret) {
|
||||
ath10k_warn(ar, "failed to set inactivity time for vdev %d: %i\n",
|
||||
arvif->vdev_id, ret);
|
||||
|
@ -1409,9 +1471,22 @@ static void ath10k_peer_assoc_h_qos(struct ath10k *ar,
|
|||
if (vif->bss_conf.qos)
|
||||
arg->peer_flags |= WMI_PEER_QOS;
|
||||
break;
|
||||
case WMI_VDEV_TYPE_IBSS:
|
||||
if (sta->wme)
|
||||
arg->peer_flags |= WMI_PEER_QOS;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
ath10k_dbg(ar, ATH10K_DBG_MAC, "mac peer %pM qos %d\n",
|
||||
sta->addr, !!(arg->peer_flags & WMI_PEER_QOS));
|
||||
}
|
||||
|
||||
static bool ath10k_mac_sta_has_11g_rates(struct ieee80211_sta *sta)
|
||||
{
|
||||
/* First 4 rates in ath10k_rates are CCK (11b) rates. */
|
||||
return sta->supp_rates[IEEE80211_BAND_2GHZ] >> 4;
|
||||
}
|
||||
|
||||
static void ath10k_peer_assoc_h_phymode(struct ath10k *ar,
|
||||
|
@ -1428,8 +1503,10 @@ static void ath10k_peer_assoc_h_phymode(struct ath10k *ar,
|
|||
phymode = MODE_11NG_HT40;
|
||||
else
|
||||
phymode = MODE_11NG_HT20;
|
||||
} else {
|
||||
} else if (ath10k_mac_sta_has_11g_rates(sta)) {
|
||||
phymode = MODE_11G;
|
||||
} else {
|
||||
phymode = MODE_11B;
|
||||
}
|
||||
|
||||
break;
|
||||
|
@ -2894,10 +2971,11 @@ static int ath10k_add_interface(struct ieee80211_hw *hw,
|
|||
arvif->vdev_id = bit;
|
||||
arvif->vdev_subtype = WMI_VDEV_SUBTYPE_NONE;
|
||||
|
||||
if (ar->p2p)
|
||||
arvif->vdev_subtype = WMI_VDEV_SUBTYPE_P2P_DEVICE;
|
||||
|
||||
switch (vif->type) {
|
||||
case NL80211_IFTYPE_P2P_DEVICE:
|
||||
arvif->vdev_type = WMI_VDEV_TYPE_STA;
|
||||
arvif->vdev_subtype = WMI_VDEV_SUBTYPE_P2P_DEVICE;
|
||||
break;
|
||||
case NL80211_IFTYPE_UNSPECIFIED:
|
||||
case NL80211_IFTYPE_STATION:
|
||||
arvif->vdev_type = WMI_VDEV_TYPE_STA;
|
||||
|
@ -3026,22 +3104,16 @@ static int ath10k_add_interface(struct ieee80211_hw *hw,
|
|||
goto err_peer_delete;
|
||||
}
|
||||
|
||||
param = WMI_STA_PS_PARAM_TX_WAKE_THRESHOLD;
|
||||
value = WMI_STA_PS_TX_WAKE_THRESHOLD_ALWAYS;
|
||||
ret = ath10k_wmi_set_sta_ps_param(ar, arvif->vdev_id,
|
||||
param, value);
|
||||
ret = ath10k_mac_vif_recalc_ps_wake_threshold(arvif);
|
||||
if (ret) {
|
||||
ath10k_warn(ar, "failed to set vdev %i TX wake thresh: %d\n",
|
||||
ath10k_warn(ar, "failed to recalc ps wake threshold on vdev %i: %d\n",
|
||||
arvif->vdev_id, ret);
|
||||
goto err_peer_delete;
|
||||
}
|
||||
|
||||
param = WMI_STA_PS_PARAM_PSPOLL_COUNT;
|
||||
value = WMI_STA_PS_PSPOLL_COUNT_NO_MAX;
|
||||
ret = ath10k_wmi_set_sta_ps_param(ar, arvif->vdev_id,
|
||||
param, value);
|
||||
ret = ath10k_mac_vif_recalc_ps_poll_count(arvif);
|
||||
if (ret) {
|
||||
ath10k_warn(ar, "failed to set vdev %i PSPOLL count: %d\n",
|
||||
ath10k_warn(ar, "failed to recalc ps poll count on vdev %i: %d\n",
|
||||
arvif->vdev_id, ret);
|
||||
goto err_peer_delete;
|
||||
}
|
||||
|
@ -3314,6 +3386,13 @@ static void ath10k_bss_info_changed(struct ieee80211_hw *hw,
|
|||
ath10k_warn(ar, "failed to recalc tx power: %d\n", ret);
|
||||
}
|
||||
|
||||
if (changed & BSS_CHANGED_PS) {
|
||||
ret = ath10k_mac_vif_setup_ps(arvif);
|
||||
if (ret)
|
||||
ath10k_warn(ar, "failed to setup ps on vdev %i: %d\n",
|
||||
arvif->vdev_id, ret);
|
||||
}
|
||||
|
||||
mutex_unlock(&ar->conf_mutex);
|
||||
}
|
||||
|
||||
|
@ -3583,8 +3662,9 @@ static void ath10k_sta_rc_update_wk(struct work_struct *wk)
|
|||
sta->addr, smps, err);
|
||||
}
|
||||
|
||||
if (changed & IEEE80211_RC_SUPP_RATES_CHANGED) {
|
||||
ath10k_dbg(ar, ATH10K_DBG_MAC, "mac update sta %pM supp rates\n",
|
||||
if (changed & IEEE80211_RC_SUPP_RATES_CHANGED ||
|
||||
changed & IEEE80211_RC_NSS_CHANGED) {
|
||||
ath10k_dbg(ar, ATH10K_DBG_MAC, "mac update sta %pM supp rates/nss\n",
|
||||
sta->addr);
|
||||
|
||||
err = ath10k_station_assoc(ar, arvif->vif, sta, true);
|
||||
|
@ -3808,6 +3888,20 @@ static int ath10k_conf_tx_uapsd(struct ath10k *ar, struct ieee80211_vif *vif,
|
|||
if (ret)
|
||||
ath10k_warn(ar, "failed to set rx wake param: %d\n", ret);
|
||||
|
||||
ret = ath10k_mac_vif_recalc_ps_wake_threshold(arvif);
|
||||
if (ret) {
|
||||
ath10k_warn(ar, "failed to recalc ps wake threshold on vdev %i: %d\n",
|
||||
arvif->vdev_id, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = ath10k_mac_vif_recalc_ps_poll_count(arvif);
|
||||
if (ret) {
|
||||
ath10k_warn(ar, "failed to recalc ps poll count on vdev %i: %d\n",
|
||||
arvif->vdev_id, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
exit:
|
||||
return ret;
|
||||
}
|
||||
|
@ -3989,29 +4083,6 @@ static int ath10k_set_rts_threshold(struct ieee80211_hw *hw, u32 value)
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int ath10k_set_frag_threshold(struct ieee80211_hw *hw, u32 value)
|
||||
{
|
||||
struct ath10k *ar = hw->priv;
|
||||
struct ath10k_vif *arvif;
|
||||
int ret = 0;
|
||||
|
||||
mutex_lock(&ar->conf_mutex);
|
||||
list_for_each_entry(arvif, &ar->arvifs, list) {
|
||||
ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vdev %d fragmentation threshold %d\n",
|
||||
arvif->vdev_id, value);
|
||||
|
||||
ret = ath10k_mac_set_frag(arvif, value);
|
||||
if (ret) {
|
||||
ath10k_warn(ar, "failed to set fragmentation threshold for vdev %d: %d\n",
|
||||
arvif->vdev_id, ret);
|
||||
break;
|
||||
}
|
||||
}
|
||||
mutex_unlock(&ar->conf_mutex);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void ath10k_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
|
||||
u32 queues, bool drop)
|
||||
{
|
||||
|
@ -4655,7 +4726,6 @@ static const struct ieee80211_ops ath10k_ops = {
|
|||
.remain_on_channel = ath10k_remain_on_channel,
|
||||
.cancel_remain_on_channel = ath10k_cancel_remain_on_channel,
|
||||
.set_rts_threshold = ath10k_set_rts_threshold,
|
||||
.set_frag_threshold = ath10k_set_frag_threshold,
|
||||
.flush = ath10k_flush,
|
||||
.tx_last_beacon = ath10k_tx_last_beacon,
|
||||
.set_antenna = ath10k_set_antenna,
|
||||
|
@ -4746,6 +4816,9 @@ static const struct ieee80211_channel ath10k_5ghz_channels[] = {
|
|||
CHAN5G(165, 5825, 0),
|
||||
};
|
||||
|
||||
/* Note: Be careful if you re-order these. There is code which depends on this
|
||||
* ordering.
|
||||
*/
|
||||
static struct ieee80211_rate ath10k_rates[] = {
|
||||
/* CCK */
|
||||
RATETAB_ENT(10, 0x82, 0),
|
||||
|
@ -4799,6 +4872,10 @@ static const struct ieee80211_iface_limit ath10k_if_limits[] = {
|
|||
.types = BIT(NL80211_IFTYPE_P2P_GO)
|
||||
},
|
||||
{
|
||||
.max = 1,
|
||||
.types = BIT(NL80211_IFTYPE_P2P_DEVICE)
|
||||
},
|
||||
{
|
||||
.max = 7,
|
||||
.types = BIT(NL80211_IFTYPE_AP)
|
||||
},
|
||||
|
@ -5018,6 +5095,7 @@ int ath10k_mac_register(struct ath10k *ar)
|
|||
|
||||
if (!test_bit(ATH10K_FW_FEATURE_NO_P2P, ar->fw_features))
|
||||
ar->hw->wiphy->interface_modes |=
|
||||
BIT(NL80211_IFTYPE_P2P_DEVICE) |
|
||||
BIT(NL80211_IFTYPE_P2P_CLIENT) |
|
||||
BIT(NL80211_IFTYPE_P2P_GO);
|
||||
|
||||
|
@ -5062,16 +5140,26 @@ int ath10k_mac_register(struct ath10k *ar)
|
|||
*/
|
||||
ar->hw->queues = 4;
|
||||
|
||||
if (test_bit(ATH10K_FW_FEATURE_WMI_10X, ar->fw_features)) {
|
||||
ar->hw->wiphy->iface_combinations = ath10k_10x_if_comb;
|
||||
ar->hw->wiphy->n_iface_combinations =
|
||||
ARRAY_SIZE(ath10k_10x_if_comb);
|
||||
} else {
|
||||
switch (ar->wmi.op_version) {
|
||||
case ATH10K_FW_WMI_OP_VERSION_MAIN:
|
||||
case ATH10K_FW_WMI_OP_VERSION_TLV:
|
||||
ar->hw->wiphy->iface_combinations = ath10k_if_comb;
|
||||
ar->hw->wiphy->n_iface_combinations =
|
||||
ARRAY_SIZE(ath10k_if_comb);
|
||||
|
||||
ar->hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_ADHOC);
|
||||
break;
|
||||
case ATH10K_FW_WMI_OP_VERSION_10_1:
|
||||
case ATH10K_FW_WMI_OP_VERSION_10_2:
|
||||
case ATH10K_FW_WMI_OP_VERSION_10_2_4:
|
||||
ar->hw->wiphy->iface_combinations = ath10k_10x_if_comb;
|
||||
ar->hw->wiphy->n_iface_combinations =
|
||||
ARRAY_SIZE(ath10k_10x_if_comb);
|
||||
break;
|
||||
case ATH10K_FW_WMI_OP_VERSION_UNSET:
|
||||
case ATH10K_FW_WMI_OP_VERSION_MAX:
|
||||
WARN_ON(1);
|
||||
ret = -EINVAL;
|
||||
goto err_free;
|
||||
}
|
||||
|
||||
ar->hw->netdev_features = NETIF_F_HW_CSUM;
|
||||
|
|
|
@ -64,6 +64,14 @@ static const struct pci_device_id ath10k_pci_id_table[] = {
|
|||
{0}
|
||||
};
|
||||
|
||||
static const struct ath10k_pci_supp_chip ath10k_pci_supp_chips[] = {
|
||||
/* QCA988X pre 2.0 chips are not supported because they need some nasty
|
||||
* hacks. ath10k doesn't have them and these devices crash horribly
|
||||
* because of that.
|
||||
*/
|
||||
{ QCA988X_2_0_DEVICE_ID, QCA988X_HW_2_0_CHIP_ID_REV },
|
||||
};
|
||||
|
||||
static void ath10k_pci_buffer_cleanup(struct ath10k *ar);
|
||||
static int ath10k_pci_cold_reset(struct ath10k *ar);
|
||||
static int ath10k_pci_warm_reset(struct ath10k *ar);
|
||||
|
@ -2476,6 +2484,23 @@ static void ath10k_pci_release(struct ath10k *ar)
|
|||
pci_disable_device(pdev);
|
||||
}
|
||||
|
||||
static bool ath10k_pci_chip_is_supported(u32 dev_id, u32 chip_id)
|
||||
{
|
||||
const struct ath10k_pci_supp_chip *supp_chip;
|
||||
int i;
|
||||
u32 rev_id = MS(chip_id, SOC_CHIP_ID_REV);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(ath10k_pci_supp_chips); i++) {
|
||||
supp_chip = &ath10k_pci_supp_chips[i];
|
||||
|
||||
if (supp_chip->dev_id == dev_id &&
|
||||
supp_chip->rev_id == rev_id)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static int ath10k_pci_probe(struct pci_dev *pdev,
|
||||
const struct pci_device_id *pci_dev)
|
||||
{
|
||||
|
@ -2521,6 +2546,12 @@ static int ath10k_pci_probe(struct pci_dev *pdev,
|
|||
goto err_sleep;
|
||||
}
|
||||
|
||||
if (!ath10k_pci_chip_is_supported(pdev->device, chip_id)) {
|
||||
ath10k_err(ar, "device %04x with chip_id %08x isn't supported\n",
|
||||
pdev->device, chip_id);
|
||||
goto err_sleep;
|
||||
}
|
||||
|
||||
ret = ath10k_pci_alloc_pipes(ar);
|
||||
if (ret) {
|
||||
ath10k_err(ar, "failed to allocate copy engine pipes: %d\n",
|
||||
|
|
|
@ -152,6 +152,11 @@ struct ath10k_pci_pipe {
|
|||
struct tasklet_struct intr;
|
||||
};
|
||||
|
||||
struct ath10k_pci_supp_chip {
|
||||
u32 dev_id;
|
||||
u32 rev_id;
|
||||
};
|
||||
|
||||
struct ath10k_pci {
|
||||
struct pci_dev *pdev;
|
||||
struct device *dev;
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
#include <linux/relay.h>
|
||||
#include "core.h"
|
||||
#include "debug.h"
|
||||
#include "wmi-ops.h"
|
||||
|
||||
static void send_fft_sample(struct ath10k *ar,
|
||||
const struct fft_sample_tlv *fft_sample_tlv)
|
||||
|
|
|
@ -187,13 +187,14 @@ static int ath10k_tm_cmd_utf_start(struct ath10k *ar, struct nlattr *tb[])
|
|||
|
||||
memcpy(ar->testmode.orig_fw_features, ar->fw_features,
|
||||
sizeof(ar->fw_features));
|
||||
ar->testmode.orig_wmi_op_version = ar->wmi.op_version;
|
||||
|
||||
/* utf.bin firmware image does not advertise firmware features. Do
|
||||
* an ugly hack where we force the firmware features so that wmi.c
|
||||
* will use the correct WMI interface.
|
||||
*/
|
||||
memset(ar->fw_features, 0, sizeof(ar->fw_features));
|
||||
__set_bit(ATH10K_FW_FEATURE_WMI_10X, ar->fw_features);
|
||||
ar->wmi.op_version = ATH10K_FW_WMI_OP_VERSION_10_1;
|
||||
|
||||
ret = ath10k_hif_power_up(ar);
|
||||
if (ret) {
|
||||
|
@ -224,6 +225,7 @@ static int ath10k_tm_cmd_utf_start(struct ath10k *ar, struct nlattr *tb[])
|
|||
/* return the original firmware features */
|
||||
memcpy(ar->fw_features, ar->testmode.orig_fw_features,
|
||||
sizeof(ar->fw_features));
|
||||
ar->wmi.op_version = ar->testmode.orig_wmi_op_version;
|
||||
|
||||
release_firmware(ar->testmode.utf);
|
||||
ar->testmode.utf = NULL;
|
||||
|
@ -250,6 +252,7 @@ static void __ath10k_tm_cmd_utf_stop(struct ath10k *ar)
|
|||
/* return the original firmware features */
|
||||
memcpy(ar->fw_features, ar->testmode.orig_fw_features,
|
||||
sizeof(ar->fw_features));
|
||||
ar->wmi.op_version = ar->testmode.orig_wmi_op_version;
|
||||
|
||||
release_firmware(ar->testmode.utf);
|
||||
ar->testmode.utf = NULL;
|
||||
|
|
|
@ -0,0 +1,243 @@
|
|||
/*
|
||||
* Copyright (c) 2014 Qualcomm Atheros, Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <linux/device.h>
|
||||
#include <linux/sysfs.h>
|
||||
#include <linux/thermal.h>
|
||||
#include <linux/hwmon.h>
|
||||
#include <linux/hwmon-sysfs.h>
|
||||
#include "core.h"
|
||||
#include "debug.h"
|
||||
#include "wmi-ops.h"
|
||||
|
||||
static int ath10k_thermal_get_active_vifs(struct ath10k *ar,
|
||||
enum wmi_vdev_type type)
|
||||
{
|
||||
struct ath10k_vif *arvif;
|
||||
int count = 0;
|
||||
|
||||
lockdep_assert_held(&ar->conf_mutex);
|
||||
|
||||
list_for_each_entry(arvif, &ar->arvifs, list) {
|
||||
if (!arvif->is_started)
|
||||
continue;
|
||||
|
||||
if (!arvif->is_up)
|
||||
continue;
|
||||
|
||||
if (arvif->vdev_type != type)
|
||||
continue;
|
||||
|
||||
count++;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
static int ath10k_thermal_get_max_dutycycle(struct thermal_cooling_device *cdev,
|
||||
unsigned long *state)
|
||||
{
|
||||
*state = ATH10K_QUIET_DUTY_CYCLE_MAX;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ath10k_thermal_get_cur_dutycycle(struct thermal_cooling_device *cdev,
|
||||
unsigned long *state)
|
||||
{
|
||||
struct ath10k *ar = cdev->devdata;
|
||||
|
||||
mutex_lock(&ar->conf_mutex);
|
||||
*state = ar->thermal.duty_cycle;
|
||||
mutex_unlock(&ar->conf_mutex);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ath10k_thermal_set_cur_dutycycle(struct thermal_cooling_device *cdev,
|
||||
unsigned long duty_cycle)
|
||||
{
|
||||
struct ath10k *ar = cdev->devdata;
|
||||
u32 period, duration, enabled;
|
||||
int num_bss, ret = 0;
|
||||
|
||||
mutex_lock(&ar->conf_mutex);
|
||||
if (ar->state != ATH10K_STATE_ON) {
|
||||
ret = -ENETDOWN;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (duty_cycle > ATH10K_QUIET_DUTY_CYCLE_MAX) {
|
||||
ath10k_warn(ar, "duty cycle %ld is exceeding the limit %d\n",
|
||||
duty_cycle, ATH10K_QUIET_DUTY_CYCLE_MAX);
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
/* TODO: Right now, thermal mitigation is handled only for single/multi
|
||||
* vif AP mode. Since quiet param is not validated in STA mode, it needs
|
||||
* to be investigated further to handle multi STA and multi-vif (AP+STA)
|
||||
* mode properly.
|
||||
*/
|
||||
num_bss = ath10k_thermal_get_active_vifs(ar, WMI_VDEV_TYPE_AP);
|
||||
if (!num_bss) {
|
||||
ath10k_warn(ar, "no active AP interfaces\n");
|
||||
ret = -ENETDOWN;
|
||||
goto out;
|
||||
}
|
||||
period = max(ATH10K_QUIET_PERIOD_MIN,
|
||||
(ATH10K_QUIET_PERIOD_DEFAULT / num_bss));
|
||||
duration = period * (duty_cycle / 100);
|
||||
enabled = duration ? 1 : 0;
|
||||
|
||||
ret = ath10k_wmi_pdev_set_quiet_mode(ar, period, duration,
|
||||
ATH10K_QUIET_START_OFFSET,
|
||||
enabled);
|
||||
if (ret) {
|
||||
ath10k_warn(ar, "failed to set quiet mode period %u duarion %u enabled %u ret %d\n",
|
||||
period, duration, enabled, ret);
|
||||
goto out;
|
||||
}
|
||||
ar->thermal.duty_cycle = duty_cycle;
|
||||
out:
|
||||
mutex_unlock(&ar->conf_mutex);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static struct thermal_cooling_device_ops ath10k_thermal_ops = {
|
||||
.get_max_state = ath10k_thermal_get_max_dutycycle,
|
||||
.get_cur_state = ath10k_thermal_get_cur_dutycycle,
|
||||
.set_cur_state = ath10k_thermal_set_cur_dutycycle,
|
||||
};
|
||||
|
||||
static ssize_t ath10k_thermal_show_temp(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
struct ath10k *ar = dev_get_drvdata(dev);
|
||||
int ret, temperature;
|
||||
|
||||
mutex_lock(&ar->conf_mutex);
|
||||
|
||||
/* Can't get temperature when the card is off */
|
||||
if (ar->state != ATH10K_STATE_ON) {
|
||||
ret = -ENETDOWN;
|
||||
goto out;
|
||||
}
|
||||
|
||||
reinit_completion(&ar->thermal.wmi_sync);
|
||||
ret = ath10k_wmi_pdev_get_temperature(ar);
|
||||
if (ret) {
|
||||
ath10k_warn(ar, "failed to read temperature %d\n", ret);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (test_bit(ATH10K_FLAG_CRASH_FLUSH, &ar->dev_flags)) {
|
||||
ret = -ESHUTDOWN;
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = wait_for_completion_timeout(&ar->thermal.wmi_sync,
|
||||
ATH10K_THERMAL_SYNC_TIMEOUT_HZ);
|
||||
if (ret == 0) {
|
||||
ath10k_warn(ar, "failed to synchronize thermal read\n");
|
||||
ret = -ETIMEDOUT;
|
||||
goto out;
|
||||
}
|
||||
|
||||
spin_lock_bh(&ar->data_lock);
|
||||
temperature = ar->thermal.temperature;
|
||||
spin_unlock_bh(&ar->data_lock);
|
||||
|
||||
ret = snprintf(buf, PAGE_SIZE, "%d", temperature);
|
||||
out:
|
||||
mutex_unlock(&ar->conf_mutex);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void ath10k_thermal_event_temperature(struct ath10k *ar, int temperature)
|
||||
{
|
||||
spin_lock_bh(&ar->data_lock);
|
||||
ar->thermal.temperature = temperature;
|
||||
spin_unlock_bh(&ar->data_lock);
|
||||
complete(&ar->thermal.wmi_sync);
|
||||
}
|
||||
|
||||
static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, ath10k_thermal_show_temp,
|
||||
NULL, 0);
|
||||
|
||||
static struct attribute *ath10k_hwmon_attrs[] = {
|
||||
&sensor_dev_attr_temp1_input.dev_attr.attr,
|
||||
NULL,
|
||||
};
|
||||
ATTRIBUTE_GROUPS(ath10k_hwmon);
|
||||
|
||||
int ath10k_thermal_register(struct ath10k *ar)
|
||||
{
|
||||
struct thermal_cooling_device *cdev;
|
||||
struct device *hwmon_dev;
|
||||
int ret;
|
||||
|
||||
cdev = thermal_cooling_device_register("ath10k_thermal", ar,
|
||||
&ath10k_thermal_ops);
|
||||
|
||||
if (IS_ERR(cdev)) {
|
||||
ath10k_err(ar, "failed to setup thermal device result: %ld\n",
|
||||
PTR_ERR(cdev));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ret = sysfs_create_link(&ar->dev->kobj, &cdev->device.kobj,
|
||||
"cooling_device");
|
||||
if (ret) {
|
||||
ath10k_err(ar, "failed to create thermal symlink\n");
|
||||
goto err_cooling_destroy;
|
||||
}
|
||||
|
||||
ar->thermal.cdev = cdev;
|
||||
|
||||
/* Do not register hwmon device when temperature reading is not
|
||||
* supported by firmware
|
||||
*/
|
||||
if (ar->wmi.op_version != ATH10K_FW_WMI_OP_VERSION_10_2_4)
|
||||
return 0;
|
||||
|
||||
/* Avoid linking error on devm_hwmon_device_register_with_groups, I
|
||||
* guess linux/hwmon.h is missing proper stubs. */
|
||||
if (!config_enabled(HWMON))
|
||||
return 0;
|
||||
|
||||
hwmon_dev = devm_hwmon_device_register_with_groups(ar->dev,
|
||||
"ath10k_hwmon", ar,
|
||||
ath10k_hwmon_groups);
|
||||
if (IS_ERR(hwmon_dev)) {
|
||||
ath10k_err(ar, "failed to register hwmon device: %ld\n",
|
||||
PTR_ERR(hwmon_dev));
|
||||
ret = -EINVAL;
|
||||
goto err_remove_link;
|
||||
}
|
||||
return 0;
|
||||
|
||||
err_remove_link:
|
||||
sysfs_remove_link(&ar->dev->kobj, "thermal_sensor");
|
||||
err_cooling_destroy:
|
||||
thermal_cooling_device_unregister(cdev);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void ath10k_thermal_unregister(struct ath10k *ar)
|
||||
{
|
||||
thermal_cooling_device_unregister(ar->thermal.cdev);
|
||||
sysfs_remove_link(&ar->dev->kobj, "cooling_device");
|
||||
}
|
|
@ -0,0 +1,58 @@
|
|||
/*
|
||||
* Copyright (c) 2014 Qualcomm Atheros, Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
#ifndef _THERMAL_
|
||||
#define _THERMAL_
|
||||
|
||||
#define ATH10K_QUIET_PERIOD_DEFAULT 100
|
||||
#define ATH10K_QUIET_PERIOD_MIN 25
|
||||
#define ATH10K_QUIET_START_OFFSET 10
|
||||
#define ATH10K_QUIET_DUTY_CYCLE_MAX 70
|
||||
#define ATH10K_HWMON_NAME_LEN 15
|
||||
#define ATH10K_THERMAL_SYNC_TIMEOUT_HZ (5*HZ)
|
||||
|
||||
struct ath10k_thermal {
|
||||
struct thermal_cooling_device *cdev;
|
||||
struct completion wmi_sync;
|
||||
|
||||
/* protected by conf_mutex */
|
||||
u32 duty_cycle;
|
||||
/* temperature value in Celcius degree
|
||||
* protected by data_lock
|
||||
*/
|
||||
int temperature;
|
||||
};
|
||||
|
||||
#ifdef CONFIG_THERMAL
|
||||
int ath10k_thermal_register(struct ath10k *ar);
|
||||
void ath10k_thermal_unregister(struct ath10k *ar);
|
||||
void ath10k_thermal_event_temperature(struct ath10k *ar, int temperature);
|
||||
#else
|
||||
static inline int ath10k_thermal_register(struct ath10k *ar)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void ath10k_thermal_unregister(struct ath10k *ar)
|
||||
{
|
||||
}
|
||||
|
||||
static inline void ath10k_thermal_event_temperature(struct ath10k *ar,
|
||||
int temperature)
|
||||
{
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif /* _THERMAL_ */
|
|
@ -0,0 +1,860 @@
|
|||
/*
|
||||
* Copyright (c) 2005-2011 Atheros Communications Inc.
|
||||
* Copyright (c) 2011-2014 Qualcomm Atheros, Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef _WMI_OPS_H_
|
||||
#define _WMI_OPS_H_
|
||||
|
||||
struct ath10k;
|
||||
struct sk_buff;
|
||||
|
||||
struct wmi_ops {
|
||||
void (*rx)(struct ath10k *ar, struct sk_buff *skb);
|
||||
void (*map_svc)(const __le32 *in, unsigned long *out, size_t len);
|
||||
|
||||
int (*pull_scan)(struct ath10k *ar, struct sk_buff *skb,
|
||||
struct wmi_scan_ev_arg *arg);
|
||||
int (*pull_mgmt_rx)(struct ath10k *ar, struct sk_buff *skb,
|
||||
struct wmi_mgmt_rx_ev_arg *arg);
|
||||
int (*pull_ch_info)(struct ath10k *ar, struct sk_buff *skb,
|
||||
struct wmi_ch_info_ev_arg *arg);
|
||||
int (*pull_vdev_start)(struct ath10k *ar, struct sk_buff *skb,
|
||||
struct wmi_vdev_start_ev_arg *arg);
|
||||
int (*pull_peer_kick)(struct ath10k *ar, struct sk_buff *skb,
|
||||
struct wmi_peer_kick_ev_arg *arg);
|
||||
int (*pull_swba)(struct ath10k *ar, struct sk_buff *skb,
|
||||
struct wmi_swba_ev_arg *arg);
|
||||
int (*pull_phyerr)(struct ath10k *ar, struct sk_buff *skb,
|
||||
struct wmi_phyerr_ev_arg *arg);
|
||||
int (*pull_svc_rdy)(struct ath10k *ar, struct sk_buff *skb,
|
||||
struct wmi_svc_rdy_ev_arg *arg);
|
||||
int (*pull_rdy)(struct ath10k *ar, struct sk_buff *skb,
|
||||
struct wmi_rdy_ev_arg *arg);
|
||||
int (*pull_fw_stats)(struct ath10k *ar, struct sk_buff *skb,
|
||||
struct ath10k_fw_stats *stats);
|
||||
|
||||
struct sk_buff *(*gen_pdev_suspend)(struct ath10k *ar, u32 suspend_opt);
|
||||
struct sk_buff *(*gen_pdev_resume)(struct ath10k *ar);
|
||||
struct sk_buff *(*gen_pdev_set_rd)(struct ath10k *ar, u16 rd, u16 rd2g,
|
||||
u16 rd5g, u16 ctl2g, u16 ctl5g,
|
||||
enum wmi_dfs_region dfs_reg);
|
||||
struct sk_buff *(*gen_pdev_set_param)(struct ath10k *ar, u32 id,
|
||||
u32 value);
|
||||
struct sk_buff *(*gen_init)(struct ath10k *ar);
|
||||
struct sk_buff *(*gen_start_scan)(struct ath10k *ar,
|
||||
const struct wmi_start_scan_arg *arg);
|
||||
struct sk_buff *(*gen_stop_scan)(struct ath10k *ar,
|
||||
const struct wmi_stop_scan_arg *arg);
|
||||
struct sk_buff *(*gen_vdev_create)(struct ath10k *ar, u32 vdev_id,
|
||||
enum wmi_vdev_type type,
|
||||
enum wmi_vdev_subtype subtype,
|
||||
const u8 macaddr[ETH_ALEN]);
|
||||
struct sk_buff *(*gen_vdev_delete)(struct ath10k *ar, u32 vdev_id);
|
||||
struct sk_buff *(*gen_vdev_start)(struct ath10k *ar,
|
||||
const struct wmi_vdev_start_request_arg *arg,
|
||||
bool restart);
|
||||
struct sk_buff *(*gen_vdev_stop)(struct ath10k *ar, u32 vdev_id);
|
||||
struct sk_buff *(*gen_vdev_up)(struct ath10k *ar, u32 vdev_id, u32 aid,
|
||||
const u8 *bssid);
|
||||
struct sk_buff *(*gen_vdev_down)(struct ath10k *ar, u32 vdev_id);
|
||||
struct sk_buff *(*gen_vdev_set_param)(struct ath10k *ar, u32 vdev_id,
|
||||
u32 param_id, u32 param_value);
|
||||
struct sk_buff *(*gen_vdev_install_key)(struct ath10k *ar,
|
||||
const struct wmi_vdev_install_key_arg *arg);
|
||||
struct sk_buff *(*gen_vdev_spectral_conf)(struct ath10k *ar,
|
||||
const struct wmi_vdev_spectral_conf_arg *arg);
|
||||
struct sk_buff *(*gen_vdev_spectral_enable)(struct ath10k *ar, u32 vdev_id,
|
||||
u32 trigger, u32 enable);
|
||||
struct sk_buff *(*gen_peer_create)(struct ath10k *ar, u32 vdev_id,
|
||||
const u8 peer_addr[ETH_ALEN]);
|
||||
struct sk_buff *(*gen_peer_delete)(struct ath10k *ar, u32 vdev_id,
|
||||
const u8 peer_addr[ETH_ALEN]);
|
||||
struct sk_buff *(*gen_peer_flush)(struct ath10k *ar, u32 vdev_id,
|
||||
const u8 peer_addr[ETH_ALEN],
|
||||
u32 tid_bitmap);
|
||||
struct sk_buff *(*gen_peer_set_param)(struct ath10k *ar, u32 vdev_id,
|
||||
const u8 *peer_addr,
|
||||
enum wmi_peer_param param_id,
|
||||
u32 param_value);
|
||||
struct sk_buff *(*gen_peer_assoc)(struct ath10k *ar,
|
||||
const struct wmi_peer_assoc_complete_arg *arg);
|
||||
struct sk_buff *(*gen_set_psmode)(struct ath10k *ar, u32 vdev_id,
|
||||
enum wmi_sta_ps_mode psmode);
|
||||
struct sk_buff *(*gen_set_sta_ps)(struct ath10k *ar, u32 vdev_id,
|
||||
enum wmi_sta_powersave_param param_id,
|
||||
u32 value);
|
||||
struct sk_buff *(*gen_set_ap_ps)(struct ath10k *ar, u32 vdev_id,
|
||||
const u8 *mac,
|
||||
enum wmi_ap_ps_peer_param param_id,
|
||||
u32 value);
|
||||
struct sk_buff *(*gen_scan_chan_list)(struct ath10k *ar,
|
||||
const struct wmi_scan_chan_list_arg *arg);
|
||||
struct sk_buff *(*gen_beacon_dma)(struct ath10k_vif *arvif);
|
||||
struct sk_buff *(*gen_pdev_set_wmm)(struct ath10k *ar,
|
||||
const struct wmi_pdev_set_wmm_params_arg *arg);
|
||||
struct sk_buff *(*gen_request_stats)(struct ath10k *ar,
|
||||
enum wmi_stats_id stats_id);
|
||||
struct sk_buff *(*gen_force_fw_hang)(struct ath10k *ar,
|
||||
enum wmi_force_fw_hang_type type,
|
||||
u32 delay_ms);
|
||||
struct sk_buff *(*gen_mgmt_tx)(struct ath10k *ar, struct sk_buff *skb);
|
||||
struct sk_buff *(*gen_dbglog_cfg)(struct ath10k *ar, u32 module_enable);
|
||||
struct sk_buff *(*gen_pktlog_enable)(struct ath10k *ar, u32 filter);
|
||||
struct sk_buff *(*gen_pktlog_disable)(struct ath10k *ar);
|
||||
struct sk_buff *(*gen_pdev_set_quiet_mode)(struct ath10k *ar,
|
||||
u32 period, u32 duration,
|
||||
u32 next_offset,
|
||||
u32 enabled);
|
||||
struct sk_buff *(*gen_pdev_get_temperature)(struct ath10k *ar);
|
||||
};
|
||||
|
||||
int ath10k_wmi_cmd_send(struct ath10k *ar, struct sk_buff *skb, u32 cmd_id);
|
||||
|
||||
static inline int
|
||||
ath10k_wmi_rx(struct ath10k *ar, struct sk_buff *skb)
|
||||
{
|
||||
if (WARN_ON_ONCE(!ar->wmi.ops->rx))
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
ar->wmi.ops->rx(ar, skb);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int
|
||||
ath10k_wmi_map_svc(struct ath10k *ar, const __le32 *in, unsigned long *out,
|
||||
size_t len)
|
||||
{
|
||||
if (!ar->wmi.ops->map_svc)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
ar->wmi.ops->map_svc(in, out, len);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int
|
||||
ath10k_wmi_pull_scan(struct ath10k *ar, struct sk_buff *skb,
|
||||
struct wmi_scan_ev_arg *arg)
|
||||
{
|
||||
if (!ar->wmi.ops->pull_scan)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
return ar->wmi.ops->pull_scan(ar, skb, arg);
|
||||
}
|
||||
|
||||
static inline int
|
||||
ath10k_wmi_pull_mgmt_rx(struct ath10k *ar, struct sk_buff *skb,
|
||||
struct wmi_mgmt_rx_ev_arg *arg)
|
||||
{
|
||||
if (!ar->wmi.ops->pull_mgmt_rx)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
return ar->wmi.ops->pull_mgmt_rx(ar, skb, arg);
|
||||
}
|
||||
|
||||
static inline int
|
||||
ath10k_wmi_pull_ch_info(struct ath10k *ar, struct sk_buff *skb,
|
||||
struct wmi_ch_info_ev_arg *arg)
|
||||
{
|
||||
if (!ar->wmi.ops->pull_ch_info)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
return ar->wmi.ops->pull_ch_info(ar, skb, arg);
|
||||
}
|
||||
|
||||
static inline int
|
||||
ath10k_wmi_pull_vdev_start(struct ath10k *ar, struct sk_buff *skb,
|
||||
struct wmi_vdev_start_ev_arg *arg)
|
||||
{
|
||||
if (!ar->wmi.ops->pull_vdev_start)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
return ar->wmi.ops->pull_vdev_start(ar, skb, arg);
|
||||
}
|
||||
|
||||
static inline int
|
||||
ath10k_wmi_pull_peer_kick(struct ath10k *ar, struct sk_buff *skb,
|
||||
struct wmi_peer_kick_ev_arg *arg)
|
||||
{
|
||||
if (!ar->wmi.ops->pull_peer_kick)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
return ar->wmi.ops->pull_peer_kick(ar, skb, arg);
|
||||
}
|
||||
|
||||
static inline int
|
||||
ath10k_wmi_pull_swba(struct ath10k *ar, struct sk_buff *skb,
|
||||
struct wmi_swba_ev_arg *arg)
|
||||
{
|
||||
if (!ar->wmi.ops->pull_swba)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
return ar->wmi.ops->pull_swba(ar, skb, arg);
|
||||
}
|
||||
|
||||
static inline int
|
||||
ath10k_wmi_pull_phyerr(struct ath10k *ar, struct sk_buff *skb,
|
||||
struct wmi_phyerr_ev_arg *arg)
|
||||
{
|
||||
if (!ar->wmi.ops->pull_phyerr)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
return ar->wmi.ops->pull_phyerr(ar, skb, arg);
|
||||
}
|
||||
|
||||
static inline int
|
||||
ath10k_wmi_pull_svc_rdy(struct ath10k *ar, struct sk_buff *skb,
|
||||
struct wmi_svc_rdy_ev_arg *arg)
|
||||
{
|
||||
if (!ar->wmi.ops->pull_svc_rdy)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
return ar->wmi.ops->pull_svc_rdy(ar, skb, arg);
|
||||
}
|
||||
|
||||
static inline int
|
||||
ath10k_wmi_pull_rdy(struct ath10k *ar, struct sk_buff *skb,
|
||||
struct wmi_rdy_ev_arg *arg)
|
||||
{
|
||||
if (!ar->wmi.ops->pull_rdy)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
return ar->wmi.ops->pull_rdy(ar, skb, arg);
|
||||
}
|
||||
|
||||
static inline int
|
||||
ath10k_wmi_pull_fw_stats(struct ath10k *ar, struct sk_buff *skb,
|
||||
struct ath10k_fw_stats *stats)
|
||||
{
|
||||
if (!ar->wmi.ops->pull_fw_stats)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
return ar->wmi.ops->pull_fw_stats(ar, skb, stats);
|
||||
}
|
||||
|
||||
static inline int
|
||||
ath10k_wmi_mgmt_tx(struct ath10k *ar, struct sk_buff *msdu)
|
||||
{
|
||||
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(msdu);
|
||||
struct sk_buff *skb;
|
||||
int ret;
|
||||
|
||||
if (!ar->wmi.ops->gen_mgmt_tx)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
skb = ar->wmi.ops->gen_mgmt_tx(ar, msdu);
|
||||
if (IS_ERR(skb))
|
||||
return PTR_ERR(skb);
|
||||
|
||||
ret = ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->mgmt_tx_cmdid);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* FIXME There's no ACK event for Management Tx. This probably
|
||||
* shouldn't be called here either. */
|
||||
info->flags |= IEEE80211_TX_STAT_ACK;
|
||||
ieee80211_tx_status_irqsafe(ar->hw, msdu);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int
|
||||
ath10k_wmi_pdev_set_regdomain(struct ath10k *ar, u16 rd, u16 rd2g, u16 rd5g,
|
||||
u16 ctl2g, u16 ctl5g,
|
||||
enum wmi_dfs_region dfs_reg)
|
||||
{
|
||||
struct sk_buff *skb;
|
||||
|
||||
if (!ar->wmi.ops->gen_pdev_set_rd)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
skb = ar->wmi.ops->gen_pdev_set_rd(ar, rd, rd2g, rd5g, ctl2g, ctl5g,
|
||||
dfs_reg);
|
||||
if (IS_ERR(skb))
|
||||
return PTR_ERR(skb);
|
||||
|
||||
return ath10k_wmi_cmd_send(ar, skb,
|
||||
ar->wmi.cmd->pdev_set_regdomain_cmdid);
|
||||
}
|
||||
|
||||
static inline int
|
||||
ath10k_wmi_pdev_suspend_target(struct ath10k *ar, u32 suspend_opt)
|
||||
{
|
||||
struct sk_buff *skb;
|
||||
|
||||
if (!ar->wmi.ops->gen_pdev_suspend)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
skb = ar->wmi.ops->gen_pdev_suspend(ar, suspend_opt);
|
||||
if (IS_ERR(skb))
|
||||
return PTR_ERR(skb);
|
||||
|
||||
return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->pdev_suspend_cmdid);
|
||||
}
|
||||
|
||||
static inline int
|
||||
ath10k_wmi_pdev_resume_target(struct ath10k *ar)
|
||||
{
|
||||
struct sk_buff *skb;
|
||||
|
||||
if (!ar->wmi.ops->gen_pdev_resume)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
skb = ar->wmi.ops->gen_pdev_resume(ar);
|
||||
if (IS_ERR(skb))
|
||||
return PTR_ERR(skb);
|
||||
|
||||
return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->pdev_resume_cmdid);
|
||||
}
|
||||
|
||||
static inline int
|
||||
ath10k_wmi_pdev_set_param(struct ath10k *ar, u32 id, u32 value)
|
||||
{
|
||||
struct sk_buff *skb;
|
||||
|
||||
if (!ar->wmi.ops->gen_pdev_set_param)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
skb = ar->wmi.ops->gen_pdev_set_param(ar, id, value);
|
||||
if (IS_ERR(skb))
|
||||
return PTR_ERR(skb);
|
||||
|
||||
return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->pdev_set_param_cmdid);
|
||||
}
|
||||
|
||||
static inline int
|
||||
ath10k_wmi_cmd_init(struct ath10k *ar)
|
||||
{
|
||||
struct sk_buff *skb;
|
||||
|
||||
if (!ar->wmi.ops->gen_init)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
skb = ar->wmi.ops->gen_init(ar);
|
||||
if (IS_ERR(skb))
|
||||
return PTR_ERR(skb);
|
||||
|
||||
return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->init_cmdid);
|
||||
}
|
||||
|
||||
static inline int
|
||||
ath10k_wmi_start_scan(struct ath10k *ar,
|
||||
const struct wmi_start_scan_arg *arg)
|
||||
{
|
||||
struct sk_buff *skb;
|
||||
|
||||
if (!ar->wmi.ops->gen_start_scan)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
skb = ar->wmi.ops->gen_start_scan(ar, arg);
|
||||
if (IS_ERR(skb))
|
||||
return PTR_ERR(skb);
|
||||
|
||||
return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->start_scan_cmdid);
|
||||
}
|
||||
|
||||
static inline int
|
||||
ath10k_wmi_stop_scan(struct ath10k *ar, const struct wmi_stop_scan_arg *arg)
|
||||
{
|
||||
struct sk_buff *skb;
|
||||
|
||||
if (!ar->wmi.ops->gen_stop_scan)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
skb = ar->wmi.ops->gen_stop_scan(ar, arg);
|
||||
if (IS_ERR(skb))
|
||||
return PTR_ERR(skb);
|
||||
|
||||
return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->stop_scan_cmdid);
|
||||
}
|
||||
|
||||
static inline int
|
||||
ath10k_wmi_vdev_create(struct ath10k *ar, u32 vdev_id,
|
||||
enum wmi_vdev_type type,
|
||||
enum wmi_vdev_subtype subtype,
|
||||
const u8 macaddr[ETH_ALEN])
|
||||
{
|
||||
struct sk_buff *skb;
|
||||
|
||||
if (!ar->wmi.ops->gen_vdev_create)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
skb = ar->wmi.ops->gen_vdev_create(ar, vdev_id, type, subtype, macaddr);
|
||||
if (IS_ERR(skb))
|
||||
return PTR_ERR(skb);
|
||||
|
||||
return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->vdev_create_cmdid);
|
||||
}
|
||||
|
||||
static inline int
|
||||
ath10k_wmi_vdev_delete(struct ath10k *ar, u32 vdev_id)
|
||||
{
|
||||
struct sk_buff *skb;
|
||||
|
||||
if (!ar->wmi.ops->gen_vdev_delete)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
skb = ar->wmi.ops->gen_vdev_delete(ar, vdev_id);
|
||||
if (IS_ERR(skb))
|
||||
return PTR_ERR(skb);
|
||||
|
||||
return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->vdev_delete_cmdid);
|
||||
}
|
||||
|
||||
static inline int
|
||||
ath10k_wmi_vdev_start(struct ath10k *ar,
|
||||
const struct wmi_vdev_start_request_arg *arg)
|
||||
{
|
||||
struct sk_buff *skb;
|
||||
|
||||
if (!ar->wmi.ops->gen_vdev_start)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
skb = ar->wmi.ops->gen_vdev_start(ar, arg, false);
|
||||
if (IS_ERR(skb))
|
||||
return PTR_ERR(skb);
|
||||
|
||||
return ath10k_wmi_cmd_send(ar, skb,
|
||||
ar->wmi.cmd->vdev_start_request_cmdid);
|
||||
}
|
||||
|
||||
static inline int
|
||||
ath10k_wmi_vdev_restart(struct ath10k *ar,
|
||||
const struct wmi_vdev_start_request_arg *arg)
|
||||
{
|
||||
struct sk_buff *skb;
|
||||
|
||||
if (!ar->wmi.ops->gen_vdev_start)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
skb = ar->wmi.ops->gen_vdev_start(ar, arg, true);
|
||||
if (IS_ERR(skb))
|
||||
return PTR_ERR(skb);
|
||||
|
||||
return ath10k_wmi_cmd_send(ar, skb,
|
||||
ar->wmi.cmd->vdev_restart_request_cmdid);
|
||||
}
|
||||
|
||||
static inline int
|
||||
ath10k_wmi_vdev_stop(struct ath10k *ar, u32 vdev_id)
|
||||
{
|
||||
struct sk_buff *skb;
|
||||
|
||||
if (!ar->wmi.ops->gen_vdev_stop)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
skb = ar->wmi.ops->gen_vdev_stop(ar, vdev_id);
|
||||
if (IS_ERR(skb))
|
||||
return PTR_ERR(skb);
|
||||
|
||||
return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->vdev_stop_cmdid);
|
||||
}
|
||||
|
||||
static inline int
|
||||
ath10k_wmi_vdev_up(struct ath10k *ar, u32 vdev_id, u32 aid, const u8 *bssid)
|
||||
{
|
||||
struct sk_buff *skb;
|
||||
|
||||
if (!ar->wmi.ops->gen_vdev_up)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
skb = ar->wmi.ops->gen_vdev_up(ar, vdev_id, aid, bssid);
|
||||
if (IS_ERR(skb))
|
||||
return PTR_ERR(skb);
|
||||
|
||||
return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->vdev_up_cmdid);
|
||||
}
|
||||
|
||||
static inline int
|
||||
ath10k_wmi_vdev_down(struct ath10k *ar, u32 vdev_id)
|
||||
{
|
||||
struct sk_buff *skb;
|
||||
|
||||
if (!ar->wmi.ops->gen_vdev_down)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
skb = ar->wmi.ops->gen_vdev_down(ar, vdev_id);
|
||||
if (IS_ERR(skb))
|
||||
return PTR_ERR(skb);
|
||||
|
||||
return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->vdev_down_cmdid);
|
||||
}
|
||||
|
||||
static inline int
|
||||
ath10k_wmi_vdev_set_param(struct ath10k *ar, u32 vdev_id, u32 param_id,
|
||||
u32 param_value)
|
||||
{
|
||||
struct sk_buff *skb;
|
||||
|
||||
if (!ar->wmi.ops->gen_vdev_set_param)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
skb = ar->wmi.ops->gen_vdev_set_param(ar, vdev_id, param_id,
|
||||
param_value);
|
||||
if (IS_ERR(skb))
|
||||
return PTR_ERR(skb);
|
||||
|
||||
return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->vdev_set_param_cmdid);
|
||||
}
|
||||
|
||||
static inline int
|
||||
ath10k_wmi_vdev_install_key(struct ath10k *ar,
|
||||
const struct wmi_vdev_install_key_arg *arg)
|
||||
{
|
||||
struct sk_buff *skb;
|
||||
|
||||
if (!ar->wmi.ops->gen_vdev_install_key)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
skb = ar->wmi.ops->gen_vdev_install_key(ar, arg);
|
||||
if (IS_ERR(skb))
|
||||
return PTR_ERR(skb);
|
||||
|
||||
return ath10k_wmi_cmd_send(ar, skb,
|
||||
ar->wmi.cmd->vdev_install_key_cmdid);
|
||||
}
|
||||
|
||||
static inline int
|
||||
ath10k_wmi_vdev_spectral_conf(struct ath10k *ar,
|
||||
const struct wmi_vdev_spectral_conf_arg *arg)
|
||||
{
|
||||
struct sk_buff *skb;
|
||||
u32 cmd_id;
|
||||
|
||||
skb = ar->wmi.ops->gen_vdev_spectral_conf(ar, arg);
|
||||
if (IS_ERR(skb))
|
||||
return PTR_ERR(skb);
|
||||
|
||||
cmd_id = ar->wmi.cmd->vdev_spectral_scan_configure_cmdid;
|
||||
return ath10k_wmi_cmd_send(ar, skb, cmd_id);
|
||||
}
|
||||
|
||||
static inline int
|
||||
ath10k_wmi_vdev_spectral_enable(struct ath10k *ar, u32 vdev_id, u32 trigger,
|
||||
u32 enable)
|
||||
{
|
||||
struct sk_buff *skb;
|
||||
u32 cmd_id;
|
||||
|
||||
skb = ar->wmi.ops->gen_vdev_spectral_enable(ar, vdev_id, trigger,
|
||||
enable);
|
||||
if (IS_ERR(skb))
|
||||
return PTR_ERR(skb);
|
||||
|
||||
cmd_id = ar->wmi.cmd->vdev_spectral_scan_enable_cmdid;
|
||||
return ath10k_wmi_cmd_send(ar, skb, cmd_id);
|
||||
}
|
||||
|
||||
static inline int
|
||||
ath10k_wmi_peer_create(struct ath10k *ar, u32 vdev_id,
|
||||
const u8 peer_addr[ETH_ALEN])
|
||||
{
|
||||
struct sk_buff *skb;
|
||||
|
||||
if (!ar->wmi.ops->gen_peer_create)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
skb = ar->wmi.ops->gen_peer_create(ar, vdev_id, peer_addr);
|
||||
if (IS_ERR(skb))
|
||||
return PTR_ERR(skb);
|
||||
|
||||
return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->peer_create_cmdid);
|
||||
}
|
||||
|
||||
static inline int
|
||||
ath10k_wmi_peer_delete(struct ath10k *ar, u32 vdev_id,
|
||||
const u8 peer_addr[ETH_ALEN])
|
||||
{
|
||||
struct sk_buff *skb;
|
||||
|
||||
if (!ar->wmi.ops->gen_peer_delete)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
skb = ar->wmi.ops->gen_peer_delete(ar, vdev_id, peer_addr);
|
||||
if (IS_ERR(skb))
|
||||
return PTR_ERR(skb);
|
||||
|
||||
return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->peer_delete_cmdid);
|
||||
}
|
||||
|
||||
static inline int
|
||||
ath10k_wmi_peer_flush(struct ath10k *ar, u32 vdev_id,
|
||||
const u8 peer_addr[ETH_ALEN], u32 tid_bitmap)
|
||||
{
|
||||
struct sk_buff *skb;
|
||||
|
||||
if (!ar->wmi.ops->gen_peer_flush)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
skb = ar->wmi.ops->gen_peer_flush(ar, vdev_id, peer_addr, tid_bitmap);
|
||||
if (IS_ERR(skb))
|
||||
return PTR_ERR(skb);
|
||||
|
||||
return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->peer_flush_tids_cmdid);
|
||||
}
|
||||
|
||||
static inline int
|
||||
ath10k_wmi_peer_set_param(struct ath10k *ar, u32 vdev_id, const u8 *peer_addr,
|
||||
enum wmi_peer_param param_id, u32 param_value)
|
||||
{
|
||||
struct sk_buff *skb;
|
||||
|
||||
if (!ar->wmi.ops->gen_peer_set_param)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
skb = ar->wmi.ops->gen_peer_set_param(ar, vdev_id, peer_addr, param_id,
|
||||
param_value);
|
||||
if (IS_ERR(skb))
|
||||
return PTR_ERR(skb);
|
||||
|
||||
return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->peer_set_param_cmdid);
|
||||
}
|
||||
|
||||
static inline int
|
||||
ath10k_wmi_set_psmode(struct ath10k *ar, u32 vdev_id,
|
||||
enum wmi_sta_ps_mode psmode)
|
||||
{
|
||||
struct sk_buff *skb;
|
||||
|
||||
if (!ar->wmi.ops->gen_set_psmode)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
skb = ar->wmi.ops->gen_set_psmode(ar, vdev_id, psmode);
|
||||
if (IS_ERR(skb))
|
||||
return PTR_ERR(skb);
|
||||
|
||||
return ath10k_wmi_cmd_send(ar, skb,
|
||||
ar->wmi.cmd->sta_powersave_mode_cmdid);
|
||||
}
|
||||
|
||||
static inline int
|
||||
ath10k_wmi_set_sta_ps_param(struct ath10k *ar, u32 vdev_id,
|
||||
enum wmi_sta_powersave_param param_id, u32 value)
|
||||
{
|
||||
struct sk_buff *skb;
|
||||
|
||||
if (!ar->wmi.ops->gen_set_sta_ps)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
skb = ar->wmi.ops->gen_set_sta_ps(ar, vdev_id, param_id, value);
|
||||
if (IS_ERR(skb))
|
||||
return PTR_ERR(skb);
|
||||
|
||||
return ath10k_wmi_cmd_send(ar, skb,
|
||||
ar->wmi.cmd->sta_powersave_param_cmdid);
|
||||
}
|
||||
|
||||
static inline int
|
||||
ath10k_wmi_set_ap_ps_param(struct ath10k *ar, u32 vdev_id, const u8 *mac,
|
||||
enum wmi_ap_ps_peer_param param_id, u32 value)
|
||||
{
|
||||
struct sk_buff *skb;
|
||||
|
||||
if (!ar->wmi.ops->gen_set_ap_ps)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
skb = ar->wmi.ops->gen_set_ap_ps(ar, vdev_id, mac, param_id, value);
|
||||
if (IS_ERR(skb))
|
||||
return PTR_ERR(skb);
|
||||
|
||||
return ath10k_wmi_cmd_send(ar, skb,
|
||||
ar->wmi.cmd->ap_ps_peer_param_cmdid);
|
||||
}
|
||||
|
||||
static inline int
|
||||
ath10k_wmi_scan_chan_list(struct ath10k *ar,
|
||||
const struct wmi_scan_chan_list_arg *arg)
|
||||
{
|
||||
struct sk_buff *skb;
|
||||
|
||||
if (!ar->wmi.ops->gen_scan_chan_list)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
skb = ar->wmi.ops->gen_scan_chan_list(ar, arg);
|
||||
if (IS_ERR(skb))
|
||||
return PTR_ERR(skb);
|
||||
|
||||
return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->scan_chan_list_cmdid);
|
||||
}
|
||||
|
||||
static inline int
|
||||
ath10k_wmi_peer_assoc(struct ath10k *ar,
|
||||
const struct wmi_peer_assoc_complete_arg *arg)
|
||||
{
|
||||
struct sk_buff *skb;
|
||||
|
||||
if (!ar->wmi.ops->gen_peer_assoc)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
skb = ar->wmi.ops->gen_peer_assoc(ar, arg);
|
||||
if (IS_ERR(skb))
|
||||
return PTR_ERR(skb);
|
||||
|
||||
return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->peer_assoc_cmdid);
|
||||
}
|
||||
|
||||
static inline int
|
||||
ath10k_wmi_beacon_send_ref_nowait(struct ath10k_vif *arvif)
|
||||
{
|
||||
struct ath10k *ar = arvif->ar;
|
||||
struct sk_buff *skb;
|
||||
int ret;
|
||||
|
||||
if (!ar->wmi.ops->gen_beacon_dma)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
skb = ar->wmi.ops->gen_beacon_dma(arvif);
|
||||
if (IS_ERR(skb))
|
||||
return PTR_ERR(skb);
|
||||
|
||||
ret = ath10k_wmi_cmd_send_nowait(ar, skb,
|
||||
ar->wmi.cmd->pdev_send_bcn_cmdid);
|
||||
if (ret) {
|
||||
dev_kfree_skb(skb);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int
|
||||
ath10k_wmi_pdev_set_wmm_params(struct ath10k *ar,
|
||||
const struct wmi_pdev_set_wmm_params_arg *arg)
|
||||
{
|
||||
struct sk_buff *skb;
|
||||
|
||||
if (!ar->wmi.ops->gen_pdev_set_wmm)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
skb = ar->wmi.ops->gen_pdev_set_wmm(ar, arg);
|
||||
if (IS_ERR(skb))
|
||||
return PTR_ERR(skb);
|
||||
|
||||
return ath10k_wmi_cmd_send(ar, skb,
|
||||
ar->wmi.cmd->pdev_set_wmm_params_cmdid);
|
||||
}
|
||||
|
||||
static inline int
|
||||
ath10k_wmi_request_stats(struct ath10k *ar, enum wmi_stats_id stats_id)
|
||||
{
|
||||
struct sk_buff *skb;
|
||||
|
||||
if (!ar->wmi.ops->gen_request_stats)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
skb = ar->wmi.ops->gen_request_stats(ar, stats_id);
|
||||
if (IS_ERR(skb))
|
||||
return PTR_ERR(skb);
|
||||
|
||||
return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->request_stats_cmdid);
|
||||
}
|
||||
|
||||
static inline int
|
||||
ath10k_wmi_force_fw_hang(struct ath10k *ar,
|
||||
enum wmi_force_fw_hang_type type, u32 delay_ms)
|
||||
{
|
||||
struct sk_buff *skb;
|
||||
|
||||
if (!ar->wmi.ops->gen_force_fw_hang)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
skb = ar->wmi.ops->gen_force_fw_hang(ar, type, delay_ms);
|
||||
if (IS_ERR(skb))
|
||||
return PTR_ERR(skb);
|
||||
|
||||
return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->force_fw_hang_cmdid);
|
||||
}
|
||||
|
||||
static inline int
|
||||
ath10k_wmi_dbglog_cfg(struct ath10k *ar, u32 module_enable)
|
||||
{
|
||||
struct sk_buff *skb;
|
||||
|
||||
if (!ar->wmi.ops->gen_dbglog_cfg)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
skb = ar->wmi.ops->gen_dbglog_cfg(ar, module_enable);
|
||||
if (IS_ERR(skb))
|
||||
return PTR_ERR(skb);
|
||||
|
||||
return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->dbglog_cfg_cmdid);
|
||||
}
|
||||
|
||||
static inline int
|
||||
ath10k_wmi_pdev_pktlog_enable(struct ath10k *ar, u32 filter)
|
||||
{
|
||||
struct sk_buff *skb;
|
||||
|
||||
if (!ar->wmi.ops->gen_pktlog_enable)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
skb = ar->wmi.ops->gen_pktlog_enable(ar, filter);
|
||||
if (IS_ERR(skb))
|
||||
return PTR_ERR(skb);
|
||||
|
||||
return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->pdev_pktlog_enable_cmdid);
|
||||
}
|
||||
|
||||
static inline int
|
||||
ath10k_wmi_pdev_pktlog_disable(struct ath10k *ar)
|
||||
{
|
||||
struct sk_buff *skb;
|
||||
|
||||
if (!ar->wmi.ops->gen_pktlog_disable)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
skb = ar->wmi.ops->gen_pktlog_disable(ar);
|
||||
if (IS_ERR(skb))
|
||||
return PTR_ERR(skb);
|
||||
|
||||
return ath10k_wmi_cmd_send(ar, skb,
|
||||
ar->wmi.cmd->pdev_pktlog_disable_cmdid);
|
||||
}
|
||||
|
||||
static inline int
|
||||
ath10k_wmi_pdev_set_quiet_mode(struct ath10k *ar, u32 period, u32 duration,
|
||||
u32 next_offset, u32 enabled)
|
||||
{
|
||||
struct sk_buff *skb;
|
||||
|
||||
if (!ar->wmi.ops->gen_pdev_set_quiet_mode)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
skb = ar->wmi.ops->gen_pdev_set_quiet_mode(ar, period, duration,
|
||||
next_offset, enabled);
|
||||
if (IS_ERR(skb))
|
||||
return PTR_ERR(skb);
|
||||
|
||||
return ath10k_wmi_cmd_send(ar, skb,
|
||||
ar->wmi.cmd->pdev_set_quiet_mode_cmdid);
|
||||
}
|
||||
|
||||
static inline int
|
||||
ath10k_wmi_pdev_get_temperature(struct ath10k *ar)
|
||||
{
|
||||
struct sk_buff *skb;
|
||||
|
||||
if (!ar->wmi.ops->gen_pdev_get_temperature)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
skb = ar->wmi.ops->gen_pdev_get_temperature(ar);
|
||||
if (IS_ERR(skb))
|
||||
return PTR_ERR(skb);
|
||||
|
||||
return ath10k_wmi_cmd_send(ar, skb,
|
||||
ar->wmi.cmd->pdev_get_temperature_cmdid);
|
||||
}
|
||||
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -109,6 +109,45 @@ enum wmi_service {
|
|||
WMI_SERVICE_BURST,
|
||||
WMI_SERVICE_SMART_ANTENNA_SW_SUPPORT,
|
||||
WMI_SERVICE_SMART_ANTENNA_HW_SUPPORT,
|
||||
WMI_SERVICE_ROAM_SCAN_OFFLOAD,
|
||||
WMI_SERVICE_AP_PS_DETECT_OUT_OF_SYNC,
|
||||
WMI_SERVICE_EARLY_RX,
|
||||
WMI_SERVICE_STA_SMPS,
|
||||
WMI_SERVICE_FWTEST,
|
||||
WMI_SERVICE_STA_WMMAC,
|
||||
WMI_SERVICE_TDLS,
|
||||
WMI_SERVICE_MCC_BCN_INTERVAL_CHANGE,
|
||||
WMI_SERVICE_ADAPTIVE_OCS,
|
||||
WMI_SERVICE_BA_SSN_SUPPORT,
|
||||
WMI_SERVICE_FILTER_IPSEC_NATKEEPALIVE,
|
||||
WMI_SERVICE_WLAN_HB,
|
||||
WMI_SERVICE_LTE_ANT_SHARE_SUPPORT,
|
||||
WMI_SERVICE_BATCH_SCAN,
|
||||
WMI_SERVICE_QPOWER,
|
||||
WMI_SERVICE_PLMREQ,
|
||||
WMI_SERVICE_THERMAL_MGMT,
|
||||
WMI_SERVICE_RMC,
|
||||
WMI_SERVICE_MHF_OFFLOAD,
|
||||
WMI_SERVICE_COEX_SAR,
|
||||
WMI_SERVICE_BCN_TXRATE_OVERRIDE,
|
||||
WMI_SERVICE_NAN,
|
||||
WMI_SERVICE_L1SS_STAT,
|
||||
WMI_SERVICE_ESTIMATE_LINKSPEED,
|
||||
WMI_SERVICE_OBSS_SCAN,
|
||||
WMI_SERVICE_TDLS_OFFCHAN,
|
||||
WMI_SERVICE_TDLS_UAPSD_BUFFER_STA,
|
||||
WMI_SERVICE_TDLS_UAPSD_SLEEP_STA,
|
||||
WMI_SERVICE_IBSS_PWRSAVE,
|
||||
WMI_SERVICE_LPASS,
|
||||
WMI_SERVICE_EXTSCAN,
|
||||
WMI_SERVICE_D0WOW,
|
||||
WMI_SERVICE_HSOFFLOAD,
|
||||
WMI_SERVICE_ROAM_HO_OFFLOAD,
|
||||
WMI_SERVICE_RX_FULL_REORDER,
|
||||
WMI_SERVICE_DHCP_OFFLOAD,
|
||||
WMI_SERVICE_STA_RX_IPA_OFFLOAD_SUPPORT,
|
||||
WMI_SERVICE_MDNS_OFFLOAD,
|
||||
WMI_SERVICE_SAP_AUTH_OFFLOAD,
|
||||
|
||||
/* keep last */
|
||||
WMI_SERVICE_MAX,
|
||||
|
@ -215,6 +254,45 @@ static inline char *wmi_service_name(int service_id)
|
|||
SVCSTR(WMI_SERVICE_BURST);
|
||||
SVCSTR(WMI_SERVICE_SMART_ANTENNA_SW_SUPPORT);
|
||||
SVCSTR(WMI_SERVICE_SMART_ANTENNA_HW_SUPPORT);
|
||||
SVCSTR(WMI_SERVICE_ROAM_SCAN_OFFLOAD);
|
||||
SVCSTR(WMI_SERVICE_AP_PS_DETECT_OUT_OF_SYNC);
|
||||
SVCSTR(WMI_SERVICE_EARLY_RX);
|
||||
SVCSTR(WMI_SERVICE_STA_SMPS);
|
||||
SVCSTR(WMI_SERVICE_FWTEST);
|
||||
SVCSTR(WMI_SERVICE_STA_WMMAC);
|
||||
SVCSTR(WMI_SERVICE_TDLS);
|
||||
SVCSTR(WMI_SERVICE_MCC_BCN_INTERVAL_CHANGE);
|
||||
SVCSTR(WMI_SERVICE_ADAPTIVE_OCS);
|
||||
SVCSTR(WMI_SERVICE_BA_SSN_SUPPORT);
|
||||
SVCSTR(WMI_SERVICE_FILTER_IPSEC_NATKEEPALIVE);
|
||||
SVCSTR(WMI_SERVICE_WLAN_HB);
|
||||
SVCSTR(WMI_SERVICE_LTE_ANT_SHARE_SUPPORT);
|
||||
SVCSTR(WMI_SERVICE_BATCH_SCAN);
|
||||
SVCSTR(WMI_SERVICE_QPOWER);
|
||||
SVCSTR(WMI_SERVICE_PLMREQ);
|
||||
SVCSTR(WMI_SERVICE_THERMAL_MGMT);
|
||||
SVCSTR(WMI_SERVICE_RMC);
|
||||
SVCSTR(WMI_SERVICE_MHF_OFFLOAD);
|
||||
SVCSTR(WMI_SERVICE_COEX_SAR);
|
||||
SVCSTR(WMI_SERVICE_BCN_TXRATE_OVERRIDE);
|
||||
SVCSTR(WMI_SERVICE_NAN);
|
||||
SVCSTR(WMI_SERVICE_L1SS_STAT);
|
||||
SVCSTR(WMI_SERVICE_ESTIMATE_LINKSPEED);
|
||||
SVCSTR(WMI_SERVICE_OBSS_SCAN);
|
||||
SVCSTR(WMI_SERVICE_TDLS_OFFCHAN);
|
||||
SVCSTR(WMI_SERVICE_TDLS_UAPSD_BUFFER_STA);
|
||||
SVCSTR(WMI_SERVICE_TDLS_UAPSD_SLEEP_STA);
|
||||
SVCSTR(WMI_SERVICE_IBSS_PWRSAVE);
|
||||
SVCSTR(WMI_SERVICE_LPASS);
|
||||
SVCSTR(WMI_SERVICE_EXTSCAN);
|
||||
SVCSTR(WMI_SERVICE_D0WOW);
|
||||
SVCSTR(WMI_SERVICE_HSOFFLOAD);
|
||||
SVCSTR(WMI_SERVICE_ROAM_HO_OFFLOAD);
|
||||
SVCSTR(WMI_SERVICE_RX_FULL_REORDER);
|
||||
SVCSTR(WMI_SERVICE_DHCP_OFFLOAD);
|
||||
SVCSTR(WMI_SERVICE_STA_RX_IPA_OFFLOAD_SUPPORT);
|
||||
SVCSTR(WMI_SERVICE_MDNS_OFFLOAD);
|
||||
SVCSTR(WMI_SERVICE_SAP_AUTH_OFFLOAD);
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
|
@ -472,6 +550,7 @@ struct wmi_cmd_map {
|
|||
u32 force_fw_hang_cmdid;
|
||||
u32 gpio_config_cmdid;
|
||||
u32 gpio_output_cmdid;
|
||||
u32 pdev_get_temperature_cmdid;
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -1076,6 +1155,11 @@ enum wmi_10_2_cmd_id {
|
|||
WMI_10_2_PDEV_SET_MIMOGAIN_TABLE_CMDID,
|
||||
WMI_10_2_PDEV_RATEPWR_TABLE_CMDID,
|
||||
WMI_10_2_PDEV_RATEPWR_CHAINMSK_TABLE_CMDID,
|
||||
WMI_10_2_PDEV_GET_INFO,
|
||||
WMI_10_2_VDEV_GET_INFO,
|
||||
WMI_10_2_VDEV_ATF_REQUEST_CMDID,
|
||||
WMI_10_2_PEER_ATF_REQUEST_CMDID,
|
||||
WMI_10_2_PDEV_GET_TEMPERATURE_CMDID,
|
||||
WMI_10_2_PDEV_UTF_CMDID = WMI_10_2_END_CMDID - 1,
|
||||
};
|
||||
|
||||
|
@ -1117,6 +1201,8 @@ enum wmi_10_2_event_id {
|
|||
WMI_10_2_MCAST_BUF_RELEASE_EVENTID,
|
||||
WMI_10_2_MCAST_LIST_AGEOUT_EVENTID,
|
||||
WMI_10_2_WDS_PEER_EVENTID,
|
||||
WMI_10_2_PEER_STA_PS_STATECHG_EVENTID,
|
||||
WMI_10_2_PDEV_TEMPERATURE_EVENTID,
|
||||
WMI_10_2_PDEV_UTF_EVENTID = WMI_10_2_END_EVENTID - 1,
|
||||
};
|
||||
|
||||
|
@ -1862,6 +1948,11 @@ struct wmi_resource_config_10x {
|
|||
__le32 max_frag_entries;
|
||||
} __packed;
|
||||
|
||||
enum wmi_10_2_feature_mask {
|
||||
WMI_10_2_RX_BATCH_MODE = BIT(0),
|
||||
WMI_10_2_ATF_CONFIG = BIT(1),
|
||||
};
|
||||
|
||||
struct wmi_resource_config_10_2 {
|
||||
struct wmi_resource_config_10x common;
|
||||
__le32 max_peer_ext_stats;
|
||||
|
@ -1870,7 +1961,7 @@ struct wmi_resource_config_10_2 {
|
|||
__le32 be_min_free;
|
||||
__le32 vi_min_free;
|
||||
__le32 vo_min_free;
|
||||
__le32 rx_batchmode; /* 0-disable, 1-enable */
|
||||
__le32 feature_mask;
|
||||
} __packed;
|
||||
|
||||
#define NUM_UNITS_IS_NUM_VDEVS 0x1
|
||||
|
@ -2505,6 +2596,7 @@ struct wmi_pdev_param_map {
|
|||
u32 fast_channel_reset;
|
||||
u32 burst_dur;
|
||||
u32 burst_enable;
|
||||
u32 cal_period;
|
||||
};
|
||||
|
||||
#define WMI_PDEV_PARAM_UNSUPPORTED 0
|
||||
|
@ -2715,6 +2807,9 @@ enum wmi_10x_pdev_param {
|
|||
WMI_10X_PDEV_PARAM_SET_MCAST2UCAST_MODE,
|
||||
WMI_10X_PDEV_PARAM_SET_MCAST2UCAST_BUFFER,
|
||||
WMI_10X_PDEV_PARAM_REMOVE_MCAST2UCAST_BUFFER,
|
||||
WMI_10X_PDEV_PARAM_PEER_STA_PS_STATECHG_ENABLE,
|
||||
WMI_10X_PDEV_PARAM_RTS_FIXED_RATE,
|
||||
WMI_10X_PDEV_PARAM_CAL_PERIOD
|
||||
};
|
||||
|
||||
struct wmi_pdev_set_param_cmd {
|
||||
|
@ -2722,6 +2817,9 @@ struct wmi_pdev_set_param_cmd {
|
|||
__le32 param_value;
|
||||
} __packed;
|
||||
|
||||
/* valid period is 1 ~ 60000ms, unit in millisecond */
|
||||
#define WMI_PDEV_PARAM_CAL_PERIOD_MAX 60000
|
||||
|
||||
struct wmi_pdev_get_tpc_config_cmd {
|
||||
/* parameter */
|
||||
__le32 param;
|
||||
|
@ -3930,6 +4028,13 @@ enum wmi_sta_ps_param_pspoll_count {
|
|||
* Values greater than 0 indicate the maximum numer of PS-Poll frames
|
||||
* FW will send before waking up.
|
||||
*/
|
||||
|
||||
/* When u-APSD is enabled the firmware will be very reluctant to exit
|
||||
* STA PS. This could result in very poor Rx performance with STA doing
|
||||
* PS-Poll for each and every buffered frame. This value is a bit
|
||||
* arbitrary.
|
||||
*/
|
||||
WMI_STA_PS_PSPOLL_COUNT_UAPSD = 3,
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -4120,7 +4225,7 @@ struct wmi_bcn_info {
|
|||
|
||||
struct wmi_host_swba_event {
|
||||
__le32 vdev_map;
|
||||
struct wmi_bcn_info bcn_info[1];
|
||||
struct wmi_bcn_info bcn_info[0];
|
||||
} __packed;
|
||||
|
||||
#define WMI_MAX_AP_VDEV 16
|
||||
|
@ -4567,6 +4672,58 @@ struct wmi_dbglog_cfg_cmd {
|
|||
|
||||
#define WMI_MAX_MEM_REQS 16
|
||||
|
||||
struct wmi_scan_ev_arg {
|
||||
__le32 event_type; /* %WMI_SCAN_EVENT_ */
|
||||
__le32 reason; /* %WMI_SCAN_REASON_ */
|
||||
__le32 channel_freq; /* only valid for WMI_SCAN_EVENT_FOREIGN_CHANNEL */
|
||||
__le32 scan_req_id;
|
||||
__le32 scan_id;
|
||||
__le32 vdev_id;
|
||||
};
|
||||
|
||||
struct wmi_mgmt_rx_ev_arg {
|
||||
__le32 channel;
|
||||
__le32 snr;
|
||||
__le32 rate;
|
||||
__le32 phy_mode;
|
||||
__le32 buf_len;
|
||||
__le32 status; /* %WMI_RX_STATUS_ */
|
||||
};
|
||||
|
||||
struct wmi_ch_info_ev_arg {
|
||||
__le32 err_code;
|
||||
__le32 freq;
|
||||
__le32 cmd_flags;
|
||||
__le32 noise_floor;
|
||||
__le32 rx_clear_count;
|
||||
__le32 cycle_count;
|
||||
};
|
||||
|
||||
struct wmi_vdev_start_ev_arg {
|
||||
__le32 vdev_id;
|
||||
__le32 req_id;
|
||||
__le32 resp_type; /* %WMI_VDEV_RESP_ */
|
||||
__le32 status;
|
||||
};
|
||||
|
||||
struct wmi_peer_kick_ev_arg {
|
||||
const u8 *mac_addr;
|
||||
};
|
||||
|
||||
struct wmi_swba_ev_arg {
|
||||
__le32 vdev_map;
|
||||
const struct wmi_tim_info *tim_info[WMI_MAX_AP_VDEV];
|
||||
const struct wmi_p2p_noa_info *noa_info[WMI_MAX_AP_VDEV];
|
||||
};
|
||||
|
||||
struct wmi_phyerr_ev_arg {
|
||||
__le32 num_phyerrs;
|
||||
__le32 tsf_l32;
|
||||
__le32 tsf_u32;
|
||||
__le32 buf_len;
|
||||
const struct wmi_phyerr *phyerrs;
|
||||
};
|
||||
|
||||
struct wmi_svc_rdy_ev_arg {
|
||||
__le32 min_tx_power;
|
||||
__le32 max_tx_power;
|
||||
|
@ -4574,6 +4731,7 @@ struct wmi_svc_rdy_ev_arg {
|
|||
__le32 vht_cap;
|
||||
__le32 sw_ver0;
|
||||
__le32 sw_ver1;
|
||||
__le32 fw_build;
|
||||
__le32 phy_capab;
|
||||
__le32 num_rf_chains;
|
||||
__le32 eeprom_rd;
|
||||
|
@ -4583,83 +4741,93 @@ struct wmi_svc_rdy_ev_arg {
|
|||
const struct wlan_host_mem_req *mem_reqs[WMI_MAX_MEM_REQS];
|
||||
};
|
||||
|
||||
struct wmi_rdy_ev_arg {
|
||||
__le32 sw_version;
|
||||
__le32 abi_version;
|
||||
__le32 status;
|
||||
const u8 *mac_addr;
|
||||
};
|
||||
|
||||
struct wmi_pdev_temperature_event {
|
||||
/* temperature value in Celcius degree */
|
||||
__le32 temperature;
|
||||
} __packed;
|
||||
|
||||
struct ath10k;
|
||||
struct ath10k_vif;
|
||||
struct ath10k_fw_stats;
|
||||
struct ath10k_fw_stats_pdev;
|
||||
struct ath10k_fw_stats_peer;
|
||||
|
||||
int ath10k_wmi_attach(struct ath10k *ar);
|
||||
void ath10k_wmi_detach(struct ath10k *ar);
|
||||
int ath10k_wmi_wait_for_service_ready(struct ath10k *ar);
|
||||
int ath10k_wmi_wait_for_unified_ready(struct ath10k *ar);
|
||||
|
||||
struct sk_buff *ath10k_wmi_alloc_skb(struct ath10k *ar, u32 len);
|
||||
int ath10k_wmi_connect(struct ath10k *ar);
|
||||
|
||||
struct sk_buff *ath10k_wmi_alloc_skb(struct ath10k *ar, u32 len);
|
||||
int ath10k_wmi_cmd_send(struct ath10k *ar, struct sk_buff *skb, u32 cmd_id);
|
||||
|
||||
int ath10k_wmi_pdev_suspend_target(struct ath10k *ar, u32 suspend_opt);
|
||||
int ath10k_wmi_pdev_resume_target(struct ath10k *ar);
|
||||
int ath10k_wmi_pdev_set_regdomain(struct ath10k *ar, u16 rd, u16 rd2g,
|
||||
u16 rd5g, u16 ctl2g, u16 ctl5g,
|
||||
enum wmi_dfs_region dfs_reg);
|
||||
int ath10k_wmi_pdev_set_param(struct ath10k *ar, u32 id, u32 value);
|
||||
int ath10k_wmi_cmd_init(struct ath10k *ar);
|
||||
int ath10k_wmi_start_scan(struct ath10k *ar, const struct wmi_start_scan_arg *);
|
||||
int ath10k_wmi_cmd_send_nowait(struct ath10k *ar, struct sk_buff *skb,
|
||||
u32 cmd_id);
|
||||
void ath10k_wmi_start_scan_init(struct ath10k *ar, struct wmi_start_scan_arg *);
|
||||
int ath10k_wmi_stop_scan(struct ath10k *ar,
|
||||
const struct wmi_stop_scan_arg *arg);
|
||||
int ath10k_wmi_vdev_create(struct ath10k *ar, u32 vdev_id,
|
||||
enum wmi_vdev_type type,
|
||||
enum wmi_vdev_subtype subtype,
|
||||
const u8 macaddr[ETH_ALEN]);
|
||||
int ath10k_wmi_vdev_delete(struct ath10k *ar, u32 vdev_id);
|
||||
int ath10k_wmi_vdev_start(struct ath10k *ar,
|
||||
const struct wmi_vdev_start_request_arg *);
|
||||
int ath10k_wmi_vdev_restart(struct ath10k *ar,
|
||||
const struct wmi_vdev_start_request_arg *);
|
||||
int ath10k_wmi_vdev_stop(struct ath10k *ar, u32 vdev_id);
|
||||
int ath10k_wmi_vdev_up(struct ath10k *ar, u32 vdev_id, u32 aid,
|
||||
const u8 *bssid);
|
||||
int ath10k_wmi_vdev_down(struct ath10k *ar, u32 vdev_id);
|
||||
int ath10k_wmi_vdev_set_param(struct ath10k *ar, u32 vdev_id,
|
||||
u32 param_id, u32 param_value);
|
||||
int ath10k_wmi_vdev_install_key(struct ath10k *ar,
|
||||
const struct wmi_vdev_install_key_arg *arg);
|
||||
int ath10k_wmi_vdev_spectral_conf(struct ath10k *ar,
|
||||
const struct wmi_vdev_spectral_conf_arg *arg);
|
||||
int ath10k_wmi_vdev_spectral_enable(struct ath10k *ar, u32 vdev_id, u32 trigger,
|
||||
u32 enable);
|
||||
int ath10k_wmi_peer_create(struct ath10k *ar, u32 vdev_id,
|
||||
const u8 peer_addr[ETH_ALEN]);
|
||||
int ath10k_wmi_peer_delete(struct ath10k *ar, u32 vdev_id,
|
||||
const u8 peer_addr[ETH_ALEN]);
|
||||
int ath10k_wmi_peer_flush(struct ath10k *ar, u32 vdev_id,
|
||||
const u8 peer_addr[ETH_ALEN], u32 tid_bitmap);
|
||||
int ath10k_wmi_peer_set_param(struct ath10k *ar, u32 vdev_id,
|
||||
const u8 *peer_addr,
|
||||
enum wmi_peer_param param_id, u32 param_value);
|
||||
int ath10k_wmi_peer_assoc(struct ath10k *ar,
|
||||
const struct wmi_peer_assoc_complete_arg *arg);
|
||||
int ath10k_wmi_set_psmode(struct ath10k *ar, u32 vdev_id,
|
||||
enum wmi_sta_ps_mode psmode);
|
||||
int ath10k_wmi_set_sta_ps_param(struct ath10k *ar, u32 vdev_id,
|
||||
enum wmi_sta_powersave_param param_id,
|
||||
u32 value);
|
||||
int ath10k_wmi_set_ap_ps_param(struct ath10k *ar, u32 vdev_id, const u8 *mac,
|
||||
enum wmi_ap_ps_peer_param param_id, u32 value);
|
||||
int ath10k_wmi_scan_chan_list(struct ath10k *ar,
|
||||
const struct wmi_scan_chan_list_arg *arg);
|
||||
int ath10k_wmi_beacon_send_ref_nowait(struct ath10k_vif *arvif);
|
||||
int ath10k_wmi_pdev_set_wmm_params(struct ath10k *ar,
|
||||
const struct wmi_pdev_set_wmm_params_arg *arg);
|
||||
int ath10k_wmi_request_stats(struct ath10k *ar, enum wmi_stats_id stats_id);
|
||||
int ath10k_wmi_force_fw_hang(struct ath10k *ar,
|
||||
enum wmi_force_fw_hang_type type, u32 delay_ms);
|
||||
int ath10k_wmi_mgmt_tx(struct ath10k *ar, struct sk_buff *skb);
|
||||
int ath10k_wmi_dbglog_cfg(struct ath10k *ar, u32 module_enable);
|
||||
int ath10k_wmi_pull_fw_stats(struct ath10k *ar, struct sk_buff *skb,
|
||||
struct ath10k_fw_stats *stats);
|
||||
int ath10k_wmi_pdev_pktlog_enable(struct ath10k *ar, u32 ev_list);
|
||||
int ath10k_wmi_pdev_pktlog_disable(struct ath10k *ar);
|
||||
|
||||
void ath10k_wmi_pull_pdev_stats(const struct wmi_pdev_stats *src,
|
||||
struct ath10k_fw_stats_pdev *dst);
|
||||
void ath10k_wmi_pull_peer_stats(const struct wmi_peer_stats *src,
|
||||
struct ath10k_fw_stats_peer *dst);
|
||||
void ath10k_wmi_put_host_mem_chunks(struct ath10k *ar,
|
||||
struct wmi_host_mem_chunks *chunks);
|
||||
void ath10k_wmi_put_start_scan_common(struct wmi_start_scan_common *cmn,
|
||||
const struct wmi_start_scan_arg *arg);
|
||||
void ath10k_wmi_pdev_set_wmm_param(struct wmi_wmm_params *params,
|
||||
const struct wmi_wmm_params_arg *arg);
|
||||
void ath10k_wmi_put_wmi_channel(struct wmi_channel *ch,
|
||||
const struct wmi_channel_arg *arg);
|
||||
int ath10k_wmi_start_scan_verify(const struct wmi_start_scan_arg *arg);
|
||||
|
||||
int ath10k_wmi_event_scan(struct ath10k *ar, struct sk_buff *skb);
|
||||
int ath10k_wmi_event_mgmt_rx(struct ath10k *ar, struct sk_buff *skb);
|
||||
void ath10k_wmi_event_chan_info(struct ath10k *ar, struct sk_buff *skb);
|
||||
void ath10k_wmi_event_echo(struct ath10k *ar, struct sk_buff *skb);
|
||||
int ath10k_wmi_event_debug_mesg(struct ath10k *ar, struct sk_buff *skb);
|
||||
void ath10k_wmi_event_update_stats(struct ath10k *ar, struct sk_buff *skb);
|
||||
void ath10k_wmi_event_vdev_start_resp(struct ath10k *ar, struct sk_buff *skb);
|
||||
void ath10k_wmi_event_vdev_stopped(struct ath10k *ar, struct sk_buff *skb);
|
||||
void ath10k_wmi_event_peer_sta_kickout(struct ath10k *ar, struct sk_buff *skb);
|
||||
void ath10k_wmi_event_host_swba(struct ath10k *ar, struct sk_buff *skb);
|
||||
void ath10k_wmi_event_tbttoffset_update(struct ath10k *ar, struct sk_buff *skb);
|
||||
void ath10k_wmi_event_dfs(struct ath10k *ar,
|
||||
const struct wmi_phyerr *phyerr, u64 tsf);
|
||||
void ath10k_wmi_event_spectral_scan(struct ath10k *ar,
|
||||
const struct wmi_phyerr *phyerr,
|
||||
u64 tsf);
|
||||
void ath10k_wmi_event_phyerr(struct ath10k *ar, struct sk_buff *skb);
|
||||
void ath10k_wmi_event_roam(struct ath10k *ar, struct sk_buff *skb);
|
||||
void ath10k_wmi_event_profile_match(struct ath10k *ar, struct sk_buff *skb);
|
||||
void ath10k_wmi_event_debug_print(struct ath10k *ar, struct sk_buff *skb);
|
||||
void ath10k_wmi_event_pdev_qvit(struct ath10k *ar, struct sk_buff *skb);
|
||||
void ath10k_wmi_event_wlan_profile_data(struct ath10k *ar, struct sk_buff *skb);
|
||||
void ath10k_wmi_event_rtt_measurement_report(struct ath10k *ar,
|
||||
struct sk_buff *skb);
|
||||
void ath10k_wmi_event_tsf_measurement_report(struct ath10k *ar,
|
||||
struct sk_buff *skb);
|
||||
void ath10k_wmi_event_rtt_error_report(struct ath10k *ar, struct sk_buff *skb);
|
||||
void ath10k_wmi_event_wow_wakeup_host(struct ath10k *ar, struct sk_buff *skb);
|
||||
void ath10k_wmi_event_dcs_interference(struct ath10k *ar, struct sk_buff *skb);
|
||||
void ath10k_wmi_event_pdev_tpc_config(struct ath10k *ar, struct sk_buff *skb);
|
||||
void ath10k_wmi_event_pdev_ftm_intg(struct ath10k *ar, struct sk_buff *skb);
|
||||
void ath10k_wmi_event_gtk_offload_status(struct ath10k *ar,
|
||||
struct sk_buff *skb);
|
||||
void ath10k_wmi_event_gtk_rekey_fail(struct ath10k *ar, struct sk_buff *skb);
|
||||
void ath10k_wmi_event_delba_complete(struct ath10k *ar, struct sk_buff *skb);
|
||||
void ath10k_wmi_event_addba_complete(struct ath10k *ar, struct sk_buff *skb);
|
||||
void ath10k_wmi_event_vdev_install_key_complete(struct ath10k *ar,
|
||||
struct sk_buff *skb);
|
||||
void ath10k_wmi_event_inst_rssi_stats(struct ath10k *ar, struct sk_buff *skb);
|
||||
void ath10k_wmi_event_vdev_standby_req(struct ath10k *ar, struct sk_buff *skb);
|
||||
void ath10k_wmi_event_vdev_resume_req(struct ath10k *ar, struct sk_buff *skb);
|
||||
void ath10k_wmi_event_service_ready(struct ath10k *ar, struct sk_buff *skb);
|
||||
int ath10k_wmi_event_ready(struct ath10k *ar, struct sk_buff *skb);
|
||||
|
||||
#endif /* _WMI_H_ */
|
||||
|
|
Loading…
Reference in New Issue