Merge ath-next from git://git.kernel.org/pub/scm/linux/kernel/git/kvalo/ath.git
ath.git patches for v5.18. Major changes: ath11k * debugfs interface to configure firmware debug log level * debugfs interface to test Target Wake Time (TWT) * provide 802.11ax High Efficiency (HE) data via radiotap ath9k * use hw_random API instead of directly dumping into random.c wcn36xx * fix wcn3660 to work on 5 GHz band
This commit is contained in:
commit
c7723917a4
37 changed files with 2014 additions and 203 deletions
|
@ -429,7 +429,7 @@ static int ath10k_htt_rx_amsdu_pop(struct ath10k_htt *htt,
|
|||
RX_MSDU_END_INFO0_LAST_MSDU;
|
||||
|
||||
/* FIXME: why are we skipping the first part of the rx_desc? */
|
||||
trace_ath10k_htt_rx_desc(ar, rx_desc + sizeof(u32),
|
||||
trace_ath10k_htt_rx_desc(ar, (void *)rx_desc + sizeof(u32),
|
||||
hw->rx_desc_ops->rx_desc_size - sizeof(u32));
|
||||
|
||||
if (last_msdu)
|
||||
|
|
|
@ -17,7 +17,7 @@ struct ath10k_fw_file;
|
|||
struct ath10k_swap_code_seg_tlv {
|
||||
__le32 address;
|
||||
__le32 length;
|
||||
u8 data[0];
|
||||
u8 data[];
|
||||
} __packed;
|
||||
|
||||
struct ath10k_swap_code_seg_tail {
|
||||
|
|
|
@ -391,6 +391,8 @@ static void ath11k_ahb_free_ext_irq(struct ath11k_base *ab)
|
|||
|
||||
for (j = 0; j < irq_grp->num_irq; j++)
|
||||
free_irq(ab->irq_num[irq_grp->irqs[j]], irq_grp);
|
||||
|
||||
netif_napi_del(&irq_grp->napi);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -466,7 +468,7 @@ static irqreturn_t ath11k_ahb_ext_interrupt_handler(int irq, void *arg)
|
|||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static int ath11k_ahb_ext_irq_config(struct ath11k_base *ab)
|
||||
static int ath11k_ahb_config_ext_irq(struct ath11k_base *ab)
|
||||
{
|
||||
struct ath11k_hw_params *hw = &ab->hw_params;
|
||||
int i, j;
|
||||
|
@ -574,7 +576,7 @@ static int ath11k_ahb_config_irq(struct ath11k_base *ab)
|
|||
}
|
||||
|
||||
/* Configure external interrupts */
|
||||
ret = ath11k_ahb_ext_irq_config(ab);
|
||||
ret = ath11k_ahb_config_ext_irq(ab);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -145,7 +145,7 @@ struct ath11k_ce_ring {
|
|||
u32 hal_ring_id;
|
||||
|
||||
/* keep last */
|
||||
struct sk_buff *skb[0];
|
||||
struct sk_buff *skb[];
|
||||
};
|
||||
|
||||
struct ath11k_ce_pipe {
|
||||
|
|
|
@ -99,6 +99,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = {
|
|||
.supports_rssi_stats = false,
|
||||
.fw_wmi_diag_event = false,
|
||||
.current_cc_support = false,
|
||||
.dbr_debug_support = true,
|
||||
},
|
||||
{
|
||||
.hw_rev = ATH11K_HW_IPQ6018_HW10,
|
||||
|
@ -164,6 +165,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = {
|
|||
.supports_rssi_stats = false,
|
||||
.fw_wmi_diag_event = false,
|
||||
.current_cc_support = false,
|
||||
.dbr_debug_support = true,
|
||||
},
|
||||
{
|
||||
.name = "qca6390 hw2.0",
|
||||
|
@ -228,6 +230,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = {
|
|||
.supports_rssi_stats = true,
|
||||
.fw_wmi_diag_event = true,
|
||||
.current_cc_support = true,
|
||||
.dbr_debug_support = false,
|
||||
},
|
||||
{
|
||||
.name = "qcn9074 hw1.0",
|
||||
|
@ -292,6 +295,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = {
|
|||
.supports_rssi_stats = false,
|
||||
.fw_wmi_diag_event = false,
|
||||
.current_cc_support = false,
|
||||
.dbr_debug_support = true,
|
||||
},
|
||||
{
|
||||
.name = "wcn6855 hw2.0",
|
||||
|
@ -356,6 +360,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = {
|
|||
.supports_rssi_stats = true,
|
||||
.fw_wmi_diag_event = true,
|
||||
.current_cc_support = true,
|
||||
.dbr_debug_support = false,
|
||||
},
|
||||
{
|
||||
.name = "wcn6855 hw2.1",
|
||||
|
@ -419,6 +424,7 @@ static const struct ath11k_hw_params ath11k_hw_params[] = {
|
|||
.supports_rssi_stats = true,
|
||||
.fw_wmi_diag_event = true,
|
||||
.current_cc_support = true,
|
||||
.dbr_debug_support = false,
|
||||
},
|
||||
};
|
||||
|
||||
|
|
|
@ -263,6 +263,9 @@ struct ath11k_vif {
|
|||
bool bcca_zero_sent;
|
||||
bool do_not_send_tmpl;
|
||||
struct ieee80211_chanctx_conf chanctx;
|
||||
#ifdef CONFIG_ATH11K_DEBUGFS
|
||||
struct dentry *debugfs_twt;
|
||||
#endif /* CONFIG_ATH11K_DEBUGFS */
|
||||
};
|
||||
|
||||
struct ath11k_vif_iter {
|
||||
|
@ -441,6 +444,8 @@ struct ath11k_dbg_htt_stats {
|
|||
spinlock_t lock;
|
||||
};
|
||||
|
||||
#define MAX_MODULE_ID_BITMAP_WORDS 16
|
||||
|
||||
struct ath11k_debug {
|
||||
struct dentry *debugfs_pdev;
|
||||
struct ath11k_dbg_htt_stats htt_stats;
|
||||
|
@ -454,6 +459,9 @@ struct ath11k_debug {
|
|||
u32 pktlog_peer_valid;
|
||||
u8 pktlog_peer_addr[ETH_ALEN];
|
||||
u32 rx_filter;
|
||||
u32 mem_offset;
|
||||
u32 module_id_bitmap[MAX_MODULE_ID_BITMAP_WORDS];
|
||||
struct ath11k_debug_dbr *dbr_debug[WMI_DIRECT_BUF_MAX];
|
||||
};
|
||||
|
||||
struct ath11k_per_peer_tx_stats {
|
||||
|
@ -604,6 +612,7 @@ struct ath11k {
|
|||
bool pending_11d;
|
||||
bool regdom_set_by_user;
|
||||
int hw_rate_code;
|
||||
u8 twt_enabled;
|
||||
};
|
||||
|
||||
struct ath11k_band_cap {
|
||||
|
@ -807,7 +816,7 @@ struct ath11k_base {
|
|||
} id;
|
||||
|
||||
/* must be last */
|
||||
u8 drv_priv[0] __aligned(sizeof(void *));
|
||||
u8 drv_priv[] __aligned(sizeof(void *));
|
||||
};
|
||||
|
||||
struct ath11k_fw_stats_pdev {
|
||||
|
|
|
@ -37,7 +37,8 @@ static void ath11k_dbring_fill_magic_value(struct ath11k *ar,
|
|||
|
||||
static int ath11k_dbring_bufs_replenish(struct ath11k *ar,
|
||||
struct ath11k_dbring *ring,
|
||||
struct ath11k_dbring_element *buff)
|
||||
struct ath11k_dbring_element *buff,
|
||||
enum wmi_direct_buffer_module id)
|
||||
{
|
||||
struct ath11k_base *ab = ar->ab;
|
||||
struct hal_srng *srng;
|
||||
|
@ -84,6 +85,7 @@ static int ath11k_dbring_bufs_replenish(struct ath11k *ar,
|
|||
|
||||
ath11k_hal_rx_buf_addr_info_set(desc, paddr, cookie, 0);
|
||||
|
||||
ath11k_debugfs_add_dbring_entry(ar, id, ATH11K_DBG_DBR_EVENT_REPLENISH, srng);
|
||||
ath11k_hal_srng_access_end(ab, srng);
|
||||
|
||||
return 0;
|
||||
|
@ -101,7 +103,8 @@ err:
|
|||
}
|
||||
|
||||
static int ath11k_dbring_fill_bufs(struct ath11k *ar,
|
||||
struct ath11k_dbring *ring)
|
||||
struct ath11k_dbring *ring,
|
||||
enum wmi_direct_buffer_module id)
|
||||
{
|
||||
struct ath11k_dbring_element *buff;
|
||||
struct hal_srng *srng;
|
||||
|
@ -129,7 +132,7 @@ static int ath11k_dbring_fill_bufs(struct ath11k *ar,
|
|||
kfree(buff);
|
||||
break;
|
||||
}
|
||||
ret = ath11k_dbring_bufs_replenish(ar, ring, buff);
|
||||
ret = ath11k_dbring_bufs_replenish(ar, ring, buff, id);
|
||||
if (ret) {
|
||||
ath11k_warn(ar->ab, "failed to replenish db ring num_remain %d req_ent %d\n",
|
||||
num_remain, req_entries);
|
||||
|
@ -210,7 +213,7 @@ int ath11k_dbring_buf_setup(struct ath11k *ar,
|
|||
ring->hp_addr = ath11k_hal_srng_get_hp_addr(ar->ab, srng);
|
||||
ring->tp_addr = ath11k_hal_srng_get_tp_addr(ar->ab, srng);
|
||||
|
||||
ret = ath11k_dbring_fill_bufs(ar, ring);
|
||||
ret = ath11k_dbring_fill_bufs(ar, ring, db_cap->id);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -270,7 +273,7 @@ int ath11k_dbring_buffer_release_event(struct ath11k_base *ab,
|
|||
struct ath11k_buffer_addr desc;
|
||||
u8 *vaddr_unalign;
|
||||
u32 num_entry, num_buff_reaped;
|
||||
u8 pdev_idx, rbm;
|
||||
u8 pdev_idx, rbm, module_id;
|
||||
u32 cookie;
|
||||
int buf_id;
|
||||
int size;
|
||||
|
@ -278,6 +281,7 @@ int ath11k_dbring_buffer_release_event(struct ath11k_base *ab,
|
|||
int ret = 0;
|
||||
|
||||
pdev_idx = ev->fixed.pdev_id;
|
||||
module_id = ev->fixed.module_id;
|
||||
|
||||
if (pdev_idx >= ab->num_radios) {
|
||||
ath11k_warn(ab, "Invalid pdev id %d\n", pdev_idx);
|
||||
|
@ -346,6 +350,9 @@ int ath11k_dbring_buffer_release_event(struct ath11k_base *ab,
|
|||
dma_unmap_single(ab->dev, buff->paddr, ring->buf_sz,
|
||||
DMA_FROM_DEVICE);
|
||||
|
||||
ath11k_debugfs_add_dbring_entry(ar, module_id,
|
||||
ATH11K_DBG_DBR_EVENT_RX, srng);
|
||||
|
||||
if (ring->handler) {
|
||||
vaddr_unalign = buff->payload;
|
||||
handler_data.data = PTR_ALIGN(vaddr_unalign,
|
||||
|
@ -357,7 +364,7 @@ int ath11k_dbring_buffer_release_event(struct ath11k_base *ab,
|
|||
|
||||
buff->paddr = 0;
|
||||
memset(buff->payload, 0, size);
|
||||
ath11k_dbring_bufs_replenish(ar, ring, buff);
|
||||
ath11k_dbring_bufs_replenish(ar, ring, buff, module_id);
|
||||
}
|
||||
|
||||
spin_unlock_bh(&srng->lock);
|
||||
|
|
|
@ -52,6 +52,45 @@ static const char *htt_bp_lmac_ring[HTT_SW_LMAC_RING_IDX_MAX] = {
|
|||
"MONITOR_DEST_RING",
|
||||
};
|
||||
|
||||
void ath11k_debugfs_add_dbring_entry(struct ath11k *ar,
|
||||
enum wmi_direct_buffer_module id,
|
||||
enum ath11k_dbg_dbr_event event,
|
||||
struct hal_srng *srng)
|
||||
{
|
||||
struct ath11k_debug_dbr *dbr_debug;
|
||||
struct ath11k_dbg_dbr_data *dbr_data;
|
||||
struct ath11k_dbg_dbr_entry *entry;
|
||||
|
||||
if (id >= WMI_DIRECT_BUF_MAX || event >= ATH11K_DBG_DBR_EVENT_MAX)
|
||||
return;
|
||||
|
||||
dbr_debug = ar->debug.dbr_debug[id];
|
||||
if (!dbr_debug)
|
||||
return;
|
||||
|
||||
if (!dbr_debug->dbr_debug_enabled)
|
||||
return;
|
||||
|
||||
dbr_data = &dbr_debug->dbr_dbg_data;
|
||||
|
||||
spin_lock_bh(&dbr_data->lock);
|
||||
|
||||
if (dbr_data->entries) {
|
||||
entry = &dbr_data->entries[dbr_data->dbr_debug_idx];
|
||||
entry->hp = srng->u.src_ring.hp;
|
||||
entry->tp = *srng->u.src_ring.tp_addr;
|
||||
entry->timestamp = jiffies;
|
||||
entry->event = event;
|
||||
|
||||
dbr_data->dbr_debug_idx++;
|
||||
if (dbr_data->dbr_debug_idx ==
|
||||
dbr_data->num_ring_debug_entries)
|
||||
dbr_data->dbr_debug_idx = 0;
|
||||
}
|
||||
|
||||
spin_unlock_bh(&dbr_data->lock);
|
||||
}
|
||||
|
||||
static void ath11k_fw_stats_pdevs_free(struct list_head *head)
|
||||
{
|
||||
struct ath11k_fw_stats_pdev *i, *tmp;
|
||||
|
@ -876,6 +915,69 @@ static const struct file_operations fops_soc_dp_stats = {
|
|||
.llseek = default_llseek,
|
||||
};
|
||||
|
||||
static ssize_t ath11k_write_fw_dbglog(struct file *file,
|
||||
const char __user *user_buf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
struct ath11k *ar = file->private_data;
|
||||
char buf[128] = {0};
|
||||
struct ath11k_fw_dbglog dbglog;
|
||||
unsigned int param, mod_id_index, is_end;
|
||||
u64 value;
|
||||
int ret, num;
|
||||
|
||||
ret = simple_write_to_buffer(buf, sizeof(buf) - 1, ppos,
|
||||
user_buf, count);
|
||||
if (ret <= 0)
|
||||
return ret;
|
||||
|
||||
num = sscanf(buf, "%u %llx %u %u", ¶m, &value, &mod_id_index, &is_end);
|
||||
|
||||
if (num < 2)
|
||||
return -EINVAL;
|
||||
|
||||
mutex_lock(&ar->conf_mutex);
|
||||
if (param == WMI_DEBUG_LOG_PARAM_MOD_ENABLE_BITMAP ||
|
||||
param == WMI_DEBUG_LOG_PARAM_WOW_MOD_ENABLE_BITMAP) {
|
||||
if (num != 4 || mod_id_index > (MAX_MODULE_ID_BITMAP_WORDS - 1)) {
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
ar->debug.module_id_bitmap[mod_id_index] = upper_32_bits(value);
|
||||
if (!is_end) {
|
||||
ret = count;
|
||||
goto out;
|
||||
}
|
||||
} else {
|
||||
if (num != 2) {
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
dbglog.param = param;
|
||||
dbglog.value = lower_32_bits(value);
|
||||
ret = ath11k_wmi_fw_dbglog_cfg(ar, ar->debug.module_id_bitmap, &dbglog);
|
||||
if (ret) {
|
||||
ath11k_warn(ar->ab, "fw dbglog config failed from debugfs: %d\n",
|
||||
ret);
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = count;
|
||||
|
||||
out:
|
||||
mutex_unlock(&ar->conf_mutex);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const struct file_operations fops_fw_dbglog = {
|
||||
.write = ath11k_write_fw_dbglog,
|
||||
.open = simple_open,
|
||||
.owner = THIS_MODULE,
|
||||
.llseek = default_llseek,
|
||||
};
|
||||
|
||||
int ath11k_debugfs_pdev_create(struct ath11k_base *ab)
|
||||
{
|
||||
if (test_bit(ATH11K_FLAG_REGISTERED, &ab->dev_flags))
|
||||
|
@ -1113,6 +1215,169 @@ static const struct file_operations fops_simulate_radar = {
|
|||
.open = simple_open
|
||||
};
|
||||
|
||||
static ssize_t ath11k_debug_dump_dbr_entries(struct file *file,
|
||||
char __user *user_buf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
struct ath11k_dbg_dbr_data *dbr_dbg_data = file->private_data;
|
||||
static const char * const event_id_to_string[] = {"empty", "Rx", "Replenish"};
|
||||
int size = ATH11K_DEBUG_DBR_ENTRIES_MAX * 100;
|
||||
char *buf;
|
||||
int i, ret;
|
||||
int len = 0;
|
||||
|
||||
buf = kzalloc(size, GFP_KERNEL);
|
||||
if (!buf)
|
||||
return -ENOMEM;
|
||||
|
||||
len += scnprintf(buf + len, size - len,
|
||||
"-----------------------------------------\n");
|
||||
len += scnprintf(buf + len, size - len,
|
||||
"| idx | hp | tp | timestamp | event |\n");
|
||||
len += scnprintf(buf + len, size - len,
|
||||
"-----------------------------------------\n");
|
||||
|
||||
spin_lock_bh(&dbr_dbg_data->lock);
|
||||
|
||||
for (i = 0; i < dbr_dbg_data->num_ring_debug_entries; i++) {
|
||||
len += scnprintf(buf + len, size - len,
|
||||
"|%4u|%8u|%8u|%11llu|%8s|\n", i,
|
||||
dbr_dbg_data->entries[i].hp,
|
||||
dbr_dbg_data->entries[i].tp,
|
||||
dbr_dbg_data->entries[i].timestamp,
|
||||
event_id_to_string[dbr_dbg_data->entries[i].event]);
|
||||
}
|
||||
|
||||
spin_unlock_bh(&dbr_dbg_data->lock);
|
||||
|
||||
ret = simple_read_from_buffer(user_buf, count, ppos, buf, len);
|
||||
kfree(buf);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const struct file_operations fops_debug_dump_dbr_entries = {
|
||||
.read = ath11k_debug_dump_dbr_entries,
|
||||
.open = simple_open,
|
||||
.owner = THIS_MODULE,
|
||||
.llseek = default_llseek,
|
||||
};
|
||||
|
||||
static void ath11k_debugfs_dbr_dbg_destroy(struct ath11k *ar, int dbr_id)
|
||||
{
|
||||
struct ath11k_debug_dbr *dbr_debug;
|
||||
struct ath11k_dbg_dbr_data *dbr_dbg_data;
|
||||
|
||||
if (!ar->debug.dbr_debug[dbr_id])
|
||||
return;
|
||||
|
||||
dbr_debug = ar->debug.dbr_debug[dbr_id];
|
||||
dbr_dbg_data = &dbr_debug->dbr_dbg_data;
|
||||
|
||||
debugfs_remove_recursive(dbr_debug->dbr_debugfs);
|
||||
kfree(dbr_dbg_data->entries);
|
||||
kfree(dbr_debug);
|
||||
ar->debug.dbr_debug[dbr_id] = NULL;
|
||||
}
|
||||
|
||||
static int ath11k_debugfs_dbr_dbg_init(struct ath11k *ar, int dbr_id)
|
||||
{
|
||||
struct ath11k_debug_dbr *dbr_debug;
|
||||
struct ath11k_dbg_dbr_data *dbr_dbg_data;
|
||||
static const char * const dbr_id_to_str[] = {"spectral", "CFR"};
|
||||
|
||||
if (ar->debug.dbr_debug[dbr_id])
|
||||
return 0;
|
||||
|
||||
ar->debug.dbr_debug[dbr_id] = kzalloc(sizeof(*dbr_debug),
|
||||
GFP_KERNEL);
|
||||
|
||||
if (!ar->debug.dbr_debug[dbr_id])
|
||||
return -ENOMEM;
|
||||
|
||||
dbr_debug = ar->debug.dbr_debug[dbr_id];
|
||||
dbr_dbg_data = &dbr_debug->dbr_dbg_data;
|
||||
|
||||
if (dbr_debug->dbr_debugfs)
|
||||
return 0;
|
||||
|
||||
dbr_debug->dbr_debugfs = debugfs_create_dir(dbr_id_to_str[dbr_id],
|
||||
ar->debug.debugfs_pdev);
|
||||
if (IS_ERR_OR_NULL(dbr_debug->dbr_debugfs)) {
|
||||
if (IS_ERR(dbr_debug->dbr_debugfs))
|
||||
return PTR_ERR(dbr_debug->dbr_debugfs);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
dbr_debug->dbr_debug_enabled = true;
|
||||
dbr_dbg_data->num_ring_debug_entries = ATH11K_DEBUG_DBR_ENTRIES_MAX;
|
||||
dbr_dbg_data->dbr_debug_idx = 0;
|
||||
dbr_dbg_data->entries = kcalloc(ATH11K_DEBUG_DBR_ENTRIES_MAX,
|
||||
sizeof(struct ath11k_dbg_dbr_entry),
|
||||
GFP_KERNEL);
|
||||
if (!dbr_dbg_data->entries)
|
||||
return -ENOMEM;
|
||||
|
||||
spin_lock_init(&dbr_dbg_data->lock);
|
||||
|
||||
debugfs_create_file("dump_dbr_debug", 0444, dbr_debug->dbr_debugfs,
|
||||
dbr_dbg_data, &fops_debug_dump_dbr_entries);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static ssize_t ath11k_debugfs_write_enable_dbr_dbg(struct file *file,
|
||||
const char __user *ubuf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
struct ath11k *ar = file->private_data;
|
||||
char buf[32] = {0};
|
||||
u32 dbr_id, enable;
|
||||
int ret;
|
||||
|
||||
mutex_lock(&ar->conf_mutex);
|
||||
|
||||
if (ar->state != ATH11K_STATE_ON) {
|
||||
ret = -ENETDOWN;
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = simple_write_to_buffer(buf, sizeof(buf) - 1, ppos, ubuf, count);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
|
||||
buf[ret] = '\0';
|
||||
ret = sscanf(buf, "%u %u", &dbr_id, &enable);
|
||||
if (ret != 2 || dbr_id > 1 || enable > 1) {
|
||||
ret = -EINVAL;
|
||||
ath11k_warn(ar->ab, "usage: echo <dbr_id> <val> dbr_id:0-Spectral 1-CFR val:0-disable 1-enable\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (enable) {
|
||||
ret = ath11k_debugfs_dbr_dbg_init(ar, dbr_id);
|
||||
if (ret) {
|
||||
ath11k_warn(ar->ab, "db ring module debugfs init failed: %d\n",
|
||||
ret);
|
||||
goto out;
|
||||
}
|
||||
} else {
|
||||
ath11k_debugfs_dbr_dbg_destroy(ar, dbr_id);
|
||||
}
|
||||
|
||||
ret = count;
|
||||
out:
|
||||
mutex_unlock(&ar->conf_mutex);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const struct file_operations fops_dbr_debug = {
|
||||
.write = ath11k_debugfs_write_enable_dbr_dbg,
|
||||
.open = simple_open,
|
||||
.owner = THIS_MODULE,
|
||||
.llseek = default_llseek,
|
||||
};
|
||||
|
||||
int ath11k_debugfs_register(struct ath11k *ar)
|
||||
{
|
||||
struct ath11k_base *ab = ar->ab;
|
||||
|
@ -1142,6 +1407,9 @@ int ath11k_debugfs_register(struct ath11k *ar)
|
|||
debugfs_create_file("pktlog_filter", 0644,
|
||||
ar->debug.debugfs_pdev, ar,
|
||||
&fops_pktlog_filter);
|
||||
debugfs_create_file("fw_dbglog_config", 0600,
|
||||
ar->debug.debugfs_pdev, ar,
|
||||
&fops_fw_dbglog);
|
||||
|
||||
if (ar->hw->wiphy->bands[NL80211_BAND_5GHZ]) {
|
||||
debugfs_create_file("dfs_simulate_radar", 0200,
|
||||
|
@ -1152,9 +1420,250 @@ int ath11k_debugfs_register(struct ath11k *ar)
|
|||
&ar->dfs_block_radar_events);
|
||||
}
|
||||
|
||||
if (ab->hw_params.dbr_debug_support)
|
||||
debugfs_create_file("enable_dbr_debug", 0200, ar->debug.debugfs_pdev,
|
||||
ar, &fops_dbr_debug);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ath11k_debugfs_unregister(struct ath11k *ar)
|
||||
{
|
||||
struct ath11k_debug_dbr *dbr_debug;
|
||||
struct ath11k_dbg_dbr_data *dbr_dbg_data;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < WMI_DIRECT_BUF_MAX; i++) {
|
||||
dbr_debug = ar->debug.dbr_debug[i];
|
||||
if (!dbr_debug)
|
||||
continue;
|
||||
|
||||
dbr_dbg_data = &dbr_debug->dbr_dbg_data;
|
||||
kfree(dbr_dbg_data->entries);
|
||||
debugfs_remove_recursive(dbr_debug->dbr_debugfs);
|
||||
kfree(dbr_debug);
|
||||
ar->debug.dbr_debug[i] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static ssize_t ath11k_write_twt_add_dialog(struct file *file,
|
||||
const char __user *ubuf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
struct ath11k_vif *arvif = file->private_data;
|
||||
struct wmi_twt_add_dialog_params params = { 0 };
|
||||
u8 buf[128] = {0};
|
||||
int ret;
|
||||
|
||||
if (arvif->ar->twt_enabled == 0) {
|
||||
ath11k_err(arvif->ar->ab, "twt support is not enabled\n");
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
ret = simple_write_to_buffer(buf, sizeof(buf) - 1, ppos, ubuf, count);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
buf[ret] = '\0';
|
||||
ret = sscanf(buf,
|
||||
"%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx %u %u %u %u %u %hhu %hhu %hhu %hhu %hhu",
|
||||
¶ms.peer_macaddr[0],
|
||||
¶ms.peer_macaddr[1],
|
||||
¶ms.peer_macaddr[2],
|
||||
¶ms.peer_macaddr[3],
|
||||
¶ms.peer_macaddr[4],
|
||||
¶ms.peer_macaddr[5],
|
||||
¶ms.dialog_id,
|
||||
¶ms.wake_intvl_us,
|
||||
¶ms.wake_intvl_mantis,
|
||||
¶ms.wake_dura_us,
|
||||
¶ms.sp_offset_us,
|
||||
¶ms.twt_cmd,
|
||||
¶ms.flag_bcast,
|
||||
¶ms.flag_trigger,
|
||||
¶ms.flag_flow_type,
|
||||
¶ms.flag_protection);
|
||||
if (ret != 16)
|
||||
return -EINVAL;
|
||||
|
||||
params.vdev_id = arvif->vdev_id;
|
||||
|
||||
ret = ath11k_wmi_send_twt_add_dialog_cmd(arvif->ar, ¶ms);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static ssize_t ath11k_write_twt_del_dialog(struct file *file,
|
||||
const char __user *ubuf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
struct ath11k_vif *arvif = file->private_data;
|
||||
struct wmi_twt_del_dialog_params params = { 0 };
|
||||
u8 buf[64] = {0};
|
||||
int ret;
|
||||
|
||||
if (arvif->ar->twt_enabled == 0) {
|
||||
ath11k_err(arvif->ar->ab, "twt support is not enabled\n");
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
ret = simple_write_to_buffer(buf, sizeof(buf) - 1, ppos, ubuf, count);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
buf[ret] = '\0';
|
||||
ret = sscanf(buf, "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx %u",
|
||||
¶ms.peer_macaddr[0],
|
||||
¶ms.peer_macaddr[1],
|
||||
¶ms.peer_macaddr[2],
|
||||
¶ms.peer_macaddr[3],
|
||||
¶ms.peer_macaddr[4],
|
||||
¶ms.peer_macaddr[5],
|
||||
¶ms.dialog_id);
|
||||
if (ret != 7)
|
||||
return -EINVAL;
|
||||
|
||||
params.vdev_id = arvif->vdev_id;
|
||||
|
||||
ret = ath11k_wmi_send_twt_del_dialog_cmd(arvif->ar, ¶ms);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static ssize_t ath11k_write_twt_pause_dialog(struct file *file,
|
||||
const char __user *ubuf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
struct ath11k_vif *arvif = file->private_data;
|
||||
struct wmi_twt_pause_dialog_params params = { 0 };
|
||||
u8 buf[64] = {0};
|
||||
int ret;
|
||||
|
||||
if (arvif->ar->twt_enabled == 0) {
|
||||
ath11k_err(arvif->ar->ab, "twt support is not enabled\n");
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
ret = simple_write_to_buffer(buf, sizeof(buf) - 1, ppos, ubuf, count);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
buf[ret] = '\0';
|
||||
ret = sscanf(buf, "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx %u",
|
||||
¶ms.peer_macaddr[0],
|
||||
¶ms.peer_macaddr[1],
|
||||
¶ms.peer_macaddr[2],
|
||||
¶ms.peer_macaddr[3],
|
||||
¶ms.peer_macaddr[4],
|
||||
¶ms.peer_macaddr[5],
|
||||
¶ms.dialog_id);
|
||||
if (ret != 7)
|
||||
return -EINVAL;
|
||||
|
||||
params.vdev_id = arvif->vdev_id;
|
||||
|
||||
ret = ath11k_wmi_send_twt_pause_dialog_cmd(arvif->ar, ¶ms);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static ssize_t ath11k_write_twt_resume_dialog(struct file *file,
|
||||
const char __user *ubuf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
struct ath11k_vif *arvif = file->private_data;
|
||||
struct wmi_twt_resume_dialog_params params = { 0 };
|
||||
u8 buf[64] = {0};
|
||||
int ret;
|
||||
|
||||
if (arvif->ar->twt_enabled == 0) {
|
||||
ath11k_err(arvif->ar->ab, "twt support is not enabled\n");
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
ret = simple_write_to_buffer(buf, sizeof(buf) - 1, ppos, ubuf, count);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
buf[ret] = '\0';
|
||||
ret = sscanf(buf, "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx %u %u %u",
|
||||
¶ms.peer_macaddr[0],
|
||||
¶ms.peer_macaddr[1],
|
||||
¶ms.peer_macaddr[2],
|
||||
¶ms.peer_macaddr[3],
|
||||
¶ms.peer_macaddr[4],
|
||||
¶ms.peer_macaddr[5],
|
||||
¶ms.dialog_id,
|
||||
¶ms.sp_offset_us,
|
||||
¶ms.next_twt_size);
|
||||
if (ret != 9)
|
||||
return -EINVAL;
|
||||
|
||||
params.vdev_id = arvif->vdev_id;
|
||||
|
||||
ret = ath11k_wmi_send_twt_resume_dialog_cmd(arvif->ar, ¶ms);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static const struct file_operations ath11k_fops_twt_add_dialog = {
|
||||
.write = ath11k_write_twt_add_dialog,
|
||||
.open = simple_open
|
||||
};
|
||||
|
||||
static const struct file_operations ath11k_fops_twt_del_dialog = {
|
||||
.write = ath11k_write_twt_del_dialog,
|
||||
.open = simple_open
|
||||
};
|
||||
|
||||
static const struct file_operations ath11k_fops_twt_pause_dialog = {
|
||||
.write = ath11k_write_twt_pause_dialog,
|
||||
.open = simple_open
|
||||
};
|
||||
|
||||
static const struct file_operations ath11k_fops_twt_resume_dialog = {
|
||||
.write = ath11k_write_twt_resume_dialog,
|
||||
.open = simple_open
|
||||
};
|
||||
|
||||
int ath11k_debugfs_add_interface(struct ath11k_vif *arvif)
|
||||
{
|
||||
if (arvif->vif->type == NL80211_IFTYPE_AP && !arvif->debugfs_twt) {
|
||||
arvif->debugfs_twt = debugfs_create_dir("twt",
|
||||
arvif->vif->debugfs_dir);
|
||||
if (!arvif->debugfs_twt || IS_ERR(arvif->debugfs_twt)) {
|
||||
ath11k_warn(arvif->ar->ab,
|
||||
"failed to create directory %p\n",
|
||||
arvif->debugfs_twt);
|
||||
arvif->debugfs_twt = NULL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
debugfs_create_file("add_dialog", 0200, arvif->debugfs_twt,
|
||||
arvif, &ath11k_fops_twt_add_dialog);
|
||||
|
||||
debugfs_create_file("del_dialog", 0200, arvif->debugfs_twt,
|
||||
arvif, &ath11k_fops_twt_del_dialog);
|
||||
|
||||
debugfs_create_file("pause_dialog", 0200, arvif->debugfs_twt,
|
||||
arvif, &ath11k_fops_twt_pause_dialog);
|
||||
|
||||
debugfs_create_file("resume_dialog", 0200, arvif->debugfs_twt,
|
||||
arvif, &ath11k_fops_twt_resume_dialog);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ath11k_debugfs_remove_interface(struct ath11k_vif *arvif)
|
||||
{
|
||||
debugfs_remove_recursive(arvif->debugfs_twt);
|
||||
arvif->debugfs_twt = NULL;
|
||||
}
|
||||
|
|
|
@ -47,6 +47,36 @@ enum ath11k_dbg_htt_ext_stats_type {
|
|||
ATH11K_DBG_HTT_NUM_EXT_STATS,
|
||||
};
|
||||
|
||||
#define ATH11K_DEBUG_DBR_ENTRIES_MAX 512
|
||||
|
||||
enum ath11k_dbg_dbr_event {
|
||||
ATH11K_DBG_DBR_EVENT_INVALID,
|
||||
ATH11K_DBG_DBR_EVENT_RX,
|
||||
ATH11K_DBG_DBR_EVENT_REPLENISH,
|
||||
ATH11K_DBG_DBR_EVENT_MAX,
|
||||
};
|
||||
|
||||
struct ath11k_dbg_dbr_entry {
|
||||
u32 hp;
|
||||
u32 tp;
|
||||
u64 timestamp;
|
||||
enum ath11k_dbg_dbr_event event;
|
||||
};
|
||||
|
||||
struct ath11k_dbg_dbr_data {
|
||||
/* protects ath11k_db_ring_debug data */
|
||||
spinlock_t lock;
|
||||
struct ath11k_dbg_dbr_entry *entries;
|
||||
u32 dbr_debug_idx;
|
||||
u32 num_ring_debug_entries;
|
||||
};
|
||||
|
||||
struct ath11k_debug_dbr {
|
||||
struct ath11k_dbg_dbr_data dbr_dbg_data;
|
||||
struct dentry *dbr_debugfs;
|
||||
bool dbr_debug_enabled;
|
||||
};
|
||||
|
||||
struct debug_htt_stats_req {
|
||||
bool done;
|
||||
u8 pdev_id;
|
||||
|
@ -88,6 +118,7 @@ enum ath11k_pktlog_mode {
|
|||
};
|
||||
|
||||
enum ath11k_pktlog_enum {
|
||||
ATH11K_PKTLOG_TYPE_INVALID = 0,
|
||||
ATH11K_PKTLOG_TYPE_TX_CTRL = 1,
|
||||
ATH11K_PKTLOG_TYPE_TX_STAT = 2,
|
||||
ATH11K_PKTLOG_TYPE_TX_MSDU_ID = 3,
|
||||
|
@ -107,6 +138,130 @@ enum ath11k_dbg_aggr_mode {
|
|||
ATH11K_DBG_AGGR_MODE_MAX,
|
||||
};
|
||||
|
||||
enum fw_dbglog_wlan_module_id {
|
||||
WLAN_MODULE_ID_MIN = 0,
|
||||
WLAN_MODULE_INF = WLAN_MODULE_ID_MIN,
|
||||
WLAN_MODULE_WMI,
|
||||
WLAN_MODULE_STA_PWRSAVE,
|
||||
WLAN_MODULE_WHAL,
|
||||
WLAN_MODULE_COEX,
|
||||
WLAN_MODULE_ROAM,
|
||||
WLAN_MODULE_RESMGR_CHAN_MANAGER,
|
||||
WLAN_MODULE_RESMGR,
|
||||
WLAN_MODULE_VDEV_MGR,
|
||||
WLAN_MODULE_SCAN,
|
||||
WLAN_MODULE_RATECTRL,
|
||||
WLAN_MODULE_AP_PWRSAVE,
|
||||
WLAN_MODULE_BLOCKACK,
|
||||
WLAN_MODULE_MGMT_TXRX,
|
||||
WLAN_MODULE_DATA_TXRX,
|
||||
WLAN_MODULE_HTT,
|
||||
WLAN_MODULE_HOST,
|
||||
WLAN_MODULE_BEACON,
|
||||
WLAN_MODULE_OFFLOAD,
|
||||
WLAN_MODULE_WAL,
|
||||
WLAN_WAL_MODULE_DE,
|
||||
WLAN_MODULE_PCIELP,
|
||||
WLAN_MODULE_RTT,
|
||||
WLAN_MODULE_RESOURCE,
|
||||
WLAN_MODULE_DCS,
|
||||
WLAN_MODULE_CACHEMGR,
|
||||
WLAN_MODULE_ANI,
|
||||
WLAN_MODULE_P2P,
|
||||
WLAN_MODULE_CSA,
|
||||
WLAN_MODULE_NLO,
|
||||
WLAN_MODULE_CHATTER,
|
||||
WLAN_MODULE_WOW,
|
||||
WLAN_MODULE_WAL_VDEV,
|
||||
WLAN_MODULE_WAL_PDEV,
|
||||
WLAN_MODULE_TEST,
|
||||
WLAN_MODULE_STA_SMPS,
|
||||
WLAN_MODULE_SWBMISS,
|
||||
WLAN_MODULE_WMMAC,
|
||||
WLAN_MODULE_TDLS,
|
||||
WLAN_MODULE_HB,
|
||||
WLAN_MODULE_TXBF,
|
||||
WLAN_MODULE_BATCH_SCAN,
|
||||
WLAN_MODULE_THERMAL_MGR,
|
||||
WLAN_MODULE_PHYERR_DFS,
|
||||
WLAN_MODULE_RMC,
|
||||
WLAN_MODULE_STATS,
|
||||
WLAN_MODULE_NAN,
|
||||
WLAN_MODULE_IBSS_PWRSAVE,
|
||||
WLAN_MODULE_HIF_UART,
|
||||
WLAN_MODULE_LPI,
|
||||
WLAN_MODULE_EXTSCAN,
|
||||
WLAN_MODULE_UNIT_TEST,
|
||||
WLAN_MODULE_MLME,
|
||||
WLAN_MODULE_SUPPL,
|
||||
WLAN_MODULE_ERE,
|
||||
WLAN_MODULE_OCB,
|
||||
WLAN_MODULE_RSSI_MONITOR,
|
||||
WLAN_MODULE_WPM,
|
||||
WLAN_MODULE_CSS,
|
||||
WLAN_MODULE_PPS,
|
||||
WLAN_MODULE_SCAN_CH_PREDICT,
|
||||
WLAN_MODULE_MAWC,
|
||||
WLAN_MODULE_CMC_QMIC,
|
||||
WLAN_MODULE_EGAP,
|
||||
WLAN_MODULE_NAN20,
|
||||
WLAN_MODULE_QBOOST,
|
||||
WLAN_MODULE_P2P_LISTEN_OFFLOAD,
|
||||
WLAN_MODULE_HALPHY,
|
||||
WLAN_WAL_MODULE_ENQ,
|
||||
WLAN_MODULE_GNSS,
|
||||
WLAN_MODULE_WAL_MEM,
|
||||
WLAN_MODULE_SCHED_ALGO,
|
||||
WLAN_MODULE_TX,
|
||||
WLAN_MODULE_RX,
|
||||
WLAN_MODULE_WLM,
|
||||
WLAN_MODULE_RU_ALLOCATOR,
|
||||
WLAN_MODULE_11K_OFFLOAD,
|
||||
WLAN_MODULE_STA_TWT,
|
||||
WLAN_MODULE_AP_TWT,
|
||||
WLAN_MODULE_UL_OFDMA,
|
||||
WLAN_MODULE_HPCS_PULSE,
|
||||
WLAN_MODULE_DTF,
|
||||
WLAN_MODULE_QUIET_IE,
|
||||
WLAN_MODULE_SHMEM_MGR,
|
||||
WLAN_MODULE_CFIR,
|
||||
WLAN_MODULE_CODE_COVER,
|
||||
WLAN_MODULE_SHO,
|
||||
WLAN_MODULE_MLO_MGR,
|
||||
WLAN_MODULE_PEER_INIT,
|
||||
WLAN_MODULE_STA_MLO_PS,
|
||||
|
||||
WLAN_MODULE_ID_MAX,
|
||||
WLAN_MODULE_ID_INVALID = WLAN_MODULE_ID_MAX,
|
||||
};
|
||||
|
||||
enum fw_dbglog_log_level {
|
||||
ATH11K_FW_DBGLOG_ML = 0,
|
||||
ATH11K_FW_DBGLOG_VERBOSE = 0,
|
||||
ATH11K_FW_DBGLOG_INFO,
|
||||
ATH11K_FW_DBGLOG_INFO_LVL_1,
|
||||
ATH11K_FW_DBGLOG_INFO_LVL_2,
|
||||
ATH11K_FW_DBGLOG_WARN,
|
||||
ATH11K_FW_DBGLOG_ERR,
|
||||
ATH11K_FW_DBGLOG_LVL_MAX
|
||||
};
|
||||
|
||||
struct ath11k_fw_dbglog {
|
||||
enum wmi_debug_log_param param;
|
||||
union {
|
||||
struct {
|
||||
/* log_level values are given in enum fw_dbglog_log_level */
|
||||
u16 log_level;
|
||||
/* module_id values are given in enum fw_dbglog_wlan_module_id */
|
||||
u16 module_id;
|
||||
};
|
||||
/* value is either log_level&module_id/vdev_id/vdev_id_bitmap/log_level
|
||||
* according to param
|
||||
*/
|
||||
u32 value;
|
||||
};
|
||||
};
|
||||
|
||||
#ifdef CONFIG_ATH11K_DEBUGFS
|
||||
int ath11k_debugfs_soc_create(struct ath11k_base *ab);
|
||||
void ath11k_debugfs_soc_destroy(struct ath11k_base *ab);
|
||||
|
@ -151,6 +306,13 @@ static inline int ath11k_debugfs_rx_filter(struct ath11k *ar)
|
|||
return ar->debug.rx_filter;
|
||||
}
|
||||
|
||||
int ath11k_debugfs_add_interface(struct ath11k_vif *arvif);
|
||||
void ath11k_debugfs_remove_interface(struct ath11k_vif *arvif);
|
||||
void ath11k_debugfs_add_dbring_entry(struct ath11k *ar,
|
||||
enum wmi_direct_buffer_module id,
|
||||
enum ath11k_dbg_dbr_event event,
|
||||
struct hal_srng *srng);
|
||||
|
||||
#else
|
||||
static inline int ath11k_debugfs_soc_create(struct ath11k_base *ab)
|
||||
{
|
||||
|
@ -224,6 +386,22 @@ static inline int ath11k_debugfs_get_fw_stats(struct ath11k *ar,
|
|||
return 0;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_MAC80211_DEBUGFS*/
|
||||
static inline int ath11k_debugfs_add_interface(struct ath11k_vif *arvif)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void ath11k_debugfs_remove_interface(struct ath11k_vif *arvif)
|
||||
{
|
||||
}
|
||||
|
||||
static inline void
|
||||
ath11k_debugfs_add_dbring_entry(struct ath11k *ar,
|
||||
enum wmi_direct_buffer_module id,
|
||||
enum ath11k_dbg_dbr_event event,
|
||||
struct hal_srng *srng)
|
||||
{
|
||||
}
|
||||
#endif /* CONFIG_ATH11K_DEBUGFS*/
|
||||
|
||||
#endif /* _ATH11K_DEBUGFS_H_ */
|
||||
|
|
|
@ -115,6 +115,8 @@ struct ath11k_pdev_mon_stats {
|
|||
u32 dest_mpdu_drop;
|
||||
u32 dup_mon_linkdesc_cnt;
|
||||
u32 dup_mon_buf_cnt;
|
||||
u32 dest_mon_stuck;
|
||||
u32 dest_mon_not_reaped;
|
||||
};
|
||||
|
||||
struct dp_full_mon_mpdu {
|
||||
|
@ -167,6 +169,7 @@ struct ath11k_mon_data {
|
|||
|
||||
struct ath11k_pdev_dp {
|
||||
u32 mac_id;
|
||||
u32 mon_dest_ring_stuck_cnt;
|
||||
atomic_t num_tx_pending;
|
||||
wait_queue_head_t tx_empty_waitq;
|
||||
struct dp_rxdma_ring rx_refill_buf_ring;
|
||||
|
@ -1170,12 +1173,12 @@ struct ath11k_htt_ppdu_stats_msg {
|
|||
u32 ppdu_id;
|
||||
u32 timestamp;
|
||||
u32 rsvd;
|
||||
u8 data[0];
|
||||
u8 data[];
|
||||
} __packed;
|
||||
|
||||
struct htt_tlv {
|
||||
u32 header;
|
||||
u8 value[0];
|
||||
u8 value[];
|
||||
} __packed;
|
||||
|
||||
#define HTT_TLV_TAG GENMASK(11, 0)
|
||||
|
@ -1362,7 +1365,7 @@ struct htt_ppdu_stats_usr_cmn_array {
|
|||
* tx_ppdu_stats_info is variable length, with length =
|
||||
* number_of_ppdu_stats * sizeof (struct htt_tx_ppdu_stats_info)
|
||||
*/
|
||||
struct htt_tx_ppdu_stats_info tx_ppdu_info[0];
|
||||
struct htt_tx_ppdu_stats_info tx_ppdu_info[];
|
||||
} __packed;
|
||||
|
||||
struct htt_ppdu_user_stats {
|
||||
|
@ -1424,7 +1427,7 @@ struct htt_ppdu_stats_info {
|
|||
*/
|
||||
struct htt_pktlog_msg {
|
||||
u32 hdr;
|
||||
u8 payload[0];
|
||||
u8 payload[];
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -1645,7 +1648,7 @@ struct ath11k_htt_extd_stats_msg {
|
|||
u32 info0;
|
||||
u64 cookie;
|
||||
u32 info1;
|
||||
u8 data[0];
|
||||
u8 data[];
|
||||
} __packed;
|
||||
|
||||
#define HTT_MAC_ADDR_L32_0 GENMASK(7, 0)
|
||||
|
|
|
@ -2652,9 +2652,9 @@ int ath11k_dp_process_rx(struct ath11k_base *ab, int ring_id,
|
|||
|
||||
spin_lock_bh(&srng->lock);
|
||||
|
||||
try_again:
|
||||
ath11k_hal_srng_access_begin(ab, srng);
|
||||
|
||||
try_again:
|
||||
while (likely(desc =
|
||||
(struct hal_reo_dest_ring *)ath11k_hal_srng_dst_get_next_entry(ab,
|
||||
srng))) {
|
||||
|
@ -4807,7 +4807,6 @@ ath11k_dp_rx_mon_merg_msdus(struct ath11k *ar,
|
|||
{
|
||||
struct ath11k_base *ab = ar->ab;
|
||||
struct sk_buff *msdu, *prev_buf;
|
||||
u32 wifi_hdr_len;
|
||||
struct hal_rx_desc *rx_desc;
|
||||
char *hdr_desc;
|
||||
u8 *dest, decap_format;
|
||||
|
@ -4849,38 +4848,27 @@ ath11k_dp_rx_mon_merg_msdus(struct ath11k *ar,
|
|||
|
||||
skb_trim(prev_buf, prev_buf->len - HAL_RX_FCS_LEN);
|
||||
} else if (decap_format == DP_RX_DECAP_TYPE_NATIVE_WIFI) {
|
||||
__le16 qos_field;
|
||||
u8 qos_pkt = 0;
|
||||
|
||||
rx_desc = (struct hal_rx_desc *)head_msdu->data;
|
||||
hdr_desc = ath11k_dp_rxdesc_get_80211hdr(ab, rx_desc);
|
||||
|
||||
/* Base size */
|
||||
wifi_hdr_len = sizeof(struct ieee80211_hdr_3addr);
|
||||
wh = (struct ieee80211_hdr_3addr *)hdr_desc;
|
||||
|
||||
if (ieee80211_is_data_qos(wh->frame_control)) {
|
||||
struct ieee80211_qos_hdr *qwh =
|
||||
(struct ieee80211_qos_hdr *)hdr_desc;
|
||||
|
||||
qos_field = qwh->qos_ctrl;
|
||||
if (ieee80211_is_data_qos(wh->frame_control))
|
||||
qos_pkt = 1;
|
||||
}
|
||||
|
||||
msdu = head_msdu;
|
||||
|
||||
while (msdu) {
|
||||
rx_desc = (struct hal_rx_desc *)msdu->data;
|
||||
hdr_desc = ath11k_dp_rxdesc_get_80211hdr(ab, rx_desc);
|
||||
|
||||
ath11k_dp_rx_msdus_set_payload(ar, msdu);
|
||||
if (qos_pkt) {
|
||||
dest = skb_push(msdu, sizeof(__le16));
|
||||
if (!dest)
|
||||
goto err_merge_fail;
|
||||
memcpy(dest, hdr_desc, wifi_hdr_len);
|
||||
memcpy(dest + wifi_hdr_len,
|
||||
(u8 *)&qos_field, sizeof(__le16));
|
||||
memcpy(dest, hdr_desc, sizeof(struct ieee80211_qos_hdr));
|
||||
}
|
||||
ath11k_dp_rx_msdus_set_payload(ar, msdu);
|
||||
prev_buf = msdu;
|
||||
msdu = msdu->next;
|
||||
}
|
||||
|
@ -4904,8 +4892,98 @@ err_merge_fail:
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
ath11k_dp_rx_update_radiotap_he(struct hal_rx_mon_ppdu_info *rx_status,
|
||||
u8 *rtap_buf)
|
||||
{
|
||||
u32 rtap_len = 0;
|
||||
|
||||
put_unaligned_le16(rx_status->he_data1, &rtap_buf[rtap_len]);
|
||||
rtap_len += 2;
|
||||
|
||||
put_unaligned_le16(rx_status->he_data2, &rtap_buf[rtap_len]);
|
||||
rtap_len += 2;
|
||||
|
||||
put_unaligned_le16(rx_status->he_data3, &rtap_buf[rtap_len]);
|
||||
rtap_len += 2;
|
||||
|
||||
put_unaligned_le16(rx_status->he_data4, &rtap_buf[rtap_len]);
|
||||
rtap_len += 2;
|
||||
|
||||
put_unaligned_le16(rx_status->he_data5, &rtap_buf[rtap_len]);
|
||||
rtap_len += 2;
|
||||
|
||||
put_unaligned_le16(rx_status->he_data6, &rtap_buf[rtap_len]);
|
||||
}
|
||||
|
||||
static void
|
||||
ath11k_dp_rx_update_radiotap_he_mu(struct hal_rx_mon_ppdu_info *rx_status,
|
||||
u8 *rtap_buf)
|
||||
{
|
||||
u32 rtap_len = 0;
|
||||
|
||||
put_unaligned_le16(rx_status->he_flags1, &rtap_buf[rtap_len]);
|
||||
rtap_len += 2;
|
||||
|
||||
put_unaligned_le16(rx_status->he_flags2, &rtap_buf[rtap_len]);
|
||||
rtap_len += 2;
|
||||
|
||||
rtap_buf[rtap_len] = rx_status->he_RU[0];
|
||||
rtap_len += 1;
|
||||
|
||||
rtap_buf[rtap_len] = rx_status->he_RU[1];
|
||||
rtap_len += 1;
|
||||
|
||||
rtap_buf[rtap_len] = rx_status->he_RU[2];
|
||||
rtap_len += 1;
|
||||
|
||||
rtap_buf[rtap_len] = rx_status->he_RU[3];
|
||||
}
|
||||
|
||||
static void ath11k_update_radiotap(struct ath11k *ar,
|
||||
struct hal_rx_mon_ppdu_info *ppduinfo,
|
||||
struct sk_buff *mon_skb,
|
||||
struct ieee80211_rx_status *rxs)
|
||||
{
|
||||
struct ieee80211_supported_band *sband;
|
||||
u8 *ptr = NULL;
|
||||
|
||||
rxs->flag |= RX_FLAG_MACTIME_START;
|
||||
rxs->signal = ppduinfo->rssi_comb + ATH11K_DEFAULT_NOISE_FLOOR;
|
||||
|
||||
if (ppduinfo->nss)
|
||||
rxs->nss = ppduinfo->nss;
|
||||
|
||||
if (ppduinfo->he_mu_flags) {
|
||||
rxs->flag |= RX_FLAG_RADIOTAP_HE_MU;
|
||||
rxs->encoding = RX_ENC_HE;
|
||||
ptr = skb_push(mon_skb, sizeof(struct ieee80211_radiotap_he_mu));
|
||||
ath11k_dp_rx_update_radiotap_he_mu(ppduinfo, ptr);
|
||||
} else if (ppduinfo->he_flags) {
|
||||
rxs->flag |= RX_FLAG_RADIOTAP_HE;
|
||||
rxs->encoding = RX_ENC_HE;
|
||||
ptr = skb_push(mon_skb, sizeof(struct ieee80211_radiotap_he));
|
||||
ath11k_dp_rx_update_radiotap_he(ppduinfo, ptr);
|
||||
rxs->rate_idx = ppduinfo->rate;
|
||||
} else if (ppduinfo->vht_flags) {
|
||||
rxs->encoding = RX_ENC_VHT;
|
||||
rxs->rate_idx = ppduinfo->rate;
|
||||
} else if (ppduinfo->ht_flags) {
|
||||
rxs->encoding = RX_ENC_HT;
|
||||
rxs->rate_idx = ppduinfo->rate;
|
||||
} else {
|
||||
rxs->encoding = RX_ENC_LEGACY;
|
||||
sband = &ar->mac.sbands[rxs->band];
|
||||
rxs->rate_idx = ath11k_mac_hw_rate_to_idx(sband, ppduinfo->rate,
|
||||
ppduinfo->cck_flag);
|
||||
}
|
||||
|
||||
rxs->mactime = ppduinfo->tsft;
|
||||
}
|
||||
|
||||
static int ath11k_dp_rx_mon_deliver(struct ath11k *ar, u32 mac_id,
|
||||
struct sk_buff *head_msdu,
|
||||
struct hal_rx_mon_ppdu_info *ppduinfo,
|
||||
struct sk_buff *tail_msdu,
|
||||
struct napi_struct *napi)
|
||||
{
|
||||
|
@ -4940,7 +5018,7 @@ static int ath11k_dp_rx_mon_deliver(struct ath11k *ar, u32 mac_id,
|
|||
} else {
|
||||
rxs->flag |= RX_FLAG_ALLOW_SAME_PN;
|
||||
}
|
||||
rxs->flag |= RX_FLAG_ONLY_MONITOR;
|
||||
ath11k_update_radiotap(ar, ppduinfo, mon_skb, rxs);
|
||||
|
||||
ath11k_dp_rx_deliver_msdu(ar, napi, mon_skb, rxs);
|
||||
mon_skb = skb_next;
|
||||
|
@ -4959,6 +5037,12 @@ mon_deliver_fail:
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* The destination ring processing is stuck if the destination is not
|
||||
* moving while status ring moves 16 PPDU. The destination ring processing
|
||||
* skips this destination ring PPDU as a workaround.
|
||||
*/
|
||||
#define MON_DEST_RING_STUCK_MAX_CNT 16
|
||||
|
||||
static void ath11k_dp_rx_mon_dest_process(struct ath11k *ar, int mac_id,
|
||||
u32 quota, struct napi_struct *napi)
|
||||
{
|
||||
|
@ -4972,6 +5056,7 @@ static void ath11k_dp_rx_mon_dest_process(struct ath11k *ar, int mac_id,
|
|||
u32 ring_id;
|
||||
struct ath11k_pdev_mon_stats *rx_mon_stats;
|
||||
u32 npackets = 0;
|
||||
u32 mpdu_rx_bufs_used;
|
||||
|
||||
if (ar->ab->hw_params.rxdma1_enable)
|
||||
ring_id = dp->rxdma_mon_dst_ring.ring_id;
|
||||
|
@ -5001,20 +5086,44 @@ static void ath11k_dp_rx_mon_dest_process(struct ath11k *ar, int mac_id,
|
|||
head_msdu = NULL;
|
||||
tail_msdu = NULL;
|
||||
|
||||
rx_bufs_used += ath11k_dp_rx_mon_mpdu_pop(ar, mac_id, ring_entry,
|
||||
&head_msdu,
|
||||
&tail_msdu,
|
||||
&npackets, &ppdu_id);
|
||||
mpdu_rx_bufs_used = ath11k_dp_rx_mon_mpdu_pop(ar, mac_id, ring_entry,
|
||||
&head_msdu,
|
||||
&tail_msdu,
|
||||
&npackets, &ppdu_id);
|
||||
|
||||
rx_bufs_used += mpdu_rx_bufs_used;
|
||||
|
||||
if (mpdu_rx_bufs_used) {
|
||||
dp->mon_dest_ring_stuck_cnt = 0;
|
||||
} else {
|
||||
dp->mon_dest_ring_stuck_cnt++;
|
||||
rx_mon_stats->dest_mon_not_reaped++;
|
||||
}
|
||||
|
||||
if (dp->mon_dest_ring_stuck_cnt > MON_DEST_RING_STUCK_MAX_CNT) {
|
||||
rx_mon_stats->dest_mon_stuck++;
|
||||
ath11k_dbg(ar->ab, ATH11K_DBG_DATA,
|
||||
"status ring ppdu_id=%d dest ring ppdu_id=%d mon_dest_ring_stuck_cnt=%d dest_mon_not_reaped=%u dest_mon_stuck=%u\n",
|
||||
pmon->mon_ppdu_info.ppdu_id, ppdu_id,
|
||||
dp->mon_dest_ring_stuck_cnt,
|
||||
rx_mon_stats->dest_mon_not_reaped,
|
||||
rx_mon_stats->dest_mon_stuck);
|
||||
pmon->mon_ppdu_info.ppdu_id = ppdu_id;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ppdu_id != pmon->mon_ppdu_info.ppdu_id) {
|
||||
pmon->mon_ppdu_status = DP_PPDU_STATUS_START;
|
||||
ath11k_dbg(ar->ab, ATH11K_DBG_DATA,
|
||||
"dest_rx: new ppdu_id %x != status ppdu_id %x",
|
||||
ppdu_id, pmon->mon_ppdu_info.ppdu_id);
|
||||
"dest_rx: new ppdu_id %x != status ppdu_id %x dest_mon_not_reaped = %u dest_mon_stuck = %u\n",
|
||||
ppdu_id, pmon->mon_ppdu_info.ppdu_id,
|
||||
rx_mon_stats->dest_mon_not_reaped,
|
||||
rx_mon_stats->dest_mon_stuck);
|
||||
break;
|
||||
}
|
||||
if (head_msdu && tail_msdu) {
|
||||
ath11k_dp_rx_mon_deliver(ar, dp->mac_id, head_msdu,
|
||||
&pmon->mon_ppdu_info,
|
||||
tail_msdu, napi);
|
||||
rx_mon_stats->dest_mpdu_done++;
|
||||
}
|
||||
|
@ -5054,7 +5163,7 @@ int ath11k_dp_rx_process_mon_status(struct ath11k_base *ab, int mac_id,
|
|||
struct ath11k_sta *arsta;
|
||||
int num_buffs_reaped = 0;
|
||||
u32 rx_buf_sz;
|
||||
u16 log_type = 0;
|
||||
u16 log_type;
|
||||
struct ath11k_mon_data *pmon = (struct ath11k_mon_data *)&ar->dp.mon_data;
|
||||
struct ath11k_pdev_mon_stats *rx_mon_stats = &pmon->rx_mon_stats;
|
||||
struct hal_rx_mon_ppdu_info *ppdu_info = &pmon->mon_ppdu_info;
|
||||
|
@ -5076,11 +5185,15 @@ int ath11k_dp_rx_process_mon_status(struct ath11k_base *ab, int mac_id,
|
|||
} else if (ath11k_debugfs_is_pktlog_rx_stats_enabled(ar)) {
|
||||
log_type = ATH11K_PKTLOG_TYPE_RX_STATBUF;
|
||||
rx_buf_sz = DP_RX_BUFFER_SIZE;
|
||||
} else {
|
||||
log_type = ATH11K_PKTLOG_TYPE_INVALID;
|
||||
rx_buf_sz = 0;
|
||||
}
|
||||
|
||||
if (log_type)
|
||||
if (log_type != ATH11K_PKTLOG_TYPE_INVALID)
|
||||
trace_ath11k_htt_rxdesc(ar, skb->data, log_type, rx_buf_sz);
|
||||
|
||||
memset(ppdu_info, 0, sizeof(struct hal_rx_mon_ppdu_info));
|
||||
hal_status = ath11k_hal_rx_parse_mon_status(ab, ppdu_info, skb);
|
||||
|
||||
if (test_bit(ATH11K_FLAG_MONITOR_STARTED, &ar->monitor_flags) &&
|
||||
|
@ -5341,6 +5454,7 @@ static int ath11k_dp_rx_full_mon_deliver_ppdu(struct ath11k *ar,
|
|||
tail_msdu = mon_mpdu->tail;
|
||||
if (head_msdu && tail_msdu) {
|
||||
ret = ath11k_dp_rx_mon_deliver(ar, mac_id, head_msdu,
|
||||
&pmon->mon_ppdu_info,
|
||||
tail_msdu, napi);
|
||||
rx_mon_stats->dest_mpdu_done++;
|
||||
ath11k_dbg(ar->ab, ATH11K_DBG_DATA, "full mon: deliver ppdu\n");
|
||||
|
|
|
@ -427,7 +427,7 @@ void ath11k_dp_tx_update_txcompl(struct ath11k *ar, struct hal_tx_status *ts)
|
|||
struct ath11k_sta *arsta;
|
||||
struct ieee80211_sta *sta;
|
||||
u16 rate, ru_tones;
|
||||
u8 mcs, rate_idx, ofdma;
|
||||
u8 mcs, rate_idx = 0, ofdma;
|
||||
int ret;
|
||||
|
||||
spin_lock_bh(&ab->base_lock);
|
||||
|
@ -519,9 +519,13 @@ static void ath11k_dp_tx_complete_msdu(struct ath11k *ar,
|
|||
struct sk_buff *msdu,
|
||||
struct hal_tx_status *ts)
|
||||
{
|
||||
struct ieee80211_tx_status status = { 0 };
|
||||
struct ath11k_base *ab = ar->ab;
|
||||
struct ieee80211_tx_info *info;
|
||||
struct ath11k_skb_cb *skb_cb;
|
||||
struct ath11k_peer *peer;
|
||||
struct ath11k_sta *arsta;
|
||||
struct rate_info rate;
|
||||
|
||||
if (WARN_ON_ONCE(ts->buf_rel_source != HAL_WBM_REL_SRC_MODULE_TQM)) {
|
||||
/* Must not happen */
|
||||
|
@ -584,12 +588,26 @@ static void ath11k_dp_tx_complete_msdu(struct ath11k *ar,
|
|||
ath11k_dp_tx_cache_peer_stats(ar, msdu, ts);
|
||||
}
|
||||
|
||||
/* NOTE: Tx rate status reporting. Tx completion status does not have
|
||||
* necessary information (for example nss) to build the tx rate.
|
||||
* Might end up reporting it out-of-band from HTT stats.
|
||||
*/
|
||||
spin_lock_bh(&ab->base_lock);
|
||||
peer = ath11k_peer_find_by_id(ab, ts->peer_id);
|
||||
if (!peer || !peer->sta) {
|
||||
ath11k_dbg(ab, ATH11K_DBG_DATA,
|
||||
"dp_tx: failed to find the peer with peer_id %d\n",
|
||||
ts->peer_id);
|
||||
spin_unlock_bh(&ab->base_lock);
|
||||
dev_kfree_skb_any(msdu);
|
||||
return;
|
||||
}
|
||||
arsta = (struct ath11k_sta *)peer->sta->drv_priv;
|
||||
status.sta = peer->sta;
|
||||
status.skb = msdu;
|
||||
status.info = info;
|
||||
rate = arsta->last_txrate;
|
||||
status.rate = &rate;
|
||||
|
||||
ieee80211_tx_status(ar->hw, msdu);
|
||||
spin_unlock_bh(&ab->base_lock);
|
||||
|
||||
ieee80211_tx_status_ext(ar->hw, &status);
|
||||
}
|
||||
|
||||
static inline void ath11k_dp_tx_status_parse(struct ath11k_base *ab,
|
||||
|
|
|
@ -474,6 +474,7 @@ enum hal_tlv_tag {
|
|||
|
||||
#define HAL_TLV_HDR_TAG GENMASK(9, 1)
|
||||
#define HAL_TLV_HDR_LEN GENMASK(25, 10)
|
||||
#define HAL_TLV_USR_ID GENMASK(31, 26)
|
||||
|
||||
#define HAL_TLV_ALIGN 4
|
||||
|
||||
|
|
|
@ -453,10 +453,12 @@ void ath11k_hal_reo_status_queue_stats(struct ath11k_base *ab, u32 *reo_desc,
|
|||
desc->info0));
|
||||
ath11k_dbg(ab, ATH11k_DBG_HAL, "pn = [%08x, %08x, %08x, %08x]\n",
|
||||
desc->pn[0], desc->pn[1], desc->pn[2], desc->pn[3]);
|
||||
ath11k_dbg(ab, ATH11k_DBG_HAL, "last_rx: enqueue_tstamp %08x dequeue_tstamp %08x\n",
|
||||
ath11k_dbg(ab, ATH11k_DBG_HAL,
|
||||
"last_rx: enqueue_tstamp %08x dequeue_tstamp %08x\n",
|
||||
desc->last_rx_enqueue_timestamp,
|
||||
desc->last_rx_dequeue_timestamp);
|
||||
ath11k_dbg(ab, ATH11k_DBG_HAL, "rx_bitmap [%08x %08x %08x %08x %08x %08x %08x %08x]\n",
|
||||
ath11k_dbg(ab, ATH11k_DBG_HAL,
|
||||
"rx_bitmap [%08x %08x %08x %08x %08x %08x %08x %08x]\n",
|
||||
desc->rx_bitmap[0], desc->rx_bitmap[1], desc->rx_bitmap[2],
|
||||
desc->rx_bitmap[3], desc->rx_bitmap[4], desc->rx_bitmap[5],
|
||||
desc->rx_bitmap[6], desc->rx_bitmap[7]);
|
||||
|
@ -802,12 +804,75 @@ void ath11k_hal_reo_init_cmd_ring(struct ath11k_base *ab,
|
|||
}
|
||||
}
|
||||
|
||||
#define HAL_MAX_UL_MU_USERS 37
|
||||
static inline void
|
||||
ath11k_hal_rx_handle_ofdma_info(void *rx_tlv,
|
||||
struct hal_rx_user_status *rx_user_status)
|
||||
{
|
||||
struct hal_rx_ppdu_end_user_stats *ppdu_end_user =
|
||||
(struct hal_rx_ppdu_end_user_stats *)rx_tlv;
|
||||
|
||||
rx_user_status->ul_ofdma_user_v0_word0 = __le32_to_cpu(ppdu_end_user->info6);
|
||||
|
||||
rx_user_status->ul_ofdma_user_v0_word1 = __le32_to_cpu(ppdu_end_user->rsvd2[10]);
|
||||
}
|
||||
|
||||
static inline void
|
||||
ath11k_hal_rx_populate_byte_count(void *rx_tlv, void *ppduinfo,
|
||||
struct hal_rx_user_status *rx_user_status)
|
||||
{
|
||||
struct hal_rx_ppdu_end_user_stats *ppdu_end_user =
|
||||
(struct hal_rx_ppdu_end_user_stats *)rx_tlv;
|
||||
|
||||
rx_user_status->mpdu_ok_byte_count =
|
||||
FIELD_GET(HAL_RX_PPDU_END_USER_STATS_RSVD2_6_MPDU_OK_BYTE_COUNT,
|
||||
__le32_to_cpu(ppdu_end_user->rsvd2[6]));
|
||||
rx_user_status->mpdu_err_byte_count =
|
||||
FIELD_GET(HAL_RX_PPDU_END_USER_STATS_RSVD2_8_MPDU_ERR_BYTE_COUNT,
|
||||
__le32_to_cpu(ppdu_end_user->rsvd2[8]));
|
||||
}
|
||||
|
||||
static inline void
|
||||
ath11k_hal_rx_populate_mu_user_info(void *rx_tlv, struct hal_rx_mon_ppdu_info *ppdu_info,
|
||||
struct hal_rx_user_status *rx_user_status)
|
||||
{
|
||||
rx_user_status->ast_index = ppdu_info->ast_index;
|
||||
rx_user_status->tid = ppdu_info->tid;
|
||||
rx_user_status->tcp_msdu_count =
|
||||
ppdu_info->tcp_msdu_count;
|
||||
rx_user_status->udp_msdu_count =
|
||||
ppdu_info->udp_msdu_count;
|
||||
rx_user_status->other_msdu_count =
|
||||
ppdu_info->other_msdu_count;
|
||||
rx_user_status->frame_control = ppdu_info->frame_control;
|
||||
rx_user_status->frame_control_info_valid =
|
||||
ppdu_info->frame_control_info_valid;
|
||||
rx_user_status->data_sequence_control_info_valid =
|
||||
ppdu_info->data_sequence_control_info_valid;
|
||||
rx_user_status->first_data_seq_ctrl =
|
||||
ppdu_info->first_data_seq_ctrl;
|
||||
rx_user_status->preamble_type = ppdu_info->preamble_type;
|
||||
rx_user_status->ht_flags = ppdu_info->ht_flags;
|
||||
rx_user_status->vht_flags = ppdu_info->vht_flags;
|
||||
rx_user_status->he_flags = ppdu_info->he_flags;
|
||||
rx_user_status->rs_flags = ppdu_info->rs_flags;
|
||||
|
||||
rx_user_status->mpdu_cnt_fcs_ok =
|
||||
ppdu_info->num_mpdu_fcs_ok;
|
||||
rx_user_status->mpdu_cnt_fcs_err =
|
||||
ppdu_info->num_mpdu_fcs_err;
|
||||
|
||||
ath11k_hal_rx_populate_byte_count(rx_tlv, ppdu_info, rx_user_status);
|
||||
}
|
||||
|
||||
static enum hal_rx_mon_status
|
||||
ath11k_hal_rx_parse_mon_status_tlv(struct ath11k_base *ab,
|
||||
struct hal_rx_mon_ppdu_info *ppdu_info,
|
||||
u32 tlv_tag, u8 *tlv_data)
|
||||
u32 tlv_tag, u8 *tlv_data, u32 userid)
|
||||
{
|
||||
u32 info0, info1;
|
||||
u32 info0, info1, value;
|
||||
u8 he_dcm = 0, he_stbc = 0;
|
||||
u16 he_gi = 0, he_ltf = 0;
|
||||
|
||||
switch (tlv_tag) {
|
||||
case HAL_RX_PPDU_START: {
|
||||
|
@ -828,6 +893,9 @@ ath11k_hal_rx_parse_mon_status_tlv(struct ath11k_base *ab,
|
|||
info0 = __le32_to_cpu(eu_stats->info0);
|
||||
info1 = __le32_to_cpu(eu_stats->info1);
|
||||
|
||||
ppdu_info->ast_index =
|
||||
FIELD_GET(HAL_RX_PPDU_END_USER_STATS_INFO2_AST_INDEX,
|
||||
__le32_to_cpu(eu_stats->info2));
|
||||
ppdu_info->tid =
|
||||
ffs(FIELD_GET(HAL_RX_PPDU_END_USER_STATS_INFO6_TID_BITMAP,
|
||||
__le32_to_cpu(eu_stats->info6))) - 1;
|
||||
|
@ -851,6 +919,44 @@ ath11k_hal_rx_parse_mon_status_tlv(struct ath11k_base *ab,
|
|||
ppdu_info->num_mpdu_fcs_err =
|
||||
FIELD_GET(HAL_RX_PPDU_END_USER_STATS_INFO0_MPDU_CNT_FCS_ERR,
|
||||
info0);
|
||||
switch (ppdu_info->preamble_type) {
|
||||
case HAL_RX_PREAMBLE_11N:
|
||||
ppdu_info->ht_flags = 1;
|
||||
break;
|
||||
case HAL_RX_PREAMBLE_11AC:
|
||||
ppdu_info->vht_flags = 1;
|
||||
break;
|
||||
case HAL_RX_PREAMBLE_11AX:
|
||||
ppdu_info->he_flags = 1;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (userid < HAL_MAX_UL_MU_USERS) {
|
||||
struct hal_rx_user_status *rxuser_stats =
|
||||
&ppdu_info->userstats;
|
||||
|
||||
ath11k_hal_rx_handle_ofdma_info(tlv_data, rxuser_stats);
|
||||
ath11k_hal_rx_populate_mu_user_info(tlv_data, ppdu_info,
|
||||
rxuser_stats);
|
||||
}
|
||||
ppdu_info->userstats.mpdu_fcs_ok_bitmap[0] =
|
||||
__le32_to_cpu(eu_stats->rsvd1[0]);
|
||||
ppdu_info->userstats.mpdu_fcs_ok_bitmap[1] =
|
||||
__le32_to_cpu(eu_stats->rsvd1[1]);
|
||||
|
||||
break;
|
||||
}
|
||||
case HAL_RX_PPDU_END_USER_STATS_EXT: {
|
||||
struct hal_rx_ppdu_end_user_stats_ext *eu_stats =
|
||||
(struct hal_rx_ppdu_end_user_stats_ext *)tlv_data;
|
||||
ppdu_info->userstats.mpdu_fcs_ok_bitmap[2] = eu_stats->info1;
|
||||
ppdu_info->userstats.mpdu_fcs_ok_bitmap[3] = eu_stats->info2;
|
||||
ppdu_info->userstats.mpdu_fcs_ok_bitmap[4] = eu_stats->info3;
|
||||
ppdu_info->userstats.mpdu_fcs_ok_bitmap[5] = eu_stats->info4;
|
||||
ppdu_info->userstats.mpdu_fcs_ok_bitmap[6] = eu_stats->info5;
|
||||
ppdu_info->userstats.mpdu_fcs_ok_bitmap[7] = eu_stats->info6;
|
||||
break;
|
||||
}
|
||||
case HAL_PHYRX_HT_SIG: {
|
||||
|
@ -949,50 +1055,151 @@ ath11k_hal_rx_parse_mon_status_tlv(struct ath11k_base *ab,
|
|||
else
|
||||
ppdu_info->reception_type =
|
||||
HAL_RX_RECEPTION_TYPE_MU_MIMO;
|
||||
ppdu_info->vht_flag_values5 = group_id;
|
||||
ppdu_info->vht_flag_values3[0] = (((ppdu_info->mcs) << 4) |
|
||||
ppdu_info->nss);
|
||||
ppdu_info->vht_flag_values2 = ppdu_info->bw;
|
||||
ppdu_info->vht_flag_values4 =
|
||||
FIELD_GET(HAL_RX_VHT_SIG_A_INFO_INFO1_SU_MU_CODING, info1);
|
||||
break;
|
||||
}
|
||||
case HAL_PHYRX_HE_SIG_A_SU: {
|
||||
struct hal_rx_he_sig_a_su_info *he_sig_a =
|
||||
(struct hal_rx_he_sig_a_su_info *)tlv_data;
|
||||
u32 nsts, cp_ltf, dcm;
|
||||
|
||||
ppdu_info->he_flags = 1;
|
||||
info0 = __le32_to_cpu(he_sig_a->info0);
|
||||
info1 = __le32_to_cpu(he_sig_a->info1);
|
||||
|
||||
ppdu_info->mcs =
|
||||
FIELD_GET(HAL_RX_HE_SIG_A_SU_INFO_INFO0_TRANSMIT_MCS,
|
||||
info0);
|
||||
ppdu_info->bw =
|
||||
FIELD_GET(HAL_RX_HE_SIG_A_SU_INFO_INFO0_TRANSMIT_BW,
|
||||
info0);
|
||||
ppdu_info->ldpc = FIELD_GET(HAL_RX_HE_SIG_A_SU_INFO_INFO1_CODING, info0);
|
||||
ppdu_info->is_stbc = info1 &
|
||||
HAL_RX_HE_SIG_A_SU_INFO_INFO1_STBC;
|
||||
ppdu_info->beamformed = info1 &
|
||||
HAL_RX_HE_SIG_A_SU_INFO_INFO1_TXBF;
|
||||
dcm = info0 & HAL_RX_HE_SIG_A_SU_INFO_INFO0_DCM;
|
||||
cp_ltf = FIELD_GET(HAL_RX_HE_SIG_A_SU_INFO_INFO0_CP_LTF_SIZE,
|
||||
info0);
|
||||
nsts = FIELD_GET(HAL_RX_HE_SIG_A_SU_INFO_INFO0_NSTS, info0);
|
||||
value = FIELD_GET(HAL_RX_HE_SIG_A_SU_INFO_INFO0_FORMAT_IND, info0);
|
||||
|
||||
switch (cp_ltf) {
|
||||
if (value == 0)
|
||||
ppdu_info->he_data1 = IEEE80211_RADIOTAP_HE_DATA1_FORMAT_TRIG;
|
||||
else
|
||||
ppdu_info->he_data1 = IEEE80211_RADIOTAP_HE_DATA1_FORMAT_SU;
|
||||
|
||||
ppdu_info->he_data1 |=
|
||||
IEEE80211_RADIOTAP_HE_DATA1_BSS_COLOR_KNOWN |
|
||||
IEEE80211_RADIOTAP_HE_DATA1_BEAM_CHANGE_KNOWN |
|
||||
IEEE80211_RADIOTAP_HE_DATA1_UL_DL_KNOWN |
|
||||
IEEE80211_RADIOTAP_HE_DATA1_DATA_MCS_KNOWN |
|
||||
IEEE80211_RADIOTAP_HE_DATA1_DATA_DCM_KNOWN |
|
||||
IEEE80211_RADIOTAP_HE_DATA1_CODING_KNOWN |
|
||||
IEEE80211_RADIOTAP_HE_DATA1_LDPC_XSYMSEG_KNOWN |
|
||||
IEEE80211_RADIOTAP_HE_DATA1_STBC_KNOWN |
|
||||
IEEE80211_RADIOTAP_HE_DATA1_BW_RU_ALLOC_KNOWN |
|
||||
IEEE80211_RADIOTAP_HE_DATA1_DOPPLER_KNOWN;
|
||||
|
||||
ppdu_info->he_data2 |=
|
||||
IEEE80211_RADIOTAP_HE_DATA2_GI_KNOWN |
|
||||
IEEE80211_RADIOTAP_HE_DATA2_TXBF_KNOWN |
|
||||
IEEE80211_RADIOTAP_HE_DATA2_PE_DISAMBIG_KNOWN |
|
||||
IEEE80211_RADIOTAP_HE_DATA2_TXOP_KNOWN |
|
||||
IEEE80211_RADIOTAP_HE_DATA2_NUM_LTF_SYMS_KNOWN |
|
||||
IEEE80211_RADIOTAP_HE_DATA2_PRE_FEC_PAD_KNOWN |
|
||||
IEEE80211_RADIOTAP_HE_DATA2_MIDAMBLE_KNOWN;
|
||||
|
||||
value = FIELD_GET(HAL_RX_HE_SIG_A_SU_INFO_INFO0_BSS_COLOR, info0);
|
||||
ppdu_info->he_data3 =
|
||||
FIELD_PREP(IEEE80211_RADIOTAP_HE_DATA3_BSS_COLOR, value);
|
||||
value = FIELD_GET(HAL_RX_HE_SIG_A_SU_INFO_INFO0_BEAM_CHANGE, info0);
|
||||
ppdu_info->he_data3 |=
|
||||
FIELD_PREP(IEEE80211_RADIOTAP_HE_DATA3_BEAM_CHANGE, value);
|
||||
value = FIELD_GET(HAL_RX_HE_SIG_A_SU_INFO_INFO0_DL_UL_FLAG, info0);
|
||||
ppdu_info->he_data3 |=
|
||||
FIELD_PREP(IEEE80211_RADIOTAP_HE_DATA3_UL_DL, value);
|
||||
value = FIELD_GET(HAL_RX_HE_SIG_A_SU_INFO_INFO0_TRANSMIT_MCS, info0);
|
||||
ppdu_info->mcs = value;
|
||||
ppdu_info->he_data3 |=
|
||||
FIELD_PREP(IEEE80211_RADIOTAP_HE_DATA3_DATA_MCS, value);
|
||||
|
||||
he_dcm = FIELD_GET(HAL_RX_HE_SIG_A_SU_INFO_INFO0_DCM, info0);
|
||||
ppdu_info->dcm = he_dcm;
|
||||
ppdu_info->he_data3 |=
|
||||
FIELD_PREP(IEEE80211_RADIOTAP_HE_DATA3_DATA_DCM, he_dcm);
|
||||
value = FIELD_GET(HAL_RX_HE_SIG_A_SU_INFO_INFO1_CODING, info1);
|
||||
ppdu_info->ldpc = (value == HAL_RX_SU_MU_CODING_LDPC) ? 1 : 0;
|
||||
ppdu_info->he_data3 |=
|
||||
FIELD_PREP(IEEE80211_RADIOTAP_HE_DATA3_CODING, value);
|
||||
value = FIELD_GET(HAL_RX_HE_SIG_A_SU_INFO_INFO1_LDPC_EXTRA, info1);
|
||||
ppdu_info->he_data3 |=
|
||||
FIELD_PREP(IEEE80211_RADIOTAP_HE_DATA3_LDPC_XSYMSEG, value);
|
||||
he_stbc = FIELD_GET(HAL_RX_HE_SIG_A_SU_INFO_INFO1_STBC, info1);
|
||||
ppdu_info->is_stbc = he_stbc;
|
||||
ppdu_info->he_data3 |=
|
||||
FIELD_PREP(IEEE80211_RADIOTAP_HE_DATA3_STBC, he_stbc);
|
||||
|
||||
/* data4 */
|
||||
value = FIELD_GET(HAL_RX_HE_SIG_A_SU_INFO_INFO0_SPATIAL_REUSE, info0);
|
||||
ppdu_info->he_data4 =
|
||||
FIELD_PREP(IEEE80211_RADIOTAP_HE_DATA4_SU_MU_SPTL_REUSE, value);
|
||||
|
||||
/* data5 */
|
||||
value = FIELD_GET(HAL_RX_HE_SIG_A_SU_INFO_INFO0_TRANSMIT_BW, info0);
|
||||
ppdu_info->bw = value;
|
||||
ppdu_info->he_data5 =
|
||||
FIELD_PREP(IEEE80211_RADIOTAP_HE_DATA5_DATA_BW_RU_ALLOC, value);
|
||||
value = FIELD_GET(HAL_RX_HE_SIG_A_SU_INFO_INFO0_CP_LTF_SIZE, info0);
|
||||
switch (value) {
|
||||
case 0:
|
||||
he_gi = HE_GI_0_8;
|
||||
he_ltf = HE_LTF_1_X;
|
||||
break;
|
||||
case 1:
|
||||
ppdu_info->gi = HAL_RX_GI_0_8_US;
|
||||
break;
|
||||
he_gi = HE_GI_0_8;
|
||||
he_ltf = HE_LTF_2_X;
|
||||
break;
|
||||
case 2:
|
||||
ppdu_info->gi = HAL_RX_GI_1_6_US;
|
||||
break;
|
||||
he_gi = HE_GI_1_6;
|
||||
he_ltf = HE_LTF_2_X;
|
||||
break;
|
||||
case 3:
|
||||
if (dcm && ppdu_info->is_stbc)
|
||||
ppdu_info->gi = HAL_RX_GI_0_8_US;
|
||||
else
|
||||
ppdu_info->gi = HAL_RX_GI_3_2_US;
|
||||
break;
|
||||
if (he_dcm && he_stbc) {
|
||||
he_gi = HE_GI_0_8;
|
||||
he_ltf = HE_LTF_4_X;
|
||||
} else {
|
||||
he_gi = HE_GI_3_2;
|
||||
he_ltf = HE_LTF_4_X;
|
||||
}
|
||||
break;
|
||||
}
|
||||
ppdu_info->gi = he_gi;
|
||||
he_gi = (he_gi != 0) ? he_gi - 1 : 0;
|
||||
ppdu_info->he_data5 |= FIELD_PREP(IEEE80211_RADIOTAP_HE_DATA5_GI, he_gi);
|
||||
ppdu_info->ltf_size = he_ltf;
|
||||
ppdu_info->he_data5 |=
|
||||
FIELD_PREP(IEEE80211_RADIOTAP_HE_DATA5_LTF_SIZE,
|
||||
(he_ltf == HE_LTF_4_X) ? he_ltf - 1 : he_ltf);
|
||||
|
||||
value = FIELD_GET(HAL_RX_HE_SIG_A_SU_INFO_INFO0_NSTS, info0);
|
||||
ppdu_info->he_data5 |=
|
||||
FIELD_PREP(IEEE80211_RADIOTAP_HE_DATA5_NUM_LTF_SYMS, value);
|
||||
|
||||
value = FIELD_GET(HAL_RX_HE_SIG_A_SU_INFO_INFO1_PKT_EXT_FACTOR, info1);
|
||||
ppdu_info->he_data5 |=
|
||||
FIELD_PREP(IEEE80211_RADIOTAP_HE_DATA5_PRE_FEC_PAD, value);
|
||||
|
||||
value = FIELD_GET(HAL_RX_HE_SIG_A_SU_INFO_INFO1_TXBF, info1);
|
||||
ppdu_info->beamformed = value;
|
||||
ppdu_info->he_data5 |=
|
||||
FIELD_PREP(IEEE80211_RADIOTAP_HE_DATA5_TXBF, value);
|
||||
value = FIELD_GET(HAL_RX_HE_SIG_A_SU_INFO_INFO1_PKT_EXT_PE_DISAM, info1);
|
||||
ppdu_info->he_data5 |=
|
||||
FIELD_PREP(IEEE80211_RADIOTAP_HE_DATA5_PE_DISAMBIG, value);
|
||||
|
||||
/* data6 */
|
||||
value = FIELD_GET(HAL_RX_HE_SIG_A_SU_INFO_INFO0_NSTS, info0);
|
||||
value++;
|
||||
ppdu_info->nss = value;
|
||||
ppdu_info->he_data6 =
|
||||
FIELD_PREP(IEEE80211_RADIOTAP_HE_DATA6_NSTS, value);
|
||||
value = FIELD_GET(HAL_RX_HE_SIG_A_SU_INFO_INFO1_DOPPLER_IND, info1);
|
||||
ppdu_info->he_data6 |=
|
||||
FIELD_PREP(IEEE80211_RADIOTAP_HE_DATA6_DOPPLER, value);
|
||||
value = FIELD_GET(HAL_RX_HE_SIG_A_SU_INFO_INFO1_TXOP_DURATION, info1);
|
||||
ppdu_info->he_data6 |=
|
||||
FIELD_PREP(IEEE80211_RADIOTAP_HE_DATA6_TXOP, value);
|
||||
|
||||
ppdu_info->nss = nsts + 1;
|
||||
ppdu_info->dcm = dcm;
|
||||
ppdu_info->reception_type = HAL_RX_RECEPTION_TYPE_SU;
|
||||
break;
|
||||
}
|
||||
|
@ -1000,29 +1207,142 @@ ath11k_hal_rx_parse_mon_status_tlv(struct ath11k_base *ab,
|
|||
struct hal_rx_he_sig_a_mu_dl_info *he_sig_a_mu_dl =
|
||||
(struct hal_rx_he_sig_a_mu_dl_info *)tlv_data;
|
||||
|
||||
u32 cp_ltf;
|
||||
|
||||
info0 = __le32_to_cpu(he_sig_a_mu_dl->info0);
|
||||
info1 = __le32_to_cpu(he_sig_a_mu_dl->info1);
|
||||
|
||||
ppdu_info->bw =
|
||||
FIELD_GET(HAL_RX_HE_SIG_A_MU_DL_INFO_INFO0_TRANSMIT_BW,
|
||||
info0);
|
||||
cp_ltf = FIELD_GET(HAL_RX_HE_SIG_A_MU_DL_INFO_INFO0_CP_LTF_SIZE,
|
||||
info0);
|
||||
ppdu_info->he_mu_flags = 1;
|
||||
|
||||
switch (cp_ltf) {
|
||||
ppdu_info->he_data1 = IEEE80211_RADIOTAP_HE_DATA1_FORMAT_MU;
|
||||
ppdu_info->he_data1 |=
|
||||
IEEE80211_RADIOTAP_HE_DATA1_BSS_COLOR_KNOWN |
|
||||
IEEE80211_RADIOTAP_HE_DATA1_UL_DL_KNOWN |
|
||||
IEEE80211_RADIOTAP_HE_DATA1_LDPC_XSYMSEG_KNOWN |
|
||||
IEEE80211_RADIOTAP_HE_DATA1_STBC_KNOWN |
|
||||
IEEE80211_RADIOTAP_HE_DATA1_BW_RU_ALLOC_KNOWN |
|
||||
IEEE80211_RADIOTAP_HE_DATA1_DOPPLER_KNOWN;
|
||||
|
||||
ppdu_info->he_data2 =
|
||||
IEEE80211_RADIOTAP_HE_DATA2_GI_KNOWN |
|
||||
IEEE80211_RADIOTAP_HE_DATA2_NUM_LTF_SYMS_KNOWN |
|
||||
IEEE80211_RADIOTAP_HE_DATA2_PRE_FEC_PAD_KNOWN |
|
||||
IEEE80211_RADIOTAP_HE_DATA2_PE_DISAMBIG_KNOWN |
|
||||
IEEE80211_RADIOTAP_HE_DATA2_TXOP_KNOWN |
|
||||
IEEE80211_RADIOTAP_HE_DATA2_MIDAMBLE_KNOWN;
|
||||
|
||||
/*data3*/
|
||||
value = FIELD_GET(HAL_RX_HE_SIG_A_MU_DL_INFO_INFO0_BSS_COLOR, info0);
|
||||
ppdu_info->he_data3 =
|
||||
FIELD_PREP(IEEE80211_RADIOTAP_HE_DATA3_BSS_COLOR, value);
|
||||
|
||||
value = FIELD_GET(HAL_RX_HE_SIG_A_MU_DL_INFO_INFO0_UL_FLAG, info0);
|
||||
ppdu_info->he_data3 |=
|
||||
FIELD_PREP(IEEE80211_RADIOTAP_HE_DATA3_UL_DL, value);
|
||||
|
||||
value = FIELD_GET(HAL_RX_HE_SIG_A_MU_DL_INFO_INFO1_LDPC_EXTRA, info1);
|
||||
ppdu_info->he_data3 |=
|
||||
FIELD_PREP(IEEE80211_RADIOTAP_HE_DATA3_LDPC_XSYMSEG, value);
|
||||
|
||||
value = FIELD_GET(HAL_RX_HE_SIG_A_MU_DL_INFO_INFO1_STBC, info1);
|
||||
he_stbc = value;
|
||||
ppdu_info->he_data3 |=
|
||||
FIELD_PREP(IEEE80211_RADIOTAP_HE_DATA3_STBC, value);
|
||||
|
||||
/*data4*/
|
||||
value = FIELD_GET(HAL_RX_HE_SIG_A_MU_DL_INFO_INFO0_SPATIAL_REUSE, info0);
|
||||
ppdu_info->he_data4 =
|
||||
FIELD_PREP(IEEE80211_RADIOTAP_HE_DATA4_SU_MU_SPTL_REUSE, value);
|
||||
|
||||
/*data5*/
|
||||
value = FIELD_GET(HAL_RX_HE_SIG_A_MU_DL_INFO_INFO0_TRANSMIT_BW, info0);
|
||||
ppdu_info->bw = value;
|
||||
ppdu_info->he_data5 =
|
||||
FIELD_PREP(IEEE80211_RADIOTAP_HE_DATA5_DATA_BW_RU_ALLOC, value);
|
||||
|
||||
value = FIELD_GET(HAL_RX_HE_SIG_A_MU_DL_INFO_INFO0_CP_LTF_SIZE, info0);
|
||||
switch (value) {
|
||||
case 0:
|
||||
he_gi = HE_GI_0_8;
|
||||
he_ltf = HE_LTF_4_X;
|
||||
break;
|
||||
case 1:
|
||||
ppdu_info->gi = HAL_RX_GI_0_8_US;
|
||||
he_gi = HE_GI_0_8;
|
||||
he_ltf = HE_LTF_2_X;
|
||||
break;
|
||||
case 2:
|
||||
ppdu_info->gi = HAL_RX_GI_1_6_US;
|
||||
he_gi = HE_GI_1_6;
|
||||
he_ltf = HE_LTF_2_X;
|
||||
break;
|
||||
case 3:
|
||||
ppdu_info->gi = HAL_RX_GI_3_2_US;
|
||||
he_gi = HE_GI_3_2;
|
||||
he_ltf = HE_LTF_4_X;
|
||||
break;
|
||||
}
|
||||
ppdu_info->gi = he_gi;
|
||||
he_gi = (he_gi != 0) ? he_gi - 1 : 0;
|
||||
ppdu_info->he_data5 |= FIELD_PREP(IEEE80211_RADIOTAP_HE_DATA5_GI, he_gi);
|
||||
ppdu_info->ltf_size = he_ltf;
|
||||
ppdu_info->he_data5 |=
|
||||
FIELD_PREP(IEEE80211_RADIOTAP_HE_DATA5_LTF_SIZE,
|
||||
(he_ltf == HE_LTF_4_X) ? he_ltf - 1 : he_ltf);
|
||||
|
||||
value = FIELD_GET(HAL_RX_HE_SIG_A_MU_DL_INFO_INFO1_NUM_LTF_SYMB, info1);
|
||||
ppdu_info->he_data5 |=
|
||||
FIELD_PREP(IEEE80211_RADIOTAP_HE_DATA5_NUM_LTF_SYMS, value);
|
||||
|
||||
value = FIELD_GET(HAL_RX_HE_SIG_A_MU_DL_INFO_INFO1_PKT_EXT_FACTOR,
|
||||
info1);
|
||||
ppdu_info->he_data5 |=
|
||||
FIELD_PREP(IEEE80211_RADIOTAP_HE_DATA5_PRE_FEC_PAD, value);
|
||||
|
||||
value = FIELD_GET(HAL_RX_HE_SIG_A_MU_DL_INFO_INFO1_PKT_EXT_PE_DISAM,
|
||||
info1);
|
||||
ppdu_info->he_data5 |=
|
||||
FIELD_PREP(IEEE80211_RADIOTAP_HE_DATA5_PE_DISAMBIG, value);
|
||||
|
||||
/*data6*/
|
||||
value = FIELD_GET(HAL_RX_HE_SIG_A_MU_DL_INFO_INFO0_DOPPLER_INDICATION,
|
||||
info0);
|
||||
ppdu_info->he_data6 |=
|
||||
FIELD_PREP(IEEE80211_RADIOTAP_HE_DATA6_DOPPLER, value);
|
||||
|
||||
value = FIELD_GET(HAL_RX_HE_SIG_A_MU_DL_INFO_INFO1_TXOP_DURATION, info1);
|
||||
ppdu_info->he_data6 |=
|
||||
FIELD_PREP(IEEE80211_RADIOTAP_HE_DATA6_TXOP, value);
|
||||
|
||||
/* HE-MU Flags */
|
||||
/* HE-MU-flags1 */
|
||||
ppdu_info->he_flags1 =
|
||||
IEEE80211_RADIOTAP_HE_MU_FLAGS1_SIG_B_MCS_KNOWN |
|
||||
IEEE80211_RADIOTAP_HE_MU_FLAGS1_SIG_B_DCM_KNOWN |
|
||||
IEEE80211_RADIOTAP_HE_MU_FLAGS1_SIG_B_COMP_KNOWN |
|
||||
IEEE80211_RADIOTAP_HE_MU_FLAGS1_SIG_B_SYMS_USERS_KNOWN |
|
||||
IEEE80211_RADIOTAP_HE_MU_FLAGS1_CH1_RU_KNOWN;
|
||||
|
||||
value = FIELD_GET(HAL_RX_HE_SIG_A_MU_DL_INFO_INFO0_MCS_OF_SIGB, info0);
|
||||
ppdu_info->he_flags1 |=
|
||||
FIELD_PREP(IEEE80211_RADIOTAP_HE_MU_FLAGS1_SIG_B_MCS_KNOWN,
|
||||
value);
|
||||
value = FIELD_GET(HAL_RX_HE_SIG_A_MU_DL_INFO_INFO0_DCM_OF_SIGB, info0);
|
||||
ppdu_info->he_flags1 |=
|
||||
FIELD_PREP(IEEE80211_RADIOTAP_HE_MU_FLAGS1_SIG_B_DCM_KNOWN,
|
||||
value);
|
||||
|
||||
/* HE-MU-flags2 */
|
||||
ppdu_info->he_flags2 =
|
||||
IEEE80211_RADIOTAP_HE_MU_FLAGS2_BW_FROM_SIG_A_BW_KNOWN;
|
||||
|
||||
value = FIELD_GET(HAL_RX_HE_SIG_A_MU_DL_INFO_INFO0_TRANSMIT_BW, info0);
|
||||
ppdu_info->he_flags2 |=
|
||||
FIELD_PREP(IEEE80211_RADIOTAP_HE_MU_FLAGS2_BW_FROM_SIG_A_BW,
|
||||
value);
|
||||
value = FIELD_GET(HAL_RX_HE_SIG_A_MU_DL_INFO_INFO0_COMP_MODE_SIGB, info0);
|
||||
ppdu_info->he_flags2 |=
|
||||
FIELD_PREP(IEEE80211_RADIOTAP_HE_MU_FLAGS2_SIG_B_COMP, value);
|
||||
value = FIELD_GET(HAL_RX_HE_SIG_A_MU_DL_INFO_INFO0_NUM_SIGB_SYMB, info0);
|
||||
value = value - 1;
|
||||
ppdu_info->he_flags2 |=
|
||||
FIELD_PREP(IEEE80211_RADIOTAP_HE_MU_FLAGS2_SIG_B_SYMS_USERS,
|
||||
value);
|
||||
|
||||
ppdu_info->is_stbc = info1 &
|
||||
HAL_RX_HE_SIG_A_MU_DL_INFO_INFO1_STBC;
|
||||
|
@ -1040,7 +1360,7 @@ ath11k_hal_rx_parse_mon_status_tlv(struct ath11k_base *ab,
|
|||
info0);
|
||||
ppdu_info->ru_alloc =
|
||||
ath11k_mac_phy_he_ru_to_nl80211_he_ru_alloc(ru_tones);
|
||||
|
||||
ppdu_info->he_RU[0] = ru_tones;
|
||||
ppdu_info->reception_type = HAL_RX_RECEPTION_TYPE_MU_MIMO;
|
||||
break;
|
||||
}
|
||||
|
@ -1050,14 +1370,25 @@ ath11k_hal_rx_parse_mon_status_tlv(struct ath11k_base *ab,
|
|||
|
||||
info0 = __le32_to_cpu(he_sig_b2_mu->info0);
|
||||
|
||||
ppdu_info->he_data1 |= IEEE80211_RADIOTAP_HE_DATA1_DATA_MCS_KNOWN |
|
||||
IEEE80211_RADIOTAP_HE_DATA1_CODING_KNOWN;
|
||||
|
||||
ppdu_info->mcs =
|
||||
FIELD_GET(HAL_RX_HE_SIG_B2_MU_INFO_INFO0_STA_MCS,
|
||||
info0);
|
||||
FIELD_GET(HAL_RX_HE_SIG_B2_MU_INFO_INFO0_STA_MCS, info0);
|
||||
ppdu_info->he_data3 |=
|
||||
FIELD_PREP(IEEE80211_RADIOTAP_HE_DATA3_DATA_MCS, ppdu_info->mcs);
|
||||
|
||||
value = FIELD_GET(HAL_RX_HE_SIG_B2_MU_INFO_INFO0_STA_CODING, info0);
|
||||
ppdu_info->ldpc = value;
|
||||
ppdu_info->he_data3 |=
|
||||
FIELD_PREP(IEEE80211_RADIOTAP_HE_DATA3_CODING, value);
|
||||
|
||||
value = FIELD_GET(HAL_RX_HE_SIG_B2_MU_INFO_INFO0_STA_ID, info0);
|
||||
ppdu_info->he_data4 |=
|
||||
FIELD_PREP(IEEE80211_RADIOTAP_HE_DATA4_MU_STA_ID, value);
|
||||
|
||||
ppdu_info->nss =
|
||||
FIELD_GET(HAL_RX_HE_SIG_B2_MU_INFO_INFO0_STA_NSTS,
|
||||
info0) + 1;
|
||||
ppdu_info->ldpc = FIELD_GET(HAL_RX_HE_SIG_B2_MU_INFO_INFO0_STA_CODING,
|
||||
info0);
|
||||
FIELD_GET(HAL_RX_HE_SIG_B2_MU_INFO_INFO0_STA_NSTS, info0) + 1;
|
||||
break;
|
||||
}
|
||||
case HAL_PHYRX_HE_SIG_B2_OFDMA: {
|
||||
|
@ -1066,17 +1397,40 @@ ath11k_hal_rx_parse_mon_status_tlv(struct ath11k_base *ab,
|
|||
|
||||
info0 = __le32_to_cpu(he_sig_b2_ofdma->info0);
|
||||
|
||||
ppdu_info->he_data1 |=
|
||||
IEEE80211_RADIOTAP_HE_DATA1_DATA_MCS_KNOWN |
|
||||
IEEE80211_RADIOTAP_HE_DATA1_DATA_DCM_KNOWN |
|
||||
IEEE80211_RADIOTAP_HE_DATA1_CODING_KNOWN;
|
||||
|
||||
/* HE-data2 */
|
||||
ppdu_info->he_data2 |= IEEE80211_RADIOTAP_HE_DATA2_TXBF_KNOWN;
|
||||
|
||||
ppdu_info->mcs =
|
||||
FIELD_GET(HAL_RX_HE_SIG_B2_OFDMA_INFO_INFO0_STA_MCS,
|
||||
info0);
|
||||
ppdu_info->he_data3 |=
|
||||
FIELD_PREP(IEEE80211_RADIOTAP_HE_DATA3_DATA_MCS, ppdu_info->mcs);
|
||||
|
||||
value = FIELD_GET(HAL_RX_HE_SIG_B2_OFDMA_INFO_INFO0_STA_DCM, info0);
|
||||
he_dcm = value;
|
||||
ppdu_info->he_data3 |=
|
||||
FIELD_PREP(IEEE80211_RADIOTAP_HE_DATA3_DATA_DCM, value);
|
||||
|
||||
value = FIELD_GET(HAL_RX_HE_SIG_B2_OFDMA_INFO_INFO0_STA_CODING, info0);
|
||||
ppdu_info->ldpc = value;
|
||||
ppdu_info->he_data3 |=
|
||||
FIELD_PREP(IEEE80211_RADIOTAP_HE_DATA3_CODING, value);
|
||||
|
||||
/* HE-data4 */
|
||||
value = FIELD_GET(HAL_RX_HE_SIG_B2_OFDMA_INFO_INFO0_STA_ID, info0);
|
||||
ppdu_info->he_data4 |=
|
||||
FIELD_PREP(IEEE80211_RADIOTAP_HE_DATA4_MU_STA_ID, value);
|
||||
|
||||
ppdu_info->nss =
|
||||
FIELD_GET(HAL_RX_HE_SIG_B2_OFDMA_INFO_INFO0_STA_NSTS,
|
||||
info0) + 1;
|
||||
ppdu_info->beamformed =
|
||||
info0 &
|
||||
HAL_RX_HE_SIG_B2_OFDMA_INFO_INFO0_STA_TXBF;
|
||||
ppdu_info->ldpc = FIELD_GET(HAL_RX_HE_SIG_B2_OFDMA_INFO_INFO0_STA_CODING,
|
||||
info0);
|
||||
info0 & HAL_RX_HE_SIG_B2_OFDMA_INFO_INFO0_STA_TXBF;
|
||||
ppdu_info->reception_type = HAL_RX_RECEPTION_TYPE_MU_OFDMA;
|
||||
break;
|
||||
}
|
||||
|
@ -1118,6 +1472,9 @@ ath11k_hal_rx_parse_mon_status_tlv(struct ath11k_base *ab,
|
|||
ppdu_info->rx_duration =
|
||||
FIELD_GET(HAL_RX_PPDU_END_DURATION,
|
||||
__le32_to_cpu(ppdu_rx_duration->info0));
|
||||
ppdu_info->tsft = __le32_to_cpu(ppdu_rx_duration->rsvd0[1]);
|
||||
ppdu_info->tsft = (ppdu_info->tsft << 32) |
|
||||
__le32_to_cpu(ppdu_rx_duration->rsvd0[0]);
|
||||
break;
|
||||
}
|
||||
case HAL_DUMMY:
|
||||
|
@ -1141,12 +1498,14 @@ ath11k_hal_rx_parse_mon_status(struct ath11k_base *ab,
|
|||
enum hal_rx_mon_status hal_status = HAL_RX_MON_STATUS_BUF_DONE;
|
||||
u16 tlv_tag;
|
||||
u16 tlv_len;
|
||||
u32 tlv_userid = 0;
|
||||
u8 *ptr = skb->data;
|
||||
|
||||
do {
|
||||
tlv = (struct hal_tlv_hdr *)ptr;
|
||||
tlv_tag = FIELD_GET(HAL_TLV_HDR_TAG, tlv->tl);
|
||||
tlv_len = FIELD_GET(HAL_TLV_HDR_LEN, tlv->tl);
|
||||
tlv_userid = FIELD_GET(HAL_TLV_USR_ID, tlv->tl);
|
||||
ptr += sizeof(*tlv);
|
||||
|
||||
/* The actual length of PPDU_END is the combined length of many PHY
|
||||
|
@ -1158,7 +1517,7 @@ ath11k_hal_rx_parse_mon_status(struct ath11k_base *ab,
|
|||
tlv_len = sizeof(struct hal_rx_rxpcu_classification_overview);
|
||||
|
||||
hal_status = ath11k_hal_rx_parse_mon_status_tlv(ab, ppdu_info,
|
||||
tlv_tag, ptr);
|
||||
tlv_tag, ptr, tlv_userid);
|
||||
ptr += tlv_len;
|
||||
ptr = PTR_ALIGN(ptr, HAL_TLV_ALIGN);
|
||||
|
||||
|
|
|
@ -73,6 +73,36 @@ enum hal_rx_mon_status {
|
|||
HAL_RX_MON_STATUS_BUF_DONE,
|
||||
};
|
||||
|
||||
struct hal_rx_user_status {
|
||||
u32 mcs:4,
|
||||
nss:3,
|
||||
ofdma_info_valid:1,
|
||||
dl_ofdma_ru_start_index:7,
|
||||
dl_ofdma_ru_width:7,
|
||||
dl_ofdma_ru_size:8;
|
||||
u32 ul_ofdma_user_v0_word0;
|
||||
u32 ul_ofdma_user_v0_word1;
|
||||
u32 ast_index;
|
||||
u32 tid;
|
||||
u16 tcp_msdu_count;
|
||||
u16 udp_msdu_count;
|
||||
u16 other_msdu_count;
|
||||
u16 frame_control;
|
||||
u8 frame_control_info_valid;
|
||||
u8 data_sequence_control_info_valid;
|
||||
u16 first_data_seq_ctrl;
|
||||
u32 preamble_type;
|
||||
u16 ht_flags;
|
||||
u16 vht_flags;
|
||||
u16 he_flags;
|
||||
u8 rs_flags;
|
||||
u32 mpdu_cnt_fcs_ok;
|
||||
u32 mpdu_cnt_fcs_err;
|
||||
u32 mpdu_fcs_ok_bitmap[8];
|
||||
u32 mpdu_ok_byte_count;
|
||||
u32 mpdu_err_byte_count;
|
||||
};
|
||||
|
||||
#define HAL_TLV_STATUS_PPDU_NOT_DONE HAL_RX_MON_STATUS_PPDU_NOT_DONE
|
||||
#define HAL_TLV_STATUS_PPDU_DONE HAL_RX_MON_STATUS_PPDU_DONE
|
||||
#define HAL_TLV_STATUS_BUF_DONE HAL_RX_MON_STATUS_BUF_DONE
|
||||
|
@ -107,6 +137,12 @@ struct hal_rx_mon_ppdu_info {
|
|||
u8 mcs;
|
||||
u8 nss;
|
||||
u8 bw;
|
||||
u8 vht_flag_values1;
|
||||
u8 vht_flag_values2;
|
||||
u8 vht_flag_values3[4];
|
||||
u8 vht_flag_values4;
|
||||
u8 vht_flag_values5;
|
||||
u16 vht_flag_values6;
|
||||
u8 is_stbc;
|
||||
u8 gi;
|
||||
u8 ldpc;
|
||||
|
@ -114,10 +150,46 @@ struct hal_rx_mon_ppdu_info {
|
|||
u8 rssi_comb;
|
||||
u8 rssi_chain_pri20[HAL_RX_MAX_NSS];
|
||||
u8 tid;
|
||||
u16 ht_flags;
|
||||
u16 vht_flags;
|
||||
u16 he_flags;
|
||||
u16 he_mu_flags;
|
||||
u8 dcm;
|
||||
u8 ru_alloc;
|
||||
u8 reception_type;
|
||||
u64 tsft;
|
||||
u64 rx_duration;
|
||||
u16 frame_control;
|
||||
u32 ast_index;
|
||||
u8 rs_fcs_err;
|
||||
u8 rs_flags;
|
||||
u8 cck_flag;
|
||||
u8 ofdm_flag;
|
||||
u8 ulofdma_flag;
|
||||
u8 frame_control_info_valid;
|
||||
u16 he_per_user_1;
|
||||
u16 he_per_user_2;
|
||||
u8 he_per_user_position;
|
||||
u8 he_per_user_known;
|
||||
u16 he_flags1;
|
||||
u16 he_flags2;
|
||||
u8 he_RU[4];
|
||||
u16 he_data1;
|
||||
u16 he_data2;
|
||||
u16 he_data3;
|
||||
u16 he_data4;
|
||||
u16 he_data5;
|
||||
u16 he_data6;
|
||||
u32 ppdu_len;
|
||||
u32 prev_ppdu_id;
|
||||
u32 device_id;
|
||||
u16 first_data_seq_ctrl;
|
||||
u8 monitor_direct_used;
|
||||
u8 data_sequence_control_info_valid;
|
||||
u8 ltf_size;
|
||||
u8 rxpcu_filter_pass;
|
||||
char rssi_chain[8][8];
|
||||
struct hal_rx_user_status userstats;
|
||||
};
|
||||
|
||||
#define HAL_RX_PPDU_START_INFO0_PPDU_ID GENMASK(15, 0)
|
||||
|
@ -150,6 +222,9 @@ struct hal_rx_ppdu_start {
|
|||
#define HAL_RX_PPDU_END_USER_STATS_INFO6_TID_BITMAP GENMASK(15, 0)
|
||||
#define HAL_RX_PPDU_END_USER_STATS_INFO6_TID_EOSP_BITMAP GENMASK(31, 16)
|
||||
|
||||
#define HAL_RX_PPDU_END_USER_STATS_RSVD2_6_MPDU_OK_BYTE_COUNT GENMASK(24, 0)
|
||||
#define HAL_RX_PPDU_END_USER_STATS_RSVD2_8_MPDU_ERR_BYTE_COUNT GENMASK(24, 0)
|
||||
|
||||
struct hal_rx_ppdu_end_user_stats {
|
||||
__le32 rsvd0[2];
|
||||
__le32 info0;
|
||||
|
@ -164,6 +239,16 @@ struct hal_rx_ppdu_end_user_stats {
|
|||
__le32 rsvd2[11];
|
||||
} __packed;
|
||||
|
||||
struct hal_rx_ppdu_end_user_stats_ext {
|
||||
u32 info0;
|
||||
u32 info1;
|
||||
u32 info2;
|
||||
u32 info3;
|
||||
u32 info4;
|
||||
u32 info5;
|
||||
u32 info6;
|
||||
} __packed;
|
||||
|
||||
#define HAL_RX_HT_SIG_INFO_INFO0_MCS GENMASK(6, 0)
|
||||
#define HAL_RX_HT_SIG_INFO_INFO0_BW BIT(7)
|
||||
|
||||
|
@ -212,25 +297,62 @@ enum hal_rx_vht_sig_a_gi_setting {
|
|||
HAL_RX_VHT_SIG_A_SHORT_GI_AMBIGUITY = 3,
|
||||
};
|
||||
|
||||
#define HAL_RX_SU_MU_CODING_LDPC 0x01
|
||||
|
||||
#define HE_GI_0_8 0
|
||||
#define HE_GI_0_4 1
|
||||
#define HE_GI_1_6 2
|
||||
#define HE_GI_3_2 3
|
||||
|
||||
#define HE_LTF_1_X 0
|
||||
#define HE_LTF_2_X 1
|
||||
#define HE_LTF_4_X 2
|
||||
#define HE_LTF_UNKNOWN 3
|
||||
|
||||
#define HAL_RX_HE_SIG_A_SU_INFO_INFO0_TRANSMIT_MCS GENMASK(6, 3)
|
||||
#define HAL_RX_HE_SIG_A_SU_INFO_INFO0_DCM BIT(7)
|
||||
#define HAL_RX_HE_SIG_A_SU_INFO_INFO0_TRANSMIT_BW GENMASK(20, 19)
|
||||
#define HAL_RX_HE_SIG_A_SU_INFO_INFO0_CP_LTF_SIZE GENMASK(22, 21)
|
||||
#define HAL_RX_HE_SIG_A_SU_INFO_INFO0_NSTS GENMASK(25, 23)
|
||||
#define HAL_RX_HE_SIG_A_SU_INFO_INFO0_BSS_COLOR GENMASK(13, 8)
|
||||
#define HAL_RX_HE_SIG_A_SU_INFO_INFO0_SPATIAL_REUSE GENMASK(18, 15)
|
||||
#define HAL_RX_HE_SIG_A_SU_INFO_INFO0_FORMAT_IND BIT(0)
|
||||
#define HAL_RX_HE_SIG_A_SU_INFO_INFO0_BEAM_CHANGE BIT(1)
|
||||
#define HAL_RX_HE_SIG_A_SU_INFO_INFO0_DL_UL_FLAG BIT(2)
|
||||
|
||||
#define HAL_RX_HE_SIG_A_SU_INFO_INFO1_TXOP_DURATION GENMASK(6, 0)
|
||||
#define HAL_RX_HE_SIG_A_SU_INFO_INFO1_CODING BIT(7)
|
||||
#define HAL_RX_HE_SIG_A_SU_INFO_INFO1_LDPC_EXTRA BIT(8)
|
||||
#define HAL_RX_HE_SIG_A_SU_INFO_INFO1_STBC BIT(9)
|
||||
#define HAL_RX_HE_SIG_A_SU_INFO_INFO1_TXBF BIT(10)
|
||||
#define HAL_RX_HE_SIG_A_SU_INFO_INFO1_PKT_EXT_FACTOR GENMASK(12, 11)
|
||||
#define HAL_RX_HE_SIG_A_SU_INFO_INFO1_PKT_EXT_PE_DISAM BIT(13)
|
||||
#define HAL_RX_HE_SIG_A_SU_INFO_INFO1_DOPPLER_IND BIT(15)
|
||||
|
||||
struct hal_rx_he_sig_a_su_info {
|
||||
__le32 info0;
|
||||
__le32 info1;
|
||||
} __packed;
|
||||
|
||||
#define HAL_RX_HE_SIG_A_MU_DL_INFO_INFO0_TRANSMIT_BW GENMASK(17, 15)
|
||||
#define HAL_RX_HE_SIG_A_MU_DL_INFO_INFO0_CP_LTF_SIZE GENMASK(24, 23)
|
||||
#define HAL_RX_HE_SIG_A_MU_DL_INFO_INFO0_UL_FLAG BIT(1)
|
||||
#define HAL_RX_HE_SIG_A_MU_DL_INFO_INFO0_MCS_OF_SIGB GENMASK(3, 1)
|
||||
#define HAL_RX_HE_SIG_A_MU_DL_INFO_INFO0_DCM_OF_SIGB BIT(4)
|
||||
#define HAL_RX_HE_SIG_A_MU_DL_INFO_INFO0_BSS_COLOR GENMASK(10, 5)
|
||||
#define HAL_RX_HE_SIG_A_MU_DL_INFO_INFO0_SPATIAL_REUSE GENMASK(14, 11)
|
||||
#define HAL_RX_HE_SIG_A_MU_DL_INFO_INFO0_TRANSMIT_BW GENMASK(17, 15)
|
||||
#define HAL_RX_HE_SIG_A_MU_DL_INFO_INFO0_NUM_SIGB_SYMB GENMASK(21, 18)
|
||||
#define HAL_RX_HE_SIG_A_MU_DL_INFO_INFO0_COMP_MODE_SIGB BIT(22)
|
||||
#define HAL_RX_HE_SIG_A_MU_DL_INFO_INFO0_CP_LTF_SIZE GENMASK(24, 23)
|
||||
#define HAL_RX_HE_SIG_A_MU_DL_INFO_INFO0_DOPPLER_INDICATION BIT(25)
|
||||
|
||||
#define HAL_RX_HE_SIG_A_MU_DL_INFO_INFO1_TXOP_DURATION GENMASK(6, 0)
|
||||
#define HAL_RX_HE_SIG_A_MU_DL_INFO_INFO1_CODING BIT(7)
|
||||
#define HAL_RX_HE_SIG_A_MU_DL_INFO_INFO1_NUM_LTF_SYMB GENMASK(10, 8)
|
||||
#define HAL_RX_HE_SIG_A_MU_DL_INFO_INFO1_LDPC_EXTRA BIT(11)
|
||||
#define HAL_RX_HE_SIG_A_MU_DL_INFO_INFO1_STBC BIT(12)
|
||||
#define HAL_RX_HE_SIG_A_MU_DL_INFO_INFO1_TXBF BIT(10)
|
||||
#define HAL_RX_HE_SIG_A_MU_DL_INFO_INFO1_PKT_EXT_FACTOR GENMASK(14, 13)
|
||||
#define HAL_RX_HE_SIG_A_MU_DL_INFO_INFO1_PKT_EXT_PE_DISAM BIT(15)
|
||||
|
||||
struct hal_rx_he_sig_a_mu_dl_info {
|
||||
__le32 info0;
|
||||
|
@ -243,6 +365,7 @@ struct hal_rx_he_sig_b1_mu_info {
|
|||
__le32 info0;
|
||||
} __packed;
|
||||
|
||||
#define HAL_RX_HE_SIG_B2_MU_INFO_INFO0_STA_ID GENMASK(10, 0)
|
||||
#define HAL_RX_HE_SIG_B2_MU_INFO_INFO0_STA_MCS GENMASK(18, 15)
|
||||
#define HAL_RX_HE_SIG_B2_MU_INFO_INFO0_STA_CODING BIT(20)
|
||||
#define HAL_RX_HE_SIG_B2_MU_INFO_INFO0_STA_NSTS GENMASK(31, 29)
|
||||
|
@ -251,6 +374,7 @@ struct hal_rx_he_sig_b2_mu_info {
|
|||
__le32 info0;
|
||||
} __packed;
|
||||
|
||||
#define HAL_RX_HE_SIG_B2_OFDMA_INFO_INFO0_STA_ID GENMASK(10, 0)
|
||||
#define HAL_RX_HE_SIG_B2_OFDMA_INFO_INFO0_STA_NSTS GENMASK(13, 11)
|
||||
#define HAL_RX_HE_SIG_B2_OFDMA_INFO_INFO0_STA_TXBF BIT(19)
|
||||
#define HAL_RX_HE_SIG_B2_OFDMA_INFO_INFO0_STA_MCS GENMASK(18, 15)
|
||||
|
@ -279,11 +403,14 @@ struct hal_rx_phyrx_rssi_legacy_info {
|
|||
|
||||
#define HAL_RX_MPDU_INFO_INFO0_PEERID GENMASK(31, 16)
|
||||
#define HAL_RX_MPDU_INFO_INFO0_PEERID_WCN6855 GENMASK(15, 0)
|
||||
#define HAL_RX_MPDU_INFO_INFO1_MPDU_LEN GENMASK(13, 0)
|
||||
|
||||
struct hal_rx_mpdu_info {
|
||||
__le32 rsvd0;
|
||||
__le32 info0;
|
||||
__le32 rsvd1[21];
|
||||
__le32 rsvd1[11];
|
||||
__le32 info1;
|
||||
__le32 rsvd2[9];
|
||||
} __packed;
|
||||
|
||||
struct hal_rx_mpdu_info_wcn6855 {
|
||||
|
|
|
@ -813,6 +813,12 @@ static u16 ath11k_hw_wcn6855_mpdu_info_get_peerid(u8 *tlv_data)
|
|||
return peer_id;
|
||||
}
|
||||
|
||||
static bool ath11k_hw_wcn6855_rx_desc_get_ldpc_support(struct hal_rx_desc *desc)
|
||||
{
|
||||
return FIELD_GET(RX_MSDU_START_INFO2_LDPC,
|
||||
__le32_to_cpu(desc->u.wcn6855.msdu_start.info2));
|
||||
}
|
||||
|
||||
const struct ath11k_hw_ops ipq8074_ops = {
|
||||
.get_hw_mac_from_pdev_id = ath11k_hw_ipq8074_mac_from_pdev_id,
|
||||
.wmi_init_config = ath11k_init_wmi_config_ipq8074,
|
||||
|
@ -983,6 +989,7 @@ const struct ath11k_hw_ops wcn6855_ops = {
|
|||
.rx_desc_get_encrypt_type = ath11k_hw_wcn6855_rx_desc_get_encrypt_type,
|
||||
.rx_desc_get_decap_type = ath11k_hw_wcn6855_rx_desc_get_decap_type,
|
||||
.rx_desc_get_mesh_ctl = ath11k_hw_wcn6855_rx_desc_get_mesh_ctl,
|
||||
.rx_desc_get_ldpc_support = ath11k_hw_wcn6855_rx_desc_get_ldpc_support,
|
||||
.rx_desc_get_mpdu_seq_ctl_vld = ath11k_hw_wcn6855_rx_desc_get_mpdu_seq_ctl_vld,
|
||||
.rx_desc_get_mpdu_fc_valid = ath11k_hw_wcn6855_rx_desc_get_mpdu_fc_valid,
|
||||
.rx_desc_get_mpdu_start_seq_no = ath11k_hw_wcn6855_rx_desc_get_mpdu_start_seq_no,
|
||||
|
|
|
@ -193,6 +193,7 @@ struct ath11k_hw_params {
|
|||
bool supports_rssi_stats;
|
||||
bool fw_wmi_diag_event;
|
||||
bool current_cc_support;
|
||||
bool dbr_debug_support;
|
||||
};
|
||||
|
||||
struct ath11k_hw_ops {
|
||||
|
|
|
@ -5579,7 +5579,7 @@ static int ath11k_mac_mgmt_tx(struct ath11k *ar, struct sk_buff *skb,
|
|||
|
||||
skb_queue_tail(q, skb);
|
||||
atomic_inc(&ar->num_pending_mgmt_tx);
|
||||
ieee80211_queue_work(ar->hw, &ar->wmi_mgmt_tx_work);
|
||||
queue_work(ar->ab->workqueue, &ar->wmi_mgmt_tx_work);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -6354,6 +6354,10 @@ static int ath11k_mac_op_add_interface(struct ieee80211_hw *hw,
|
|||
}
|
||||
}
|
||||
|
||||
ret = ath11k_debugfs_add_interface(arvif);
|
||||
if (ret)
|
||||
goto err_peer_del;
|
||||
|
||||
mutex_unlock(&ar->conf_mutex);
|
||||
|
||||
return 0;
|
||||
|
@ -6388,6 +6392,7 @@ err_vdev_del:
|
|||
spin_unlock_bh(&ar->data_lock);
|
||||
|
||||
err:
|
||||
ath11k_debugfs_remove_interface(arvif);
|
||||
mutex_unlock(&ar->conf_mutex);
|
||||
|
||||
return ret;
|
||||
|
@ -6486,6 +6491,8 @@ err_vdev_del:
|
|||
/* Recalc txpower for remaining vdev */
|
||||
ath11k_mac_txpower_recalc(ar);
|
||||
|
||||
ath11k_debugfs_remove_interface(arvif);
|
||||
|
||||
/* TODO: recal traffic pause state based on the available vdevs */
|
||||
|
||||
mutex_unlock(&ar->conf_mutex);
|
||||
|
@ -6623,12 +6630,13 @@ static void ath11k_mac_op_remove_chanctx(struct ieee80211_hw *hw,
|
|||
|
||||
static int
|
||||
ath11k_mac_vdev_start_restart(struct ath11k_vif *arvif,
|
||||
const struct cfg80211_chan_def *chandef,
|
||||
struct ieee80211_chanctx_conf *ctx,
|
||||
bool restart)
|
||||
{
|
||||
struct ath11k *ar = arvif->ar;
|
||||
struct ath11k_base *ab = ar->ab;
|
||||
struct wmi_vdev_start_req_arg arg = {};
|
||||
const struct cfg80211_chan_def *chandef = &ctx->def;
|
||||
int he_support = arvif->vif->bss_conf.he_support;
|
||||
int ret = 0;
|
||||
|
||||
|
@ -6663,8 +6671,7 @@ ath11k_mac_vdev_start_restart(struct ath11k_vif *arvif,
|
|||
arg.channel.chan_radar =
|
||||
!!(chandef->chan->flags & IEEE80211_CHAN_RADAR);
|
||||
|
||||
arg.channel.freq2_radar =
|
||||
!!(chandef->chan->flags & IEEE80211_CHAN_RADAR);
|
||||
arg.channel.freq2_radar = ctx->radar_enabled;
|
||||
|
||||
arg.channel.passive = arg.channel.chan_radar;
|
||||
|
||||
|
@ -6774,15 +6781,15 @@ err:
|
|||
}
|
||||
|
||||
static int ath11k_mac_vdev_start(struct ath11k_vif *arvif,
|
||||
const struct cfg80211_chan_def *chandef)
|
||||
struct ieee80211_chanctx_conf *ctx)
|
||||
{
|
||||
return ath11k_mac_vdev_start_restart(arvif, chandef, false);
|
||||
return ath11k_mac_vdev_start_restart(arvif, ctx, false);
|
||||
}
|
||||
|
||||
static int ath11k_mac_vdev_restart(struct ath11k_vif *arvif,
|
||||
const struct cfg80211_chan_def *chandef)
|
||||
struct ieee80211_chanctx_conf *ctx)
|
||||
{
|
||||
return ath11k_mac_vdev_start_restart(arvif, chandef, true);
|
||||
return ath11k_mac_vdev_start_restart(arvif, ctx, true);
|
||||
}
|
||||
|
||||
struct ath11k_mac_change_chanctx_arg {
|
||||
|
@ -6849,13 +6856,33 @@ ath11k_mac_update_vif_chan(struct ath11k *ar,
|
|||
if (WARN_ON(!arvif->is_started))
|
||||
continue;
|
||||
|
||||
if (WARN_ON(!arvif->is_up))
|
||||
continue;
|
||||
/* change_chanctx can be called even before vdev_up from
|
||||
* ieee80211_start_ap->ieee80211_vif_use_channel->
|
||||
* ieee80211_recalc_radar_chanctx.
|
||||
*
|
||||
* Firmware expect vdev_restart only if vdev is up.
|
||||
* If vdev is down then it expect vdev_stop->vdev_start.
|
||||
*/
|
||||
if (arvif->is_up) {
|
||||
ret = ath11k_mac_vdev_restart(arvif, vifs[i].new_ctx);
|
||||
if (ret) {
|
||||
ath11k_warn(ab, "failed to restart vdev %d: %d\n",
|
||||
arvif->vdev_id, ret);
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
ret = ath11k_mac_vdev_stop(arvif);
|
||||
if (ret) {
|
||||
ath11k_warn(ab, "failed to stop vdev %d: %d\n",
|
||||
arvif->vdev_id, ret);
|
||||
continue;
|
||||
}
|
||||
|
||||
ret = ath11k_mac_vdev_start(arvif, vifs[i].new_ctx);
|
||||
if (ret)
|
||||
ath11k_warn(ab, "failed to start vdev %d: %d\n",
|
||||
arvif->vdev_id, ret);
|
||||
|
||||
ret = ath11k_mac_vdev_restart(arvif, &vifs[i].new_ctx->def);
|
||||
if (ret) {
|
||||
ath11k_warn(ab, "failed to restart vdev %d: %d\n",
|
||||
arvif->vdev_id, ret);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -6940,7 +6967,8 @@ static void ath11k_mac_op_change_chanctx(struct ieee80211_hw *hw,
|
|||
if (WARN_ON(changed & IEEE80211_CHANCTX_CHANGE_CHANNEL))
|
||||
goto unlock;
|
||||
|
||||
if (changed & IEEE80211_CHANCTX_CHANGE_WIDTH)
|
||||
if (changed & IEEE80211_CHANCTX_CHANGE_WIDTH ||
|
||||
changed & IEEE80211_CHANCTX_CHANGE_RADAR)
|
||||
ath11k_mac_update_active_vif_chan(ar, ctx);
|
||||
|
||||
/* TODO: Recalc radar detection */
|
||||
|
@ -6960,7 +6988,7 @@ static int ath11k_start_vdev_delay(struct ieee80211_hw *hw,
|
|||
if (WARN_ON(arvif->is_started))
|
||||
return -EBUSY;
|
||||
|
||||
ret = ath11k_mac_vdev_start(arvif, &arvif->chanctx.def);
|
||||
ret = ath11k_mac_vdev_start(arvif, &arvif->chanctx);
|
||||
if (ret) {
|
||||
ath11k_warn(ab, "failed to start vdev %i addr %pM on freq %d: %d\n",
|
||||
arvif->vdev_id, vif->addr,
|
||||
|
@ -7054,7 +7082,7 @@ ath11k_mac_op_assign_vif_chanctx(struct ieee80211_hw *hw,
|
|||
goto out;
|
||||
}
|
||||
|
||||
ret = ath11k_mac_vdev_start(arvif, &ctx->def);
|
||||
ret = ath11k_mac_vdev_start(arvif, ctx);
|
||||
if (ret) {
|
||||
ath11k_warn(ab, "failed to start vdev %i addr %pM on freq %d: %d\n",
|
||||
arvif->vdev_id, vif->addr,
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#include "pci.h"
|
||||
|
||||
#define MHI_TIMEOUT_DEFAULT_MS 90000
|
||||
#define RDDM_DUMP_SIZE 0x420000
|
||||
|
||||
static struct mhi_channel_config ath11k_mhi_channels_qca6390[] = {
|
||||
{
|
||||
|
@ -382,6 +383,7 @@ int ath11k_mhi_register(struct ath11k_pci *ab_pci)
|
|||
mhi_ctrl->iova_stop = 0xFFFFFFFF;
|
||||
}
|
||||
|
||||
mhi_ctrl->rddm_size = RDDM_DUMP_SIZE;
|
||||
mhi_ctrl->sbl_size = SZ_512K;
|
||||
mhi_ctrl->seg_len = SZ_512K;
|
||||
mhi_ctrl->fbc_download = true;
|
||||
|
@ -561,7 +563,7 @@ static int ath11k_mhi_set_state(struct ath11k_pci *ab_pci,
|
|||
ret = 0;
|
||||
break;
|
||||
case ATH11K_MHI_POWER_ON:
|
||||
ret = mhi_async_power_up(ab_pci->mhi_ctrl);
|
||||
ret = mhi_sync_power_up(ab_pci->mhi_ctrl);
|
||||
break;
|
||||
case ATH11K_MHI_POWER_OFF:
|
||||
mhi_power_down(ab_pci->mhi_ctrl, true);
|
||||
|
|
|
@ -1571,6 +1571,11 @@ static __maybe_unused int ath11k_pci_pm_suspend(struct device *dev)
|
|||
struct ath11k_base *ab = dev_get_drvdata(dev);
|
||||
int ret;
|
||||
|
||||
if (test_bit(ATH11K_FLAG_QMI_FAIL, &ab->dev_flags)) {
|
||||
ath11k_dbg(ab, ATH11K_DBG_BOOT, "boot skipping pci suspend as qmi is not initialised\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
ret = ath11k_core_suspend(ab);
|
||||
if (ret)
|
||||
ath11k_warn(ab, "failed to suspend core: %d\n", ret);
|
||||
|
@ -1583,6 +1588,11 @@ static __maybe_unused int ath11k_pci_pm_resume(struct device *dev)
|
|||
struct ath11k_base *ab = dev_get_drvdata(dev);
|
||||
int ret;
|
||||
|
||||
if (test_bit(ATH11K_FLAG_QMI_FAIL, &ab->dev_flags)) {
|
||||
ath11k_dbg(ab, ATH11K_DBG_BOOT, "boot skipping pci resume as qmi is not initialised\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
ret = ath11k_core_resume(ab);
|
||||
if (ret)
|
||||
ath11k_warn(ab, "failed to resume core: %d\n", ret);
|
||||
|
|
|
@ -2342,6 +2342,7 @@ static void ath11k_qmi_m3_free(struct ath11k_base *ab)
|
|||
dma_free_coherent(ab->dev, m3_mem->size,
|
||||
m3_mem->vaddr, m3_mem->paddr);
|
||||
m3_mem->vaddr = NULL;
|
||||
m3_mem->size = 0;
|
||||
}
|
||||
|
||||
static int ath11k_qmi_wlanfw_m3_info_send(struct ath11k_base *ab)
|
||||
|
@ -2959,7 +2960,11 @@ static void ath11k_qmi_driver_event_work(struct work_struct *work)
|
|||
clear_bit(ATH11K_FLAG_CRASH_FLUSH,
|
||||
&ab->dev_flags);
|
||||
clear_bit(ATH11K_FLAG_RECOVERY, &ab->dev_flags);
|
||||
ath11k_core_qmi_firmware_ready(ab);
|
||||
ret = ath11k_core_qmi_firmware_ready(ab);
|
||||
if (ret) {
|
||||
set_bit(ATH11K_FLAG_QMI_FAIL, &ab->dev_flags);
|
||||
break;
|
||||
}
|
||||
set_bit(ATH11K_FLAG_REGISTERED, &ab->dev_flags);
|
||||
}
|
||||
|
||||
|
@ -3025,3 +3030,8 @@ void ath11k_qmi_deinit_service(struct ath11k_base *ab)
|
|||
}
|
||||
EXPORT_SYMBOL(ath11k_qmi_deinit_service);
|
||||
|
||||
void ath11k_qmi_free_resource(struct ath11k_base *ab)
|
||||
{
|
||||
ath11k_qmi_free_target_mem_chunk(ab);
|
||||
ath11k_qmi_m3_free(ab);
|
||||
}
|
||||
|
|
|
@ -492,5 +492,6 @@ void ath11k_qmi_event_work(struct work_struct *work);
|
|||
void ath11k_qmi_msg_recv_work(struct work_struct *work);
|
||||
void ath11k_qmi_deinit_service(struct ath11k_base *ab);
|
||||
int ath11k_qmi_init_service(struct ath11k_base *ab);
|
||||
void ath11k_qmi_free_resource(struct ath11k_base *ab);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1445,7 +1445,7 @@ struct hal_rx_desc_ipq8074 {
|
|||
__le32 hdr_status_tag;
|
||||
__le32 phy_ppdu_id;
|
||||
u8 hdr_status[HAL_RX_DESC_HDR_STATUS_LEN];
|
||||
u8 msdu_payload[0];
|
||||
u8 msdu_payload[];
|
||||
} __packed;
|
||||
|
||||
struct hal_rx_desc_qcn9074 {
|
||||
|
@ -1464,7 +1464,7 @@ struct hal_rx_desc_qcn9074 {
|
|||
__le32 hdr_status_tag;
|
||||
__le32 phy_ppdu_id;
|
||||
u8 hdr_status[HAL_RX_DESC_HDR_STATUS_LEN];
|
||||
u8 msdu_payload[0];
|
||||
u8 msdu_payload[];
|
||||
} __packed;
|
||||
|
||||
struct hal_rx_desc_wcn6855 {
|
||||
|
@ -1483,7 +1483,7 @@ struct hal_rx_desc_wcn6855 {
|
|||
__le32 hdr_status_tag;
|
||||
__le32 phy_ppdu_id;
|
||||
u8 hdr_status[HAL_RX_DESC_HDR_STATUS_LEN];
|
||||
u8 msdu_payload[0];
|
||||
u8 msdu_payload[];
|
||||
} __packed;
|
||||
|
||||
struct hal_rx_desc {
|
||||
|
|
|
@ -107,7 +107,7 @@ struct spectral_search_fft_report {
|
|||
__le32 info1;
|
||||
__le32 info2;
|
||||
__le32 reserve0;
|
||||
u8 bins[0];
|
||||
u8 bins[];
|
||||
} __packed;
|
||||
|
||||
struct ath11k_spectral_search_report {
|
||||
|
|
|
@ -144,6 +144,8 @@ static const struct wmi_tlv_policy wmi_tlv_policies[] = {
|
|||
.min_len = sizeof(struct wmi_11d_new_cc_ev) },
|
||||
[WMI_TAG_PER_CHAIN_RSSI_STATS] = {
|
||||
.min_len = sizeof(struct wmi_per_chain_rssi_stats) },
|
||||
[WMI_TAG_TWT_ADD_DIALOG_COMPLETE_EVENT] = {
|
||||
.min_len = sizeof(struct wmi_twt_add_dialog_event) },
|
||||
};
|
||||
|
||||
#define PRIMAP(_hw_mode_) \
|
||||
|
@ -3085,11 +3087,12 @@ ath11k_wmi_send_twt_enable_cmd(struct ath11k *ar, u32 pdev_id)
|
|||
/* TODO add MBSSID support */
|
||||
cmd->mbss_support = 0;
|
||||
|
||||
ret = ath11k_wmi_cmd_send(wmi, skb,
|
||||
WMI_TWT_ENABLE_CMDID);
|
||||
ret = ath11k_wmi_cmd_send(wmi, skb, WMI_TWT_ENABLE_CMDID);
|
||||
if (ret) {
|
||||
ath11k_warn(ab, "Failed to send WMI_TWT_ENABLE_CMDID");
|
||||
dev_kfree_skb(skb);
|
||||
} else {
|
||||
ar->twt_enabled = 1;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
@ -3114,11 +3117,181 @@ ath11k_wmi_send_twt_disable_cmd(struct ath11k *ar, u32 pdev_id)
|
|||
FIELD_PREP(WMI_TLV_LEN, len - TLV_HDR_SIZE);
|
||||
cmd->pdev_id = pdev_id;
|
||||
|
||||
ret = ath11k_wmi_cmd_send(wmi, skb,
|
||||
WMI_TWT_DISABLE_CMDID);
|
||||
ret = ath11k_wmi_cmd_send(wmi, skb, WMI_TWT_DISABLE_CMDID);
|
||||
if (ret) {
|
||||
ath11k_warn(ab, "Failed to send WMI_TWT_DISABLE_CMDID");
|
||||
dev_kfree_skb(skb);
|
||||
} else {
|
||||
ar->twt_enabled = 0;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ath11k_wmi_send_twt_add_dialog_cmd(struct ath11k *ar,
|
||||
struct wmi_twt_add_dialog_params *params)
|
||||
{
|
||||
struct ath11k_pdev_wmi *wmi = ar->wmi;
|
||||
struct ath11k_base *ab = wmi->wmi_ab->ab;
|
||||
struct wmi_twt_add_dialog_params_cmd *cmd;
|
||||
struct sk_buff *skb;
|
||||
int ret, len;
|
||||
|
||||
len = sizeof(*cmd);
|
||||
|
||||
skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, len);
|
||||
if (!skb)
|
||||
return -ENOMEM;
|
||||
|
||||
cmd = (struct wmi_twt_add_dialog_params_cmd *)skb->data;
|
||||
cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_TWT_ADD_DIALOG_CMD) |
|
||||
FIELD_PREP(WMI_TLV_LEN, len - TLV_HDR_SIZE);
|
||||
|
||||
cmd->vdev_id = params->vdev_id;
|
||||
ether_addr_copy(cmd->peer_macaddr.addr, params->peer_macaddr);
|
||||
cmd->dialog_id = params->dialog_id;
|
||||
cmd->wake_intvl_us = params->wake_intvl_us;
|
||||
cmd->wake_intvl_mantis = params->wake_intvl_mantis;
|
||||
cmd->wake_dura_us = params->wake_dura_us;
|
||||
cmd->sp_offset_us = params->sp_offset_us;
|
||||
cmd->flags = params->twt_cmd;
|
||||
if (params->flag_bcast)
|
||||
cmd->flags |= WMI_TWT_ADD_DIALOG_FLAG_BCAST;
|
||||
if (params->flag_trigger)
|
||||
cmd->flags |= WMI_TWT_ADD_DIALOG_FLAG_TRIGGER;
|
||||
if (params->flag_flow_type)
|
||||
cmd->flags |= WMI_TWT_ADD_DIALOG_FLAG_FLOW_TYPE;
|
||||
if (params->flag_protection)
|
||||
cmd->flags |= WMI_TWT_ADD_DIALOG_FLAG_PROTECTION;
|
||||
|
||||
ath11k_dbg(ar->ab, ATH11K_DBG_WMI,
|
||||
"wmi add twt dialog vdev %u dialog id %u wake interval %u mantissa %u wake duration %u service period offset %u flags 0x%x\n",
|
||||
cmd->vdev_id, cmd->dialog_id, cmd->wake_intvl_us,
|
||||
cmd->wake_intvl_mantis, cmd->wake_dura_us, cmd->sp_offset_us,
|
||||
cmd->flags);
|
||||
|
||||
ret = ath11k_wmi_cmd_send(wmi, skb, WMI_TWT_ADD_DIALOG_CMDID);
|
||||
|
||||
if (ret) {
|
||||
ath11k_warn(ab,
|
||||
"failed to send wmi command to add twt dialog: %d",
|
||||
ret);
|
||||
dev_kfree_skb(skb);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ath11k_wmi_send_twt_del_dialog_cmd(struct ath11k *ar,
|
||||
struct wmi_twt_del_dialog_params *params)
|
||||
{
|
||||
struct ath11k_pdev_wmi *wmi = ar->wmi;
|
||||
struct ath11k_base *ab = wmi->wmi_ab->ab;
|
||||
struct wmi_twt_del_dialog_params_cmd *cmd;
|
||||
struct sk_buff *skb;
|
||||
int ret, len;
|
||||
|
||||
len = sizeof(*cmd);
|
||||
|
||||
skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, len);
|
||||
if (!skb)
|
||||
return -ENOMEM;
|
||||
|
||||
cmd = (struct wmi_twt_del_dialog_params_cmd *)skb->data;
|
||||
cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_TWT_DEL_DIALOG_CMD) |
|
||||
FIELD_PREP(WMI_TLV_LEN, len - TLV_HDR_SIZE);
|
||||
|
||||
cmd->vdev_id = params->vdev_id;
|
||||
ether_addr_copy(cmd->peer_macaddr.addr, params->peer_macaddr);
|
||||
cmd->dialog_id = params->dialog_id;
|
||||
|
||||
ath11k_dbg(ar->ab, ATH11K_DBG_WMI,
|
||||
"wmi delete twt dialog vdev %u dialog id %u\n",
|
||||
cmd->vdev_id, cmd->dialog_id);
|
||||
|
||||
ret = ath11k_wmi_cmd_send(wmi, skb, WMI_TWT_DEL_DIALOG_CMDID);
|
||||
if (ret) {
|
||||
ath11k_warn(ab,
|
||||
"failed to send wmi command to delete twt dialog: %d",
|
||||
ret);
|
||||
dev_kfree_skb(skb);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ath11k_wmi_send_twt_pause_dialog_cmd(struct ath11k *ar,
|
||||
struct wmi_twt_pause_dialog_params *params)
|
||||
{
|
||||
struct ath11k_pdev_wmi *wmi = ar->wmi;
|
||||
struct ath11k_base *ab = wmi->wmi_ab->ab;
|
||||
struct wmi_twt_pause_dialog_params_cmd *cmd;
|
||||
struct sk_buff *skb;
|
||||
int ret, len;
|
||||
|
||||
len = sizeof(*cmd);
|
||||
|
||||
skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, len);
|
||||
if (!skb)
|
||||
return -ENOMEM;
|
||||
|
||||
cmd = (struct wmi_twt_pause_dialog_params_cmd *)skb->data;
|
||||
cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG,
|
||||
WMI_TAG_TWT_PAUSE_DIALOG_CMD) |
|
||||
FIELD_PREP(WMI_TLV_LEN, len - TLV_HDR_SIZE);
|
||||
|
||||
cmd->vdev_id = params->vdev_id;
|
||||
ether_addr_copy(cmd->peer_macaddr.addr, params->peer_macaddr);
|
||||
cmd->dialog_id = params->dialog_id;
|
||||
|
||||
ath11k_dbg(ar->ab, ATH11K_DBG_WMI,
|
||||
"wmi pause twt dialog vdev %u dialog id %u\n",
|
||||
cmd->vdev_id, cmd->dialog_id);
|
||||
|
||||
ret = ath11k_wmi_cmd_send(wmi, skb, WMI_TWT_PAUSE_DIALOG_CMDID);
|
||||
if (ret) {
|
||||
ath11k_warn(ab,
|
||||
"failed to send wmi command to pause twt dialog: %d",
|
||||
ret);
|
||||
dev_kfree_skb(skb);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ath11k_wmi_send_twt_resume_dialog_cmd(struct ath11k *ar,
|
||||
struct wmi_twt_resume_dialog_params *params)
|
||||
{
|
||||
struct ath11k_pdev_wmi *wmi = ar->wmi;
|
||||
struct ath11k_base *ab = wmi->wmi_ab->ab;
|
||||
struct wmi_twt_resume_dialog_params_cmd *cmd;
|
||||
struct sk_buff *skb;
|
||||
int ret, len;
|
||||
|
||||
len = sizeof(*cmd);
|
||||
|
||||
skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, len);
|
||||
if (!skb)
|
||||
return -ENOMEM;
|
||||
|
||||
cmd = (struct wmi_twt_resume_dialog_params_cmd *)skb->data;
|
||||
cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG,
|
||||
WMI_TAG_TWT_RESUME_DIALOG_CMD) |
|
||||
FIELD_PREP(WMI_TLV_LEN, len - TLV_HDR_SIZE);
|
||||
|
||||
cmd->vdev_id = params->vdev_id;
|
||||
ether_addr_copy(cmd->peer_macaddr.addr, params->peer_macaddr);
|
||||
cmd->dialog_id = params->dialog_id;
|
||||
cmd->sp_offset_us = params->sp_offset_us;
|
||||
cmd->next_twt_size = params->next_twt_size;
|
||||
|
||||
ath11k_dbg(ar->ab, ATH11K_DBG_WMI,
|
||||
"wmi resume twt dialog vdev %u dialog id %u service period offset %u next twt subfield size %u\n",
|
||||
cmd->vdev_id, cmd->dialog_id, cmd->sp_offset_us,
|
||||
cmd->next_twt_size);
|
||||
|
||||
ret = ath11k_wmi_cmd_send(wmi, skb, WMI_TWT_RESUME_DIALOG_CMDID);
|
||||
if (ret) {
|
||||
ath11k_warn(ab,
|
||||
"failed to send wmi command to resume twt dialog: %d",
|
||||
ret);
|
||||
dev_kfree_skb(skb);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
@ -7532,6 +7705,66 @@ ath11k_wmi_diag_event(struct ath11k_base *ab,
|
|||
trace_ath11k_wmi_diag(ab, skb->data, skb->len);
|
||||
}
|
||||
|
||||
static const char *ath11k_wmi_twt_add_dialog_event_status(u32 status)
|
||||
{
|
||||
switch (status) {
|
||||
case WMI_ADD_TWT_STATUS_OK:
|
||||
return "ok";
|
||||
case WMI_ADD_TWT_STATUS_TWT_NOT_ENABLED:
|
||||
return "twt disabled";
|
||||
case WMI_ADD_TWT_STATUS_USED_DIALOG_ID:
|
||||
return "dialog id in use";
|
||||
case WMI_ADD_TWT_STATUS_INVALID_PARAM:
|
||||
return "invalid parameters";
|
||||
case WMI_ADD_TWT_STATUS_NOT_READY:
|
||||
return "not ready";
|
||||
case WMI_ADD_TWT_STATUS_NO_RESOURCE:
|
||||
return "resource unavailable";
|
||||
case WMI_ADD_TWT_STATUS_NO_ACK:
|
||||
return "no ack";
|
||||
case WMI_ADD_TWT_STATUS_NO_RESPONSE:
|
||||
return "no response";
|
||||
case WMI_ADD_TWT_STATUS_DENIED:
|
||||
return "denied";
|
||||
case WMI_ADD_TWT_STATUS_UNKNOWN_ERROR:
|
||||
fallthrough;
|
||||
default:
|
||||
return "unknown error";
|
||||
}
|
||||
}
|
||||
|
||||
static void ath11k_wmi_twt_add_dialog_event(struct ath11k_base *ab,
|
||||
struct sk_buff *skb)
|
||||
{
|
||||
const void **tb;
|
||||
const struct wmi_twt_add_dialog_event *ev;
|
||||
int ret;
|
||||
|
||||
tb = ath11k_wmi_tlv_parse_alloc(ab, skb->data, skb->len, GFP_ATOMIC);
|
||||
if (IS_ERR(tb)) {
|
||||
ret = PTR_ERR(tb);
|
||||
ath11k_warn(ab,
|
||||
"failed to parse wmi twt add dialog status event tlv: %d\n",
|
||||
ret);
|
||||
return;
|
||||
}
|
||||
|
||||
ev = tb[WMI_TAG_TWT_ADD_DIALOG_COMPLETE_EVENT];
|
||||
if (!ev) {
|
||||
ath11k_warn(ab, "failed to fetch twt add dialog wmi event\n");
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (ev->status)
|
||||
ath11k_warn(ab,
|
||||
"wmi add twt dialog event vdev %d dialog id %d status %s\n",
|
||||
ev->vdev_id, ev->dialog_id,
|
||||
ath11k_wmi_twt_add_dialog_event_status(ev->status));
|
||||
|
||||
exit:
|
||||
kfree(tb);
|
||||
}
|
||||
|
||||
static void ath11k_wmi_tlv_op_rx(struct ath11k_base *ab, struct sk_buff *skb)
|
||||
{
|
||||
struct wmi_cmd_hdr *cmd_hdr;
|
||||
|
@ -7629,11 +7862,17 @@ static void ath11k_wmi_tlv_op_rx(struct ath11k_base *ab, struct sk_buff *skb)
|
|||
case WMI_OBSS_COLOR_COLLISION_DETECTION_EVENTID:
|
||||
ath11k_wmi_obss_color_collision_event(ab, skb);
|
||||
break;
|
||||
case WMI_TWT_ADD_DIALOG_EVENTID:
|
||||
ath11k_wmi_twt_add_dialog_event(ab, skb);
|
||||
break;
|
||||
/* add Unsupported events here */
|
||||
case WMI_TBTTOFFSET_EXT_UPDATE_EVENTID:
|
||||
case WMI_PEER_OPER_MODE_CHANGE_EVENTID:
|
||||
case WMI_TWT_ENABLE_EVENTID:
|
||||
case WMI_TWT_DISABLE_EVENTID:
|
||||
case WMI_TWT_DEL_DIALOG_EVENTID:
|
||||
case WMI_TWT_PAUSE_DIALOG_EVENTID:
|
||||
case WMI_TWT_RESUME_DIALOG_EVENTID:
|
||||
case WMI_PDEV_DMA_RING_CFG_RSP_EVENTID:
|
||||
case WMI_PEER_CREATE_CONF_EVENTID:
|
||||
ath11k_dbg(ab, ATH11K_DBG_WMI,
|
||||
|
@ -7798,6 +8037,59 @@ int ath11k_wmi_simulate_radar(struct ath11k *ar)
|
|||
return ath11k_wmi_send_unit_test_cmd(ar, wmi_ut, dfs_args);
|
||||
}
|
||||
|
||||
int ath11k_wmi_fw_dbglog_cfg(struct ath11k *ar, u32 *module_id_bitmap,
|
||||
struct ath11k_fw_dbglog *dbglog)
|
||||
{
|
||||
struct ath11k_pdev_wmi *wmi = ar->wmi;
|
||||
struct wmi_debug_log_config_cmd_fixed_param *cmd;
|
||||
struct sk_buff *skb;
|
||||
struct wmi_tlv *tlv;
|
||||
int ret, len;
|
||||
|
||||
len = sizeof(*cmd) + TLV_HDR_SIZE + (MAX_MODULE_ID_BITMAP_WORDS * sizeof(u32));
|
||||
skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, len);
|
||||
if (!skb)
|
||||
return -ENOMEM;
|
||||
|
||||
cmd = (struct wmi_debug_log_config_cmd_fixed_param *)skb->data;
|
||||
cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_DEBUG_LOG_CONFIG_CMD) |
|
||||
FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE);
|
||||
cmd->dbg_log_param = dbglog->param;
|
||||
|
||||
tlv = (struct wmi_tlv *)((u8 *)cmd + sizeof(*cmd));
|
||||
tlv->header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_ARRAY_UINT32) |
|
||||
FIELD_PREP(WMI_TLV_LEN, MAX_MODULE_ID_BITMAP_WORDS * sizeof(u32));
|
||||
|
||||
switch (dbglog->param) {
|
||||
case WMI_DEBUG_LOG_PARAM_LOG_LEVEL:
|
||||
case WMI_DEBUG_LOG_PARAM_VDEV_ENABLE:
|
||||
case WMI_DEBUG_LOG_PARAM_VDEV_DISABLE:
|
||||
case WMI_DEBUG_LOG_PARAM_VDEV_ENABLE_BITMAP:
|
||||
cmd->value = dbglog->value;
|
||||
break;
|
||||
case WMI_DEBUG_LOG_PARAM_MOD_ENABLE_BITMAP:
|
||||
case WMI_DEBUG_LOG_PARAM_WOW_MOD_ENABLE_BITMAP:
|
||||
cmd->value = dbglog->value;
|
||||
memcpy(tlv->value, module_id_bitmap,
|
||||
MAX_MODULE_ID_BITMAP_WORDS * sizeof(u32));
|
||||
/* clear current config to be used for next user config */
|
||||
memset(module_id_bitmap, 0,
|
||||
MAX_MODULE_ID_BITMAP_WORDS * sizeof(u32));
|
||||
break;
|
||||
default:
|
||||
dev_kfree_skb(skb);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ret = ath11k_wmi_cmd_send(wmi, skb, WMI_DBGLOG_CFG_CMDID);
|
||||
if (ret) {
|
||||
ath11k_warn(ar->ab,
|
||||
"failed to send WMI_DBGLOG_CFG_CMDID\n");
|
||||
dev_kfree_skb(skb);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ath11k_wmi_connect(struct ath11k_base *ab)
|
||||
{
|
||||
u32 i;
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
struct ath11k_base;
|
||||
struct ath11k;
|
||||
struct ath11k_fw_stats;
|
||||
struct ath11k_fw_dbglog;
|
||||
|
||||
#define PSOC_HOST_MAX_NUM_SS (8)
|
||||
|
||||
|
@ -4952,6 +4953,112 @@ struct wmi_twt_disable_params_cmd {
|
|||
u32 pdev_id;
|
||||
} __packed;
|
||||
|
||||
enum WMI_HOST_TWT_COMMAND {
|
||||
WMI_HOST_TWT_COMMAND_REQUEST_TWT = 0,
|
||||
WMI_HOST_TWT_COMMAND_SUGGEST_TWT,
|
||||
WMI_HOST_TWT_COMMAND_DEMAND_TWT,
|
||||
WMI_HOST_TWT_COMMAND_TWT_GROUPING,
|
||||
WMI_HOST_TWT_COMMAND_ACCEPT_TWT,
|
||||
WMI_HOST_TWT_COMMAND_ALTERNATE_TWT,
|
||||
WMI_HOST_TWT_COMMAND_DICTATE_TWT,
|
||||
WMI_HOST_TWT_COMMAND_REJECT_TWT,
|
||||
};
|
||||
|
||||
#define WMI_TWT_ADD_DIALOG_FLAG_BCAST BIT(8)
|
||||
#define WMI_TWT_ADD_DIALOG_FLAG_TRIGGER BIT(9)
|
||||
#define WMI_TWT_ADD_DIALOG_FLAG_FLOW_TYPE BIT(10)
|
||||
#define WMI_TWT_ADD_DIALOG_FLAG_PROTECTION BIT(11)
|
||||
|
||||
struct wmi_twt_add_dialog_params_cmd {
|
||||
u32 tlv_header;
|
||||
u32 vdev_id;
|
||||
struct wmi_mac_addr peer_macaddr;
|
||||
u32 dialog_id;
|
||||
u32 wake_intvl_us;
|
||||
u32 wake_intvl_mantis;
|
||||
u32 wake_dura_us;
|
||||
u32 sp_offset_us;
|
||||
u32 flags;
|
||||
} __packed;
|
||||
|
||||
struct wmi_twt_add_dialog_params {
|
||||
u32 vdev_id;
|
||||
u8 peer_macaddr[ETH_ALEN];
|
||||
u32 dialog_id;
|
||||
u32 wake_intvl_us;
|
||||
u32 wake_intvl_mantis;
|
||||
u32 wake_dura_us;
|
||||
u32 sp_offset_us;
|
||||
u8 twt_cmd;
|
||||
u8 flag_bcast;
|
||||
u8 flag_trigger;
|
||||
u8 flag_flow_type;
|
||||
u8 flag_protection;
|
||||
} __packed;
|
||||
|
||||
enum wmi_twt_add_dialog_status {
|
||||
WMI_ADD_TWT_STATUS_OK,
|
||||
WMI_ADD_TWT_STATUS_TWT_NOT_ENABLED,
|
||||
WMI_ADD_TWT_STATUS_USED_DIALOG_ID,
|
||||
WMI_ADD_TWT_STATUS_INVALID_PARAM,
|
||||
WMI_ADD_TWT_STATUS_NOT_READY,
|
||||
WMI_ADD_TWT_STATUS_NO_RESOURCE,
|
||||
WMI_ADD_TWT_STATUS_NO_ACK,
|
||||
WMI_ADD_TWT_STATUS_NO_RESPONSE,
|
||||
WMI_ADD_TWT_STATUS_DENIED,
|
||||
WMI_ADD_TWT_STATUS_UNKNOWN_ERROR,
|
||||
};
|
||||
|
||||
struct wmi_twt_add_dialog_event {
|
||||
u32 vdev_id;
|
||||
struct wmi_mac_addr peer_macaddr;
|
||||
u32 dialog_id;
|
||||
u32 status;
|
||||
} __packed;
|
||||
|
||||
struct wmi_twt_del_dialog_params {
|
||||
u32 vdev_id;
|
||||
u8 peer_macaddr[ETH_ALEN];
|
||||
u32 dialog_id;
|
||||
} __packed;
|
||||
|
||||
struct wmi_twt_del_dialog_params_cmd {
|
||||
u32 tlv_header;
|
||||
u32 vdev_id;
|
||||
struct wmi_mac_addr peer_macaddr;
|
||||
u32 dialog_id;
|
||||
} __packed;
|
||||
|
||||
struct wmi_twt_pause_dialog_params {
|
||||
u32 vdev_id;
|
||||
u8 peer_macaddr[ETH_ALEN];
|
||||
u32 dialog_id;
|
||||
} __packed;
|
||||
|
||||
struct wmi_twt_pause_dialog_params_cmd {
|
||||
u32 tlv_header;
|
||||
u32 vdev_id;
|
||||
struct wmi_mac_addr peer_macaddr;
|
||||
u32 dialog_id;
|
||||
} __packed;
|
||||
|
||||
struct wmi_twt_resume_dialog_params {
|
||||
u32 vdev_id;
|
||||
u8 peer_macaddr[ETH_ALEN];
|
||||
u32 dialog_id;
|
||||
u32 sp_offset_us;
|
||||
u32 next_twt_size;
|
||||
} __packed;
|
||||
|
||||
struct wmi_twt_resume_dialog_params_cmd {
|
||||
u32 tlv_header;
|
||||
u32 vdev_id;
|
||||
struct wmi_mac_addr peer_macaddr;
|
||||
u32 dialog_id;
|
||||
u32 sp_offset_us;
|
||||
u32 next_twt_size;
|
||||
} __packed;
|
||||
|
||||
struct wmi_obss_spatial_reuse_params_cmd {
|
||||
u32 tlv_header;
|
||||
u32 pdev_id;
|
||||
|
@ -5240,6 +5347,21 @@ struct wmi_rfkill_state_change_ev {
|
|||
u32 radio_state;
|
||||
} __packed;
|
||||
|
||||
enum wmi_debug_log_param {
|
||||
WMI_DEBUG_LOG_PARAM_LOG_LEVEL = 0x1,
|
||||
WMI_DEBUG_LOG_PARAM_VDEV_ENABLE,
|
||||
WMI_DEBUG_LOG_PARAM_VDEV_DISABLE,
|
||||
WMI_DEBUG_LOG_PARAM_VDEV_ENABLE_BITMAP,
|
||||
WMI_DEBUG_LOG_PARAM_MOD_ENABLE_BITMAP,
|
||||
WMI_DEBUG_LOG_PARAM_WOW_MOD_ENABLE_BITMAP,
|
||||
};
|
||||
|
||||
struct wmi_debug_log_config_cmd_fixed_param {
|
||||
u32 tlv_header;
|
||||
u32 dbg_log_param;
|
||||
u32 value;
|
||||
} __packed;
|
||||
|
||||
#define WMI_MAX_MEM_REQS 32
|
||||
|
||||
#define MAX_RADIOS 3
|
||||
|
@ -5546,6 +5668,14 @@ void ath11k_wmi_fw_stats_fill(struct ath11k *ar,
|
|||
int ath11k_wmi_simulate_radar(struct ath11k *ar);
|
||||
int ath11k_wmi_send_twt_enable_cmd(struct ath11k *ar, u32 pdev_id);
|
||||
int ath11k_wmi_send_twt_disable_cmd(struct ath11k *ar, u32 pdev_id);
|
||||
int ath11k_wmi_send_twt_add_dialog_cmd(struct ath11k *ar,
|
||||
struct wmi_twt_add_dialog_params *params);
|
||||
int ath11k_wmi_send_twt_del_dialog_cmd(struct ath11k *ar,
|
||||
struct wmi_twt_del_dialog_params *params);
|
||||
int ath11k_wmi_send_twt_pause_dialog_cmd(struct ath11k *ar,
|
||||
struct wmi_twt_pause_dialog_params *params);
|
||||
int ath11k_wmi_send_twt_resume_dialog_cmd(struct ath11k *ar,
|
||||
struct wmi_twt_resume_dialog_params *params);
|
||||
int ath11k_wmi_send_obss_spr_cmd(struct ath11k *ar, u32 vdev_id,
|
||||
struct ieee80211_he_obss_pd *he_obss_pd);
|
||||
int ath11k_wmi_pdev_set_srg_bss_color_bitmap(struct ath11k *ar, u32 *bitmap);
|
||||
|
@ -5582,4 +5712,6 @@ int ath11k_wmi_wow_host_wakeup_ind(struct ath11k *ar);
|
|||
int ath11k_wmi_wow_enable(struct ath11k *ar);
|
||||
int ath11k_wmi_scan_prob_req_oui(struct ath11k *ar,
|
||||
const u8 mac_addr[ETH_ALEN]);
|
||||
int ath11k_wmi_fw_dbglog_cfg(struct ath11k *ar, u32 *module_id_bitmap,
|
||||
struct ath11k_fw_dbglog *dbglog);
|
||||
#endif
|
||||
|
|
|
@ -1637,7 +1637,7 @@ struct bss_bias {
|
|||
|
||||
struct bss_bias_info {
|
||||
u8 num_bss;
|
||||
struct bss_bias bss_bias[0];
|
||||
struct bss_bias bss_bias[];
|
||||
} __packed;
|
||||
|
||||
struct low_rssi_scan_params {
|
||||
|
@ -1720,7 +1720,7 @@ struct wmi_neighbor_info {
|
|||
|
||||
struct wmi_neighbor_report_event {
|
||||
u8 num_neighbors;
|
||||
struct wmi_neighbor_info neighbor[0];
|
||||
struct wmi_neighbor_info neighbor[];
|
||||
} __packed;
|
||||
|
||||
/* TKIP MIC Error Event */
|
||||
|
@ -2051,7 +2051,7 @@ struct wmi_get_keepalive_cmd {
|
|||
struct wmi_set_appie_cmd {
|
||||
u8 mgmt_frm_type; /* enum wmi_mgmt_frame_type */
|
||||
u8 ie_len;
|
||||
u8 ie_info[0];
|
||||
u8 ie_info[];
|
||||
} __packed;
|
||||
|
||||
struct wmi_set_ie_cmd {
|
||||
|
@ -2059,7 +2059,7 @@ struct wmi_set_ie_cmd {
|
|||
u8 ie_field; /* enum wmi_ie_field_type */
|
||||
u8 ie_len;
|
||||
u8 reserved;
|
||||
u8 ie_info[0];
|
||||
u8 ie_info[];
|
||||
} __packed;
|
||||
|
||||
/* Notify the WSC registration status to the target */
|
||||
|
@ -2127,7 +2127,7 @@ struct wmi_add_wow_pattern_cmd {
|
|||
u8 filter_list_id;
|
||||
u8 filter_size;
|
||||
u8 filter_offset;
|
||||
u8 filter[0];
|
||||
u8 filter[];
|
||||
} __packed;
|
||||
|
||||
struct wmi_del_wow_pattern_cmd {
|
||||
|
@ -2360,7 +2360,7 @@ struct wmi_send_action_cmd {
|
|||
__le32 freq;
|
||||
__le32 wait;
|
||||
__le16 len;
|
||||
u8 data[0];
|
||||
u8 data[];
|
||||
} __packed;
|
||||
|
||||
struct wmi_send_mgmt_cmd {
|
||||
|
@ -2369,7 +2369,7 @@ struct wmi_send_mgmt_cmd {
|
|||
__le32 wait;
|
||||
__le32 no_cck;
|
||||
__le16 len;
|
||||
u8 data[0];
|
||||
u8 data[];
|
||||
} __packed;
|
||||
|
||||
struct wmi_tx_status_event {
|
||||
|
@ -2389,7 +2389,7 @@ struct wmi_set_appie_extended_cmd {
|
|||
u8 role_id;
|
||||
u8 mgmt_frm_type;
|
||||
u8 ie_len;
|
||||
u8 ie_info[0];
|
||||
u8 ie_info[];
|
||||
} __packed;
|
||||
|
||||
struct wmi_remain_on_chnl_event {
|
||||
|
@ -2406,18 +2406,18 @@ struct wmi_cancel_remain_on_chnl_event {
|
|||
struct wmi_rx_action_event {
|
||||
__le32 freq;
|
||||
__le16 len;
|
||||
u8 data[0];
|
||||
u8 data[];
|
||||
} __packed;
|
||||
|
||||
struct wmi_p2p_capabilities_event {
|
||||
__le16 len;
|
||||
u8 data[0];
|
||||
u8 data[];
|
||||
} __packed;
|
||||
|
||||
struct wmi_p2p_rx_probe_req_event {
|
||||
__le32 freq;
|
||||
__le16 len;
|
||||
u8 data[0];
|
||||
u8 data[];
|
||||
} __packed;
|
||||
|
||||
#define P2P_FLAG_CAPABILITIES_REQ (0x00000001)
|
||||
|
@ -2431,7 +2431,7 @@ struct wmi_get_p2p_info {
|
|||
struct wmi_p2p_info_event {
|
||||
__le32 info_req_flags;
|
||||
__le16 len;
|
||||
u8 data[0];
|
||||
u8 data[];
|
||||
} __packed;
|
||||
|
||||
struct wmi_p2p_capabilities {
|
||||
|
@ -2450,7 +2450,7 @@ struct wmi_p2p_probe_response_cmd {
|
|||
__le32 freq;
|
||||
u8 destination_addr[ETH_ALEN];
|
||||
__le16 len;
|
||||
u8 data[0];
|
||||
u8 data[];
|
||||
} __packed;
|
||||
|
||||
/* Extended WMI (WMIX)
|
||||
|
|
|
@ -1071,8 +1071,9 @@ struct ath_softc {
|
|||
#endif
|
||||
|
||||
#ifdef CONFIG_ATH9K_HWRNG
|
||||
struct hwrng rng_ops;
|
||||
u32 rng_last;
|
||||
struct task_struct *rng_task;
|
||||
char rng_name[sizeof("ath9k_65535")];
|
||||
#endif
|
||||
};
|
||||
|
||||
|
|
|
@ -21,11 +21,6 @@
|
|||
#include "hw.h"
|
||||
#include "ar9003_phy.h"
|
||||
|
||||
#define ATH9K_RNG_BUF_SIZE 320
|
||||
#define ATH9K_RNG_ENTROPY(x) (((x) * 8 * 10) >> 5) /* quality: 10/32 */
|
||||
|
||||
static DECLARE_WAIT_QUEUE_HEAD(rng_queue);
|
||||
|
||||
static int ath9k_rng_data_read(struct ath_softc *sc, u32 *buf, u32 buf_size)
|
||||
{
|
||||
int i, j;
|
||||
|
@ -71,61 +66,56 @@ static u32 ath9k_rng_delay_get(u32 fail_stats)
|
|||
return delay;
|
||||
}
|
||||
|
||||
static int ath9k_rng_kthread(void *data)
|
||||
static int ath9k_rng_read(struct hwrng *rng, void *buf, size_t max, bool wait)
|
||||
{
|
||||
int bytes_read;
|
||||
struct ath_softc *sc = data;
|
||||
u32 *rng_buf;
|
||||
u32 delay, fail_stats = 0;
|
||||
struct ath_softc *sc = container_of(rng, struct ath_softc, rng_ops);
|
||||
u32 fail_stats = 0, word;
|
||||
int bytes_read = 0;
|
||||
|
||||
rng_buf = kmalloc_array(ATH9K_RNG_BUF_SIZE, sizeof(u32), GFP_KERNEL);
|
||||
if (!rng_buf)
|
||||
goto out;
|
||||
|
||||
while (!kthread_should_stop()) {
|
||||
bytes_read = ath9k_rng_data_read(sc, rng_buf,
|
||||
ATH9K_RNG_BUF_SIZE);
|
||||
if (unlikely(!bytes_read)) {
|
||||
delay = ath9k_rng_delay_get(++fail_stats);
|
||||
wait_event_interruptible_timeout(rng_queue,
|
||||
kthread_should_stop(),
|
||||
msecs_to_jiffies(delay));
|
||||
continue;
|
||||
for (;;) {
|
||||
if (max & ~3UL)
|
||||
bytes_read = ath9k_rng_data_read(sc, buf, max >> 2);
|
||||
if ((max & 3UL) && ath9k_rng_data_read(sc, &word, 1)) {
|
||||
memcpy(buf + bytes_read, &word, max & 3UL);
|
||||
bytes_read += max & 3UL;
|
||||
memzero_explicit(&word, sizeof(word));
|
||||
}
|
||||
if (!wait || !max || likely(bytes_read) || fail_stats > 110)
|
||||
break;
|
||||
|
||||
fail_stats = 0;
|
||||
|
||||
/* sleep until entropy bits under write_wakeup_threshold */
|
||||
add_hwgenerator_randomness((void *)rng_buf, bytes_read,
|
||||
ATH9K_RNG_ENTROPY(bytes_read));
|
||||
msleep_interruptible(ath9k_rng_delay_get(++fail_stats));
|
||||
}
|
||||
|
||||
kfree(rng_buf);
|
||||
out:
|
||||
sc->rng_task = NULL;
|
||||
|
||||
return 0;
|
||||
if (wait && !bytes_read && max)
|
||||
bytes_read = -EIO;
|
||||
return bytes_read;
|
||||
}
|
||||
|
||||
void ath9k_rng_start(struct ath_softc *sc)
|
||||
{
|
||||
static atomic_t serial = ATOMIC_INIT(0);
|
||||
struct ath_hw *ah = sc->sc_ah;
|
||||
|
||||
if (sc->rng_task)
|
||||
if (sc->rng_ops.read)
|
||||
return;
|
||||
|
||||
if (!AR_SREV_9300_20_OR_LATER(ah))
|
||||
return;
|
||||
|
||||
sc->rng_task = kthread_run(ath9k_rng_kthread, sc, "ath9k-hwrng");
|
||||
if (IS_ERR(sc->rng_task))
|
||||
sc->rng_task = NULL;
|
||||
snprintf(sc->rng_name, sizeof(sc->rng_name), "ath9k_%u",
|
||||
(atomic_inc_return(&serial) - 1) & U16_MAX);
|
||||
sc->rng_ops.name = sc->rng_name;
|
||||
sc->rng_ops.read = ath9k_rng_read;
|
||||
sc->rng_ops.quality = 320;
|
||||
|
||||
if (devm_hwrng_register(sc->dev, &sc->rng_ops))
|
||||
sc->rng_ops.read = NULL;
|
||||
}
|
||||
|
||||
void ath9k_rng_stop(struct ath_softc *sc)
|
||||
{
|
||||
if (sc->rng_task) {
|
||||
kthread_stop(sc->rng_task);
|
||||
sc->rng_task = NULL;
|
||||
if (sc->rng_ops.read) {
|
||||
devm_hwrng_unregister(sc->dev, &sc->rng_ops);
|
||||
sc->rng_ops.read = NULL;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -149,7 +149,7 @@ struct carl9170fw_fix_entry {
|
|||
|
||||
struct carl9170fw_fix_desc {
|
||||
struct carl9170fw_desc_head head;
|
||||
struct carl9170fw_fix_entry data[0];
|
||||
struct carl9170fw_fix_entry data[];
|
||||
} __packed;
|
||||
#define CARL9170FW_FIX_DESC_SIZE \
|
||||
(sizeof(struct carl9170fw_fix_desc))
|
||||
|
|
|
@ -1914,7 +1914,7 @@ static int carl9170_parse_eeprom(struct ar9170 *ar)
|
|||
WARN_ON(!(tx_streams >= 1 && tx_streams <=
|
||||
IEEE80211_HT_MCS_TX_MAX_STREAMS));
|
||||
|
||||
tx_params = (tx_streams - 1) <<
|
||||
tx_params |= (tx_streams - 1) <<
|
||||
IEEE80211_HT_MCS_TX_MAX_STREAMS_SHIFT;
|
||||
|
||||
carl9170_band_2GHz.ht_cap.mcs.tx_params |= tx_params;
|
||||
|
|
|
@ -327,7 +327,7 @@ struct _carl9170_tx_superdesc {
|
|||
struct _carl9170_tx_superframe {
|
||||
struct _carl9170_tx_superdesc s;
|
||||
struct _ar9170_tx_hwdesc f;
|
||||
u8 frame_data[0];
|
||||
u8 frame_data[];
|
||||
} __packed __aligned(4);
|
||||
|
||||
#define CARL9170_TX_SUPERDESC_LEN 24
|
||||
|
|
|
@ -108,7 +108,7 @@ struct fft_sample_ath10k {
|
|||
u8 avgpwr_db;
|
||||
u8 max_exp;
|
||||
|
||||
u8 data[0];
|
||||
u8 data[];
|
||||
} __packed;
|
||||
|
||||
struct fft_sample_ath11k {
|
||||
|
@ -123,7 +123,7 @@ struct fft_sample_ath11k {
|
|||
__be32 tsf;
|
||||
__be32 noise;
|
||||
|
||||
u8 data[0];
|
||||
u8 data[];
|
||||
} __packed;
|
||||
|
||||
#endif /* SPECTRAL_COMMON_H */
|
||||
|
|
|
@ -394,7 +394,7 @@ static void wcn36xx_change_opchannel(struct wcn36xx *wcn, int ch)
|
|||
struct ieee80211_vif *vif = NULL;
|
||||
struct wcn36xx_vif *tmp;
|
||||
struct ieee80211_supported_band *band;
|
||||
struct ieee80211_channel *channel;
|
||||
struct ieee80211_channel *channel = NULL;
|
||||
unsigned long flags;
|
||||
int i, j;
|
||||
|
||||
|
@ -1391,11 +1391,11 @@ static int wcn36xx_get_survey(struct ieee80211_hw *hw, int idx,
|
|||
|
||||
spin_unlock_irqrestore(&wcn->survey_lock, flags);
|
||||
|
||||
wcn36xx_dbg(WCN36XX_DBG_MAC,
|
||||
"ch %d rssi %d snr %d noise %d filled %x freq %d\n",
|
||||
HW_VALUE_CHANNEL(survey->channel->hw_value),
|
||||
chan_survey->rssi, chan_survey->snr, survey->noise,
|
||||
survey->filled, survey->channel->center_freq);
|
||||
wcn36xx_dbg(WCN36XX_DBG_MAC,
|
||||
"ch %d rssi %d snr %d noise %d filled %x freq %d\n",
|
||||
HW_VALUE_CHANNEL(survey->channel->hw_value),
|
||||
chan_survey->rssi, chan_survey->snr, survey->noise,
|
||||
survey->filled, survey->channel->center_freq);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -1583,6 +1583,9 @@ static int wcn36xx_platform_get_resources(struct wcn36xx *wcn,
|
|||
if (iris_node) {
|
||||
if (of_device_is_compatible(iris_node, "qcom,wcn3620"))
|
||||
wcn->rf_id = RF_IRIS_WCN3620;
|
||||
if (of_device_is_compatible(iris_node, "qcom,wcn3660") ||
|
||||
of_device_is_compatible(iris_node, "qcom,wcn3660b"))
|
||||
wcn->rf_id = RF_IRIS_WCN3660;
|
||||
if (of_device_is_compatible(iris_node, "qcom,wcn3680"))
|
||||
wcn->rf_id = RF_IRIS_WCN3680;
|
||||
of_node_put(iris_node);
|
||||
|
|
|
@ -3347,7 +3347,7 @@ int wcn36xx_smd_rsp_process(struct rpmsg_device *rpdev,
|
|||
case WCN36XX_HAL_DELETE_STA_CONTEXT_IND:
|
||||
case WCN36XX_HAL_PRINT_REG_INFO_IND:
|
||||
case WCN36XX_HAL_SCAN_OFFLOAD_IND:
|
||||
msg_ind = kmalloc(sizeof(*msg_ind) + len, GFP_ATOMIC);
|
||||
msg_ind = kmalloc(struct_size(msg_ind, msg, len), GFP_ATOMIC);
|
||||
if (!msg_ind) {
|
||||
wcn36xx_err("Run out of memory while handling SMD_EVENT (%d)\n",
|
||||
msg_header->msg_type);
|
||||
|
|
|
@ -376,8 +376,8 @@ int wcn36xx_rx_skb(struct wcn36xx *wcn, struct sk_buff *skb)
|
|||
status.freq = WCN36XX_CENTER_FREQ(wcn);
|
||||
}
|
||||
|
||||
wcn36xx_update_survey(wcn, status.signal, get_snr(bd),
|
||||
status.band, status.freq);
|
||||
wcn36xx_update_survey(wcn, status.signal, get_snr(bd),
|
||||
status.band, status.freq);
|
||||
|
||||
if (bd->rate_id < ARRAY_SIZE(wcn36xx_rate_table)) {
|
||||
rate = &wcn36xx_rate_table[bd->rate_id];
|
||||
|
|
|
@ -97,6 +97,7 @@ enum wcn36xx_ampdu_state {
|
|||
|
||||
#define RF_UNKNOWN 0x0000
|
||||
#define RF_IRIS_WCN3620 0x3620
|
||||
#define RF_IRIS_WCN3660 0x3660
|
||||
#define RF_IRIS_WCN3680 0x3680
|
||||
|
||||
static inline void buff_to_be(u32 *buf, size_t len)
|
||||
|
|
Loading…
Add table
Reference in a new issue