mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2024-12-11 14:16:43 +07:00
Merge branch 'for-linville' of git://github.com/kvalo/ath
This commit is contained in:
commit
687b93082c
@ -24,7 +24,7 @@ config ATH10K_DEBUG
|
||||
|
||||
config ATH10K_DEBUGFS
|
||||
bool "Atheros ath10k debugfs support"
|
||||
depends on ATH10K
|
||||
depends on ATH10K && DEBUG_FS
|
||||
select RELAY
|
||||
---help---
|
||||
Enabled debugfs support
|
||||
|
@ -11,6 +11,7 @@ ath10k_core-y += mac.o \
|
||||
bmi.o
|
||||
|
||||
ath10k_core-$(CONFIG_ATH10K_DEBUGFS) += spectral.o
|
||||
ath10k_core-$(CONFIG_NL80211_TESTMODE) += testmode.o
|
||||
ath10k_core-$(CONFIG_ATH10K_TRACING) += trace.o
|
||||
|
||||
obj-$(CONFIG_ATH10K_PCI) += ath10k_pci.o
|
||||
|
@ -177,7 +177,6 @@ struct bmi_target_info {
|
||||
u32 type;
|
||||
};
|
||||
|
||||
|
||||
/* in msec */
|
||||
#define BMI_COMMUNICATION_TIMEOUT_HZ (1*HZ)
|
||||
|
||||
|
@ -260,7 +260,6 @@ static inline void ath10k_ce_engine_int_status_clear(struct ath10k *ar,
|
||||
ath10k_pci_write32(ar, ce_ctrl_addr + HOST_IS_ADDRESS, mask);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Guts of ath10k_ce_send, used by both ath10k_ce_send and
|
||||
* ath10k_ce_sendlist_send.
|
||||
@ -385,7 +384,6 @@ int ath10k_ce_num_free_src_entries(struct ath10k_ce_pipe *pipe)
|
||||
return delta;
|
||||
}
|
||||
|
||||
|
||||
int __ath10k_ce_rx_num_free_bufs(struct ath10k_ce_pipe *pipe)
|
||||
{
|
||||
struct ath10k *ar = pipe->ar;
|
||||
|
@ -20,7 +20,6 @@
|
||||
|
||||
#include "hif.h"
|
||||
|
||||
|
||||
/* Maximum number of Copy Engine's supported */
|
||||
#define CE_COUNT_MAX 8
|
||||
#define CE_HTT_H2T_MSG_SRC_NENTRIES 4096
|
||||
@ -37,7 +36,6 @@
|
||||
|
||||
struct ath10k_ce_pipe;
|
||||
|
||||
|
||||
#define CE_DESC_FLAGS_GATHER (1 << 0)
|
||||
#define CE_DESC_FLAGS_BYTE_SWAP (1 << 1)
|
||||
#define CE_DESC_FLAGS_META_DATA_MASK 0xFFFC
|
||||
@ -189,10 +187,10 @@ int ath10k_ce_completed_recv_next(struct ath10k_ce_pipe *ce_state,
|
||||
* Pops 1 completed send buffer from Source ring.
|
||||
*/
|
||||
int ath10k_ce_completed_send_next(struct ath10k_ce_pipe *ce_state,
|
||||
void **per_transfer_contextp,
|
||||
u32 *bufferp,
|
||||
unsigned int *nbytesp,
|
||||
unsigned int *transfer_idp);
|
||||
void **per_transfer_contextp,
|
||||
u32 *bufferp,
|
||||
unsigned int *nbytesp,
|
||||
unsigned int *transfer_idp);
|
||||
|
||||
/*==================CE Engine Initialization=======================*/
|
||||
|
||||
@ -202,7 +200,7 @@ int ath10k_ce_init_pipe(struct ath10k *ar, unsigned int ce_id,
|
||||
void (*recv_cb)(struct ath10k_ce_pipe *));
|
||||
void ath10k_ce_deinit_pipe(struct ath10k *ar, unsigned int ce_id);
|
||||
int ath10k_ce_alloc_pipe(struct ath10k *ar, int ce_id,
|
||||
const struct ce_attr *attr);
|
||||
const struct ce_attr *attr);
|
||||
void ath10k_ce_free_pipe(struct ath10k *ar, int ce_id);
|
||||
|
||||
/*==================CE Engine Shutdown=======================*/
|
||||
@ -383,7 +381,6 @@ struct ce_attr {
|
||||
#define DST_WATERMARK_HIGH_RESET 0
|
||||
#define DST_WATERMARK_ADDRESS 0x0050
|
||||
|
||||
|
||||
static inline u32 ath10k_ce_base_address(unsigned int ce_id)
|
||||
{
|
||||
return CE0_BASE_ADDRESS + (CE1_BASE_ADDRESS - CE0_BASE_ADDRESS) * ce_id;
|
||||
|
@ -26,6 +26,7 @@
|
||||
#include "bmi.h"
|
||||
#include "debug.h"
|
||||
#include "htt.h"
|
||||
#include "testmode.h"
|
||||
|
||||
unsigned int ath10k_debug_mask;
|
||||
static bool uart_print;
|
||||
@ -257,21 +258,42 @@ static int ath10k_download_and_run_otp(struct ath10k *ar)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ath10k_download_fw(struct ath10k *ar)
|
||||
static int ath10k_download_fw(struct ath10k *ar, enum ath10k_firmware_mode mode)
|
||||
{
|
||||
u32 address;
|
||||
u32 address, data_len;
|
||||
const char *mode_name;
|
||||
const void *data;
|
||||
int ret;
|
||||
|
||||
address = ar->hw_params.patch_load_addr;
|
||||
|
||||
ret = ath10k_bmi_fast_download(ar, address, ar->firmware_data,
|
||||
ar->firmware_len);
|
||||
if (ret) {
|
||||
ath10k_err(ar, "could not write fw (%d)\n", ret);
|
||||
goto exit;
|
||||
switch (mode) {
|
||||
case ATH10K_FIRMWARE_MODE_NORMAL:
|
||||
data = ar->firmware_data;
|
||||
data_len = ar->firmware_len;
|
||||
mode_name = "normal";
|
||||
break;
|
||||
case ATH10K_FIRMWARE_MODE_UTF:
|
||||
data = ar->testmode.utf->data;
|
||||
data_len = ar->testmode.utf->size;
|
||||
mode_name = "utf";
|
||||
break;
|
||||
default:
|
||||
ath10k_err(ar, "unknown firmware mode: %d\n", mode);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ath10k_dbg(ar, ATH10K_DBG_BOOT,
|
||||
"boot uploading firmware image %p len %d mode %s\n",
|
||||
data, data_len, mode_name);
|
||||
|
||||
ret = ath10k_bmi_fast_download(ar, address, data, data_len);
|
||||
if (ret) {
|
||||
ath10k_err(ar, "failed to download %s firmware: %d\n",
|
||||
mode_name, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
exit:
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -567,7 +589,8 @@ static int ath10k_core_fetch_firmware_files(struct ath10k *ar)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ath10k_init_download_firmware(struct ath10k *ar)
|
||||
static int ath10k_init_download_firmware(struct ath10k *ar,
|
||||
enum ath10k_firmware_mode mode)
|
||||
{
|
||||
int ret;
|
||||
|
||||
@ -583,7 +606,7 @@ static int ath10k_init_download_firmware(struct ath10k *ar)
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = ath10k_download_fw(ar);
|
||||
ret = ath10k_download_fw(ar, mode);
|
||||
if (ret) {
|
||||
ath10k_err(ar, "failed to download firmware: %d\n", ret);
|
||||
return ret;
|
||||
@ -685,12 +708,15 @@ static void ath10k_core_restart(struct work_struct *work)
|
||||
case ATH10K_STATE_WEDGED:
|
||||
ath10k_warn(ar, "device is wedged, will not restart\n");
|
||||
break;
|
||||
case ATH10K_STATE_UTF:
|
||||
ath10k_warn(ar, "firmware restart in UTF mode not supported\n");
|
||||
break;
|
||||
}
|
||||
|
||||
mutex_unlock(&ar->conf_mutex);
|
||||
}
|
||||
|
||||
int ath10k_core_start(struct ath10k *ar)
|
||||
int ath10k_core_start(struct ath10k *ar, enum ath10k_firmware_mode mode)
|
||||
{
|
||||
int status;
|
||||
|
||||
@ -703,7 +729,7 @@ int ath10k_core_start(struct ath10k *ar)
|
||||
goto err;
|
||||
}
|
||||
|
||||
status = ath10k_init_download_firmware(ar);
|
||||
status = ath10k_init_download_firmware(ar, mode);
|
||||
if (status)
|
||||
goto err;
|
||||
|
||||
@ -760,10 +786,12 @@ int ath10k_core_start(struct ath10k *ar)
|
||||
goto err_hif_stop;
|
||||
}
|
||||
|
||||
status = ath10k_htt_connect(&ar->htt);
|
||||
if (status) {
|
||||
ath10k_err(ar, "failed to connect htt (%d)\n", status);
|
||||
goto err_hif_stop;
|
||||
if (mode == ATH10K_FIRMWARE_MODE_NORMAL) {
|
||||
status = ath10k_htt_connect(&ar->htt);
|
||||
if (status) {
|
||||
ath10k_err(ar, "failed to connect htt (%d)\n", status);
|
||||
goto err_hif_stop;
|
||||
}
|
||||
}
|
||||
|
||||
status = ath10k_wmi_connect(ar);
|
||||
@ -778,11 +806,13 @@ int ath10k_core_start(struct ath10k *ar)
|
||||
goto err_hif_stop;
|
||||
}
|
||||
|
||||
status = ath10k_wmi_wait_for_service_ready(ar);
|
||||
if (status <= 0) {
|
||||
ath10k_warn(ar, "wmi service ready event not received");
|
||||
status = -ETIMEDOUT;
|
||||
goto err_hif_stop;
|
||||
if (mode == ATH10K_FIRMWARE_MODE_NORMAL) {
|
||||
status = ath10k_wmi_wait_for_service_ready(ar);
|
||||
if (status <= 0) {
|
||||
ath10k_warn(ar, "wmi service ready event not received");
|
||||
status = -ETIMEDOUT;
|
||||
goto err_hif_stop;
|
||||
}
|
||||
}
|
||||
|
||||
ath10k_dbg(ar, ATH10K_DBG_BOOT, "firmware %s booted\n",
|
||||
@ -802,10 +832,13 @@ int ath10k_core_start(struct ath10k *ar)
|
||||
goto err_hif_stop;
|
||||
}
|
||||
|
||||
status = ath10k_htt_setup(&ar->htt);
|
||||
if (status) {
|
||||
ath10k_err(ar, "failed to setup htt: %d\n", status);
|
||||
goto err_hif_stop;
|
||||
/* we don't care about HTT in UTF mode */
|
||||
if (mode == ATH10K_FIRMWARE_MODE_NORMAL) {
|
||||
status = ath10k_htt_setup(&ar->htt);
|
||||
if (status) {
|
||||
ath10k_err(ar, "failed to setup htt: %d\n", status);
|
||||
goto err_hif_stop;
|
||||
}
|
||||
}
|
||||
|
||||
status = ath10k_debug_start(ar);
|
||||
@ -861,7 +894,8 @@ void ath10k_core_stop(struct ath10k *ar)
|
||||
lockdep_assert_held(&ar->conf_mutex);
|
||||
|
||||
/* try to suspend target */
|
||||
if (ar->state != ATH10K_STATE_RESTARTING)
|
||||
if (ar->state != ATH10K_STATE_RESTARTING &&
|
||||
ar->state != ATH10K_STATE_UTF)
|
||||
ath10k_wait_for_suspend(ar, WMI_PDEV_SUSPEND_AND_DISABLE_INTR);
|
||||
|
||||
ath10k_debug_stop(ar);
|
||||
@ -914,7 +948,7 @@ static int ath10k_core_probe_fw(struct ath10k *ar)
|
||||
|
||||
mutex_lock(&ar->conf_mutex);
|
||||
|
||||
ret = ath10k_core_start(ar);
|
||||
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);
|
||||
@ -977,7 +1011,7 @@ static void ath10k_core_register_work(struct work_struct *work)
|
||||
goto err_release_fw;
|
||||
}
|
||||
|
||||
status = ath10k_debug_create(ar);
|
||||
status = ath10k_debug_register(ar);
|
||||
if (status) {
|
||||
ath10k_err(ar, "unable to initialize debugfs\n");
|
||||
goto err_unregister_mac;
|
||||
@ -1041,9 +1075,11 @@ void ath10k_core_unregister(struct ath10k *ar)
|
||||
* unhappy about callback failures. */
|
||||
ath10k_mac_unregister(ar);
|
||||
|
||||
ath10k_testmode_destroy(ar);
|
||||
|
||||
ath10k_core_free_firmware_files(ar);
|
||||
|
||||
ath10k_debug_destroy(ar);
|
||||
ath10k_debug_unregister(ar);
|
||||
}
|
||||
EXPORT_SYMBOL(ath10k_core_unregister);
|
||||
|
||||
@ -1051,6 +1087,7 @@ struct ath10k *ath10k_core_create(size_t priv_size, struct device *dev,
|
||||
const struct ath10k_hif_ops *hif_ops)
|
||||
{
|
||||
struct ath10k *ar;
|
||||
int ret;
|
||||
|
||||
ar = ath10k_mac_create(priv_size);
|
||||
if (!ar)
|
||||
@ -1076,7 +1113,7 @@ struct ath10k *ath10k_core_create(size_t priv_size, struct device *dev,
|
||||
|
||||
ar->workqueue = create_singlethread_workqueue("ath10k_wq");
|
||||
if (!ar->workqueue)
|
||||
goto err_wq;
|
||||
goto err_free_mac;
|
||||
|
||||
mutex_init(&ar->conf_mutex);
|
||||
spin_lock_init(&ar->data_lock);
|
||||
@ -1094,10 +1131,18 @@ struct ath10k *ath10k_core_create(size_t priv_size, struct device *dev,
|
||||
INIT_WORK(&ar->register_work, ath10k_core_register_work);
|
||||
INIT_WORK(&ar->restart_work, ath10k_core_restart);
|
||||
|
||||
ret = ath10k_debug_create(ar);
|
||||
if (ret)
|
||||
goto err_free_wq;
|
||||
|
||||
return ar;
|
||||
|
||||
err_wq:
|
||||
err_free_wq:
|
||||
destroy_workqueue(ar->workqueue);
|
||||
|
||||
err_free_mac:
|
||||
ath10k_mac_destroy(ar);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
EXPORT_SYMBOL(ath10k_core_create);
|
||||
@ -1107,6 +1152,7 @@ void ath10k_core_destroy(struct ath10k *ar)
|
||||
flush_workqueue(ar->workqueue);
|
||||
destroy_workqueue(ar->workqueue);
|
||||
|
||||
ath10k_debug_destroy(ar);
|
||||
ath10k_mac_destroy(ar);
|
||||
}
|
||||
EXPORT_SYMBOL(ath10k_core_destroy);
|
||||
|
@ -293,7 +293,7 @@ struct ath10k_debug {
|
||||
struct dentry *debugfs_phy;
|
||||
|
||||
struct ath10k_target_stats target_stats;
|
||||
DECLARE_BITMAP(wmi_service_bitmap, WMI_SERVICE_BM_SIZE);
|
||||
DECLARE_BITMAP(wmi_service_bitmap, WMI_SERVICE_MAX);
|
||||
|
||||
struct completion event_stats_compl;
|
||||
|
||||
@ -330,6 +330,17 @@ enum ath10k_state {
|
||||
* prevents completion timeouts and makes the driver more responsive to
|
||||
* userspace commands. This is also prevents recursive recovery. */
|
||||
ATH10K_STATE_WEDGED,
|
||||
|
||||
/* factory tests */
|
||||
ATH10K_STATE_UTF,
|
||||
};
|
||||
|
||||
enum ath10k_firmware_mode {
|
||||
/* the default mode, standard 802.11 functionality */
|
||||
ATH10K_FIRMWARE_MODE_NORMAL,
|
||||
|
||||
/* factory tests etc */
|
||||
ATH10K_FIRMWARE_MODE_UTF,
|
||||
};
|
||||
|
||||
enum ath10k_fw_features {
|
||||
@ -472,7 +483,6 @@ struct ath10k {
|
||||
struct cfg80211_chan_def chandef;
|
||||
|
||||
int free_vdev_map;
|
||||
bool promisc;
|
||||
bool monitor;
|
||||
int monitor_vdev_id;
|
||||
bool monitor_started;
|
||||
@ -544,6 +554,15 @@ struct ath10k {
|
||||
struct ath10k_spec_scan config;
|
||||
} spectral;
|
||||
|
||||
struct {
|
||||
/* protected by conf_mutex */
|
||||
const struct firmware *utf;
|
||||
DECLARE_BITMAP(orig_fw_features, ATH10K_FW_FEATURE_COUNT);
|
||||
|
||||
/* protected by data_lock */
|
||||
bool utf_monitor;
|
||||
} testmode;
|
||||
|
||||
/* must be last */
|
||||
u8 drv_priv[0] __aligned(sizeof(void *));
|
||||
};
|
||||
@ -552,7 +571,7 @@ struct ath10k *ath10k_core_create(size_t priv_size, struct device *dev,
|
||||
const struct ath10k_hif_ops *hif_ops);
|
||||
void ath10k_core_destroy(struct ath10k *ar);
|
||||
|
||||
int ath10k_core_start(struct ath10k *ar);
|
||||
int ath10k_core_start(struct ath10k *ar, enum ath10k_firmware_mode mode);
|
||||
int ath10k_wait_for_suspend(struct ath10k *ar, u32 suspend_opt);
|
||||
void ath10k_core_stop(struct ath10k *ar);
|
||||
int ath10k_core_register(struct ath10k *ar, u32 chip_id);
|
||||
|
@ -117,7 +117,7 @@ int ath10k_info(struct ath10k *ar, const char *fmt, ...)
|
||||
va_start(args, fmt);
|
||||
vaf.va = &args;
|
||||
ret = dev_info(ar->dev, "%pV", &vaf);
|
||||
trace_ath10k_log_info(&vaf);
|
||||
trace_ath10k_log_info(ar, &vaf);
|
||||
va_end(args);
|
||||
|
||||
return ret;
|
||||
@ -134,11 +134,12 @@ void ath10k_print_driver_info(struct ath10k *ar)
|
||||
ar->fw_api,
|
||||
ar->htt.target_version_major,
|
||||
ar->htt.target_version_minor);
|
||||
ath10k_info(ar, "debug %d debugfs %d tracing %d dfs %d\n",
|
||||
ath10k_info(ar, "debug %d debugfs %d tracing %d dfs %d testmode %d\n",
|
||||
config_enabled(CONFIG_ATH10K_DEBUG),
|
||||
config_enabled(CONFIG_ATH10K_DEBUGFS),
|
||||
config_enabled(CONFIG_ATH10K_TRACING),
|
||||
config_enabled(CONFIG_ATH10K_DFS_CERTIFIED));
|
||||
config_enabled(CONFIG_ATH10K_DFS_CERTIFIED),
|
||||
config_enabled(CONFIG_NL80211_TESTMODE));
|
||||
}
|
||||
EXPORT_SYMBOL(ath10k_print_driver_info);
|
||||
|
||||
@ -153,7 +154,7 @@ int ath10k_err(struct ath10k *ar, const char *fmt, ...)
|
||||
va_start(args, fmt);
|
||||
vaf.va = &args;
|
||||
ret = dev_err(ar->dev, "%pV", &vaf);
|
||||
trace_ath10k_log_err(&vaf);
|
||||
trace_ath10k_log_err(ar, &vaf);
|
||||
va_end(args);
|
||||
|
||||
return ret;
|
||||
@ -170,7 +171,7 @@ int ath10k_warn(struct ath10k *ar, const char *fmt, ...)
|
||||
va_start(args, fmt);
|
||||
vaf.va = &args;
|
||||
dev_warn_ratelimited(ar->dev, "%pV", &vaf);
|
||||
trace_ath10k_log_warn(&vaf);
|
||||
trace_ath10k_log_warn(ar, &vaf);
|
||||
|
||||
va_end(args);
|
||||
|
||||
@ -208,7 +209,7 @@ static ssize_t ath10k_read_wmi_services(struct file *file,
|
||||
if (len > buf_len)
|
||||
len = buf_len;
|
||||
|
||||
for (i = 0; i < WMI_MAX_SERVICE; i++) {
|
||||
for (i = 0; i < WMI_SERVICE_MAX; i++) {
|
||||
enabled = test_bit(i, ar->debug.wmi_service_bitmap);
|
||||
name = wmi_service_name(i);
|
||||
|
||||
@ -564,16 +565,35 @@ static const struct file_operations fops_fw_stats = {
|
||||
.llseek = default_llseek,
|
||||
};
|
||||
|
||||
/* This is a clean assert crash in firmware. */
|
||||
static int ath10k_debug_fw_assert(struct ath10k *ar)
|
||||
{
|
||||
struct wmi_vdev_install_key_cmd *cmd;
|
||||
struct sk_buff *skb;
|
||||
|
||||
skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd) + 16);
|
||||
if (!skb)
|
||||
return -ENOMEM;
|
||||
|
||||
cmd = (struct wmi_vdev_install_key_cmd *)skb->data;
|
||||
memset(cmd, 0, sizeof(*cmd));
|
||||
|
||||
/* big enough number so that firmware asserts */
|
||||
cmd->vdev_id = __cpu_to_le32(0x7ffe);
|
||||
|
||||
return ath10k_wmi_cmd_send(ar, skb,
|
||||
ar->wmi.cmd->vdev_install_key_cmdid);
|
||||
}
|
||||
|
||||
static ssize_t ath10k_read_simulate_fw_crash(struct file *file,
|
||||
char __user *user_buf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
const char buf[] = "To simulate firmware crash write one of the"
|
||||
" keywords to this file:\n `soft` - this will send"
|
||||
" WMI_FORCE_FW_HANG_ASSERT to firmware if FW"
|
||||
" supports that command.\n `hard` - this will send"
|
||||
" to firmware command with illegal parameters"
|
||||
" causing firmware crash.\n";
|
||||
const char buf[] =
|
||||
"To simulate firmware crash write one of the keywords to this file:\n"
|
||||
"`soft` - this will send WMI_FORCE_FW_HANG_ASSERT to firmware if FW supports that command.\n"
|
||||
"`hard` - this will send to firmware command with illegal parameters causing firmware crash.\n"
|
||||
"`assert` - this will send special illegal parameter to firmware to cause assert failure and crash.\n";
|
||||
|
||||
return simple_read_from_buffer(user_buf, count, ppos, buf, strlen(buf));
|
||||
}
|
||||
@ -621,7 +641,11 @@ static ssize_t ath10k_write_simulate_fw_crash(struct file *file,
|
||||
* firmware variants in order to force a firmware crash.
|
||||
*/
|
||||
ret = ath10k_wmi_vdev_set_param(ar, 0x7fff,
|
||||
ar->wmi.vdev_param->rts_threshold, 0);
|
||||
ar->wmi.vdev_param->rts_threshold,
|
||||
0);
|
||||
} else if (!strcmp(buf, "assert")) {
|
||||
ath10k_info(ar, "simulating firmware assert crash\n");
|
||||
ret = ath10k_debug_fw_assert(ar);
|
||||
} else {
|
||||
ret = -EINVAL;
|
||||
goto exit;
|
||||
@ -840,8 +864,8 @@ static void ath10k_debug_htt_stats_dwork(struct work_struct *work)
|
||||
}
|
||||
|
||||
static ssize_t ath10k_read_htt_stats_mask(struct file *file,
|
||||
char __user *user_buf,
|
||||
size_t count, loff_t *ppos)
|
||||
char __user *user_buf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
struct ath10k *ar = file->private_data;
|
||||
char buf[32];
|
||||
@ -853,8 +877,8 @@ static ssize_t ath10k_read_htt_stats_mask(struct file *file,
|
||||
}
|
||||
|
||||
static ssize_t ath10k_write_htt_stats_mask(struct file *file,
|
||||
const char __user *user_buf,
|
||||
size_t count, loff_t *ppos)
|
||||
const char __user *user_buf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
struct ath10k *ar = file->private_data;
|
||||
unsigned long mask;
|
||||
@ -959,8 +983,8 @@ static const struct file_operations fops_htt_max_amsdu_ampdu = {
|
||||
};
|
||||
|
||||
static ssize_t ath10k_read_fw_dbglog(struct file *file,
|
||||
char __user *user_buf,
|
||||
size_t count, loff_t *ppos)
|
||||
char __user *user_buf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
struct ath10k *ar = file->private_data;
|
||||
unsigned int len;
|
||||
@ -1132,19 +1156,28 @@ static const struct file_operations fops_dfs_stats = {
|
||||
|
||||
int ath10k_debug_create(struct ath10k *ar)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ar->debug.fw_crash_data = vzalloc(sizeof(*ar->debug.fw_crash_data));
|
||||
if (!ar->debug.fw_crash_data) {
|
||||
ret = -ENOMEM;
|
||||
goto err;
|
||||
}
|
||||
if (!ar->debug.fw_crash_data)
|
||||
return -ENOMEM;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ath10k_debug_destroy(struct ath10k *ar)
|
||||
{
|
||||
vfree(ar->debug.fw_crash_data);
|
||||
ar->debug.fw_crash_data = NULL;
|
||||
}
|
||||
|
||||
int ath10k_debug_register(struct ath10k *ar)
|
||||
{
|
||||
ar->debug.debugfs_phy = debugfs_create_dir("ath10k",
|
||||
ar->hw->wiphy->debugfsdir);
|
||||
if (!ar->debug.debugfs_phy) {
|
||||
ret = -ENOMEM;
|
||||
goto err_free_fw_crash_data;
|
||||
if (IS_ERR_OR_NULL(ar->debug.debugfs_phy)) {
|
||||
if (IS_ERR(ar->debug.debugfs_phy))
|
||||
return PTR_ERR(ar->debug.debugfs_phy);
|
||||
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
INIT_DELAYED_WORK(&ar->debug.htt_stats_dwork,
|
||||
@ -1192,17 +1225,10 @@ int ath10k_debug_create(struct ath10k *ar)
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
err_free_fw_crash_data:
|
||||
vfree(ar->debug.fw_crash_data);
|
||||
|
||||
err:
|
||||
return ret;
|
||||
}
|
||||
|
||||
void ath10k_debug_destroy(struct ath10k *ar)
|
||||
void ath10k_debug_unregister(struct ath10k *ar)
|
||||
{
|
||||
vfree(ar->debug.fw_crash_data);
|
||||
cancel_delayed_work_sync(&ar->debug.htt_stats_dwork);
|
||||
}
|
||||
|
||||
@ -1223,7 +1249,7 @@ void ath10k_dbg(struct ath10k *ar, enum ath10k_debug_mask mask,
|
||||
if (ath10k_debug_mask & mask)
|
||||
dev_printk(KERN_DEBUG, ar->dev, "%pV", &vaf);
|
||||
|
||||
trace_ath10k_log_dbg(mask, &vaf);
|
||||
trace_ath10k_log_dbg(ar, mask, &vaf);
|
||||
|
||||
va_end(args);
|
||||
}
|
||||
@ -1242,7 +1268,7 @@ void ath10k_dbg_dump(struct ath10k *ar,
|
||||
}
|
||||
|
||||
/* tracing code doesn't like null strings :/ */
|
||||
trace_ath10k_log_dbg_dump(msg ? msg : "", prefix ? prefix : "",
|
||||
trace_ath10k_log_dbg_dump(ar, msg ? msg : "", prefix ? prefix : "",
|
||||
buf, len);
|
||||
}
|
||||
EXPORT_SYMBOL(ath10k_dbg_dump);
|
||||
|
@ -34,6 +34,7 @@ enum ath10k_debug_mask {
|
||||
ATH10K_DBG_DATA = 0x00000200,
|
||||
ATH10K_DBG_BMI = 0x00000400,
|
||||
ATH10K_DBG_REGULATORY = 0x00000800,
|
||||
ATH10K_DBG_TESTMODE = 0x00001000,
|
||||
ATH10K_DBG_ANY = 0xffffffff,
|
||||
};
|
||||
|
||||
@ -49,6 +50,8 @@ int ath10k_debug_start(struct ath10k *ar);
|
||||
void ath10k_debug_stop(struct ath10k *ar);
|
||||
int ath10k_debug_create(struct ath10k *ar);
|
||||
void ath10k_debug_destroy(struct ath10k *ar);
|
||||
int ath10k_debug_register(struct ath10k *ar);
|
||||
void ath10k_debug_unregister(struct ath10k *ar);
|
||||
void ath10k_debug_read_service_map(struct ath10k *ar,
|
||||
void *service_map,
|
||||
size_t map_size);
|
||||
@ -80,6 +83,15 @@ static inline void ath10k_debug_destroy(struct ath10k *ar)
|
||||
{
|
||||
}
|
||||
|
||||
static inline int ath10k_debug_register(struct ath10k *ar)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void ath10k_debug_unregister(struct ath10k *ar)
|
||||
{
|
||||
}
|
||||
|
||||
static inline void ath10k_debug_read_service_map(struct ath10k *ar,
|
||||
void *service_map,
|
||||
size_t map_size)
|
||||
|
@ -91,7 +91,6 @@ struct ath10k_hif_ops {
|
||||
int (*resume)(struct ath10k *ar);
|
||||
};
|
||||
|
||||
|
||||
static inline int ath10k_hif_tx_sg(struct ath10k *ar, u8 pipe_id,
|
||||
struct ath10k_hif_sg_item *items,
|
||||
int n_items)
|
||||
|
@ -45,10 +45,8 @@ static struct sk_buff *ath10k_htc_build_tx_ctrl_skb(void *ar)
|
||||
struct ath10k_skb_cb *skb_cb;
|
||||
|
||||
skb = dev_alloc_skb(ATH10K_HTC_CONTROL_BUFFER_SIZE);
|
||||
if (!skb) {
|
||||
ath10k_warn(ar, "Unable to allocate ctrl skb\n");
|
||||
if (!skb)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
skb_reserve(skb, 20); /* FIXME: why 20 bytes? */
|
||||
WARN_ONCE((unsigned long)skb->data & 3, "unaligned skb");
|
||||
@ -569,7 +567,7 @@ int ath10k_htc_wait_target(struct ath10k_htc *htc)
|
||||
ath10k_hif_send_complete_check(htc->ar, i, 1);
|
||||
|
||||
status = wait_for_completion_timeout(&htc->ctl_resp,
|
||||
ATH10K_HTC_WAIT_TIMEOUT_HZ);
|
||||
ATH10K_HTC_WAIT_TIMEOUT_HZ);
|
||||
|
||||
if (status == 0)
|
||||
status = -ETIMEDOUT;
|
||||
@ -806,10 +804,8 @@ struct sk_buff *ath10k_htc_alloc_skb(struct ath10k *ar, int size)
|
||||
struct sk_buff *skb;
|
||||
|
||||
skb = dev_alloc_skb(size + sizeof(struct ath10k_htc_hdr));
|
||||
if (!skb) {
|
||||
ath10k_warn(ar, "could not allocate HTC tx skb\n");
|
||||
if (!skb)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
skb_reserve(skb, sizeof(struct ath10k_htc_hdr));
|
||||
|
||||
|
@ -214,7 +214,6 @@ struct ath10k_htc_frame {
|
||||
struct ath10k_htc_record trailer[0];
|
||||
} __packed __aligned(4);
|
||||
|
||||
|
||||
/*******************/
|
||||
/* Host-side stuff */
|
||||
/*******************/
|
||||
|
@ -101,7 +101,7 @@ int ath10k_htt_setup(struct ath10k_htt *htt)
|
||||
return status;
|
||||
|
||||
status = wait_for_completion_timeout(&htt->target_version_received,
|
||||
HTT_TARGET_VERSION_TIMEOUT_HZ);
|
||||
HTT_TARGET_VERSION_TIMEOUT_HZ);
|
||||
if (status <= 0) {
|
||||
ath10k_warn(ar, "htt version request timed out\n");
|
||||
return -ETIMEDOUT;
|
||||
|
@ -265,7 +265,6 @@ enum htt_mgmt_tx_status {
|
||||
|
||||
/*=== target -> host messages ===============================================*/
|
||||
|
||||
|
||||
enum htt_t2h_msg_type {
|
||||
HTT_T2H_MSG_TYPE_VERSION_CONF = 0x0,
|
||||
HTT_T2H_MSG_TYPE_RX_IND = 0x1,
|
||||
@ -1032,6 +1031,7 @@ static inline struct htt_stats_conf_item *htt_stats_conf_next_item(
|
||||
{
|
||||
return (void *)item + sizeof(*item) + roundup(item->length, 4);
|
||||
}
|
||||
|
||||
/*
|
||||
* host -> target FRAG DESCRIPTOR/MSDU_EXT DESC bank
|
||||
*
|
||||
@ -1148,7 +1148,6 @@ struct htt_resp {
|
||||
};
|
||||
} __packed;
|
||||
|
||||
|
||||
/*** host side structures follow ***/
|
||||
|
||||
struct htt_tx_done {
|
||||
|
@ -42,7 +42,6 @@
|
||||
/* when under memory pressure rx ring refill may fail and needs a retry */
|
||||
#define HTT_RX_RING_REFILL_RETRY_MS 50
|
||||
|
||||
|
||||
static int ath10k_htt_rx_get_csum_state(struct sk_buff *skb);
|
||||
static void ath10k_htt_txrx_compl_task(unsigned long ptr);
|
||||
|
||||
@ -133,7 +132,7 @@ static int __ath10k_htt_rx_ring_fill_n(struct ath10k_htt *htt, int num)
|
||||
dma_addr_t paddr;
|
||||
int ret = 0, idx;
|
||||
|
||||
idx = __le32_to_cpu(*(htt->rx_ring.alloc_idx.vaddr));
|
||||
idx = __le32_to_cpu(*htt->rx_ring.alloc_idx.vaddr);
|
||||
while (num > 0) {
|
||||
skb = dev_alloc_skb(HTT_RX_BUF_SIZE + HTT_RX_DESC_ALIGN);
|
||||
if (!skb) {
|
||||
@ -171,7 +170,7 @@ static int __ath10k_htt_rx_ring_fill_n(struct ath10k_htt *htt, int num)
|
||||
}
|
||||
|
||||
fail:
|
||||
*(htt->rx_ring.alloc_idx.vaddr) = __cpu_to_le32(idx);
|
||||
*htt->rx_ring.alloc_idx.vaddr = __cpu_to_le32(idx);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -223,6 +222,7 @@ static void ath10k_htt_rx_msdu_buff_replenish(struct ath10k_htt *htt)
|
||||
static void ath10k_htt_rx_ring_refill_retry(unsigned long arg)
|
||||
{
|
||||
struct ath10k_htt *htt = (struct ath10k_htt *)arg;
|
||||
|
||||
ath10k_htt_rx_msdu_buff_replenish(htt);
|
||||
}
|
||||
|
||||
@ -314,7 +314,7 @@ static int ath10k_htt_rx_amsdu_pop(struct ath10k_htt *htt,
|
||||
{
|
||||
struct ath10k *ar = htt->ar;
|
||||
int msdu_len, msdu_chaining = 0;
|
||||
struct sk_buff *msdu;
|
||||
struct sk_buff *msdu, *next;
|
||||
struct htt_rx_desc *rx_desc;
|
||||
|
||||
lockdep_assert_held(&htt->rx_ring.lock);
|
||||
@ -450,11 +450,11 @@ static int ath10k_htt_rx_amsdu_pop(struct ath10k_htt *htt,
|
||||
if (last_msdu) {
|
||||
msdu->next = NULL;
|
||||
break;
|
||||
} else {
|
||||
struct sk_buff *next = ath10k_htt_rx_netbuf_pop(htt);
|
||||
msdu->next = next;
|
||||
msdu = next;
|
||||
}
|
||||
|
||||
next = ath10k_htt_rx_netbuf_pop(htt);
|
||||
msdu->next = next;
|
||||
msdu = next;
|
||||
}
|
||||
*tail_msdu = msdu;
|
||||
|
||||
@ -480,6 +480,7 @@ static int ath10k_htt_rx_amsdu_pop(struct ath10k_htt *htt,
|
||||
static void ath10k_htt_rx_replenish_task(unsigned long ptr)
|
||||
{
|
||||
struct ath10k_htt *htt = (struct ath10k_htt *)ptr;
|
||||
|
||||
ath10k_htt_rx_msdu_buff_replenish(htt);
|
||||
}
|
||||
|
||||
@ -488,6 +489,7 @@ int ath10k_htt_rx_alloc(struct ath10k_htt *htt)
|
||||
struct ath10k *ar = htt->ar;
|
||||
dma_addr_t paddr;
|
||||
void *vaddr;
|
||||
size_t size;
|
||||
struct timer_list *timer = &htt->rx_ring.refill_retry_timer;
|
||||
|
||||
htt->rx_ring.size = ath10k_htt_rx_ring_size(htt);
|
||||
@ -515,9 +517,9 @@ int ath10k_htt_rx_alloc(struct ath10k_htt *htt)
|
||||
if (!htt->rx_ring.netbufs_ring)
|
||||
goto err_netbuf;
|
||||
|
||||
vaddr = dma_alloc_coherent(htt->ar->dev,
|
||||
(htt->rx_ring.size * sizeof(htt->rx_ring.paddrs_ring)),
|
||||
&paddr, GFP_DMA);
|
||||
size = htt->rx_ring.size * sizeof(htt->rx_ring.paddrs_ring);
|
||||
|
||||
vaddr = dma_alloc_coherent(htt->ar->dev, size, &paddr, GFP_DMA);
|
||||
if (!vaddr)
|
||||
goto err_dma_ring;
|
||||
|
||||
@ -625,19 +627,21 @@ static struct ieee80211_hdr *ath10k_htt_rx_skb_get_hdr(struct sk_buff *skb)
|
||||
|
||||
rxd = (void *)skb->data - sizeof(*rxd);
|
||||
fmt = MS(__le32_to_cpu(rxd->msdu_start.info1),
|
||||
RX_MSDU_START_INFO1_DECAP_FORMAT);
|
||||
RX_MSDU_START_INFO1_DECAP_FORMAT);
|
||||
|
||||
if (fmt == RX_MSDU_DECAP_RAW)
|
||||
return (void *)skb->data;
|
||||
else
|
||||
return (void *)skb->data - RX_HTT_HDR_STATUS_LEN;
|
||||
|
||||
return (void *)skb->data - RX_HTT_HDR_STATUS_LEN;
|
||||
}
|
||||
|
||||
/* This function only applies for first msdu in an msdu chain */
|
||||
static bool ath10k_htt_rx_hdr_is_amsdu(struct ieee80211_hdr *hdr)
|
||||
{
|
||||
u8 *qc;
|
||||
|
||||
if (ieee80211_is_data_qos(hdr->frame_control)) {
|
||||
u8 *qc = ieee80211_get_qos_ctl(hdr);
|
||||
qc = ieee80211_get_qos_ctl(hdr);
|
||||
if (qc[0] & 0x80)
|
||||
return true;
|
||||
}
|
||||
@ -914,7 +918,7 @@ static void ath10k_htt_rx_amsdu(struct ath10k_htt *htt,
|
||||
|
||||
rxd = (void *)skb->data - sizeof(*rxd);
|
||||
enctype = MS(__le32_to_cpu(rxd->mpdu_start.info0),
|
||||
RX_MPDU_START_INFO0_ENCRYPT_TYPE);
|
||||
RX_MPDU_START_INFO0_ENCRYPT_TYPE);
|
||||
|
||||
hdr = (struct ieee80211_hdr *)rxd->rx_hdr_status;
|
||||
hdr_len = ieee80211_hdrlen(hdr->frame_control);
|
||||
@ -950,8 +954,8 @@ static void ath10k_htt_rx_amsdu(struct ath10k_htt *htt,
|
||||
/* pull decapped header and copy SA & DA */
|
||||
hdr = (struct ieee80211_hdr *)skb->data;
|
||||
hdr_len = ath10k_htt_rx_nwifi_hdrlen(hdr);
|
||||
memcpy(da, ieee80211_get_DA(hdr), ETH_ALEN);
|
||||
memcpy(sa, ieee80211_get_SA(hdr), ETH_ALEN);
|
||||
ether_addr_copy(da, ieee80211_get_DA(hdr));
|
||||
ether_addr_copy(sa, ieee80211_get_SA(hdr));
|
||||
skb_pull(skb, hdr_len);
|
||||
|
||||
/* push original 802.11 header */
|
||||
@ -968,8 +972,8 @@ static void ath10k_htt_rx_amsdu(struct ath10k_htt *htt,
|
||||
/* original 802.11 header has a different DA and in
|
||||
* case of 4addr it may also have different SA
|
||||
*/
|
||||
memcpy(ieee80211_get_DA(hdr), da, ETH_ALEN);
|
||||
memcpy(ieee80211_get_SA(hdr), sa, ETH_ALEN);
|
||||
ether_addr_copy(ieee80211_get_DA(hdr), da);
|
||||
ether_addr_copy(ieee80211_get_SA(hdr), sa);
|
||||
break;
|
||||
case RX_MSDU_DECAP_ETHERNET2_DIX:
|
||||
/* strip ethernet header and insert decapped 802.11
|
||||
@ -1029,9 +1033,9 @@ static void ath10k_htt_rx_msdu(struct ath10k_htt *htt,
|
||||
|
||||
rxd = (void *)skb->data - sizeof(*rxd);
|
||||
fmt = MS(__le32_to_cpu(rxd->msdu_start.info1),
|
||||
RX_MSDU_START_INFO1_DECAP_FORMAT);
|
||||
RX_MSDU_START_INFO1_DECAP_FORMAT);
|
||||
enctype = MS(__le32_to_cpu(rxd->mpdu_start.info0),
|
||||
RX_MPDU_START_INFO0_ENCRYPT_TYPE);
|
||||
RX_MPDU_START_INFO0_ENCRYPT_TYPE);
|
||||
hdr = (struct ieee80211_hdr *)rxd->rx_hdr_status;
|
||||
hdr_len = ieee80211_hdrlen(hdr->frame_control);
|
||||
|
||||
@ -1332,7 +1336,7 @@ static void ath10k_htt_rx_handler(struct ath10k_htt *htt,
|
||||
}
|
||||
|
||||
static void ath10k_htt_rx_frag_handler(struct ath10k_htt *htt,
|
||||
struct htt_rx_fragment_indication *frag)
|
||||
struct htt_rx_fragment_indication *frag)
|
||||
{
|
||||
struct ath10k *ar = htt->ar;
|
||||
struct sk_buff *msdu_head, *msdu_tail;
|
||||
@ -1378,7 +1382,7 @@ static void ath10k_htt_rx_frag_handler(struct ath10k_htt *htt,
|
||||
tkip_mic_err = !!(attention & RX_ATTENTION_FLAGS_TKIP_MIC_ERR);
|
||||
decrypt_err = !!(attention & RX_ATTENTION_FLAGS_DECRYPT_ERR);
|
||||
fmt = MS(__le32_to_cpu(rxd->msdu_start.info1),
|
||||
RX_MSDU_START_INFO1_DECAP_FORMAT);
|
||||
RX_MSDU_START_INFO1_DECAP_FORMAT);
|
||||
|
||||
if (fmt != RX_MSDU_DECAP_RAW) {
|
||||
ath10k_warn(ar, "we dont support non-raw fragmented rx yet\n");
|
||||
@ -1654,7 +1658,7 @@ void ath10k_htt_t2h_msg_handler(struct ath10k *ar, struct sk_buff *skb)
|
||||
/* FIX THIS */
|
||||
break;
|
||||
case HTT_T2H_MSG_TYPE_STATS_CONF:
|
||||
trace_ath10k_htt_stats(skb->data, skb->len);
|
||||
trace_ath10k_htt_stats(ar, skb->data, skb->len);
|
||||
break;
|
||||
case HTT_T2H_MSG_TYPE_TX_INSPECT_IND:
|
||||
/* Firmware can return tx frames if it's unable to fully
|
||||
|
@ -154,7 +154,6 @@ void ath10k_htt_tx_free(struct ath10k_htt *htt)
|
||||
kfree(htt->pending_tx);
|
||||
kfree(htt->used_msdu_ids);
|
||||
dma_pool_destroy(htt->tx_pool);
|
||||
return;
|
||||
}
|
||||
|
||||
void ath10k_htt_htc_tx_complete(struct ath10k *ar, struct sk_buff *skb)
|
||||
@ -377,7 +376,6 @@ int ath10k_htt_mgmt_tx(struct ath10k_htt *htt, struct sk_buff *msdu)
|
||||
int msdu_id = -1;
|
||||
int res;
|
||||
|
||||
|
||||
res = ath10k_htt_tx_inc_pending(htt);
|
||||
if (res)
|
||||
goto err;
|
||||
|
@ -36,6 +36,8 @@
|
||||
#define ATH10K_FW_API2_FILE "firmware-2.bin"
|
||||
#define ATH10K_FW_API3_FILE "firmware-3.bin"
|
||||
|
||||
#define ATH10K_FW_UTF_FILE "utf.bin"
|
||||
|
||||
/* includes also the null byte */
|
||||
#define ATH10K_FIRMWARE_MAGIC "QCA-ATH10K"
|
||||
|
||||
|
@ -26,6 +26,7 @@
|
||||
#include "wmi.h"
|
||||
#include "htt.h"
|
||||
#include "txrx.h"
|
||||
#include "testmode.h"
|
||||
|
||||
/**********/
|
||||
/* Crypto */
|
||||
@ -198,7 +199,7 @@ static int ath10k_clear_vdev_key(struct ath10k_vif *arvif,
|
||||
list_for_each_entry(peer, &ar->peers, list) {
|
||||
for (i = 0; i < ARRAY_SIZE(peer->keys); i++) {
|
||||
if (peer->keys[i] == key) {
|
||||
memcpy(addr, peer->addr, ETH_ALEN);
|
||||
ether_addr_copy(addr, peer->addr);
|
||||
peer->keys[i] = NULL;
|
||||
break;
|
||||
}
|
||||
@ -224,7 +225,6 @@ static int ath10k_clear_vdev_key(struct ath10k_vif *arvif,
|
||||
return first_errno;
|
||||
}
|
||||
|
||||
|
||||
/*********************/
|
||||
/* General utilities */
|
||||
/*********************/
|
||||
@ -493,19 +493,6 @@ static inline int ath10k_vdev_setup_sync(struct ath10k *ar)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool ath10k_monitor_is_enabled(struct ath10k *ar)
|
||||
{
|
||||
lockdep_assert_held(&ar->conf_mutex);
|
||||
|
||||
ath10k_dbg(ar, ATH10K_DBG_MAC,
|
||||
"mac monitor refs: promisc %d monitor %d cac %d\n",
|
||||
ar->promisc, ar->monitor,
|
||||
test_bit(ATH10K_CAC_RUNNING, &ar->dev_flags));
|
||||
|
||||
return ar->promisc || ar->monitor ||
|
||||
test_bit(ATH10K_CAC_RUNNING, &ar->dev_flags);
|
||||
}
|
||||
|
||||
static int ath10k_monitor_vdev_start(struct ath10k *ar, int vdev_id)
|
||||
{
|
||||
struct cfg80211_chan_def *chandef = &ar->chandef;
|
||||
@ -649,16 +636,6 @@ static int ath10k_monitor_start(struct ath10k *ar)
|
||||
|
||||
lockdep_assert_held(&ar->conf_mutex);
|
||||
|
||||
if (!ath10k_monitor_is_enabled(ar)) {
|
||||
ath10k_warn(ar, "trying to start monitor with no references\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (ar->monitor_started) {
|
||||
ath10k_dbg(ar, ATH10K_DBG_MAC, "mac monitor already started\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
ret = ath10k_monitor_vdev_create(ar);
|
||||
if (ret) {
|
||||
ath10k_warn(ar, "failed to create monitor vdev: %d\n", ret);
|
||||
@ -678,34 +655,51 @@ static int ath10k_monitor_start(struct ath10k *ar)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void ath10k_monitor_stop(struct ath10k *ar)
|
||||
static int ath10k_monitor_stop(struct ath10k *ar)
|
||||
{
|
||||
int ret;
|
||||
|
||||
lockdep_assert_held(&ar->conf_mutex);
|
||||
|
||||
if (ath10k_monitor_is_enabled(ar)) {
|
||||
ath10k_dbg(ar, ATH10K_DBG_MAC,
|
||||
"mac monitor will be stopped later\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!ar->monitor_started) {
|
||||
ath10k_dbg(ar, ATH10K_DBG_MAC,
|
||||
"mac monitor probably failed to start earlier\n");
|
||||
return;
|
||||
}
|
||||
|
||||
ret = ath10k_monitor_vdev_stop(ar);
|
||||
if (ret)
|
||||
if (ret) {
|
||||
ath10k_warn(ar, "failed to stop monitor vdev: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = ath10k_monitor_vdev_delete(ar);
|
||||
if (ret)
|
||||
if (ret) {
|
||||
ath10k_warn(ar, "failed to delete monitor vdev: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ar->monitor_started = false;
|
||||
ath10k_dbg(ar, ATH10K_DBG_MAC, "mac monitor stopped\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ath10k_monitor_recalc(struct ath10k *ar)
|
||||
{
|
||||
bool should_start;
|
||||
|
||||
lockdep_assert_held(&ar->conf_mutex);
|
||||
|
||||
should_start = ar->monitor ||
|
||||
ar->filter_flags & FIF_PROMISC_IN_BSS ||
|
||||
test_bit(ATH10K_CAC_RUNNING, &ar->dev_flags);
|
||||
|
||||
ath10k_dbg(ar, ATH10K_DBG_MAC,
|
||||
"mac monitor recalc started? %d should? %d\n",
|
||||
ar->monitor_started, should_start);
|
||||
|
||||
if (should_start == ar->monitor_started)
|
||||
return 0;
|
||||
|
||||
if (should_start)
|
||||
return ath10k_monitor_start(ar);
|
||||
|
||||
return ath10k_monitor_stop(ar);
|
||||
}
|
||||
|
||||
static int ath10k_recalc_rtscts_prot(struct ath10k_vif *arvif)
|
||||
@ -736,7 +730,7 @@ static int ath10k_start_cac(struct ath10k *ar)
|
||||
|
||||
set_bit(ATH10K_CAC_RUNNING, &ar->dev_flags);
|
||||
|
||||
ret = ath10k_monitor_start(ar);
|
||||
ret = ath10k_monitor_recalc(ar);
|
||||
if (ret) {
|
||||
ath10k_warn(ar, "failed to start monitor (cac): %d\n", ret);
|
||||
clear_bit(ATH10K_CAC_RUNNING, &ar->dev_flags);
|
||||
@ -901,7 +895,7 @@ static int ath10k_vdev_stop(struct ath10k_vif *arvif)
|
||||
}
|
||||
|
||||
static void ath10k_control_beaconing(struct ath10k_vif *arvif,
|
||||
struct ieee80211_bss_conf *info)
|
||||
struct ieee80211_bss_conf *info)
|
||||
{
|
||||
struct ath10k *ar = arvif->ar;
|
||||
int ret = 0;
|
||||
@ -936,7 +930,7 @@ static void ath10k_control_beaconing(struct ath10k_vif *arvif,
|
||||
return;
|
||||
|
||||
arvif->aid = 0;
|
||||
memcpy(arvif->bssid, info->bssid, ETH_ALEN);
|
||||
ether_addr_copy(arvif->bssid, info->bssid);
|
||||
|
||||
ret = ath10k_wmi_vdev_up(arvif->ar, arvif->vdev_id, arvif->aid,
|
||||
arvif->bssid);
|
||||
@ -1056,7 +1050,7 @@ static void ath10k_peer_assoc_h_basic(struct ath10k *ar,
|
||||
{
|
||||
lockdep_assert_held(&ar->conf_mutex);
|
||||
|
||||
memcpy(arg->addr, sta->addr, ETH_ALEN);
|
||||
ether_addr_copy(arg->addr, sta->addr);
|
||||
arg->vdev_id = arvif->vdev_id;
|
||||
arg->peer_aid = sta->aid;
|
||||
arg->peer_flags |= WMI_PEER_AUTH;
|
||||
@ -1111,9 +1105,9 @@ static void ath10k_peer_assoc_h_crypto(struct ath10k *ar,
|
||||
ies = rcu_dereference(bss->ies);
|
||||
|
||||
wpaie = cfg80211_find_vendor_ie(WLAN_OUI_MICROSOFT,
|
||||
WLAN_OUI_TYPE_MICROSOFT_WPA,
|
||||
ies->data,
|
||||
ies->len);
|
||||
WLAN_OUI_TYPE_MICROSOFT_WPA,
|
||||
ies->data,
|
||||
ies->len);
|
||||
rcu_read_unlock();
|
||||
cfg80211_put_bss(ar->hw->wiphy, bss);
|
||||
}
|
||||
@ -1163,6 +1157,7 @@ static void ath10k_peer_assoc_h_ht(struct ath10k *ar,
|
||||
{
|
||||
const struct ieee80211_sta_ht_cap *ht_cap = &sta->ht_cap;
|
||||
int i, n;
|
||||
u32 stbc;
|
||||
|
||||
lockdep_assert_held(&ar->conf_mutex);
|
||||
|
||||
@ -1199,7 +1194,6 @@ static void ath10k_peer_assoc_h_ht(struct ath10k *ar,
|
||||
}
|
||||
|
||||
if (ht_cap->cap & IEEE80211_HT_CAP_RX_STBC) {
|
||||
u32 stbc;
|
||||
stbc = ht_cap->cap & IEEE80211_HT_CAP_RX_STBC;
|
||||
stbc = stbc >> IEEE80211_HT_CAP_RX_STBC_SHIFT;
|
||||
stbc = stbc << WMI_RC_RX_STBC_FLAG_S;
|
||||
@ -1267,7 +1261,6 @@ static int ath10k_peer_assoc_qos_ap(struct ath10k *ar,
|
||||
uapsd |= WMI_AP_PS_UAPSD_AC0_DELIVERY_EN |
|
||||
WMI_AP_PS_UAPSD_AC0_TRIGGER_EN;
|
||||
|
||||
|
||||
if (sta->max_sp < MAX_WMI_AP_PS_PEER_PARAM_MAX_SP)
|
||||
max_sp = sta->max_sp;
|
||||
|
||||
@ -1296,7 +1289,8 @@ static int ath10k_peer_assoc_qos_ap(struct ath10k *ar,
|
||||
sta->listen_interval - mac80211 patch required.
|
||||
Currently use 10 seconds */
|
||||
ret = ath10k_wmi_set_ap_ps_param(ar, arvif->vdev_id, sta->addr,
|
||||
WMI_AP_PS_PEER_PARAM_AGEOUT_TIME, 10);
|
||||
WMI_AP_PS_PEER_PARAM_AGEOUT_TIME,
|
||||
10);
|
||||
if (ret) {
|
||||
ath10k_warn(ar, "failed to set ap ps peer param ageout time for vdev %i: %d\n",
|
||||
arvif->vdev_id, ret);
|
||||
@ -1320,7 +1314,6 @@ static void ath10k_peer_assoc_h_vht(struct ath10k *ar,
|
||||
arg->peer_flags |= WMI_PEER_VHT;
|
||||
arg->peer_vht_caps = vht_cap->cap;
|
||||
|
||||
|
||||
ampdu_factor = (vht_cap->cap &
|
||||
IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MASK) >>
|
||||
IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_SHIFT;
|
||||
@ -1531,7 +1524,7 @@ static void ath10k_bss_assoc(struct ieee80211_hw *hw,
|
||||
arvif->vdev_id, bss_conf->bssid, bss_conf->aid);
|
||||
|
||||
arvif->aid = bss_conf->aid;
|
||||
memcpy(arvif->bssid, bss_conf->bssid, ETH_ALEN);
|
||||
ether_addr_copy(arvif->bssid, bss_conf->bssid);
|
||||
|
||||
ret = ath10k_wmi_vdev_up(ar, arvif->vdev_id, arvif->aid, arvif->bssid);
|
||||
if (ret) {
|
||||
@ -1615,7 +1608,7 @@ static int ath10k_station_assoc(struct ath10k *ar, struct ath10k_vif *arvif,
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (!sta->wme) {
|
||||
if (!sta->wme && !reassoc) {
|
||||
arvif->num_legacy_stations++;
|
||||
ret = ath10k_recalc_rtscts_prot(arvif);
|
||||
if (ret) {
|
||||
@ -1863,11 +1856,10 @@ static u8 ath10k_tx_h_get_tid(struct ieee80211_hdr *hdr)
|
||||
return ieee80211_get_qos_ctl(hdr)[0] & IEEE80211_QOS_CTL_TID_MASK;
|
||||
}
|
||||
|
||||
static u8 ath10k_tx_h_get_vdev_id(struct ath10k *ar,
|
||||
struct ieee80211_tx_info *info)
|
||||
static u8 ath10k_tx_h_get_vdev_id(struct ath10k *ar, struct ieee80211_vif *vif)
|
||||
{
|
||||
if (info->control.vif)
|
||||
return ath10k_vif_to_arvif(info->control.vif)->vdev_id;
|
||||
if (vif)
|
||||
return ath10k_vif_to_arvif(vif)->vdev_id;
|
||||
|
||||
if (ar->monitor_started)
|
||||
return ar->monitor_vdev_id;
|
||||
@ -2323,7 +2315,7 @@ static void ath10k_tx(struct ieee80211_hw *hw,
|
||||
|
||||
ATH10K_SKB_CB(skb)->htt.is_offchan = false;
|
||||
ATH10K_SKB_CB(skb)->htt.tid = ath10k_tx_h_get_tid(hdr);
|
||||
ATH10K_SKB_CB(skb)->vdev_id = ath10k_tx_h_get_vdev_id(ar, info);
|
||||
ATH10K_SKB_CB(skb)->vdev_id = ath10k_tx_h_get_vdev_id(ar, vif);
|
||||
|
||||
/* it makes no sense to process injected frames like that */
|
||||
if (vif && vif->type != NL80211_IFTYPE_MONITOR) {
|
||||
@ -2369,12 +2361,14 @@ void ath10k_halt(struct ath10k *ar)
|
||||
|
||||
lockdep_assert_held(&ar->conf_mutex);
|
||||
|
||||
if (ath10k_monitor_is_enabled(ar)) {
|
||||
clear_bit(ATH10K_CAC_RUNNING, &ar->dev_flags);
|
||||
ar->promisc = false;
|
||||
ar->monitor = false;
|
||||
clear_bit(ATH10K_CAC_RUNNING, &ar->dev_flags);
|
||||
ar->filter_flags = 0;
|
||||
ar->monitor = false;
|
||||
|
||||
if (ar->monitor_started)
|
||||
ath10k_monitor_stop(ar);
|
||||
}
|
||||
|
||||
ar->monitor_started = false;
|
||||
|
||||
ath10k_scan_finish(ar);
|
||||
ath10k_peer_cleanup_all(ar);
|
||||
@ -2485,6 +2479,9 @@ static int ath10k_start(struct ieee80211_hw *hw)
|
||||
WARN_ON(1);
|
||||
ret = -EINVAL;
|
||||
goto err;
|
||||
case ATH10K_STATE_UTF:
|
||||
ret = -EBUSY;
|
||||
goto err;
|
||||
}
|
||||
|
||||
ret = ath10k_hif_power_up(ar);
|
||||
@ -2493,7 +2490,7 @@ static int ath10k_start(struct ieee80211_hw *hw)
|
||||
goto err_off;
|
||||
}
|
||||
|
||||
ret = ath10k_core_start(ar);
|
||||
ret = ath10k_core_start(ar, ATH10K_FIRMWARE_MODE_NORMAL);
|
||||
if (ret) {
|
||||
ath10k_err(ar, "Could not init core: %d\n", ret);
|
||||
goto err_power_down;
|
||||
@ -2629,7 +2626,7 @@ static void ath10k_config_chan(struct ath10k *ar)
|
||||
/* First stop monitor interface. Some FW versions crash if there's a
|
||||
* lone monitor interface. */
|
||||
if (ar->monitor_started)
|
||||
ath10k_monitor_vdev_stop(ar);
|
||||
ath10k_monitor_stop(ar);
|
||||
|
||||
list_for_each_entry(arvif, &ar->arvifs, list) {
|
||||
if (!arvif->is_started)
|
||||
@ -2677,8 +2674,7 @@ static void ath10k_config_chan(struct ath10k *ar)
|
||||
}
|
||||
}
|
||||
|
||||
if (ath10k_monitor_is_enabled(ar))
|
||||
ath10k_monitor_vdev_start(ar, ar->monitor_vdev_id);
|
||||
ath10k_monitor_recalc(ar);
|
||||
}
|
||||
|
||||
static int ath10k_config(struct ieee80211_hw *hw, u32 changed)
|
||||
@ -2733,19 +2729,10 @@ static int ath10k_config(struct ieee80211_hw *hw, u32 changed)
|
||||
ath10k_config_ps(ar);
|
||||
|
||||
if (changed & IEEE80211_CONF_CHANGE_MONITOR) {
|
||||
if (conf->flags & IEEE80211_CONF_MONITOR && !ar->monitor) {
|
||||
ar->monitor = true;
|
||||
ret = ath10k_monitor_start(ar);
|
||||
if (ret) {
|
||||
ath10k_warn(ar, "failed to start monitor (config): %d\n",
|
||||
ret);
|
||||
ar->monitor = false;
|
||||
}
|
||||
} else if (!(conf->flags & IEEE80211_CONF_MONITOR) &&
|
||||
ar->monitor) {
|
||||
ar->monitor = false;
|
||||
ath10k_monitor_stop(ar);
|
||||
}
|
||||
ar->monitor = conf->flags & IEEE80211_CONF_MONITOR;
|
||||
ret = ath10k_monitor_recalc(ar);
|
||||
if (ret)
|
||||
ath10k_warn(ar, "failed to recalc monitor: %d\n", ret);
|
||||
}
|
||||
|
||||
mutex_unlock(&ar->conf_mutex);
|
||||
@ -3009,18 +2996,9 @@ static void ath10k_configure_filter(struct ieee80211_hw *hw,
|
||||
*total_flags &= SUPPORTED_FILTERS;
|
||||
ar->filter_flags = *total_flags;
|
||||
|
||||
if (ar->filter_flags & FIF_PROMISC_IN_BSS && !ar->promisc) {
|
||||
ar->promisc = true;
|
||||
ret = ath10k_monitor_start(ar);
|
||||
if (ret) {
|
||||
ath10k_warn(ar, "failed to start monitor (promisc): %d\n",
|
||||
ret);
|
||||
ar->promisc = false;
|
||||
}
|
||||
} else if (!(ar->filter_flags & FIF_PROMISC_IN_BSS) && ar->promisc) {
|
||||
ar->promisc = false;
|
||||
ath10k_monitor_stop(ar);
|
||||
}
|
||||
ret = ath10k_monitor_recalc(ar);
|
||||
if (ret)
|
||||
ath10k_warn(ar, "failed to recalc montior: %d\n", ret);
|
||||
|
||||
mutex_unlock(&ar->conf_mutex);
|
||||
}
|
||||
@ -3033,7 +3011,7 @@ static void ath10k_bss_info_changed(struct ieee80211_hw *hw,
|
||||
struct ath10k *ar = hw->priv;
|
||||
struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
|
||||
int ret = 0;
|
||||
u32 vdev_param, pdev_param;
|
||||
u32 vdev_param, pdev_param, slottime, preamble;
|
||||
|
||||
mutex_lock(&ar->conf_mutex);
|
||||
|
||||
@ -3112,7 +3090,7 @@ static void ath10k_bss_info_changed(struct ieee80211_hw *hw,
|
||||
* this is never erased as we it for crypto key
|
||||
* clearing; this is FW requirement
|
||||
*/
|
||||
memcpy(arvif->bssid, info->bssid, ETH_ALEN);
|
||||
ether_addr_copy(arvif->bssid, info->bssid);
|
||||
|
||||
ath10k_dbg(ar, ATH10K_DBG_MAC,
|
||||
"mac vdev %d start %pM\n",
|
||||
@ -3154,7 +3132,6 @@ static void ath10k_bss_info_changed(struct ieee80211_hw *hw,
|
||||
}
|
||||
|
||||
if (changed & BSS_CHANGED_ERP_SLOT) {
|
||||
u32 slottime;
|
||||
if (info->use_short_slot)
|
||||
slottime = WMI_VDEV_SLOT_TIME_SHORT; /* 9us */
|
||||
|
||||
@ -3173,7 +3150,6 @@ static void ath10k_bss_info_changed(struct ieee80211_hw *hw,
|
||||
}
|
||||
|
||||
if (changed & BSS_CHANGED_ERP_PREAMBLE) {
|
||||
u32 preamble;
|
||||
if (info->use_short_preamble)
|
||||
preamble = WMI_VDEV_PREAMBLE_SHORT;
|
||||
else
|
||||
@ -3192,8 +3168,16 @@ static void ath10k_bss_info_changed(struct ieee80211_hw *hw,
|
||||
}
|
||||
|
||||
if (changed & BSS_CHANGED_ASSOC) {
|
||||
if (info->assoc)
|
||||
if (info->assoc) {
|
||||
/* Workaround: Make sure monitor vdev is not running
|
||||
* when associating to prevent some firmware revisions
|
||||
* (e.g. 10.1 and 10.2) from crashing.
|
||||
*/
|
||||
if (ar->monitor_started)
|
||||
ath10k_monitor_stop(ar);
|
||||
ath10k_bss_assoc(hw, vif, info);
|
||||
ath10k_monitor_recalc(ar);
|
||||
}
|
||||
}
|
||||
|
||||
exit:
|
||||
@ -3580,7 +3564,7 @@ static int ath10k_sta_state(struct ieee80211_hw *hw,
|
||||
}
|
||||
|
||||
static int ath10k_conf_tx_uapsd(struct ath10k *ar, struct ieee80211_vif *vif,
|
||||
u16 ac, bool enable)
|
||||
u16 ac, bool enable)
|
||||
{
|
||||
struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
|
||||
u32 value = 0;
|
||||
@ -4081,8 +4065,8 @@ ath10k_bitrate_mask_nss(const struct cfg80211_bitrate_mask *mask,
|
||||
continue;
|
||||
else if (mask->control[band].ht_mcs[i] == 0x00)
|
||||
break;
|
||||
else
|
||||
return false;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
ht_nss = i;
|
||||
@ -4093,8 +4077,8 @@ ath10k_bitrate_mask_nss(const struct cfg80211_bitrate_mask *mask,
|
||||
continue;
|
||||
else if (mask->control[band].vht_mcs[i] == 0x0000)
|
||||
break;
|
||||
else
|
||||
return false;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
vht_nss = i;
|
||||
@ -4472,6 +4456,9 @@ static const struct ieee80211_ops ath10k_ops = {
|
||||
.sta_rc_update = ath10k_sta_rc_update,
|
||||
.get_tsf = ath10k_get_tsf,
|
||||
.ampdu_action = ath10k_ampdu_action,
|
||||
|
||||
CFG80211_TESTMODE_CMD(ath10k_tm_cmd)
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
.suspend = ath10k_suspend,
|
||||
.resume = ath10k_resume,
|
||||
@ -4723,7 +4710,6 @@ static struct ieee80211_sta_ht_cap ath10k_get_ht_cap(struct ath10k *ar)
|
||||
return ht_cap;
|
||||
}
|
||||
|
||||
|
||||
static void ath10k_get_arvif_iter(void *data, u8 *mac,
|
||||
struct ieee80211_vif *vif)
|
||||
{
|
||||
|
@ -64,9 +64,6 @@ static const struct pci_device_id ath10k_pci_id_table[] = {
|
||||
{0}
|
||||
};
|
||||
|
||||
static int ath10k_pci_diag_read_access(struct ath10k *ar, u32 address,
|
||||
u32 *data);
|
||||
|
||||
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);
|
||||
@ -343,8 +340,8 @@ static void ath10k_pci_disable_and_clear_legacy_irq(struct ath10k *ar)
|
||||
|
||||
/* IMPORTANT: this extra read transaction is required to
|
||||
* flush the posted write buffer. */
|
||||
(void) ath10k_pci_read32(ar, SOC_CORE_BASE_ADDRESS +
|
||||
PCIE_INTR_ENABLE_ADDRESS);
|
||||
(void)ath10k_pci_read32(ar, SOC_CORE_BASE_ADDRESS +
|
||||
PCIE_INTR_ENABLE_ADDRESS);
|
||||
}
|
||||
|
||||
static void ath10k_pci_enable_legacy_irq(struct ath10k *ar)
|
||||
@ -355,8 +352,8 @@ static void ath10k_pci_enable_legacy_irq(struct ath10k *ar)
|
||||
|
||||
/* IMPORTANT: this extra read transaction is required to
|
||||
* flush the posted write buffer. */
|
||||
(void) ath10k_pci_read32(ar, SOC_CORE_BASE_ADDRESS +
|
||||
PCIE_INTR_ENABLE_ADDRESS);
|
||||
(void)ath10k_pci_read32(ar, SOC_CORE_BASE_ADDRESS +
|
||||
PCIE_INTR_ENABLE_ADDRESS);
|
||||
}
|
||||
|
||||
static inline const char *ath10k_pci_get_irq_method(struct ath10k *ar)
|
||||
@ -365,10 +362,11 @@ static inline const char *ath10k_pci_get_irq_method(struct ath10k *ar)
|
||||
|
||||
if (ar_pci->num_msi_intrs > 1)
|
||||
return "msi-x";
|
||||
else if (ar_pci->num_msi_intrs == 1)
|
||||
|
||||
if (ar_pci->num_msi_intrs == 1)
|
||||
return "msi";
|
||||
else
|
||||
return "legacy";
|
||||
|
||||
return "legacy";
|
||||
}
|
||||
|
||||
static int __ath10k_pci_rx_post_buf(struct ath10k_pci_pipe *pipe)
|
||||
@ -487,25 +485,6 @@ static int ath10k_pci_diag_read_mem(struct ath10k *ar, u32 address, void *data,
|
||||
void *data_buf = NULL;
|
||||
int i;
|
||||
|
||||
/*
|
||||
* This code cannot handle reads to non-memory space. Redirect to the
|
||||
* register read fn but preserve the multi word read capability of
|
||||
* this fn
|
||||
*/
|
||||
if (address < DRAM_BASE_ADDRESS) {
|
||||
if (!IS_ALIGNED(address, 4) ||
|
||||
!IS_ALIGNED((unsigned long)data, 4))
|
||||
return -EIO;
|
||||
|
||||
while ((nbytes >= 4) && ((ret = ath10k_pci_diag_read_access(
|
||||
ar, address, (u32 *)data)) == 0)) {
|
||||
nbytes -= sizeof(u32);
|
||||
address += sizeof(u32);
|
||||
data += sizeof(u32);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
ce_diag = ar_pci->ce_diag;
|
||||
|
||||
/*
|
||||
@ -549,7 +528,7 @@ static int ath10k_pci_diag_read_mem(struct ath10k *ar, u32 address, void *data,
|
||||
address);
|
||||
|
||||
ret = ath10k_ce_send(ce_diag, NULL, (u32)address, nbytes, 0,
|
||||
0);
|
||||
0);
|
||||
if (ret)
|
||||
goto done;
|
||||
|
||||
@ -569,7 +548,7 @@ static int ath10k_pci_diag_read_mem(struct ath10k *ar, u32 address, void *data,
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (buf != (u32) address) {
|
||||
if (buf != (u32)address) {
|
||||
ret = -EIO;
|
||||
goto done;
|
||||
}
|
||||
@ -652,19 +631,7 @@ static int __ath10k_pci_diag_read_hi(struct ath10k *ar, void *dest,
|
||||
}
|
||||
|
||||
#define ath10k_pci_diag_read_hi(ar, dest, src, len) \
|
||||
__ath10k_pci_diag_read_hi(ar, dest, HI_ITEM(src), len);
|
||||
|
||||
/* Read 4-byte aligned data from Target memory or register */
|
||||
static int ath10k_pci_diag_read_access(struct ath10k *ar, u32 address,
|
||||
u32 *data)
|
||||
{
|
||||
/* Assume range doesn't cross this boundary */
|
||||
if (address >= DRAM_BASE_ADDRESS)
|
||||
return ath10k_pci_diag_read32(ar, address, data);
|
||||
|
||||
*data = ath10k_pci_read32(ar, address);
|
||||
return 0;
|
||||
}
|
||||
__ath10k_pci_diag_read_hi(ar, dest, HI_ITEM(src), len)
|
||||
|
||||
static int ath10k_pci_diag_write_mem(struct ath10k *ar, u32 address,
|
||||
const void *data, int nbytes)
|
||||
@ -729,7 +696,7 @@ static int ath10k_pci_diag_write_mem(struct ath10k *ar, u32 address,
|
||||
* Request CE to send caller-supplied data that
|
||||
* was copied to bounce buffer to Target(!) address.
|
||||
*/
|
||||
ret = ath10k_ce_send(ce_diag, NULL, (u32) ce_data,
|
||||
ret = ath10k_ce_send(ce_diag, NULL, (u32)ce_data,
|
||||
nbytes, 0, 0);
|
||||
if (ret != 0)
|
||||
goto done;
|
||||
@ -803,18 +770,6 @@ static int ath10k_pci_diag_write32(struct ath10k *ar, u32 address, u32 value)
|
||||
return ath10k_pci_diag_write_mem(ar, address, &val, sizeof(val));
|
||||
}
|
||||
|
||||
/* Write 4B data to Target memory or register */
|
||||
static int ath10k_pci_diag_write_access(struct ath10k *ar, u32 address,
|
||||
u32 data)
|
||||
{
|
||||
/* Assume range doesn't cross this boundary */
|
||||
if (address >= DRAM_BASE_ADDRESS)
|
||||
return ath10k_pci_diag_write32(ar, address, data);
|
||||
|
||||
ath10k_pci_write32(ar, address, data);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool ath10k_pci_is_awake(struct ath10k *ar)
|
||||
{
|
||||
u32 val = ath10k_pci_reg_read32(ar, RTC_STATE_ADDRESS);
|
||||
@ -1152,7 +1107,7 @@ static int ath10k_pci_hif_map_service_to_pipe(struct ath10k *ar,
|
||||
}
|
||||
|
||||
static void ath10k_pci_hif_get_default_pipe(struct ath10k *ar,
|
||||
u8 *ul_pipe, u8 *dl_pipe)
|
||||
u8 *ul_pipe, u8 *dl_pipe)
|
||||
{
|
||||
int ul_is_polled, dl_is_polled;
|
||||
|
||||
@ -1172,16 +1127,8 @@ static void ath10k_pci_irq_disable(struct ath10k *ar)
|
||||
int i;
|
||||
|
||||
ath10k_ce_disable_interrupts(ar);
|
||||
|
||||
/* Regardless how many interrupts were assigned for MSI the first one
|
||||
* is always used for firmware indications (crashes). There's no way to
|
||||
* mask the irq in the device so call disable_irq(). Legacy (shared)
|
||||
* interrupts can be masked on the device though.
|
||||
*/
|
||||
if (ar_pci->num_msi_intrs > 0)
|
||||
disable_irq(ar_pci->pdev->irq);
|
||||
else
|
||||
ath10k_pci_disable_and_clear_legacy_irq(ar);
|
||||
ath10k_pci_disable_and_clear_legacy_irq(ar);
|
||||
/* FIXME: How to mask all MSI interrupts? */
|
||||
|
||||
for (i = 0; i < max(1, ar_pci->num_msi_intrs); i++)
|
||||
synchronize_irq(ar_pci->pdev->irq + i);
|
||||
@ -1189,15 +1136,9 @@ static void ath10k_pci_irq_disable(struct ath10k *ar)
|
||||
|
||||
static void ath10k_pci_irq_enable(struct ath10k *ar)
|
||||
{
|
||||
struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
|
||||
|
||||
ath10k_ce_enable_interrupts(ar);
|
||||
|
||||
/* See comment in ath10k_pci_irq_disable() */
|
||||
if (ar_pci->num_msi_intrs > 0)
|
||||
enable_irq(ar_pci->pdev->irq);
|
||||
else
|
||||
ath10k_pci_enable_legacy_irq(ar);
|
||||
ath10k_pci_enable_legacy_irq(ar);
|
||||
/* FIXME: How to unmask all MSI interrupts? */
|
||||
}
|
||||
|
||||
static int ath10k_pci_hif_start(struct ath10k *ar)
|
||||
@ -1311,14 +1252,21 @@ static void ath10k_pci_hif_stop(struct ath10k *ar)
|
||||
{
|
||||
ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot hif stop\n");
|
||||
|
||||
ath10k_pci_irq_disable(ar);
|
||||
ath10k_pci_flush(ar);
|
||||
|
||||
/* Most likely the device has HTT Rx ring configured. The only way to
|
||||
* prevent the device from accessing (and possible corrupting) host
|
||||
* memory is to reset the chip now.
|
||||
*
|
||||
* There's also no known way of masking MSI interrupts on the device.
|
||||
* For ranged MSI the CE-related interrupts can be masked. However
|
||||
* regardless how many MSI interrupts are assigned the first one
|
||||
* is always used for firmware indications (crashes) and cannot be
|
||||
* masked. To prevent the device from asserting the interrupt reset it
|
||||
* before proceeding with cleanup.
|
||||
*/
|
||||
ath10k_pci_warm_reset(ar);
|
||||
|
||||
ath10k_pci_irq_disable(ar);
|
||||
ath10k_pci_flush(ar);
|
||||
}
|
||||
|
||||
static int ath10k_pci_hif_exchange_bmi_msg(struct ath10k *ar,
|
||||
@ -1472,28 +1420,12 @@ static int ath10k_pci_bmi_wait(struct ath10k_ce_pipe *tx_pipe,
|
||||
*/
|
||||
static int ath10k_pci_wake_target_cpu(struct ath10k *ar)
|
||||
{
|
||||
int ret;
|
||||
u32 core_ctrl;
|
||||
u32 addr, val;
|
||||
|
||||
ret = ath10k_pci_diag_read_access(ar, SOC_CORE_BASE_ADDRESS |
|
||||
CORE_CTRL_ADDRESS,
|
||||
&core_ctrl);
|
||||
if (ret) {
|
||||
ath10k_warn(ar, "failed to read core_ctrl: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* A_INUM_FIRMWARE interrupt to Target CPU */
|
||||
core_ctrl |= CORE_CTRL_CPU_INTR_MASK;
|
||||
|
||||
ret = ath10k_pci_diag_write_access(ar, SOC_CORE_BASE_ADDRESS |
|
||||
CORE_CTRL_ADDRESS,
|
||||
core_ctrl);
|
||||
if (ret) {
|
||||
ath10k_warn(ar, "failed to set target CPU interrupt mask: %d\n",
|
||||
ret);
|
||||
return ret;
|
||||
}
|
||||
addr = SOC_CORE_BASE_ADDRESS | CORE_CTRL_ADDRESS;
|
||||
val = ath10k_pci_read32(ar, addr);
|
||||
val |= CORE_CTRL_CPU_INTR_MASK;
|
||||
ath10k_pci_write32(ar, addr, val);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -1516,8 +1448,8 @@ static int ath10k_pci_init_config(struct ath10k *ar)
|
||||
host_interest_item_address(HI_ITEM(hi_interconnect_state));
|
||||
|
||||
/* Supply Target-side CE configuration */
|
||||
ret = ath10k_pci_diag_read_access(ar, interconnect_targ_addr,
|
||||
&pcie_state_targ_addr);
|
||||
ret = ath10k_pci_diag_read32(ar, interconnect_targ_addr,
|
||||
&pcie_state_targ_addr);
|
||||
if (ret != 0) {
|
||||
ath10k_err(ar, "Failed to get pcie state addr: %d\n", ret);
|
||||
return ret;
|
||||
@ -1529,10 +1461,10 @@ static int ath10k_pci_init_config(struct ath10k *ar)
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = ath10k_pci_diag_read_access(ar, pcie_state_targ_addr +
|
||||
ret = ath10k_pci_diag_read32(ar, (pcie_state_targ_addr +
|
||||
offsetof(struct pcie_state,
|
||||
pipe_cfg_addr),
|
||||
&pipe_cfg_targ_addr);
|
||||
pipe_cfg_addr)),
|
||||
&pipe_cfg_targ_addr);
|
||||
if (ret != 0) {
|
||||
ath10k_err(ar, "Failed to get pipe cfg addr: %d\n", ret);
|
||||
return ret;
|
||||
@ -1545,18 +1477,18 @@ static int ath10k_pci_init_config(struct ath10k *ar)
|
||||
}
|
||||
|
||||
ret = ath10k_pci_diag_write_mem(ar, pipe_cfg_targ_addr,
|
||||
target_ce_config_wlan,
|
||||
sizeof(target_ce_config_wlan));
|
||||
target_ce_config_wlan,
|
||||
sizeof(target_ce_config_wlan));
|
||||
|
||||
if (ret != 0) {
|
||||
ath10k_err(ar, "Failed to write pipe cfg: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = ath10k_pci_diag_read_access(ar, pcie_state_targ_addr +
|
||||
ret = ath10k_pci_diag_read32(ar, (pcie_state_targ_addr +
|
||||
offsetof(struct pcie_state,
|
||||
svc_to_pipe_map),
|
||||
&svc_to_pipe_map);
|
||||
svc_to_pipe_map)),
|
||||
&svc_to_pipe_map);
|
||||
if (ret != 0) {
|
||||
ath10k_err(ar, "Failed to get svc/pipe map: %d\n", ret);
|
||||
return ret;
|
||||
@ -1569,17 +1501,17 @@ static int ath10k_pci_init_config(struct ath10k *ar)
|
||||
}
|
||||
|
||||
ret = ath10k_pci_diag_write_mem(ar, svc_to_pipe_map,
|
||||
target_service_to_ce_map_wlan,
|
||||
sizeof(target_service_to_ce_map_wlan));
|
||||
target_service_to_ce_map_wlan,
|
||||
sizeof(target_service_to_ce_map_wlan));
|
||||
if (ret != 0) {
|
||||
ath10k_err(ar, "Failed to write svc/pipe map: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = ath10k_pci_diag_read_access(ar, pcie_state_targ_addr +
|
||||
ret = ath10k_pci_diag_read32(ar, (pcie_state_targ_addr +
|
||||
offsetof(struct pcie_state,
|
||||
config_flags),
|
||||
&pcie_config_flags);
|
||||
config_flags)),
|
||||
&pcie_config_flags);
|
||||
if (ret != 0) {
|
||||
ath10k_err(ar, "Failed to get pcie config_flags: %d\n", ret);
|
||||
return ret;
|
||||
@ -1587,9 +1519,10 @@ static int ath10k_pci_init_config(struct ath10k *ar)
|
||||
|
||||
pcie_config_flags &= ~PCIE_CONFIG_FLAG_ENABLE_L1;
|
||||
|
||||
ret = ath10k_pci_diag_write_access(ar, pcie_state_targ_addr +
|
||||
offsetof(struct pcie_state, config_flags),
|
||||
pcie_config_flags);
|
||||
ret = ath10k_pci_diag_write32(ar, (pcie_state_targ_addr +
|
||||
offsetof(struct pcie_state,
|
||||
config_flags)),
|
||||
pcie_config_flags);
|
||||
if (ret != 0) {
|
||||
ath10k_err(ar, "Failed to write pcie config_flags: %d\n", ret);
|
||||
return ret;
|
||||
@ -1598,7 +1531,7 @@ static int ath10k_pci_init_config(struct ath10k *ar)
|
||||
/* configure early allocation */
|
||||
ealloc_targ_addr = host_interest_item_address(HI_ITEM(hi_early_alloc));
|
||||
|
||||
ret = ath10k_pci_diag_read_access(ar, ealloc_targ_addr, &ealloc_value);
|
||||
ret = ath10k_pci_diag_read32(ar, ealloc_targ_addr, &ealloc_value);
|
||||
if (ret != 0) {
|
||||
ath10k_err(ar, "Faile to get early alloc val: %d\n", ret);
|
||||
return ret;
|
||||
@ -1610,7 +1543,7 @@ static int ath10k_pci_init_config(struct ath10k *ar)
|
||||
ealloc_value |= ((1 << HI_EARLY_ALLOC_IRAM_BANKS_SHIFT) &
|
||||
HI_EARLY_ALLOC_IRAM_BANKS_MASK);
|
||||
|
||||
ret = ath10k_pci_diag_write_access(ar, ealloc_targ_addr, ealloc_value);
|
||||
ret = ath10k_pci_diag_write32(ar, ealloc_targ_addr, ealloc_value);
|
||||
if (ret != 0) {
|
||||
ath10k_err(ar, "Failed to set early alloc val: %d\n", ret);
|
||||
return ret;
|
||||
@ -1619,7 +1552,7 @@ static int ath10k_pci_init_config(struct ath10k *ar)
|
||||
/* Tell Target to proceed with initialization */
|
||||
flag2_targ_addr = host_interest_item_address(HI_ITEM(hi_option_flag2));
|
||||
|
||||
ret = ath10k_pci_diag_read_access(ar, flag2_targ_addr, &flag2_value);
|
||||
ret = ath10k_pci_diag_read32(ar, flag2_targ_addr, &flag2_value);
|
||||
if (ret != 0) {
|
||||
ath10k_err(ar, "Failed to get option val: %d\n", ret);
|
||||
return ret;
|
||||
@ -1627,7 +1560,7 @@ static int ath10k_pci_init_config(struct ath10k *ar)
|
||||
|
||||
flag2_value |= HI_OPTION_EARLY_CFG_DONE;
|
||||
|
||||
ret = ath10k_pci_diag_write_access(ar, flag2_targ_addr, flag2_value);
|
||||
ret = ath10k_pci_diag_write32(ar, flag2_targ_addr, flag2_value);
|
||||
if (ret != 0) {
|
||||
ath10k_err(ar, "Failed to set option val: %d\n", ret);
|
||||
return ret;
|
||||
@ -1692,7 +1625,7 @@ static int ath10k_pci_ce_init(struct ath10k *ar)
|
||||
continue;
|
||||
}
|
||||
|
||||
pipe_info->buf_sz = (size_t) (attr->src_sz_max);
|
||||
pipe_info->buf_sz = (size_t)(attr->src_sz_max);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@ -2228,7 +2161,7 @@ static int ath10k_pci_init_irq(struct ath10k *ar)
|
||||
if (ath10k_pci_irq_mode == ATH10K_PCI_IRQ_AUTO) {
|
||||
ar_pci->num_msi_intrs = MSI_NUM_REQUEST;
|
||||
ret = pci_enable_msi_range(ar_pci->pdev, ar_pci->num_msi_intrs,
|
||||
ar_pci->num_msi_intrs);
|
||||
ar_pci->num_msi_intrs);
|
||||
if (ret > 0)
|
||||
return 0;
|
||||
|
||||
@ -2554,6 +2487,7 @@ static int ath10k_pci_probe(struct pci_dev *pdev,
|
||||
|
||||
err_free_irq:
|
||||
ath10k_pci_free_irq(ar);
|
||||
ath10k_pci_kill_tasklet(ar);
|
||||
|
||||
err_deinit_irq:
|
||||
ath10k_pci_deinit_irq(ar);
|
||||
@ -2590,6 +2524,7 @@ static void ath10k_pci_remove(struct pci_dev *pdev)
|
||||
|
||||
ath10k_core_unregister(ar);
|
||||
ath10k_pci_free_irq(ar);
|
||||
ath10k_pci_kill_tasklet(ar);
|
||||
ath10k_pci_deinit_irq(ar);
|
||||
ath10k_pci_ce_deinit(ar);
|
||||
ath10k_pci_free_ce(ar);
|
||||
|
@ -839,7 +839,6 @@ struct rx_ppdu_start {
|
||||
* Reserved: HW should fill with 0, FW should ignore.
|
||||
*/
|
||||
|
||||
|
||||
#define RX_PPDU_END_FLAGS_PHY_ERR (1 << 0)
|
||||
#define RX_PPDU_END_FLAGS_RX_LOCATION (1 << 1)
|
||||
#define RX_PPDU_END_FLAGS_TXBF_H_INFO (1 << 2)
|
||||
|
@ -284,7 +284,6 @@ Fw Mode/SubMode Mask
|
||||
#define HI_OPTION_ALL_FW_SUBMODE_MASK 0xFF00
|
||||
#define HI_OPTION_ALL_FW_SUBMODE_SHIFT 0x8
|
||||
|
||||
|
||||
/* hi_option_flag2 options */
|
||||
#define HI_OPTION_OFFLOAD_AMSDU 0x01
|
||||
#define HI_OPTION_DFS_SUPPORT 0x02 /* Enable DFS support */
|
||||
|
382
drivers/net/wireless/ath/ath10k/testmode.c
Normal file
382
drivers/net/wireless/ath/ath10k/testmode.c
Normal file
@ -0,0 +1,382 @@
|
||||
/*
|
||||
* Copyright (c) 2014 Qualcomm Atheros, Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "testmode.h"
|
||||
|
||||
#include <net/netlink.h>
|
||||
#include <linux/firmware.h>
|
||||
|
||||
#include "debug.h"
|
||||
#include "wmi.h"
|
||||
#include "hif.h"
|
||||
#include "hw.h"
|
||||
|
||||
#include "testmode_i.h"
|
||||
|
||||
static const struct nla_policy ath10k_tm_policy[ATH10K_TM_ATTR_MAX + 1] = {
|
||||
[ATH10K_TM_ATTR_CMD] = { .type = NLA_U32 },
|
||||
[ATH10K_TM_ATTR_DATA] = { .type = NLA_BINARY,
|
||||
.len = ATH10K_TM_DATA_MAX_LEN },
|
||||
[ATH10K_TM_ATTR_WMI_CMDID] = { .type = NLA_U32 },
|
||||
[ATH10K_TM_ATTR_VERSION_MAJOR] = { .type = NLA_U32 },
|
||||
[ATH10K_TM_ATTR_VERSION_MINOR] = { .type = NLA_U32 },
|
||||
};
|
||||
|
||||
/* Returns true if callee consumes the skb and the skb should be discarded.
|
||||
* Returns false if skb is not used. Does not sleep.
|
||||
*/
|
||||
bool ath10k_tm_event_wmi(struct ath10k *ar, u32 cmd_id, struct sk_buff *skb)
|
||||
{
|
||||
struct sk_buff *nl_skb;
|
||||
bool consumed;
|
||||
int ret;
|
||||
|
||||
ath10k_dbg(ar, ATH10K_DBG_TESTMODE,
|
||||
"testmode event wmi cmd_id %d skb %p skb->len %d\n",
|
||||
cmd_id, skb, skb->len);
|
||||
|
||||
ath10k_dbg_dump(ar, ATH10K_DBG_TESTMODE, NULL, "", skb->data, skb->len);
|
||||
|
||||
spin_lock_bh(&ar->data_lock);
|
||||
|
||||
if (!ar->testmode.utf_monitor) {
|
||||
consumed = false;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Only testmode.c should be handling events from utf firmware,
|
||||
* otherwise all sort of problems will arise as mac80211 operations
|
||||
* are not initialised.
|
||||
*/
|
||||
consumed = true;
|
||||
|
||||
nl_skb = cfg80211_testmode_alloc_event_skb(ar->hw->wiphy,
|
||||
2 * sizeof(u32) + skb->len,
|
||||
GFP_ATOMIC);
|
||||
if (!nl_skb) {
|
||||
ath10k_warn(ar,
|
||||
"failed to allocate skb for testmode wmi event\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = nla_put_u32(nl_skb, ATH10K_TM_ATTR_CMD, ATH10K_TM_CMD_WMI);
|
||||
if (ret) {
|
||||
ath10k_warn(ar,
|
||||
"failed to to put testmode wmi event cmd attribute: %d\n",
|
||||
ret);
|
||||
kfree_skb(nl_skb);
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = nla_put_u32(nl_skb, ATH10K_TM_ATTR_WMI_CMDID, cmd_id);
|
||||
if (ret) {
|
||||
ath10k_warn(ar,
|
||||
"failed to to put testmode wmi even cmd_id: %d\n",
|
||||
ret);
|
||||
kfree_skb(nl_skb);
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = nla_put(nl_skb, ATH10K_TM_ATTR_DATA, skb->len, skb->data);
|
||||
if (ret) {
|
||||
ath10k_warn(ar,
|
||||
"failed to copy skb to testmode wmi event: %d\n",
|
||||
ret);
|
||||
kfree_skb(nl_skb);
|
||||
goto out;
|
||||
}
|
||||
|
||||
cfg80211_testmode_event(nl_skb, GFP_ATOMIC);
|
||||
|
||||
out:
|
||||
spin_unlock_bh(&ar->data_lock);
|
||||
|
||||
return consumed;
|
||||
}
|
||||
|
||||
static int ath10k_tm_cmd_get_version(struct ath10k *ar, struct nlattr *tb[])
|
||||
{
|
||||
struct sk_buff *skb;
|
||||
int ret;
|
||||
|
||||
ath10k_dbg(ar, ATH10K_DBG_TESTMODE,
|
||||
"testmode cmd get version_major %d version_minor %d\n",
|
||||
ATH10K_TESTMODE_VERSION_MAJOR,
|
||||
ATH10K_TESTMODE_VERSION_MINOR);
|
||||
|
||||
skb = cfg80211_testmode_alloc_reply_skb(ar->hw->wiphy,
|
||||
nla_total_size(sizeof(u32)));
|
||||
if (!skb)
|
||||
return -ENOMEM;
|
||||
|
||||
ret = nla_put_u32(skb, ATH10K_TM_ATTR_VERSION_MAJOR,
|
||||
ATH10K_TESTMODE_VERSION_MAJOR);
|
||||
if (ret) {
|
||||
kfree_skb(skb);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = nla_put_u32(skb, ATH10K_TM_ATTR_VERSION_MINOR,
|
||||
ATH10K_TESTMODE_VERSION_MINOR);
|
||||
if (ret) {
|
||||
kfree_skb(skb);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return cfg80211_testmode_reply(skb);
|
||||
}
|
||||
|
||||
static int ath10k_tm_cmd_utf_start(struct ath10k *ar, struct nlattr *tb[])
|
||||
{
|
||||
char filename[100];
|
||||
int ret;
|
||||
|
||||
ath10k_dbg(ar, ATH10K_DBG_TESTMODE, "testmode cmd utf start\n");
|
||||
|
||||
mutex_lock(&ar->conf_mutex);
|
||||
|
||||
if (ar->state == ATH10K_STATE_UTF) {
|
||||
ret = -EALREADY;
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* start utf only when the driver is not in use */
|
||||
if (ar->state != ATH10K_STATE_OFF) {
|
||||
ret = -EBUSY;
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (WARN_ON(ar->testmode.utf != NULL)) {
|
||||
/* utf image is already downloaded, it shouldn't be */
|
||||
ret = -EEXIST;
|
||||
goto err;
|
||||
}
|
||||
|
||||
snprintf(filename, sizeof(filename), "%s/%s",
|
||||
ar->hw_params.fw.dir, ATH10K_FW_UTF_FILE);
|
||||
|
||||
/* load utf firmware image */
|
||||
ret = request_firmware(&ar->testmode.utf, filename, ar->dev);
|
||||
if (ret) {
|
||||
ath10k_warn(ar, "failed to retrieve utf firmware '%s': %d\n",
|
||||
filename, ret);
|
||||
goto err;
|
||||
}
|
||||
|
||||
spin_lock_bh(&ar->data_lock);
|
||||
|
||||
ar->testmode.utf_monitor = true;
|
||||
|
||||
spin_unlock_bh(&ar->data_lock);
|
||||
|
||||
BUILD_BUG_ON(sizeof(ar->fw_features) !=
|
||||
sizeof(ar->testmode.orig_fw_features));
|
||||
|
||||
memcpy(ar->testmode.orig_fw_features, ar->fw_features,
|
||||
sizeof(ar->fw_features));
|
||||
|
||||
/* 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);
|
||||
|
||||
ret = ath10k_hif_power_up(ar);
|
||||
if (ret) {
|
||||
ath10k_err(ar, "failed to power up hif (testmode): %d\n", ret);
|
||||
ar->state = ATH10K_STATE_OFF;
|
||||
goto err_fw_features;
|
||||
}
|
||||
|
||||
ret = ath10k_core_start(ar, ATH10K_FIRMWARE_MODE_UTF);
|
||||
if (ret) {
|
||||
ath10k_err(ar, "failed to start core (testmode): %d\n", ret);
|
||||
ar->state = ATH10K_STATE_OFF;
|
||||
goto err_power_down;
|
||||
}
|
||||
|
||||
ar->state = ATH10K_STATE_UTF;
|
||||
|
||||
ath10k_info(ar, "UTF firmware started\n");
|
||||
|
||||
mutex_unlock(&ar->conf_mutex);
|
||||
|
||||
return 0;
|
||||
|
||||
err_power_down:
|
||||
ath10k_hif_power_down(ar);
|
||||
|
||||
err_fw_features:
|
||||
/* return the original firmware features */
|
||||
memcpy(ar->fw_features, ar->testmode.orig_fw_features,
|
||||
sizeof(ar->fw_features));
|
||||
|
||||
release_firmware(ar->testmode.utf);
|
||||
ar->testmode.utf = NULL;
|
||||
|
||||
err:
|
||||
mutex_unlock(&ar->conf_mutex);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void __ath10k_tm_cmd_utf_stop(struct ath10k *ar)
|
||||
{
|
||||
lockdep_assert_held(&ar->conf_mutex);
|
||||
|
||||
ath10k_core_stop(ar);
|
||||
ath10k_hif_power_down(ar);
|
||||
|
||||
spin_lock_bh(&ar->data_lock);
|
||||
|
||||
ar->testmode.utf_monitor = false;
|
||||
|
||||
spin_unlock_bh(&ar->data_lock);
|
||||
|
||||
/* return the original firmware features */
|
||||
memcpy(ar->fw_features, ar->testmode.orig_fw_features,
|
||||
sizeof(ar->fw_features));
|
||||
|
||||
release_firmware(ar->testmode.utf);
|
||||
ar->testmode.utf = NULL;
|
||||
|
||||
ar->state = ATH10K_STATE_OFF;
|
||||
}
|
||||
|
||||
static int ath10k_tm_cmd_utf_stop(struct ath10k *ar, struct nlattr *tb[])
|
||||
{
|
||||
int ret;
|
||||
|
||||
ath10k_dbg(ar, ATH10K_DBG_TESTMODE, "testmode cmd utf stop\n");
|
||||
|
||||
mutex_lock(&ar->conf_mutex);
|
||||
|
||||
if (ar->state != ATH10K_STATE_UTF) {
|
||||
ret = -ENETDOWN;
|
||||
goto out;
|
||||
}
|
||||
|
||||
__ath10k_tm_cmd_utf_stop(ar);
|
||||
|
||||
ret = 0;
|
||||
|
||||
ath10k_info(ar, "UTF firmware stopped\n");
|
||||
|
||||
out:
|
||||
mutex_unlock(&ar->conf_mutex);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int ath10k_tm_cmd_wmi(struct ath10k *ar, struct nlattr *tb[])
|
||||
{
|
||||
struct sk_buff *skb;
|
||||
int ret, buf_len;
|
||||
u32 cmd_id;
|
||||
void *buf;
|
||||
|
||||
mutex_lock(&ar->conf_mutex);
|
||||
|
||||
if (ar->state != ATH10K_STATE_UTF) {
|
||||
ret = -ENETDOWN;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!tb[ATH10K_TM_ATTR_DATA]) {
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!tb[ATH10K_TM_ATTR_WMI_CMDID]) {
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
buf = nla_data(tb[ATH10K_TM_ATTR_DATA]);
|
||||
buf_len = nla_len(tb[ATH10K_TM_ATTR_DATA]);
|
||||
cmd_id = nla_get_u32(tb[ATH10K_TM_ATTR_WMI_CMDID]);
|
||||
|
||||
ath10k_dbg(ar, ATH10K_DBG_TESTMODE,
|
||||
"testmode cmd wmi cmd_id %d buf %p buf_len %d\n",
|
||||
cmd_id, buf, buf_len);
|
||||
|
||||
ath10k_dbg_dump(ar, ATH10K_DBG_TESTMODE, NULL, "", buf, buf_len);
|
||||
|
||||
skb = ath10k_wmi_alloc_skb(ar, buf_len);
|
||||
if (!skb) {
|
||||
ret = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
memcpy(skb->data, buf, buf_len);
|
||||
|
||||
ret = ath10k_wmi_cmd_send(ar, skb, cmd_id);
|
||||
if (ret) {
|
||||
ath10k_warn(ar, "failed to transmit wmi command (testmode): %d\n",
|
||||
ret);
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
|
||||
out:
|
||||
mutex_unlock(&ar->conf_mutex);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ath10k_tm_cmd(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
|
||||
void *data, int len)
|
||||
{
|
||||
struct ath10k *ar = hw->priv;
|
||||
struct nlattr *tb[ATH10K_TM_ATTR_MAX + 1];
|
||||
int ret;
|
||||
|
||||
ret = nla_parse(tb, ATH10K_TM_ATTR_MAX, data, len,
|
||||
ath10k_tm_policy);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (!tb[ATH10K_TM_ATTR_CMD])
|
||||
return -EINVAL;
|
||||
|
||||
switch (nla_get_u32(tb[ATH10K_TM_ATTR_CMD])) {
|
||||
case ATH10K_TM_CMD_GET_VERSION:
|
||||
return ath10k_tm_cmd_get_version(ar, tb);
|
||||
case ATH10K_TM_CMD_UTF_START:
|
||||
return ath10k_tm_cmd_utf_start(ar, tb);
|
||||
case ATH10K_TM_CMD_UTF_STOP:
|
||||
return ath10k_tm_cmd_utf_stop(ar, tb);
|
||||
case ATH10K_TM_CMD_WMI:
|
||||
return ath10k_tm_cmd_wmi(ar, tb);
|
||||
default:
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
}
|
||||
|
||||
void ath10k_testmode_destroy(struct ath10k *ar)
|
||||
{
|
||||
mutex_lock(&ar->conf_mutex);
|
||||
|
||||
if (ar->state != ATH10K_STATE_UTF) {
|
||||
/* utf firmware is not running, nothing to do */
|
||||
goto out;
|
||||
}
|
||||
|
||||
__ath10k_tm_cmd_utf_stop(ar);
|
||||
|
||||
out:
|
||||
mutex_unlock(&ar->conf_mutex);
|
||||
}
|
46
drivers/net/wireless/ath/ath10k/testmode.h
Normal file
46
drivers/net/wireless/ath/ath10k/testmode.h
Normal file
@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Copyright (c) 2014 Qualcomm Atheros, Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "core.h"
|
||||
|
||||
#ifdef CONFIG_NL80211_TESTMODE
|
||||
|
||||
void ath10k_testmode_destroy(struct ath10k *ar);
|
||||
|
||||
bool ath10k_tm_event_wmi(struct ath10k *ar, u32 cmd_id, struct sk_buff *skb);
|
||||
int ath10k_tm_cmd(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
|
||||
void *data, int len);
|
||||
|
||||
#else
|
||||
|
||||
static inline void ath10k_testmode_destroy(struct ath10k *ar)
|
||||
{
|
||||
}
|
||||
|
||||
static inline bool ath10k_tm_event_wmi(struct ath10k *ar, u32 cmd_id,
|
||||
struct sk_buff *skb)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
static inline int ath10k_tm_cmd(struct ieee80211_hw *hw,
|
||||
struct ieee80211_vif *vif,
|
||||
void *data, int len)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
70
drivers/net/wireless/ath/ath10k/testmode_i.h
Normal file
70
drivers/net/wireless/ath/ath10k/testmode_i.h
Normal file
@ -0,0 +1,70 @@
|
||||
/*
|
||||
* Copyright (c) 2014 Qualcomm Atheros, Inc.
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* "API" level of the ath10k testmode interface. Bump it after every
|
||||
* incompatible interface change.
|
||||
*/
|
||||
#define ATH10K_TESTMODE_VERSION_MAJOR 1
|
||||
|
||||
/* Bump this after every _compatible_ interface change, for example
|
||||
* addition of a new command or an attribute.
|
||||
*/
|
||||
#define ATH10K_TESTMODE_VERSION_MINOR 0
|
||||
|
||||
#define ATH10K_TM_DATA_MAX_LEN 5000
|
||||
|
||||
enum ath10k_tm_attr {
|
||||
__ATH10K_TM_ATTR_INVALID = 0,
|
||||
ATH10K_TM_ATTR_CMD = 1,
|
||||
ATH10K_TM_ATTR_DATA = 2,
|
||||
ATH10K_TM_ATTR_WMI_CMDID = 3,
|
||||
ATH10K_TM_ATTR_VERSION_MAJOR = 4,
|
||||
ATH10K_TM_ATTR_VERSION_MINOR = 5,
|
||||
|
||||
/* keep last */
|
||||
__ATH10K_TM_ATTR_AFTER_LAST,
|
||||
ATH10K_TM_ATTR_MAX = __ATH10K_TM_ATTR_AFTER_LAST - 1,
|
||||
};
|
||||
|
||||
/* All ath10k testmode interface commands specified in
|
||||
* ATH10K_TM_ATTR_CMD
|
||||
*/
|
||||
enum ath10k_tm_cmd {
|
||||
/* Returns the supported ath10k testmode interface version in
|
||||
* ATH10K_TM_ATTR_VERSION. Always guaranteed to work. User space
|
||||
* uses this to verify it's using the correct version of the
|
||||
* testmode interface
|
||||
*/
|
||||
ATH10K_TM_CMD_GET_VERSION = 0,
|
||||
|
||||
/* Boots the UTF firmware, the netdev interface must be down at the
|
||||
* time.
|
||||
*/
|
||||
ATH10K_TM_CMD_UTF_START = 1,
|
||||
|
||||
/* Shuts down the UTF firmware and puts the driver back into OFF
|
||||
* state.
|
||||
*/
|
||||
ATH10K_TM_CMD_UTF_STOP = 2,
|
||||
|
||||
/* The command used to transmit a WMI command to the firmware and
|
||||
* the event to receive WMI events from the firmware. Without
|
||||
* struct wmi_cmd_hdr header, only the WMI payload. Command id is
|
||||
* provided with ATH10K_TM_ATTR_WMI_CMDID and payload in
|
||||
* ATH10K_TM_ATTR_DATA.
|
||||
*/
|
||||
ATH10K_TM_CMD_WMI = 3,
|
||||
};
|
@ -18,6 +18,7 @@
|
||||
#if !defined(_TRACE_H_) || defined(TRACE_HEADER_MULTI_READ)
|
||||
|
||||
#include <linux/tracepoint.h>
|
||||
#include "core.h"
|
||||
|
||||
#define _TRACE_H_
|
||||
|
||||
@ -39,59 +40,79 @@ static inline void trace_ ## name(proto) {}
|
||||
#define ATH10K_MSG_MAX 200
|
||||
|
||||
DECLARE_EVENT_CLASS(ath10k_log_event,
|
||||
TP_PROTO(struct va_format *vaf),
|
||||
TP_ARGS(vaf),
|
||||
TP_PROTO(struct ath10k *ar, struct va_format *vaf),
|
||||
TP_ARGS(ar, vaf),
|
||||
TP_STRUCT__entry(
|
||||
__string(device, dev_name(ar->dev))
|
||||
__string(driver, dev_driver_string(ar->dev))
|
||||
__dynamic_array(char, msg, ATH10K_MSG_MAX)
|
||||
),
|
||||
TP_fast_assign(
|
||||
__assign_str(device, dev_name(ar->dev));
|
||||
__assign_str(driver, dev_driver_string(ar->dev));
|
||||
WARN_ON_ONCE(vsnprintf(__get_dynamic_array(msg),
|
||||
ATH10K_MSG_MAX,
|
||||
vaf->fmt,
|
||||
*vaf->va) >= ATH10K_MSG_MAX);
|
||||
),
|
||||
TP_printk("%s", __get_str(msg))
|
||||
TP_printk(
|
||||
"%s %s %s",
|
||||
__get_str(driver),
|
||||
__get_str(device),
|
||||
__get_str(msg)
|
||||
)
|
||||
);
|
||||
|
||||
DEFINE_EVENT(ath10k_log_event, ath10k_log_err,
|
||||
TP_PROTO(struct va_format *vaf),
|
||||
TP_ARGS(vaf)
|
||||
TP_PROTO(struct ath10k *ar, struct va_format *vaf),
|
||||
TP_ARGS(ar, vaf)
|
||||
);
|
||||
|
||||
DEFINE_EVENT(ath10k_log_event, ath10k_log_warn,
|
||||
TP_PROTO(struct va_format *vaf),
|
||||
TP_ARGS(vaf)
|
||||
TP_PROTO(struct ath10k *ar, struct va_format *vaf),
|
||||
TP_ARGS(ar, vaf)
|
||||
);
|
||||
|
||||
DEFINE_EVENT(ath10k_log_event, ath10k_log_info,
|
||||
TP_PROTO(struct va_format *vaf),
|
||||
TP_ARGS(vaf)
|
||||
TP_PROTO(struct ath10k *ar, struct va_format *vaf),
|
||||
TP_ARGS(ar, vaf)
|
||||
);
|
||||
|
||||
TRACE_EVENT(ath10k_log_dbg,
|
||||
TP_PROTO(unsigned int level, struct va_format *vaf),
|
||||
TP_ARGS(level, vaf),
|
||||
TP_PROTO(struct ath10k *ar, unsigned int level, struct va_format *vaf),
|
||||
TP_ARGS(ar, level, vaf),
|
||||
TP_STRUCT__entry(
|
||||
__string(device, dev_name(ar->dev))
|
||||
__string(driver, dev_driver_string(ar->dev))
|
||||
__field(unsigned int, level)
|
||||
__dynamic_array(char, msg, ATH10K_MSG_MAX)
|
||||
),
|
||||
TP_fast_assign(
|
||||
__assign_str(device, dev_name(ar->dev));
|
||||
__assign_str(driver, dev_driver_string(ar->dev));
|
||||
__entry->level = level;
|
||||
WARN_ON_ONCE(vsnprintf(__get_dynamic_array(msg),
|
||||
ATH10K_MSG_MAX,
|
||||
vaf->fmt,
|
||||
*vaf->va) >= ATH10K_MSG_MAX);
|
||||
),
|
||||
TP_printk("%s", __get_str(msg))
|
||||
TP_printk(
|
||||
"%s %s %s",
|
||||
__get_str(driver),
|
||||
__get_str(device),
|
||||
__get_str(msg)
|
||||
)
|
||||
);
|
||||
|
||||
TRACE_EVENT(ath10k_log_dbg_dump,
|
||||
TP_PROTO(const char *msg, const char *prefix,
|
||||
TP_PROTO(struct ath10k *ar, const char *msg, const char *prefix,
|
||||
const void *buf, size_t buf_len),
|
||||
|
||||
TP_ARGS(msg, prefix, buf, buf_len),
|
||||
TP_ARGS(ar, msg, prefix, buf, buf_len),
|
||||
|
||||
TP_STRUCT__entry(
|
||||
__string(device, dev_name(ar->dev))
|
||||
__string(driver, dev_driver_string(ar->dev))
|
||||
__string(msg, msg)
|
||||
__string(prefix, prefix)
|
||||
__field(size_t, buf_len)
|
||||
@ -99,6 +120,8 @@ TRACE_EVENT(ath10k_log_dbg_dump,
|
||||
),
|
||||
|
||||
TP_fast_assign(
|
||||
__assign_str(device, dev_name(ar->dev));
|
||||
__assign_str(driver, dev_driver_string(ar->dev));
|
||||
__assign_str(msg, msg);
|
||||
__assign_str(prefix, prefix);
|
||||
__entry->buf_len = buf_len;
|
||||
@ -106,16 +129,22 @@ TRACE_EVENT(ath10k_log_dbg_dump,
|
||||
),
|
||||
|
||||
TP_printk(
|
||||
"%s/%s\n", __get_str(prefix), __get_str(msg)
|
||||
"%s %s %s/%s\n",
|
||||
__get_str(driver),
|
||||
__get_str(device),
|
||||
__get_str(prefix),
|
||||
__get_str(msg)
|
||||
)
|
||||
);
|
||||
|
||||
TRACE_EVENT(ath10k_wmi_cmd,
|
||||
TP_PROTO(int id, void *buf, size_t buf_len, int ret),
|
||||
TP_PROTO(struct ath10k *ar, int id, void *buf, size_t buf_len, int ret),
|
||||
|
||||
TP_ARGS(id, buf, buf_len, ret),
|
||||
TP_ARGS(ar, id, buf, buf_len, ret),
|
||||
|
||||
TP_STRUCT__entry(
|
||||
__string(device, dev_name(ar->dev))
|
||||
__string(driver, dev_driver_string(ar->dev))
|
||||
__field(unsigned int, id)
|
||||
__field(size_t, buf_len)
|
||||
__dynamic_array(u8, buf, buf_len)
|
||||
@ -123,6 +152,8 @@ TRACE_EVENT(ath10k_wmi_cmd,
|
||||
),
|
||||
|
||||
TP_fast_assign(
|
||||
__assign_str(device, dev_name(ar->dev));
|
||||
__assign_str(driver, dev_driver_string(ar->dev));
|
||||
__entry->id = id;
|
||||
__entry->buf_len = buf_len;
|
||||
__entry->ret = ret;
|
||||
@ -130,7 +161,9 @@ TRACE_EVENT(ath10k_wmi_cmd,
|
||||
),
|
||||
|
||||
TP_printk(
|
||||
"id %d len %zu ret %d",
|
||||
"%s %s id %d len %zu ret %d",
|
||||
__get_str(driver),
|
||||
__get_str(device),
|
||||
__entry->id,
|
||||
__entry->buf_len,
|
||||
__entry->ret
|
||||
@ -138,67 +171,85 @@ TRACE_EVENT(ath10k_wmi_cmd,
|
||||
);
|
||||
|
||||
TRACE_EVENT(ath10k_wmi_event,
|
||||
TP_PROTO(int id, void *buf, size_t buf_len),
|
||||
TP_PROTO(struct ath10k *ar, int id, void *buf, size_t buf_len),
|
||||
|
||||
TP_ARGS(id, buf, buf_len),
|
||||
TP_ARGS(ar, id, buf, buf_len),
|
||||
|
||||
TP_STRUCT__entry(
|
||||
__string(device, dev_name(ar->dev))
|
||||
__string(driver, dev_driver_string(ar->dev))
|
||||
__field(unsigned int, id)
|
||||
__field(size_t, buf_len)
|
||||
__dynamic_array(u8, buf, buf_len)
|
||||
),
|
||||
|
||||
TP_fast_assign(
|
||||
__assign_str(device, dev_name(ar->dev));
|
||||
__assign_str(driver, dev_driver_string(ar->dev));
|
||||
__entry->id = id;
|
||||
__entry->buf_len = buf_len;
|
||||
memcpy(__get_dynamic_array(buf), buf, buf_len);
|
||||
),
|
||||
|
||||
TP_printk(
|
||||
"id %d len %zu",
|
||||
"%s %s id %d len %zu",
|
||||
__get_str(driver),
|
||||
__get_str(device),
|
||||
__entry->id,
|
||||
__entry->buf_len
|
||||
)
|
||||
);
|
||||
|
||||
TRACE_EVENT(ath10k_htt_stats,
|
||||
TP_PROTO(void *buf, size_t buf_len),
|
||||
TP_PROTO(struct ath10k *ar, void *buf, size_t buf_len),
|
||||
|
||||
TP_ARGS(buf, buf_len),
|
||||
TP_ARGS(ar, buf, buf_len),
|
||||
|
||||
TP_STRUCT__entry(
|
||||
__string(device, dev_name(ar->dev))
|
||||
__string(driver, dev_driver_string(ar->dev))
|
||||
__field(size_t, buf_len)
|
||||
__dynamic_array(u8, buf, buf_len)
|
||||
),
|
||||
|
||||
TP_fast_assign(
|
||||
__assign_str(device, dev_name(ar->dev));
|
||||
__assign_str(driver, dev_driver_string(ar->dev));
|
||||
__entry->buf_len = buf_len;
|
||||
memcpy(__get_dynamic_array(buf), buf, buf_len);
|
||||
),
|
||||
|
||||
TP_printk(
|
||||
"len %zu",
|
||||
"%s %s len %zu",
|
||||
__get_str(driver),
|
||||
__get_str(device),
|
||||
__entry->buf_len
|
||||
)
|
||||
);
|
||||
|
||||
TRACE_EVENT(ath10k_wmi_dbglog,
|
||||
TP_PROTO(void *buf, size_t buf_len),
|
||||
TP_PROTO(struct ath10k *ar, void *buf, size_t buf_len),
|
||||
|
||||
TP_ARGS(buf, buf_len),
|
||||
TP_ARGS(ar, buf, buf_len),
|
||||
|
||||
TP_STRUCT__entry(
|
||||
__string(device, dev_name(ar->dev))
|
||||
__string(driver, dev_driver_string(ar->dev))
|
||||
__field(size_t, buf_len)
|
||||
__dynamic_array(u8, buf, buf_len)
|
||||
),
|
||||
|
||||
TP_fast_assign(
|
||||
__assign_str(device, dev_name(ar->dev));
|
||||
__assign_str(driver, dev_driver_string(ar->dev));
|
||||
__entry->buf_len = buf_len;
|
||||
memcpy(__get_dynamic_array(buf), buf, buf_len);
|
||||
),
|
||||
|
||||
TP_printk(
|
||||
"len %zu",
|
||||
"%s %s len %zu",
|
||||
__get_str(driver),
|
||||
__get_str(device),
|
||||
__entry->buf_len
|
||||
)
|
||||
);
|
||||
|
@ -178,7 +178,7 @@ void ath10k_peer_map_event(struct ath10k_htt *htt,
|
||||
goto exit;
|
||||
|
||||
peer->vdev_id = ev->vdev_id;
|
||||
memcpy(peer->addr, ev->addr, ETH_ALEN);
|
||||
ether_addr_copy(peer->addr, ev->addr);
|
||||
list_add(&peer->list, &ar->peers);
|
||||
wake_up(&ar->peer_mapping_wq);
|
||||
}
|
||||
|
@ -23,6 +23,7 @@
|
||||
#include "debug.h"
|
||||
#include "wmi.h"
|
||||
#include "mac.h"
|
||||
#include "testmode.h"
|
||||
|
||||
/* MAIN WMI cmd track */
|
||||
static struct wmi_cmd_map wmi_cmd_map = {
|
||||
@ -611,6 +612,7 @@ static struct wmi_cmd_map wmi_10_2_cmd_map = {
|
||||
int ath10k_wmi_wait_for_service_ready(struct ath10k *ar)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = wait_for_completion_timeout(&ar->wmi.service_ready,
|
||||
WMI_SERVICE_READY_TIMEOUT_HZ);
|
||||
return ret;
|
||||
@ -619,12 +621,13 @@ int ath10k_wmi_wait_for_service_ready(struct ath10k *ar)
|
||||
int ath10k_wmi_wait_for_unified_ready(struct ath10k *ar)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = wait_for_completion_timeout(&ar->wmi.unified_ready,
|
||||
WMI_UNIFIED_READY_TIMEOUT_HZ);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static struct sk_buff *ath10k_wmi_alloc_skb(struct ath10k *ar, u32 len)
|
||||
struct sk_buff *ath10k_wmi_alloc_skb(struct ath10k *ar, u32 len)
|
||||
{
|
||||
struct sk_buff *skb;
|
||||
u32 round_len = roundup(len, 4);
|
||||
@ -666,7 +669,7 @@ static int ath10k_wmi_cmd_send_nowait(struct ath10k *ar, struct sk_buff *skb,
|
||||
|
||||
memset(skb_cb, 0, sizeof(*skb_cb));
|
||||
ret = ath10k_htc_send(&ar->htc, ar->wmi.eid, skb);
|
||||
trace_ath10k_wmi_cmd(cmd_id, skb->data, skb->len, ret);
|
||||
trace_ath10k_wmi_cmd(ar, cmd_id, skb->data, skb->len, ret);
|
||||
|
||||
if (ret)
|
||||
goto err_pull;
|
||||
@ -725,8 +728,7 @@ static void ath10k_wmi_op_ep_tx_credits(struct ath10k *ar)
|
||||
wake_up(&ar->wmi.tx_credits_wq);
|
||||
}
|
||||
|
||||
static int ath10k_wmi_cmd_send(struct ath10k *ar, struct sk_buff *skb,
|
||||
u32 cmd_id)
|
||||
int ath10k_wmi_cmd_send(struct ath10k *ar, struct sk_buff *skb, u32 cmd_id)
|
||||
{
|
||||
int ret = -EOPNOTSUPP;
|
||||
|
||||
@ -792,7 +794,7 @@ int ath10k_wmi_mgmt_tx(struct ath10k *ar, struct sk_buff *skb)
|
||||
cmd->hdr.tx_power = 0;
|
||||
cmd->hdr.buf_len = __cpu_to_le32(buf_len);
|
||||
|
||||
memcpy(cmd->hdr.peer_macaddr.addr, ieee80211_get_DA(hdr), ETH_ALEN);
|
||||
ether_addr_copy(cmd->hdr.peer_macaddr.addr, ieee80211_get_DA(hdr));
|
||||
memcpy(cmd->buf, skb->data, skb->len);
|
||||
|
||||
ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi mgmt tx skb %p len %d ftype %02x stype %02x\n",
|
||||
@ -1288,7 +1290,7 @@ static int ath10k_wmi_event_debug_mesg(struct ath10k *ar, struct sk_buff *skb)
|
||||
ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi event debug mesg len %d\n",
|
||||
skb->len);
|
||||
|
||||
trace_ath10k_wmi_dbglog(skb->data, skb->len);
|
||||
trace_ath10k_wmi_dbglog(ar, skb->data, skb->len);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -1384,6 +1386,8 @@ static void ath10k_wmi_update_tim(struct ath10k *ar,
|
||||
struct ieee80211_tim_ie *tim;
|
||||
u8 *ies, *ie;
|
||||
u8 ie_len, pvm_len;
|
||||
__le32 t;
|
||||
u32 v;
|
||||
|
||||
/* if next SWBA has no tim_changed the tim_bitmap is garbage.
|
||||
* we must copy the bitmap upon change and reuse it later */
|
||||
@ -1394,8 +1398,8 @@ static void ath10k_wmi_update_tim(struct ath10k *ar,
|
||||
sizeof(bcn_info->tim_info.tim_bitmap));
|
||||
|
||||
for (i = 0; i < sizeof(arvif->u.ap.tim_bitmap); i++) {
|
||||
__le32 t = bcn_info->tim_info.tim_bitmap[i / 4];
|
||||
u32 v = __le32_to_cpu(t);
|
||||
t = bcn_info->tim_info.tim_bitmap[i / 4];
|
||||
v = __le32_to_cpu(t);
|
||||
arvif->u.ap.tim_bitmap[i] = (v >> ((i % 4) * 8)) & 0xFF;
|
||||
}
|
||||
|
||||
@ -1511,7 +1515,6 @@ static u32 ath10k_p2p_calc_noa_ie_len(struct wmi_p2p_noa_info *noa)
|
||||
u8 opp_ps_info = noa->ctwindow_oppps;
|
||||
bool opps_enabled = !!(opp_ps_info & WMI_P2P_OPPPS_ENABLE_BIT);
|
||||
|
||||
|
||||
if (!noa_descriptors && !opps_enabled)
|
||||
return len;
|
||||
|
||||
@ -1568,7 +1571,6 @@ static void ath10k_wmi_update_noa(struct ath10k *ar, struct ath10k_vif *arvif,
|
||||
kfree(old_data);
|
||||
}
|
||||
|
||||
|
||||
static void ath10k_wmi_event_host_swba(struct ath10k *ar, struct sk_buff *skb)
|
||||
{
|
||||
struct wmi_host_swba_event *ev;
|
||||
@ -1859,9 +1861,10 @@ static void ath10k_wmi_event_dfs(struct ath10k *ar,
|
||||
}
|
||||
}
|
||||
|
||||
static void ath10k_wmi_event_spectral_scan(struct ath10k *ar,
|
||||
struct wmi_single_phyerr_rx_event *event,
|
||||
u64 tsf)
|
||||
static void
|
||||
ath10k_wmi_event_spectral_scan(struct ath10k *ar,
|
||||
struct wmi_single_phyerr_rx_event *event,
|
||||
u64 tsf)
|
||||
{
|
||||
int buf_len, tlv_len, res, i = 0;
|
||||
struct phyerr_tlv *tlv;
|
||||
@ -1989,7 +1992,7 @@ static void ath10k_wmi_event_roam(struct ath10k *ar, struct sk_buff *skb)
|
||||
}
|
||||
|
||||
static void ath10k_wmi_event_profile_match(struct ath10k *ar,
|
||||
struct sk_buff *skb)
|
||||
struct sk_buff *skb)
|
||||
{
|
||||
ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_PROFILE_MATCH\n");
|
||||
}
|
||||
@ -2040,13 +2043,13 @@ static void ath10k_wmi_event_wlan_profile_data(struct ath10k *ar,
|
||||
}
|
||||
|
||||
static void ath10k_wmi_event_rtt_measurement_report(struct ath10k *ar,
|
||||
struct sk_buff *skb)
|
||||
struct sk_buff *skb)
|
||||
{
|
||||
ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_RTT_MEASUREMENT_REPORT_EVENTID\n");
|
||||
}
|
||||
|
||||
static void ath10k_wmi_event_tsf_measurement_report(struct ath10k *ar,
|
||||
struct sk_buff *skb)
|
||||
struct sk_buff *skb)
|
||||
{
|
||||
ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_TSF_MEASUREMENT_REPORT_EVENTID\n");
|
||||
}
|
||||
@ -2082,7 +2085,7 @@ static void ath10k_wmi_event_pdev_ftm_intg(struct ath10k *ar,
|
||||
}
|
||||
|
||||
static void ath10k_wmi_event_gtk_offload_status(struct ath10k *ar,
|
||||
struct sk_buff *skb)
|
||||
struct sk_buff *skb)
|
||||
{
|
||||
ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_GTK_OFFLOAD_STATUS_EVENTID\n");
|
||||
}
|
||||
@ -2106,7 +2109,7 @@ static void ath10k_wmi_event_addba_complete(struct ath10k *ar,
|
||||
}
|
||||
|
||||
static void ath10k_wmi_event_vdev_install_key_complete(struct ath10k *ar,
|
||||
struct sk_buff *skb)
|
||||
struct sk_buff *skb)
|
||||
{
|
||||
ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_VDEV_INSTALL_KEY_COMPLETE_EVENTID\n");
|
||||
}
|
||||
@ -2130,7 +2133,7 @@ static void ath10k_wmi_event_vdev_resume_req(struct ath10k *ar,
|
||||
}
|
||||
|
||||
static int ath10k_wmi_alloc_host_mem(struct ath10k *ar, u32 req_id,
|
||||
u32 num_units, u32 unit_len)
|
||||
u32 num_units, u32 unit_len)
|
||||
{
|
||||
dma_addr_t paddr;
|
||||
u32 pool_size;
|
||||
@ -2164,7 +2167,7 @@ static void ath10k_wmi_service_ready_event_rx(struct ath10k *ar,
|
||||
struct sk_buff *skb)
|
||||
{
|
||||
struct wmi_service_ready_event *ev = (void *)skb->data;
|
||||
DECLARE_BITMAP(svc_bmap, WMI_SERVICE_BM_SIZE) = {};
|
||||
DECLARE_BITMAP(svc_bmap, WMI_SERVICE_MAX) = {};
|
||||
|
||||
if (skb->len < sizeof(*ev)) {
|
||||
ath10k_warn(ar, "Service ready event was %d B but expected %zu B. Wrong firmware version?\n",
|
||||
@ -2241,7 +2244,7 @@ static void ath10k_wmi_10x_service_ready_event_rx(struct ath10k *ar,
|
||||
u32 num_units, req_id, unit_size, num_mem_reqs, num_unit_info, i;
|
||||
int ret;
|
||||
struct wmi_service_ready_event_10x *ev = (void *)skb->data;
|
||||
DECLARE_BITMAP(svc_bmap, WMI_SERVICE_BM_SIZE) = {};
|
||||
DECLARE_BITMAP(svc_bmap, WMI_SERVICE_MAX) = {};
|
||||
|
||||
if (skb->len < sizeof(*ev)) {
|
||||
ath10k_warn(ar, "Service ready event was %d B but expected %zu B. Wrong firmware version?\n",
|
||||
@ -2347,7 +2350,7 @@ static int ath10k_wmi_ready_event_rx(struct ath10k *ar, struct sk_buff *skb)
|
||||
if (WARN_ON(skb->len < sizeof(*ev)))
|
||||
return -EINVAL;
|
||||
|
||||
memcpy(ar->mac_addr, ev->mac_addr.addr, ETH_ALEN);
|
||||
ether_addr_copy(ar->mac_addr, ev->mac_addr.addr);
|
||||
|
||||
ath10k_dbg(ar, ATH10K_DBG_WMI,
|
||||
"wmi event ready sw_version %u abi_version %u mac_addr %pM status %d skb->len %i ev-sz %zu\n",
|
||||
@ -2371,7 +2374,7 @@ static void ath10k_wmi_main_process_rx(struct ath10k *ar, struct sk_buff *skb)
|
||||
if (skb_pull(skb, sizeof(struct wmi_cmd_hdr)) == NULL)
|
||||
return;
|
||||
|
||||
trace_ath10k_wmi_event(id, skb->data, skb->len);
|
||||
trace_ath10k_wmi_event(ar, id, skb->data, skb->len);
|
||||
|
||||
switch (id) {
|
||||
case WMI_MGMT_RX_EVENTID:
|
||||
@ -2480,6 +2483,7 @@ static void ath10k_wmi_10x_process_rx(struct ath10k *ar, struct sk_buff *skb)
|
||||
{
|
||||
struct wmi_cmd_hdr *cmd_hdr;
|
||||
enum wmi_10x_event_id id;
|
||||
bool consumed;
|
||||
|
||||
cmd_hdr = (struct wmi_cmd_hdr *)skb->data;
|
||||
id = MS(__le32_to_cpu(cmd_hdr->cmd_id), WMI_CMD_HDR_CMD_ID);
|
||||
@ -2487,7 +2491,19 @@ static void ath10k_wmi_10x_process_rx(struct ath10k *ar, struct sk_buff *skb)
|
||||
if (skb_pull(skb, sizeof(struct wmi_cmd_hdr)) == NULL)
|
||||
return;
|
||||
|
||||
trace_ath10k_wmi_event(id, skb->data, skb->len);
|
||||
trace_ath10k_wmi_event(ar, id, skb->data, skb->len);
|
||||
|
||||
consumed = ath10k_tm_event_wmi(ar, id, skb);
|
||||
|
||||
/* Ready event must be handled normally also in UTF mode so that we
|
||||
* know the UTF firmware has booted, others we are just bypass WMI
|
||||
* events to testmode.
|
||||
*/
|
||||
if (consumed && id != WMI_10X_READY_EVENTID) {
|
||||
ath10k_dbg(ar, ATH10K_DBG_WMI,
|
||||
"wmi testmode consumed 0x%x\n", id);
|
||||
goto out;
|
||||
}
|
||||
|
||||
switch (id) {
|
||||
case WMI_10X_MGMT_RX_EVENTID:
|
||||
@ -2575,11 +2591,15 @@ static void ath10k_wmi_10x_process_rx(struct ath10k *ar, struct sk_buff *skb)
|
||||
case WMI_10X_READY_EVENTID:
|
||||
ath10k_wmi_ready_event_rx(ar, skb);
|
||||
break;
|
||||
case WMI_10X_PDEV_UTF_EVENTID:
|
||||
/* ignore utf events */
|
||||
break;
|
||||
default:
|
||||
ath10k_warn(ar, "Unknown eventid: %d\n", id);
|
||||
break;
|
||||
}
|
||||
|
||||
out:
|
||||
dev_kfree_skb(skb);
|
||||
}
|
||||
|
||||
@ -2594,7 +2614,7 @@ static void ath10k_wmi_10_2_process_rx(struct ath10k *ar, struct sk_buff *skb)
|
||||
if (skb_pull(skb, sizeof(struct wmi_cmd_hdr)) == NULL)
|
||||
return;
|
||||
|
||||
trace_ath10k_wmi_event(id, skb->data, skb->len);
|
||||
trace_ath10k_wmi_event(ar, id, skb->data, skb->len);
|
||||
|
||||
switch (id) {
|
||||
case WMI_10_2_MGMT_RX_EVENTID:
|
||||
@ -3476,7 +3496,7 @@ int ath10k_wmi_vdev_create(struct ath10k *ar, u32 vdev_id,
|
||||
cmd->vdev_id = __cpu_to_le32(vdev_id);
|
||||
cmd->vdev_type = __cpu_to_le32(type);
|
||||
cmd->vdev_subtype = __cpu_to_le32(subtype);
|
||||
memcpy(cmd->vdev_macaddr.addr, macaddr, ETH_ALEN);
|
||||
ether_addr_copy(cmd->vdev_macaddr.addr, macaddr);
|
||||
|
||||
ath10k_dbg(ar, ATH10K_DBG_WMI,
|
||||
"WMI vdev create: id %d type %d subtype %d macaddr %pM\n",
|
||||
@ -3503,9 +3523,10 @@ int ath10k_wmi_vdev_delete(struct ath10k *ar, u32 vdev_id)
|
||||
return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->vdev_delete_cmdid);
|
||||
}
|
||||
|
||||
static int ath10k_wmi_vdev_start_restart(struct ath10k *ar,
|
||||
const struct wmi_vdev_start_request_arg *arg,
|
||||
u32 cmd_id)
|
||||
static int
|
||||
ath10k_wmi_vdev_start_restart(struct ath10k *ar,
|
||||
const struct wmi_vdev_start_request_arg *arg,
|
||||
u32 cmd_id)
|
||||
{
|
||||
struct wmi_vdev_start_request_cmd *cmd;
|
||||
struct sk_buff *skb;
|
||||
@ -3569,8 +3590,8 @@ static int ath10k_wmi_vdev_start_restart(struct ath10k *ar,
|
||||
cmd->chan.antenna_max = arg->channel.max_antenna_gain;
|
||||
|
||||
ath10k_dbg(ar, ATH10K_DBG_WMI,
|
||||
"wmi vdev %s id 0x%x flags: 0x%0X, freq %d, mode %d, "
|
||||
"ch_flags: 0x%0X, max_power: %d\n", cmdname, arg->vdev_id,
|
||||
"wmi vdev %s id 0x%x flags: 0x%0X, freq %d, mode %d, ch_flags: 0x%0X, max_power: %d\n",
|
||||
cmdname, arg->vdev_id,
|
||||
flags, arg->channel.freq, arg->channel.mode,
|
||||
cmd->chan.flags, arg->channel.max_power);
|
||||
|
||||
@ -3586,7 +3607,7 @@ int ath10k_wmi_vdev_start(struct ath10k *ar,
|
||||
}
|
||||
|
||||
int ath10k_wmi_vdev_restart(struct ath10k *ar,
|
||||
const struct wmi_vdev_start_request_arg *arg)
|
||||
const struct wmi_vdev_start_request_arg *arg)
|
||||
{
|
||||
u32 cmd_id = ar->wmi.cmd->vdev_restart_request_cmdid;
|
||||
|
||||
@ -3622,7 +3643,7 @@ int ath10k_wmi_vdev_up(struct ath10k *ar, u32 vdev_id, u32 aid, const u8 *bssid)
|
||||
cmd = (struct wmi_vdev_up_cmd *)skb->data;
|
||||
cmd->vdev_id = __cpu_to_le32(vdev_id);
|
||||
cmd->vdev_assoc_id = __cpu_to_le32(aid);
|
||||
memcpy(&cmd->vdev_bssid.addr, bssid, ETH_ALEN);
|
||||
ether_addr_copy(cmd->vdev_bssid.addr, bssid);
|
||||
|
||||
ath10k_dbg(ar, ATH10K_DBG_WMI,
|
||||
"wmi mgmt vdev up id 0x%x assoc id %d bssid %pM\n",
|
||||
@ -3703,7 +3724,7 @@ int ath10k_wmi_vdev_install_key(struct ath10k *ar,
|
||||
cmd->key_rxmic_len = __cpu_to_le32(arg->key_rxmic_len);
|
||||
|
||||
if (arg->macaddr)
|
||||
memcpy(cmd->peer_macaddr.addr, arg->macaddr, ETH_ALEN);
|
||||
ether_addr_copy(cmd->peer_macaddr.addr, arg->macaddr);
|
||||
if (arg->key_data)
|
||||
memcpy(cmd->key_data, arg->key_data, arg->key_len);
|
||||
|
||||
@ -3782,7 +3803,7 @@ int ath10k_wmi_peer_create(struct ath10k *ar, u32 vdev_id,
|
||||
|
||||
cmd = (struct wmi_peer_create_cmd *)skb->data;
|
||||
cmd->vdev_id = __cpu_to_le32(vdev_id);
|
||||
memcpy(cmd->peer_macaddr.addr, peer_addr, ETH_ALEN);
|
||||
ether_addr_copy(cmd->peer_macaddr.addr, peer_addr);
|
||||
|
||||
ath10k_dbg(ar, ATH10K_DBG_WMI,
|
||||
"wmi peer create vdev_id %d peer_addr %pM\n",
|
||||
@ -3802,7 +3823,7 @@ int ath10k_wmi_peer_delete(struct ath10k *ar, u32 vdev_id,
|
||||
|
||||
cmd = (struct wmi_peer_delete_cmd *)skb->data;
|
||||
cmd->vdev_id = __cpu_to_le32(vdev_id);
|
||||
memcpy(cmd->peer_macaddr.addr, peer_addr, ETH_ALEN);
|
||||
ether_addr_copy(cmd->peer_macaddr.addr, peer_addr);
|
||||
|
||||
ath10k_dbg(ar, ATH10K_DBG_WMI,
|
||||
"wmi peer delete vdev_id %d peer_addr %pM\n",
|
||||
@ -3823,7 +3844,7 @@ int ath10k_wmi_peer_flush(struct ath10k *ar, u32 vdev_id,
|
||||
cmd = (struct wmi_peer_flush_tids_cmd *)skb->data;
|
||||
cmd->vdev_id = __cpu_to_le32(vdev_id);
|
||||
cmd->peer_tid_bitmap = __cpu_to_le32(tid_bitmap);
|
||||
memcpy(cmd->peer_macaddr.addr, peer_addr, ETH_ALEN);
|
||||
ether_addr_copy(cmd->peer_macaddr.addr, peer_addr);
|
||||
|
||||
ath10k_dbg(ar, ATH10K_DBG_WMI,
|
||||
"wmi peer flush vdev_id %d peer_addr %pM tids %08x\n",
|
||||
@ -3846,7 +3867,7 @@ int ath10k_wmi_peer_set_param(struct ath10k *ar, u32 vdev_id,
|
||||
cmd->vdev_id = __cpu_to_le32(vdev_id);
|
||||
cmd->param_id = __cpu_to_le32(param_id);
|
||||
cmd->param_value = __cpu_to_le32(param_value);
|
||||
memcpy(&cmd->peer_macaddr.addr, peer_addr, ETH_ALEN);
|
||||
ether_addr_copy(cmd->peer_macaddr.addr, peer_addr);
|
||||
|
||||
ath10k_dbg(ar, ATH10K_DBG_WMI,
|
||||
"wmi vdev %d peer 0x%pM set param %d value %d\n",
|
||||
@ -3917,7 +3938,7 @@ int ath10k_wmi_set_ap_ps_param(struct ath10k *ar, u32 vdev_id, const u8 *mac,
|
||||
cmd->vdev_id = __cpu_to_le32(vdev_id);
|
||||
cmd->param_id = __cpu_to_le32(param_id);
|
||||
cmd->param_value = __cpu_to_le32(value);
|
||||
memcpy(&cmd->peer_macaddr, mac, ETH_ALEN);
|
||||
ether_addr_copy(cmd->peer_macaddr.addr, mac);
|
||||
|
||||
ath10k_dbg(ar, ATH10K_DBG_WMI,
|
||||
"wmi ap ps param vdev_id 0x%X param %d value %d mac_addr %pM\n",
|
||||
@ -4001,7 +4022,7 @@ ath10k_wmi_peer_assoc_fill(struct ath10k *ar, void *buf,
|
||||
cmd->peer_vht_caps = __cpu_to_le32(arg->peer_vht_caps);
|
||||
cmd->peer_phymode = __cpu_to_le32(arg->peer_phymode);
|
||||
|
||||
memcpy(cmd->peer_macaddr.addr, arg->addr, ETH_ALEN);
|
||||
ether_addr_copy(cmd->peer_macaddr.addr, arg->addr);
|
||||
|
||||
cmd->peer_legacy_rates.num_rates =
|
||||
__cpu_to_le32(arg->peer_legacy_rates.num_rates);
|
||||
@ -4155,7 +4176,7 @@ static void ath10k_wmi_pdev_set_wmm_param(struct wmi_wmm_params *params,
|
||||
}
|
||||
|
||||
int ath10k_wmi_pdev_set_wmm_params(struct ath10k *ar,
|
||||
const struct wmi_pdev_set_wmm_params_arg *arg)
|
||||
const struct wmi_pdev_set_wmm_params_arg *arg)
|
||||
{
|
||||
struct wmi_pdev_set_wmm_params *cmd;
|
||||
struct sk_buff *skb;
|
||||
|
@ -109,6 +109,9 @@ enum wmi_service {
|
||||
WMI_SERVICE_BURST,
|
||||
WMI_SERVICE_SMART_ANTENNA_SW_SUPPORT,
|
||||
WMI_SERVICE_SMART_ANTENNA_HW_SUPPORT,
|
||||
|
||||
/* keep last */
|
||||
WMI_SERVICE_MAX,
|
||||
};
|
||||
|
||||
enum wmi_10x_service {
|
||||
@ -219,8 +222,6 @@ static inline char *wmi_service_name(int service_id)
|
||||
#undef SVCSTR
|
||||
}
|
||||
|
||||
#define WMI_MAX_SERVICE 64
|
||||
|
||||
#define WMI_SERVICE_IS_ENABLED(wmi_svc_bmap, svc_id) \
|
||||
(__le32_to_cpu((wmi_svc_bmap)[(svc_id)/(sizeof(u32))]) & \
|
||||
BIT((svc_id)%(sizeof(u32))))
|
||||
@ -347,9 +348,6 @@ static inline void wmi_main_svc_map(const __le32 *in, unsigned long *out)
|
||||
|
||||
#undef SVCMAP
|
||||
|
||||
#define WMI_SERVICE_BM_SIZE \
|
||||
((WMI_MAX_SERVICE + sizeof(u32) - 1)/sizeof(u32))
|
||||
|
||||
/* 2 word representation of MAC addr */
|
||||
struct wmi_mac_addr {
|
||||
union {
|
||||
@ -1271,7 +1269,6 @@ enum wmi_channel_change_cause {
|
||||
WMI_HT_CAP_RX_STBC | \
|
||||
WMI_HT_CAP_LDPC)
|
||||
|
||||
|
||||
/*
|
||||
* WMI_VHT_CAP_* these maps to ieee 802.11ac vht capability information
|
||||
* field. The fields not defined here are not supported, or reserved.
|
||||
@ -1405,7 +1402,7 @@ struct wmi_service_ready_event {
|
||||
__le32 phy_capability;
|
||||
/* Maximum number of frag table entries that SW will populate less 1 */
|
||||
__le32 max_frag_entry;
|
||||
__le32 wmi_service_bitmap[WMI_SERVICE_BM_SIZE];
|
||||
__le32 wmi_service_bitmap[16];
|
||||
__le32 num_rf_chains;
|
||||
/*
|
||||
* The following field is only valid for service type
|
||||
@ -1444,7 +1441,7 @@ struct wmi_service_ready_event_10x {
|
||||
|
||||
/* Maximum number of frag table entries that SW will populate less 1 */
|
||||
__le32 max_frag_entry;
|
||||
__le32 wmi_service_bitmap[WMI_SERVICE_BM_SIZE];
|
||||
__le32 wmi_service_bitmap[16];
|
||||
__le32 num_rf_chains;
|
||||
|
||||
/*
|
||||
@ -1473,7 +1470,6 @@ struct wmi_service_ready_event_10x {
|
||||
struct wlan_host_mem_req mem_reqs[1];
|
||||
} __packed;
|
||||
|
||||
|
||||
#define WMI_SERVICE_READY_TIMEOUT_HZ (5*HZ)
|
||||
#define WMI_UNIFIED_READY_TIMEOUT_HZ (5*HZ)
|
||||
|
||||
@ -2127,7 +2123,6 @@ struct wmi_start_scan_cmd_10x {
|
||||
*/
|
||||
} __packed;
|
||||
|
||||
|
||||
struct wmi_ssid_arg {
|
||||
int len;
|
||||
const u8 *ssid;
|
||||
@ -2188,7 +2183,6 @@ struct wmi_start_scan_arg {
|
||||
/* WMI_SCAN_CLASS_MASK must be the same value as IEEE80211_SCAN_CLASS_MASK */
|
||||
#define WMI_SCAN_CLASS_MASK 0xFF000000
|
||||
|
||||
|
||||
enum wmi_stop_scan_type {
|
||||
WMI_SCAN_STOP_ONE = 0x00000000, /* stop by scan_id */
|
||||
WMI_SCAN_STOP_VDEV_ALL = 0x01000000, /* stop by vdev_id */
|
||||
@ -2373,7 +2367,6 @@ struct wmi_single_phyerr_rx_hdr {
|
||||
__le32 nf_list_1;
|
||||
__le32 nf_list_2;
|
||||
|
||||
|
||||
/* Length of the frame */
|
||||
__le32 buf_len;
|
||||
} __packed;
|
||||
@ -2475,7 +2468,6 @@ struct phyerr_fft_report {
|
||||
#define SEARCH_FFT_REPORT_REG1_NUM_STR_BINS_IB_MASK 0x000000FF
|
||||
#define SEARCH_FFT_REPORT_REG1_NUM_STR_BINS_IB_LSB 0
|
||||
|
||||
|
||||
struct phyerr_tlv {
|
||||
__le16 len;
|
||||
u8 tag;
|
||||
@ -2506,7 +2498,6 @@ struct wmi_echo_cmd {
|
||||
__le32 value;
|
||||
} __packed;
|
||||
|
||||
|
||||
struct wmi_pdev_set_regdomain_cmd {
|
||||
__le32 reg_domain;
|
||||
__le32 reg_domain_2G;
|
||||
@ -2555,7 +2546,6 @@ struct wmi_pdev_set_quiet_cmd {
|
||||
__le32 enabled;
|
||||
} __packed;
|
||||
|
||||
|
||||
/*
|
||||
* 802.11g protection mode.
|
||||
*/
|
||||
@ -4293,7 +4283,6 @@ struct wmi_tbtt_offset_event {
|
||||
__le32 tbttoffset_list[WMI_MAX_AP_VDEV];
|
||||
} __packed;
|
||||
|
||||
|
||||
struct wmi_peer_create_cmd {
|
||||
__le32 vdev_id;
|
||||
struct wmi_mac_addr peer_macaddr;
|
||||
@ -4739,6 +4728,10 @@ int ath10k_wmi_wait_for_service_ready(struct ath10k *ar);
|
||||
int ath10k_wmi_wait_for_unified_ready(struct ath10k *ar);
|
||||
|
||||
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_set_channel(struct ath10k *ar,
|
||||
const struct wmi_channel_arg *);
|
||||
int ath10k_wmi_pdev_suspend_target(struct ath10k *ar, u32 suspend_opt);
|
||||
@ -4774,11 +4767,11 @@ int ath10k_wmi_vdev_spectral_conf(struct ath10k *ar,
|
||||
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]);
|
||||
const u8 peer_addr[ETH_ALEN]);
|
||||
int ath10k_wmi_peer_delete(struct ath10k *ar, u32 vdev_id,
|
||||
const u8 peer_addr[ETH_ALEN]);
|
||||
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);
|
||||
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);
|
||||
@ -4795,7 +4788,7 @@ 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);
|
||||
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);
|
||||
|
Loading…
Reference in New Issue
Block a user