mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2025-02-11 10:15:09 +07:00
Merge ath-next from git://git.kernel.org/pub/scm/linux/kernel/git/kvalo/ath.git
ath.git patches for v5.6. Major changes: wil6210 * support set_multicast_to_unicast cfg80211 operation * support set_cqm_rssi_config cfg80211 operation wcn36xx * disable HW_CONNECTION_MONITOR as firmware is buggy
This commit is contained in:
commit
ae0a723c4c
@ -1098,7 +1098,7 @@ static int ath10k_monitor_vdev_stop(struct ath10k *ar)
|
||||
|
||||
ret = ath10k_wmi_vdev_stop(ar, ar->monitor_vdev_id);
|
||||
if (ret)
|
||||
ath10k_warn(ar, "failed to to request monitor vdev %i stop: %d\n",
|
||||
ath10k_warn(ar, "failed to request monitor vdev %i stop: %d\n",
|
||||
ar->monitor_vdev_id, ret);
|
||||
|
||||
ret = ath10k_vdev_setup_sync(ar);
|
||||
|
@ -65,7 +65,7 @@ bool ath10k_tm_event_wmi(struct ath10k *ar, u32 cmd_id, struct sk_buff *skb)
|
||||
ret = nla_put_u32(nl_skb, ATH10K_TM_ATTR_CMD, ATH10K_TM_CMD_WMI);
|
||||
if (ret) {
|
||||
ath10k_warn(ar,
|
||||
"failed to to put testmode wmi event cmd attribute: %d\n",
|
||||
"failed to put testmode wmi event cmd attribute: %d\n",
|
||||
ret);
|
||||
kfree_skb(nl_skb);
|
||||
goto out;
|
||||
@ -74,7 +74,7 @@ bool ath10k_tm_event_wmi(struct ath10k *ar, u32 cmd_id, struct sk_buff *skb)
|
||||
ret = nla_put_u32(nl_skb, ATH10K_TM_ATTR_WMI_CMDID, cmd_id);
|
||||
if (ret) {
|
||||
ath10k_warn(ar,
|
||||
"failed to to put testmode wmi even cmd_id: %d\n",
|
||||
"failed to put testmode wmi event cmd_id: %d\n",
|
||||
ret);
|
||||
kfree_skb(nl_skb);
|
||||
goto out;
|
||||
|
@ -441,6 +441,7 @@ static int ath11k_ce_alloc_pipe(struct ath11k_base *ab, int ce_id)
|
||||
{
|
||||
struct ath11k_ce_pipe *pipe = &ab->ce.ce_pipe[ce_id];
|
||||
const struct ce_attr *attr = &host_ce_config_wlan[ce_id];
|
||||
struct ath11k_ce_ring *ring;
|
||||
int nentries;
|
||||
int desc_sz;
|
||||
|
||||
@ -450,24 +451,26 @@ static int ath11k_ce_alloc_pipe(struct ath11k_base *ab, int ce_id)
|
||||
pipe->send_cb = ath11k_ce_send_done_cb;
|
||||
nentries = roundup_pow_of_two(attr->src_nentries);
|
||||
desc_sz = ath11k_hal_ce_get_desc_size(HAL_CE_DESC_SRC);
|
||||
pipe->src_ring = ath11k_ce_alloc_ring(ab, nentries, desc_sz);
|
||||
if (!pipe->src_ring)
|
||||
return -ENOMEM;
|
||||
ring = ath11k_ce_alloc_ring(ab, nentries, desc_sz);
|
||||
if (IS_ERR(ring))
|
||||
return PTR_ERR(ring);
|
||||
pipe->src_ring = ring;
|
||||
}
|
||||
|
||||
if (attr->dest_nentries) {
|
||||
pipe->recv_cb = attr->recv_cb;
|
||||
nentries = roundup_pow_of_two(attr->dest_nentries);
|
||||
desc_sz = ath11k_hal_ce_get_desc_size(HAL_CE_DESC_DST);
|
||||
pipe->dest_ring = ath11k_ce_alloc_ring(ab, nentries, desc_sz);
|
||||
|
||||
if (!pipe->dest_ring)
|
||||
return -ENOMEM;
|
||||
ring = ath11k_ce_alloc_ring(ab, nentries, desc_sz);
|
||||
if (IS_ERR(ring))
|
||||
return PTR_ERR(ring);
|
||||
pipe->dest_ring = ring;
|
||||
|
||||
desc_sz = ath11k_hal_ce_get_desc_size(HAL_CE_DESC_DST_STATUS);
|
||||
pipe->status_ring = ath11k_ce_alloc_ring(ab, nentries, desc_sz);
|
||||
if (!pipe->status_ring)
|
||||
return -ENOMEM;
|
||||
ring = ath11k_ce_alloc_ring(ab, nentries, desc_sz);
|
||||
if (IS_ERR(ring))
|
||||
return PTR_ERR(ring);
|
||||
pipe->status_ring = ring;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -651,7 +651,7 @@ static void ath11k_core_restart(struct work_struct *work)
|
||||
idr_destroy(&ar->txmgmt_idr);
|
||||
}
|
||||
|
||||
wake_up(&ab->wmi_sc.tx_credits_wq);
|
||||
wake_up(&ab->wmi_ab.tx_credits_wq);
|
||||
wake_up(&ab->peer_mapping_wq);
|
||||
|
||||
ret = ath11k_core_reconfigure_on_crash(ab);
|
||||
@ -761,7 +761,7 @@ struct ath11k_base *ath11k_core_alloc(struct device *dev)
|
||||
|
||||
INIT_LIST_HEAD(&ab->peers);
|
||||
init_waitqueue_head(&ab->peer_mapping_wq);
|
||||
init_waitqueue_head(&ab->wmi_sc.tx_credits_wq);
|
||||
init_waitqueue_head(&ab->wmi_ab.tx_credits_wq);
|
||||
INIT_WORK(&ab->restart_work, ath11k_core_restart);
|
||||
timer_setup(&ab->rx_replenish_retry, ath11k_ce_rx_replenish_retry, 0);
|
||||
ab->dev = dev;
|
||||
|
@ -578,7 +578,7 @@ struct ath11k_base {
|
||||
struct platform_device *pdev;
|
||||
struct device *dev;
|
||||
struct ath11k_qmi qmi;
|
||||
struct ath11k_wmi_base wmi_sc;
|
||||
struct ath11k_wmi_base wmi_ab;
|
||||
struct completion fw_ready;
|
||||
struct rproc *tgt_rproc;
|
||||
int num_radios;
|
||||
|
@ -541,7 +541,7 @@ static ssize_t ath11k_write_simulate_fw_crash(struct file *file,
|
||||
struct ath11k *ar = ab->pdevs[0].ar;
|
||||
char buf[32] = {0};
|
||||
ssize_t rc;
|
||||
int i, ret, radioup;
|
||||
int i, ret, radioup = 0;
|
||||
|
||||
for (i = 0; i < ab->num_radios; i++) {
|
||||
pdev = &ab->pdevs[i];
|
||||
@ -704,7 +704,7 @@ static ssize_t ath11k_write_extd_rx_stats(struct file *file,
|
||||
DP_RX_BUFFER_SIZE, &tlv_filter);
|
||||
|
||||
if (ret) {
|
||||
ath11k_warn(ar->ab, "failed to set rx filter for moniter status ring\n");
|
||||
ath11k_warn(ar->ab, "failed to set rx filter for monitor status ring\n");
|
||||
goto exit;
|
||||
}
|
||||
|
||||
@ -948,7 +948,7 @@ static ssize_t ath11k_write_pktlog_filter(struct file *file,
|
||||
HAL_RXDMA_MONITOR_STATUS,
|
||||
DP_RX_BUFFER_SIZE, &tlv_filter);
|
||||
if (ret) {
|
||||
ath11k_warn(ar->ab, "failed to set rx filter for moniter status ring\n");
|
||||
ath11k_warn(ar->ab, "failed to set rx filter for monitor status ring\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
|
@ -3512,7 +3512,7 @@ htt_print_rx_pdev_fw_stats_phy_err_tlv(const void *tag_buf,
|
||||
len += HTT_DBG_OUT(buf + len, buf_len - len, "HTT_RX_PDEV_FW_STATS_PHY_ERR_TLV:");
|
||||
len += HTT_DBG_OUT(buf + len, buf_len - len, "mac_id__word = %u",
|
||||
htt_stats_buf->mac_id__word);
|
||||
len += HTT_DBG_OUT(buf + len, buf_len - len, "tota_phy_err_nct = %u",
|
||||
len += HTT_DBG_OUT(buf + len, buf_len - len, "total_phy_err_nct = %u",
|
||||
htt_stats_buf->total_phy_err_cnt);
|
||||
|
||||
ARRAY_TO_STRING(phy_errs,
|
||||
@ -4287,7 +4287,6 @@ int ath11k_dbg_htt_stats_req(struct ath11k *ar)
|
||||
ret = ath11k_dp_tx_htt_h2t_ext_stats_req(ar, type, &cfg_params, cookie);
|
||||
if (ret) {
|
||||
ath11k_warn(ar->ab, "failed to send htt stats request: %d\n", ret);
|
||||
mutex_unlock(&ar->conf_mutex);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -129,12 +129,16 @@ void ath11k_update_per_peer_stats_from_txcompl(struct ath11k *ar,
|
||||
{
|
||||
struct ath11k_base *ab = ar->ab;
|
||||
struct ath11k_per_peer_tx_stats *peer_stats = &ar->cached_stats;
|
||||
enum hal_tx_rate_stats_pkt_type pkt_type;
|
||||
enum hal_tx_rate_stats_sgi sgi;
|
||||
enum hal_tx_rate_stats_bw bw;
|
||||
struct ath11k_peer *peer;
|
||||
struct ath11k_sta *arsta;
|
||||
struct ieee80211_sta *sta;
|
||||
u16 rate;
|
||||
u8 rate_idx;
|
||||
int ret;
|
||||
u8 mcs;
|
||||
|
||||
rcu_read_lock();
|
||||
spin_lock_bh(&ab->base_lock);
|
||||
@ -150,51 +154,52 @@ void ath11k_update_per_peer_stats_from_txcompl(struct ath11k *ar,
|
||||
arsta = (struct ath11k_sta *)sta->drv_priv;
|
||||
|
||||
memset(&arsta->txrate, 0, sizeof(arsta->txrate));
|
||||
pkt_type = FIELD_GET(HAL_TX_RATE_STATS_INFO0_PKT_TYPE,
|
||||
ts->rate_stats);
|
||||
mcs = FIELD_GET(HAL_TX_RATE_STATS_INFO0_MCS,
|
||||
ts->rate_stats);
|
||||
sgi = FIELD_GET(HAL_TX_RATE_STATS_INFO0_SGI,
|
||||
ts->rate_stats);
|
||||
bw = FIELD_GET(HAL_TX_RATE_STATS_INFO0_BW, ts->rate_stats);
|
||||
|
||||
if (ts->pkt_type == HAL_TX_RATE_STATS_PKT_TYPE_11A ||
|
||||
ts->pkt_type == HAL_TX_RATE_STATS_PKT_TYPE_11B) {
|
||||
ret = ath11k_mac_hw_ratecode_to_legacy_rate(ts->mcs,
|
||||
ts->pkt_type,
|
||||
if (pkt_type == HAL_TX_RATE_STATS_PKT_TYPE_11A ||
|
||||
pkt_type == HAL_TX_RATE_STATS_PKT_TYPE_11B) {
|
||||
ret = ath11k_mac_hw_ratecode_to_legacy_rate(mcs,
|
||||
pkt_type,
|
||||
&rate_idx,
|
||||
&rate);
|
||||
if (ret < 0) {
|
||||
spin_unlock_bh(&ab->base_lock);
|
||||
rcu_read_unlock();
|
||||
return;
|
||||
}
|
||||
if (ret < 0)
|
||||
goto err_out;
|
||||
arsta->txrate.legacy = rate;
|
||||
} else if (ts->pkt_type == HAL_TX_RATE_STATS_PKT_TYPE_11N) {
|
||||
if (ts->mcs > 7) {
|
||||
ath11k_warn(ab, "Invalid HT mcs index %d\n", ts->mcs);
|
||||
spin_unlock_bh(&ab->base_lock);
|
||||
rcu_read_unlock();
|
||||
return;
|
||||
} else if (pkt_type == HAL_TX_RATE_STATS_PKT_TYPE_11N) {
|
||||
if (mcs > 7) {
|
||||
ath11k_warn(ab, "Invalid HT mcs index %d\n", mcs);
|
||||
goto err_out;
|
||||
}
|
||||
|
||||
arsta->txrate.mcs = ts->mcs + 8 * (arsta->last_txrate.nss - 1);
|
||||
arsta->txrate.mcs = mcs + 8 * (arsta->last_txrate.nss - 1);
|
||||
arsta->txrate.flags = RATE_INFO_FLAGS_MCS;
|
||||
if (ts->sgi)
|
||||
if (sgi)
|
||||
arsta->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
|
||||
} else if (ts->pkt_type == HAL_TX_RATE_STATS_PKT_TYPE_11AC) {
|
||||
if (ts->mcs > 9) {
|
||||
ath11k_warn(ab, "Invalid VHT mcs index %d\n", ts->mcs);
|
||||
spin_unlock_bh(&ab->base_lock);
|
||||
rcu_read_unlock();
|
||||
return;
|
||||
} else if (pkt_type == HAL_TX_RATE_STATS_PKT_TYPE_11AC) {
|
||||
if (mcs > 9) {
|
||||
ath11k_warn(ab, "Invalid VHT mcs index %d\n", mcs);
|
||||
goto err_out;
|
||||
}
|
||||
|
||||
arsta->txrate.mcs = ts->mcs;
|
||||
arsta->txrate.mcs = mcs;
|
||||
arsta->txrate.flags = RATE_INFO_FLAGS_VHT_MCS;
|
||||
if (ts->sgi)
|
||||
if (sgi)
|
||||
arsta->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
|
||||
} else {
|
||||
/*TODO: update HE rates */
|
||||
} else if (pkt_type == HAL_TX_RATE_STATS_PKT_TYPE_11AX) {
|
||||
/* TODO */
|
||||
}
|
||||
|
||||
arsta->txrate.nss = arsta->last_txrate.nss;
|
||||
arsta->txrate.bw = ath11k_mac_bw_to_mac80211_bw(ts->bw);
|
||||
arsta->txrate.bw = ath11k_mac_bw_to_mac80211_bw(bw);
|
||||
|
||||
ath11k_accumulate_per_peer_tx_stats(arsta, peer_stats, rate_idx);
|
||||
err_out:
|
||||
spin_unlock_bh(&ab->base_lock);
|
||||
rcu_read_unlock();
|
||||
}
|
||||
|
@ -3,7 +3,6 @@
|
||||
* Copyright (c) 2018-2019 The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <linux/kfifo.h>
|
||||
#include "core.h"
|
||||
#include "dp_tx.h"
|
||||
#include "hal_tx.h"
|
||||
@ -828,10 +827,7 @@ void ath11k_dp_free(struct ath11k_base *ab)
|
||||
ath11k_dp_tx_pending_cleanup, ab);
|
||||
idr_destroy(&dp->tx_ring[i].txbuf_idr);
|
||||
spin_unlock_bh(&dp->tx_ring[i].tx_idr_lock);
|
||||
|
||||
spin_lock_bh(&dp->tx_ring[i].tx_status_lock);
|
||||
kfifo_free(&dp->tx_ring[i].tx_status_fifo);
|
||||
spin_unlock_bh(&dp->tx_ring[i].tx_status_lock);
|
||||
kfree(dp->tx_ring[i].tx_status);
|
||||
}
|
||||
|
||||
/* Deinit any SOC level resource */
|
||||
@ -871,17 +867,17 @@ int ath11k_dp_alloc(struct ath11k_base *ab)
|
||||
if (ret)
|
||||
goto fail_link_desc_cleanup;
|
||||
|
||||
size = roundup_pow_of_two(DP_TX_COMP_RING_SIZE);
|
||||
size = sizeof(struct hal_wbm_release_ring) * DP_TX_COMP_RING_SIZE;
|
||||
|
||||
for (i = 0; i < DP_TCL_NUM_RING_MAX; i++) {
|
||||
idr_init(&dp->tx_ring[i].txbuf_idr);
|
||||
spin_lock_init(&dp->tx_ring[i].tx_idr_lock);
|
||||
dp->tx_ring[i].tcl_data_ring_id = i;
|
||||
|
||||
spin_lock_init(&dp->tx_ring[i].tx_status_lock);
|
||||
ret = kfifo_alloc(&dp->tx_ring[i].tx_status_fifo, size,
|
||||
GFP_KERNEL);
|
||||
if (ret)
|
||||
dp->tx_ring[i].tx_status_head = 0;
|
||||
dp->tx_ring[i].tx_status_tail = DP_TX_COMP_RING_SIZE - 1;
|
||||
dp->tx_ring[i].tx_status = kmalloc(size, GFP_KERNEL);
|
||||
if (!dp->tx_ring[i].tx_status)
|
||||
goto fail_cmn_srng_cleanup;
|
||||
}
|
||||
|
||||
|
@ -6,7 +6,6 @@
|
||||
#ifndef ATH11K_DP_H
|
||||
#define ATH11K_DP_H
|
||||
|
||||
#include <linux/kfifo.h>
|
||||
#include "hal_rx.h"
|
||||
|
||||
struct ath11k_base;
|
||||
@ -58,6 +57,8 @@ struct dp_rxdma_ring {
|
||||
int bufs_max;
|
||||
};
|
||||
|
||||
#define ATH11K_TX_COMPL_NEXT(x) (((x) + 1) % DP_TX_COMP_RING_SIZE)
|
||||
|
||||
struct dp_tx_ring {
|
||||
u8 tcl_data_ring_id;
|
||||
struct dp_srng tcl_data_ring;
|
||||
@ -65,11 +66,9 @@ struct dp_tx_ring {
|
||||
struct idr txbuf_idr;
|
||||
/* Protects txbuf_idr and num_pending */
|
||||
spinlock_t tx_idr_lock;
|
||||
DECLARE_KFIFO_PTR(tx_status_fifo, struct hal_wbm_release_ring);
|
||||
/* lock to protect tx_status_fifo because tx_status_fifo can be
|
||||
* accessed concurrently.
|
||||
*/
|
||||
spinlock_t tx_status_lock;
|
||||
struct hal_wbm_release_ring *tx_status;
|
||||
int tx_status_head;
|
||||
int tx_status_tail;
|
||||
};
|
||||
|
||||
struct ath11k_pdev_mon_stats {
|
||||
|
@ -1225,12 +1225,12 @@ static
|
||||
struct htt_ppdu_stats_info *ath11k_dp_htt_get_ppdu_desc(struct ath11k *ar,
|
||||
u32 ppdu_id)
|
||||
{
|
||||
struct htt_ppdu_stats_info *ppdu_info = NULL;
|
||||
struct htt_ppdu_stats_info *ppdu_info;
|
||||
|
||||
spin_lock_bh(&ar->data_lock);
|
||||
if (!list_empty(&ar->ppdu_stats_info)) {
|
||||
list_for_each_entry(ppdu_info, &ar->ppdu_stats_info, list) {
|
||||
if (ppdu_info && ppdu_info->ppdu_id == ppdu_id) {
|
||||
if (ppdu_info->ppdu_id == ppdu_id) {
|
||||
spin_unlock_bh(&ar->data_lock);
|
||||
return ppdu_info;
|
||||
}
|
||||
|
@ -79,7 +79,6 @@ int ath11k_dp_tx(struct ath11k *ar, struct ath11k_vif *arvif,
|
||||
struct hal_srng *tcl_ring;
|
||||
struct ieee80211_hdr *hdr = (void *)skb->data;
|
||||
struct dp_tx_ring *tx_ring;
|
||||
u8 cached_desc[HAL_TCL_DESC_LEN];
|
||||
void *hal_tcl_desc;
|
||||
u8 pool_id;
|
||||
u8 hal_ring_id;
|
||||
@ -167,10 +166,6 @@ int ath11k_dp_tx(struct ath11k *ar, struct ath11k_vif *arvif,
|
||||
skb_cb->vif = arvif->vif;
|
||||
skb_cb->ar = ar;
|
||||
|
||||
memset(cached_desc, 0, HAL_TCL_DESC_LEN);
|
||||
|
||||
ath11k_hal_tx_cmd_desc_setup(ab, cached_desc, &ti);
|
||||
|
||||
hal_ring_id = tx_ring->tcl_data_ring.ring_id;
|
||||
tcl_ring = &ab->hal.srng_list[hal_ring_id];
|
||||
|
||||
@ -190,7 +185,8 @@ int ath11k_dp_tx(struct ath11k *ar, struct ath11k_vif *arvif,
|
||||
goto fail_unmap_dma;
|
||||
}
|
||||
|
||||
ath11k_hal_tx_desc_sync(cached_desc, hal_tcl_desc);
|
||||
ath11k_hal_tx_cmd_desc_setup(ab, hal_tcl_desc +
|
||||
sizeof(struct hal_tlv_hdr), &ti);
|
||||
|
||||
ath11k_hal_srng_access_end(ab, tcl_ring);
|
||||
|
||||
@ -427,6 +423,37 @@ static void ath11k_dp_tx_complete_msdu(struct ath11k *ar,
|
||||
rcu_read_unlock();
|
||||
}
|
||||
|
||||
static inline void ath11k_dp_tx_status_parse(struct ath11k_base *ab,
|
||||
struct hal_wbm_release_ring *desc,
|
||||
struct hal_tx_status *ts)
|
||||
{
|
||||
ts->buf_rel_source =
|
||||
FIELD_GET(HAL_WBM_RELEASE_INFO0_REL_SRC_MODULE, desc->info0);
|
||||
if (ts->buf_rel_source != HAL_WBM_REL_SRC_MODULE_FW &&
|
||||
ts->buf_rel_source != HAL_WBM_REL_SRC_MODULE_TQM)
|
||||
return;
|
||||
|
||||
if (ts->buf_rel_source == HAL_WBM_REL_SRC_MODULE_FW)
|
||||
return;
|
||||
|
||||
ts->status = FIELD_GET(HAL_WBM_RELEASE_INFO0_TQM_RELEASE_REASON,
|
||||
desc->info0);
|
||||
ts->ppdu_id = FIELD_GET(HAL_WBM_RELEASE_INFO1_TQM_STATUS_NUMBER,
|
||||
desc->info1);
|
||||
ts->try_cnt = FIELD_GET(HAL_WBM_RELEASE_INFO1_TRANSMIT_COUNT,
|
||||
desc->info1);
|
||||
ts->ack_rssi = FIELD_GET(HAL_WBM_RELEASE_INFO2_ACK_FRAME_RSSI,
|
||||
desc->info2);
|
||||
if (desc->info2 & HAL_WBM_RELEASE_INFO2_FIRST_MSDU)
|
||||
ts->flags |= HAL_TX_STATUS_FLAGS_FIRST_MSDU;
|
||||
ts->peer_id = FIELD_GET(HAL_WBM_RELEASE_INFO3_PEER_ID, desc->info3);
|
||||
ts->tid = FIELD_GET(HAL_WBM_RELEASE_INFO3_TID, desc->info3);
|
||||
if (desc->rate_stats.info0 & HAL_TX_RATE_STATS_INFO0_VALID)
|
||||
ts->rate_stats = desc->rate_stats.info0;
|
||||
else
|
||||
ts->rate_stats = 0;
|
||||
}
|
||||
|
||||
void ath11k_dp_tx_completion_handler(struct ath11k_base *ab, int ring_id)
|
||||
{
|
||||
struct ath11k *ar;
|
||||
@ -434,47 +461,48 @@ void ath11k_dp_tx_completion_handler(struct ath11k_base *ab, int ring_id)
|
||||
int hal_ring_id = dp->tx_ring[ring_id].tcl_comp_ring.ring_id;
|
||||
struct hal_srng *status_ring = &ab->hal.srng_list[hal_ring_id];
|
||||
struct sk_buff *msdu;
|
||||
struct hal_wbm_release_ring tx_status;
|
||||
struct hal_tx_status ts;
|
||||
struct dp_tx_ring *tx_ring = &dp->tx_ring[ring_id];
|
||||
u32 *desc;
|
||||
u32 msdu_id;
|
||||
u8 mac_id;
|
||||
|
||||
spin_lock_bh(&status_ring->lock);
|
||||
|
||||
ath11k_hal_srng_access_begin(ab, status_ring);
|
||||
|
||||
spin_lock_bh(&tx_ring->tx_status_lock);
|
||||
while (!kfifo_is_full(&tx_ring->tx_status_fifo) &&
|
||||
while ((ATH11K_TX_COMPL_NEXT(tx_ring->tx_status_head) !=
|
||||
tx_ring->tx_status_tail) &&
|
||||
(desc = ath11k_hal_srng_dst_get_next_entry(ab, status_ring))) {
|
||||
ath11k_hal_tx_status_desc_sync((void *)desc,
|
||||
(void *)&tx_status);
|
||||
kfifo_put(&tx_ring->tx_status_fifo, tx_status);
|
||||
memcpy(&tx_ring->tx_status[tx_ring->tx_status_head],
|
||||
desc, sizeof(struct hal_wbm_release_ring));
|
||||
tx_ring->tx_status_head =
|
||||
ATH11K_TX_COMPL_NEXT(tx_ring->tx_status_head);
|
||||
}
|
||||
|
||||
if ((ath11k_hal_srng_dst_peek(ab, status_ring) != NULL) &&
|
||||
kfifo_is_full(&tx_ring->tx_status_fifo)) {
|
||||
(ATH11K_TX_COMPL_NEXT(tx_ring->tx_status_head) == tx_ring->tx_status_tail)) {
|
||||
/* TODO: Process pending tx_status messages when kfifo_is_full() */
|
||||
ath11k_warn(ab, "Unable to process some of the tx_status ring desc because status_fifo is full\n");
|
||||
}
|
||||
|
||||
spin_unlock_bh(&tx_ring->tx_status_lock);
|
||||
|
||||
ath11k_hal_srng_access_end(ab, status_ring);
|
||||
spin_unlock_bh(&status_ring->lock);
|
||||
|
||||
spin_lock_bh(&tx_ring->tx_status_lock);
|
||||
while (kfifo_get(&tx_ring->tx_status_fifo, &tx_status)) {
|
||||
memset(&ts, 0, sizeof(ts));
|
||||
ath11k_hal_tx_status_parse(ab, &tx_status, &ts);
|
||||
while (ATH11K_TX_COMPL_NEXT(tx_ring->tx_status_tail) != tx_ring->tx_status_head) {
|
||||
struct hal_wbm_release_ring *tx_status;
|
||||
u32 desc_id;
|
||||
|
||||
mac_id = FIELD_GET(DP_TX_DESC_ID_MAC_ID, ts.desc_id);
|
||||
msdu_id = FIELD_GET(DP_TX_DESC_ID_MSDU_ID, ts.desc_id);
|
||||
tx_ring->tx_status_tail =
|
||||
ATH11K_TX_COMPL_NEXT(tx_ring->tx_status_tail);
|
||||
tx_status = &tx_ring->tx_status[tx_ring->tx_status_tail];
|
||||
ath11k_dp_tx_status_parse(ab, tx_status, &ts);
|
||||
|
||||
desc_id = FIELD_GET(BUFFER_ADDR_INFO1_SW_COOKIE,
|
||||
tx_status->buf_addr_info.info1);
|
||||
mac_id = FIELD_GET(DP_TX_DESC_ID_MAC_ID, desc_id);
|
||||
msdu_id = FIELD_GET(DP_TX_DESC_ID_MSDU_ID, desc_id);
|
||||
|
||||
if (ts.buf_rel_source == HAL_WBM_REL_SRC_MODULE_FW) {
|
||||
ath11k_dp_tx_process_htt_tx_complete(ab,
|
||||
(void *)&tx_status,
|
||||
(void *)tx_status,
|
||||
mac_id, msdu_id,
|
||||
tx_ring);
|
||||
continue;
|
||||
@ -496,12 +524,8 @@ void ath11k_dp_tx_completion_handler(struct ath11k_base *ab, int ring_id)
|
||||
if (atomic_dec_and_test(&ar->dp.num_tx_pending))
|
||||
wake_up(&ar->dp.tx_empty_waitq);
|
||||
|
||||
/* TODO: Locking optimization so that tx_completion for an msdu
|
||||
* is not called with tx_status_lock acquired
|
||||
*/
|
||||
ath11k_dp_tx_complete_msdu(ar, msdu, &ts);
|
||||
}
|
||||
spin_unlock_bh(&tx_ring->tx_status_lock);
|
||||
}
|
||||
|
||||
int ath11k_dp_tx_send_reo_cmd(struct ath11k_base *ab, struct dp_rx_tid *rx_tid,
|
||||
@ -645,8 +669,10 @@ int ath11k_dp_tx_htt_srng_setup(struct ath11k_base *ab, u32 ring_id,
|
||||
HAL_ADDR_MSB_REG_SHIFT;
|
||||
|
||||
ret = ath11k_hal_srng_get_entrysize(ring_type);
|
||||
if (ret < 0)
|
||||
return -EINVAL;
|
||||
if (ret < 0) {
|
||||
ret = -EINVAL;
|
||||
goto err_free;
|
||||
}
|
||||
|
||||
ring_entry_sz = ret;
|
||||
|
||||
|
@ -71,79 +71,7 @@ void ath11k_hal_tx_cmd_desc_setup(struct ath11k_base *ab, void *cmd,
|
||||
ti->dscp_tid_tbl_idx) |
|
||||
FIELD_PREP(HAL_TCL_DATA_CMD_INFO3_SEARCH_INDEX,
|
||||
ti->bss_ast_hash);
|
||||
}
|
||||
|
||||
/* Commit the descriptor to hardware */
|
||||
void ath11k_hal_tx_desc_sync(void *tx_desc_cached, void *hw_desc)
|
||||
{
|
||||
memcpy(hw_desc + sizeof(struct hal_tlv_hdr), tx_desc_cached,
|
||||
sizeof(struct hal_tcl_data_cmd));
|
||||
}
|
||||
|
||||
/* Get the descriptor status from hardware */
|
||||
void ath11k_hal_tx_status_desc_sync(void *hw_desc, void *local_desc)
|
||||
{
|
||||
memcpy(local_desc, hw_desc, HAL_TX_STATUS_DESC_LEN);
|
||||
}
|
||||
|
||||
void ath11k_hal_tx_status_parse(struct ath11k_base *ab,
|
||||
struct hal_wbm_release_ring *desc,
|
||||
struct hal_tx_status *ts)
|
||||
{
|
||||
ts->buf_rel_source =
|
||||
FIELD_GET(HAL_WBM_RELEASE_INFO0_REL_SRC_MODULE, desc->info0);
|
||||
if (ts->buf_rel_source != HAL_WBM_REL_SRC_MODULE_FW &&
|
||||
ts->buf_rel_source != HAL_WBM_REL_SRC_MODULE_TQM)
|
||||
return;
|
||||
|
||||
ts->desc_id = FIELD_GET(BUFFER_ADDR_INFO1_SW_COOKIE,
|
||||
desc->buf_addr_info.info1);
|
||||
|
||||
if (ts->buf_rel_source == HAL_WBM_REL_SRC_MODULE_FW)
|
||||
return;
|
||||
|
||||
ts->status = FIELD_GET(HAL_WBM_RELEASE_INFO0_TQM_RELEASE_REASON,
|
||||
desc->info0);
|
||||
ts->ppdu_id = FIELD_GET(HAL_WBM_RELEASE_INFO1_TQM_STATUS_NUMBER,
|
||||
desc->info1);
|
||||
ts->try_cnt = FIELD_GET(HAL_WBM_RELEASE_INFO1_TRANSMIT_COUNT,
|
||||
desc->info1);
|
||||
|
||||
ts->ack_rssi = FIELD_GET(HAL_WBM_RELEASE_INFO2_ACK_FRAME_RSSI,
|
||||
desc->info2);
|
||||
if (desc->info2 & HAL_WBM_RELEASE_INFO2_FIRST_MSDU)
|
||||
ts->flags |= HAL_TX_STATUS_FLAGS_FIRST_MSDU;
|
||||
|
||||
if (desc->info2 & HAL_WBM_RELEASE_INFO2_LAST_MSDU)
|
||||
ts->flags |= HAL_TX_STATUS_FLAGS_LAST_MSDU;
|
||||
|
||||
if (desc->info2 & HAL_WBM_RELEASE_INFO2_MSDU_IN_AMSDU)
|
||||
ts->flags |= HAL_TX_STATUS_FLAGS_MSDU_IN_AMSDU;
|
||||
|
||||
ts->peer_id = FIELD_GET(HAL_WBM_RELEASE_INFO3_PEER_ID, desc->info3);
|
||||
ts->tid = FIELD_GET(HAL_WBM_RELEASE_INFO3_TID, desc->info3);
|
||||
|
||||
if (!(desc->rate_stats.info0 & HAL_TX_RATE_STATS_INFO0_VALID))
|
||||
return;
|
||||
|
||||
ts->flags |= HAL_TX_STATUS_FLAGS_RATE_STATS_VALID;
|
||||
ts->tsf = desc->rate_stats.tsf;
|
||||
ts->bw = FIELD_GET(HAL_TX_RATE_STATS_INFO0_BW, desc->rate_stats.info0);
|
||||
ts->pkt_type = FIELD_GET(HAL_TX_RATE_STATS_INFO0_PKT_TYPE,
|
||||
desc->rate_stats.info0);
|
||||
if (desc->rate_stats.info0 & HAL_TX_RATE_STATS_INFO0_STBC)
|
||||
ts->flags |= HAL_TX_STATUS_FLAGS_RATE_STBC;
|
||||
if (desc->rate_stats.info0 & HAL_TX_RATE_STATS_INFO0_LDPC)
|
||||
ts->flags |= HAL_TX_STATUS_FLAGS_RATE_LDPC;
|
||||
if (desc->rate_stats.info0 & HAL_TX_RATE_STATS_INFO0_OFDMA_TX)
|
||||
ts->flags |= HAL_TX_STATUS_FLAGS_OFDMA;
|
||||
|
||||
ts->sgi = FIELD_GET(HAL_TX_RATE_STATS_INFO0_SGI,
|
||||
desc->rate_stats.info0);
|
||||
ts->mcs = FIELD_GET(HAL_TX_RATE_STATS_INFO0_MCS,
|
||||
desc->rate_stats.info0);
|
||||
ts->num_tones_in_ru = FIELD_GET(HAL_TX_RATE_STATS_INFO0_TONES_IN_RU,
|
||||
desc->rate_stats.info0);
|
||||
tcl_cmd->info4 = 0;
|
||||
}
|
||||
|
||||
void ath11k_hal_tx_set_dscp_tid_map(struct ath11k_base *ab, int id)
|
||||
|
@ -48,29 +48,18 @@ struct hal_tx_info {
|
||||
/* Tx status parsed from srng desc */
|
||||
struct hal_tx_status {
|
||||
enum hal_wbm_rel_src_module buf_rel_source;
|
||||
u32 desc_id;
|
||||
enum hal_wbm_tqm_rel_reason status;
|
||||
u8 ack_rssi;
|
||||
enum hal_tx_rate_stats_bw bw;
|
||||
enum hal_tx_rate_stats_pkt_type pkt_type;
|
||||
enum hal_tx_rate_stats_sgi sgi;
|
||||
u8 mcs;
|
||||
u16 num_tones_in_ru;
|
||||
u32 flags; /* %HAL_TX_STATUS_FLAGS_ */
|
||||
u32 tsf;
|
||||
u32 ppdu_id;
|
||||
u8 try_cnt;
|
||||
u8 tid;
|
||||
u16 peer_id;
|
||||
u32 rate_stats;
|
||||
};
|
||||
|
||||
void ath11k_hal_tx_cmd_desc_setup(struct ath11k_base *ab, void *cmd,
|
||||
struct hal_tx_info *ti);
|
||||
void ath11k_hal_tx_desc_sync(void *tx_desc_cached, void *hw_desc);
|
||||
void ath11k_hal_tx_status_parse(struct ath11k_base *ab,
|
||||
struct hal_wbm_release_ring *desc,
|
||||
struct hal_tx_status *ts);
|
||||
void ath11k_hal_tx_status_desc_sync(void *hw_desc, void *local_desc);
|
||||
void ath11k_hal_tx_set_dscp_tid_map(struct ath11k_base *ab, int id);
|
||||
int ath11k_hal_reo_cmd_send(struct ath11k_base *ab, struct hal_srng *srng,
|
||||
enum hal_reo_cmd_type type,
|
||||
|
@ -736,7 +736,7 @@ int ath11k_htc_init(struct ath11k_base *ab)
|
||||
|
||||
htc->ab = ab;
|
||||
|
||||
switch (ab->wmi_sc.preferred_hw_mode) {
|
||||
switch (ab->wmi_ab.preferred_hw_mode) {
|
||||
case WMI_HOST_HW_MODE_SINGLE:
|
||||
htc->wmi_ep_count = 1;
|
||||
break;
|
||||
|
@ -1758,6 +1758,20 @@ static void ath11k_mac_op_bss_info_changed(struct ieee80211_hw *hw,
|
||||
if (ret)
|
||||
ath11k_warn(ar->ab, "failed to update bcn template: %d\n",
|
||||
ret);
|
||||
|
||||
if (vif->bss_conf.he_support) {
|
||||
ret = ath11k_wmi_vdev_set_param_cmd(ar, arvif->vdev_id,
|
||||
WMI_VDEV_PARAM_BA_MODE,
|
||||
WMI_BA_MODE_BUFFER_SIZE_256);
|
||||
if (ret)
|
||||
ath11k_warn(ar->ab,
|
||||
"failed to set BA BUFFER SIZE 256 for vdev: %d\n",
|
||||
arvif->vdev_id);
|
||||
else
|
||||
ath11k_dbg(ar->ab, ATH11K_DBG_MAC,
|
||||
"Set BA BUFFER SIZE 256 for VDEV: %d\n",
|
||||
arvif->vdev_id);
|
||||
}
|
||||
}
|
||||
|
||||
if (changed & (BSS_CHANGED_BEACON_INFO | BSS_CHANGED_BEACON)) {
|
||||
@ -1917,9 +1931,9 @@ static void ath11k_mac_op_bss_info_changed(struct ieee80211_hw *hw,
|
||||
|
||||
if (changed & BSS_CHANGED_TWT) {
|
||||
if (info->twt_requester || info->twt_responder)
|
||||
ath11k_wmi_send_twt_enable_cmd(ar, ar->pdev_idx);
|
||||
ath11k_wmi_send_twt_enable_cmd(ar, ar->pdev->pdev_id);
|
||||
else
|
||||
ath11k_wmi_send_twt_disable_cmd(ar, ar->pdev_idx);
|
||||
ath11k_wmi_send_twt_disable_cmd(ar, ar->pdev->pdev_id);
|
||||
}
|
||||
|
||||
if (changed & BSS_CHANGED_HE_OBSS_PD)
|
||||
@ -3346,6 +3360,77 @@ static void ath11k_gen_ppe_thresh(struct ath11k_ppe_threshold *fw_ppet,
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
ath11k_mac_filter_he_cap_mesh(struct ieee80211_he_cap_elem *he_cap_elem)
|
||||
{
|
||||
u8 m;
|
||||
|
||||
m = IEEE80211_HE_MAC_CAP0_TWT_RES |
|
||||
IEEE80211_HE_MAC_CAP0_TWT_REQ;
|
||||
he_cap_elem->mac_cap_info[0] &= ~m;
|
||||
|
||||
m = IEEE80211_HE_MAC_CAP2_TRS |
|
||||
IEEE80211_HE_MAC_CAP2_BCAST_TWT |
|
||||
IEEE80211_HE_MAC_CAP2_MU_CASCADING;
|
||||
he_cap_elem->mac_cap_info[2] &= ~m;
|
||||
|
||||
m = IEEE80211_HE_MAC_CAP3_FLEX_TWT_SCHED |
|
||||
IEEE80211_HE_MAC_CAP2_BCAST_TWT |
|
||||
IEEE80211_HE_MAC_CAP2_MU_CASCADING;
|
||||
he_cap_elem->mac_cap_info[3] &= ~m;
|
||||
|
||||
m = IEEE80211_HE_MAC_CAP4_BSRP_BQRP_A_MPDU_AGG |
|
||||
IEEE80211_HE_MAC_CAP4_BQR;
|
||||
he_cap_elem->mac_cap_info[4] &= ~m;
|
||||
|
||||
m = IEEE80211_HE_MAC_CAP5_SUBCHAN_SELECVITE_TRANSMISSION |
|
||||
IEEE80211_HE_MAC_CAP5_UL_2x996_TONE_RU |
|
||||
IEEE80211_HE_MAC_CAP5_PUNCTURED_SOUNDING |
|
||||
IEEE80211_HE_MAC_CAP5_HT_VHT_TRIG_FRAME_RX;
|
||||
he_cap_elem->mac_cap_info[5] &= ~m;
|
||||
|
||||
m = IEEE80211_HE_PHY_CAP2_UL_MU_FULL_MU_MIMO |
|
||||
IEEE80211_HE_PHY_CAP2_UL_MU_PARTIAL_MU_MIMO;
|
||||
he_cap_elem->phy_cap_info[2] &= ~m;
|
||||
|
||||
m = IEEE80211_HE_PHY_CAP3_RX_HE_MU_PPDU_FROM_NON_AP_STA |
|
||||
IEEE80211_HE_PHY_CAP3_DCM_MAX_CONST_TX_MASK |
|
||||
IEEE80211_HE_PHY_CAP3_DCM_MAX_CONST_RX_MASK;
|
||||
he_cap_elem->phy_cap_info[3] &= ~m;
|
||||
|
||||
m = IEEE80211_HE_PHY_CAP4_MU_BEAMFORMER;
|
||||
he_cap_elem->phy_cap_info[4] &= ~m;
|
||||
|
||||
m = IEEE80211_HE_PHY_CAP5_NG16_MU_FEEDBACK;
|
||||
he_cap_elem->phy_cap_info[5] &= ~m;
|
||||
|
||||
m = IEEE80211_HE_PHY_CAP6_CODEBOOK_SIZE_75_MU |
|
||||
IEEE80211_HE_PHY_CAP6_TRIG_MU_BEAMFORMER_FB |
|
||||
IEEE80211_HE_PHY_CAP6_TRIG_CQI_FB |
|
||||
IEEE80211_HE_PHY_CAP6_PARTIAL_BANDWIDTH_DL_MUMIMO;
|
||||
he_cap_elem->phy_cap_info[6] &= ~m;
|
||||
|
||||
m = IEEE80211_HE_PHY_CAP7_SRP_BASED_SR |
|
||||
IEEE80211_HE_PHY_CAP7_POWER_BOOST_FACTOR_AR |
|
||||
IEEE80211_HE_PHY_CAP7_STBC_TX_ABOVE_80MHZ |
|
||||
IEEE80211_HE_PHY_CAP7_STBC_RX_ABOVE_80MHZ;
|
||||
he_cap_elem->phy_cap_info[7] &= ~m;
|
||||
|
||||
m = IEEE80211_HE_PHY_CAP8_HE_ER_SU_PPDU_4XLTF_AND_08_US_GI |
|
||||
IEEE80211_HE_PHY_CAP8_20MHZ_IN_40MHZ_HE_PPDU_IN_2G |
|
||||
IEEE80211_HE_PHY_CAP8_20MHZ_IN_160MHZ_HE_PPDU |
|
||||
IEEE80211_HE_PHY_CAP8_80MHZ_IN_160MHZ_HE_PPDU;
|
||||
he_cap_elem->phy_cap_info[8] &= ~m;
|
||||
|
||||
m = IEEE80211_HE_PHY_CAP9_LONGER_THAN_16_SIGB_OFDM_SYM |
|
||||
IEEE80211_HE_PHY_CAP9_NON_TRIGGERED_CQI_FEEDBACK |
|
||||
IEEE80211_HE_PHY_CAP9_RX_1024_QAM_LESS_THAN_242_TONE_RU |
|
||||
IEEE80211_HE_PHY_CAP9_TX_1024_QAM_LESS_THAN_242_TONE_RU |
|
||||
IEEE80211_HE_PHY_CAP9_RX_FULL_BW_SU_USING_MU_WITH_COMP_SIGB |
|
||||
IEEE80211_HE_PHY_CAP9_RX_FULL_BW_SU_USING_MU_WITH_NON_COMP_SIGB;
|
||||
he_cap_elem->phy_cap_info[9] &= ~m;
|
||||
}
|
||||
|
||||
static int ath11k_mac_copy_he_cap(struct ath11k *ar,
|
||||
struct ath11k_pdev_cap *cap,
|
||||
struct ieee80211_sband_iftype_data *data,
|
||||
@ -3362,6 +3447,7 @@ static int ath11k_mac_copy_he_cap(struct ath11k *ar,
|
||||
switch (i) {
|
||||
case NL80211_IFTYPE_STATION:
|
||||
case NL80211_IFTYPE_AP:
|
||||
case NL80211_IFTYPE_MESH_POINT:
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -3402,6 +3488,9 @@ static int ath11k_mac_copy_he_cap(struct ath11k *ar,
|
||||
he_cap_elem->phy_cap_info[9] |=
|
||||
IEEE80211_HE_PHY_CAP9_TX_1024_QAM_LESS_THAN_242_TONE_RU;
|
||||
break;
|
||||
case NL80211_IFTYPE_MESH_POINT:
|
||||
ath11k_mac_filter_he_cap_mesh(he_cap_elem);
|
||||
break;
|
||||
}
|
||||
|
||||
he_cap->he_mcs_nss_supp.rx_mcs_80 =
|
||||
@ -4097,6 +4186,13 @@ static int ath11k_mac_op_add_interface(struct ieee80211_hw *hw,
|
||||
arvif->vdev_id, ret);
|
||||
goto err_peer_del;
|
||||
}
|
||||
|
||||
ret = ath11k_wmi_pdev_set_ps_mode(ar, arvif->vdev_id, false);
|
||||
if (ret) {
|
||||
ath11k_warn(ar->ab, "failed to disable vdev %d ps mode: %d\n",
|
||||
arvif->vdev_id, ret);
|
||||
goto err_peer_del;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@ -5238,7 +5334,7 @@ ath11k_mac_update_bss_chan_survey(struct ath11k *ar,
|
||||
|
||||
lockdep_assert_held(&ar->conf_mutex);
|
||||
|
||||
if (!test_bit(WMI_TLV_SERVICE_BSS_CHANNEL_INFO_64, ar->ab->wmi_sc.svc_map) ||
|
||||
if (!test_bit(WMI_TLV_SERVICE_BSS_CHANNEL_INFO_64, ar->ab->wmi_ab.svc_map) ||
|
||||
ar->rx_channel != channel)
|
||||
return;
|
||||
|
||||
@ -5756,7 +5852,7 @@ int ath11k_mac_allocate(struct ath11k_base *ab)
|
||||
ar->pdev_idx = i;
|
||||
ar->lmac_id = ath11k_core_get_hw_mac_id(ab, i);
|
||||
|
||||
ar->wmi = &ab->wmi_sc.wmi[i];
|
||||
ar->wmi = &ab->wmi_ab.wmi[i];
|
||||
/* FIXME wmi[0] is already initialized during attach,
|
||||
* Should we do this again?
|
||||
*/
|
||||
|
@ -150,7 +150,7 @@ static int ath11k_tm_cmd_wmi(struct ath11k *ar, struct nlattr *tb[])
|
||||
|
||||
ath11k_dbg_dump(ar->ab, ATH11K_DBG_TESTMODE, NULL, "", buf, buf_len);
|
||||
|
||||
skb = ath11k_wmi_alloc_skb(wmi->wmi_sc, buf_len);
|
||||
skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, buf_len);
|
||||
if (!skb) {
|
||||
ret = -ENOMEM;
|
||||
goto out;
|
||||
|
@ -205,7 +205,7 @@ static int ath11k_wmi_cmd_send_nowait(struct ath11k_pdev_wmi *wmi, struct sk_buf
|
||||
u32 cmd_id)
|
||||
{
|
||||
struct ath11k_skb_cb *skb_cb = ATH11K_SKB_CB(skb);
|
||||
struct ath11k_base *ab = wmi->wmi_sc->ab;
|
||||
struct ath11k_base *ab = wmi->wmi_ab->ab;
|
||||
struct wmi_cmd_hdr *cmd_hdr;
|
||||
int ret;
|
||||
u32 cmd = 0;
|
||||
@ -234,7 +234,7 @@ static int ath11k_wmi_cmd_send_nowait(struct ath11k_pdev_wmi *wmi, struct sk_buf
|
||||
int ath11k_wmi_cmd_send(struct ath11k_pdev_wmi *wmi, struct sk_buff *skb,
|
||||
u32 cmd_id)
|
||||
{
|
||||
struct ath11k_wmi_base *wmi_sc = wmi->wmi_sc;
|
||||
struct ath11k_wmi_base *wmi_sc = wmi->wmi_ab;
|
||||
int ret = -EOPNOTSUPP;
|
||||
|
||||
might_sleep();
|
||||
@ -448,7 +448,7 @@ static void ath11k_wmi_service_bitmap_copy(struct ath11k_pdev_wmi *wmi,
|
||||
for (i = 0, j = 0; i < WMI_SERVICE_BM_SIZE && j < WMI_MAX_SERVICE; i++) {
|
||||
do {
|
||||
if (wmi_svc_bm[i] & BIT(j % WMI_SERVICE_BITS_IN_SIZE32))
|
||||
set_bit(j, wmi->wmi_sc->svc_map);
|
||||
set_bit(j, wmi->wmi_ab->svc_map);
|
||||
} while (++j % WMI_SERVICE_BITS_IN_SIZE32);
|
||||
}
|
||||
}
|
||||
@ -457,7 +457,7 @@ static int ath11k_wmi_tlv_svc_rdy_parse(struct ath11k_base *ab, u16 tag, u16 len
|
||||
const void *ptr, void *data)
|
||||
{
|
||||
struct wmi_tlv_svc_ready_parse *svc_ready = data;
|
||||
struct ath11k_pdev_wmi *wmi_handle = &ab->wmi_sc.wmi[0];
|
||||
struct ath11k_pdev_wmi *wmi_handle = &ab->wmi_ab.wmi[0];
|
||||
u16 expect_len;
|
||||
|
||||
switch (tag) {
|
||||
@ -538,7 +538,7 @@ int ath11k_wmi_mgmt_send(struct ath11k *ar, u32 vdev_id, u32 buf_id,
|
||||
|
||||
len = sizeof(*cmd) + sizeof(*frame_tlv) + roundup(buf_len, 4);
|
||||
|
||||
skb = ath11k_wmi_alloc_skb(wmi->wmi_sc, len);
|
||||
skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, len);
|
||||
if (!skb)
|
||||
return -ENOMEM;
|
||||
|
||||
@ -590,7 +590,7 @@ int ath11k_wmi_vdev_create(struct ath11k *ar, u8 *macaddr,
|
||||
len = sizeof(*cmd) + TLV_HDR_SIZE +
|
||||
(WMI_NUM_SUPPORTED_BAND_MAX * sizeof(*txrx_streams));
|
||||
|
||||
skb = ath11k_wmi_alloc_skb(wmi->wmi_sc, len);
|
||||
skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, len);
|
||||
if (!skb)
|
||||
return -ENOMEM;
|
||||
|
||||
@ -656,7 +656,7 @@ int ath11k_wmi_vdev_delete(struct ath11k *ar, u8 vdev_id)
|
||||
struct sk_buff *skb;
|
||||
int ret;
|
||||
|
||||
skb = ath11k_wmi_alloc_skb(wmi->wmi_sc, sizeof(*cmd));
|
||||
skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, sizeof(*cmd));
|
||||
if (!skb)
|
||||
return -ENOMEM;
|
||||
|
||||
@ -683,7 +683,7 @@ int ath11k_wmi_vdev_stop(struct ath11k *ar, u8 vdev_id)
|
||||
struct sk_buff *skb;
|
||||
int ret;
|
||||
|
||||
skb = ath11k_wmi_alloc_skb(wmi->wmi_sc, sizeof(*cmd));
|
||||
skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, sizeof(*cmd));
|
||||
if (!skb)
|
||||
return -ENOMEM;
|
||||
|
||||
@ -711,7 +711,7 @@ int ath11k_wmi_vdev_down(struct ath11k *ar, u8 vdev_id)
|
||||
struct sk_buff *skb;
|
||||
int ret;
|
||||
|
||||
skb = ath11k_wmi_alloc_skb(wmi->wmi_sc, sizeof(*cmd));
|
||||
skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, sizeof(*cmd));
|
||||
if (!skb)
|
||||
return -ENOMEM;
|
||||
|
||||
@ -789,7 +789,7 @@ int ath11k_wmi_vdev_start(struct ath11k *ar, struct wmi_vdev_start_req_arg *arg,
|
||||
|
||||
len = sizeof(*cmd) + sizeof(*chan) + TLV_HDR_SIZE;
|
||||
|
||||
skb = ath11k_wmi_alloc_skb(wmi->wmi_sc, len);
|
||||
skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, len);
|
||||
if (!skb)
|
||||
return -ENOMEM;
|
||||
|
||||
@ -867,7 +867,7 @@ int ath11k_wmi_vdev_up(struct ath11k *ar, u32 vdev_id, u32 aid, const u8 *bssid)
|
||||
struct sk_buff *skb;
|
||||
int ret;
|
||||
|
||||
skb = ath11k_wmi_alloc_skb(wmi->wmi_sc, sizeof(*cmd));
|
||||
skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, sizeof(*cmd));
|
||||
if (!skb)
|
||||
return -ENOMEM;
|
||||
|
||||
@ -901,7 +901,7 @@ int ath11k_wmi_send_peer_create_cmd(struct ath11k *ar,
|
||||
struct sk_buff *skb;
|
||||
int ret;
|
||||
|
||||
skb = ath11k_wmi_alloc_skb(wmi->wmi_sc, sizeof(*cmd));
|
||||
skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, sizeof(*cmd));
|
||||
if (!skb)
|
||||
return -ENOMEM;
|
||||
|
||||
@ -934,7 +934,7 @@ int ath11k_wmi_send_peer_delete_cmd(struct ath11k *ar,
|
||||
struct sk_buff *skb;
|
||||
int ret;
|
||||
|
||||
skb = ath11k_wmi_alloc_skb(wmi->wmi_sc, sizeof(*cmd));
|
||||
skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, sizeof(*cmd));
|
||||
if (!skb)
|
||||
return -ENOMEM;
|
||||
|
||||
@ -966,7 +966,7 @@ int ath11k_wmi_send_pdev_set_regdomain(struct ath11k *ar,
|
||||
struct sk_buff *skb;
|
||||
int ret;
|
||||
|
||||
skb = ath11k_wmi_alloc_skb(wmi->wmi_sc, sizeof(*cmd));
|
||||
skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, sizeof(*cmd));
|
||||
if (!skb)
|
||||
return -ENOMEM;
|
||||
|
||||
@ -1006,7 +1006,7 @@ int ath11k_wmi_set_peer_param(struct ath11k *ar, const u8 *peer_addr,
|
||||
struct sk_buff *skb;
|
||||
int ret;
|
||||
|
||||
skb = ath11k_wmi_alloc_skb(wmi->wmi_sc, sizeof(*cmd));
|
||||
skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, sizeof(*cmd));
|
||||
if (!skb)
|
||||
return -ENOMEM;
|
||||
|
||||
@ -1040,7 +1040,7 @@ int ath11k_wmi_send_peer_flush_tids_cmd(struct ath11k *ar,
|
||||
struct sk_buff *skb;
|
||||
int ret;
|
||||
|
||||
skb = ath11k_wmi_alloc_skb(wmi->wmi_sc, sizeof(*cmd));
|
||||
skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, sizeof(*cmd));
|
||||
if (!skb)
|
||||
return -ENOMEM;
|
||||
|
||||
@ -1076,7 +1076,7 @@ int ath11k_wmi_peer_rx_reorder_queue_setup(struct ath11k *ar,
|
||||
struct sk_buff *skb;
|
||||
int ret;
|
||||
|
||||
skb = ath11k_wmi_alloc_skb(ar->wmi->wmi_sc, sizeof(*cmd));
|
||||
skb = ath11k_wmi_alloc_skb(ar->wmi->wmi_ab, sizeof(*cmd));
|
||||
if (!skb)
|
||||
return -ENOMEM;
|
||||
|
||||
@ -1118,7 +1118,7 @@ ath11k_wmi_rx_reord_queue_remove(struct ath11k *ar,
|
||||
struct sk_buff *skb;
|
||||
int ret;
|
||||
|
||||
skb = ath11k_wmi_alloc_skb(wmi->wmi_sc, sizeof(*cmd));
|
||||
skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, sizeof(*cmd));
|
||||
if (!skb)
|
||||
return -ENOMEM;
|
||||
|
||||
@ -1154,7 +1154,7 @@ int ath11k_wmi_pdev_set_param(struct ath11k *ar, u32 param_id,
|
||||
struct sk_buff *skb;
|
||||
int ret;
|
||||
|
||||
skb = ath11k_wmi_alloc_skb(wmi->wmi_sc, sizeof(*cmd));
|
||||
skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, sizeof(*cmd));
|
||||
if (!skb)
|
||||
return -ENOMEM;
|
||||
|
||||
@ -1178,6 +1178,36 @@ int ath11k_wmi_pdev_set_param(struct ath11k *ar, u32 param_id,
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ath11k_wmi_pdev_set_ps_mode(struct ath11k *ar, int vdev_id, u32 enable)
|
||||
{
|
||||
struct ath11k_pdev_wmi *wmi = ar->wmi;
|
||||
struct wmi_pdev_set_ps_mode_cmd *cmd;
|
||||
struct sk_buff *skb;
|
||||
int ret;
|
||||
|
||||
skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, sizeof(*cmd));
|
||||
if (!skb)
|
||||
return -ENOMEM;
|
||||
|
||||
cmd = (struct wmi_pdev_set_ps_mode_cmd *)skb->data;
|
||||
cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_STA_POWERSAVE_MODE_CMD) |
|
||||
FIELD_PREP(WMI_TLV_LEN, sizeof(*cmd) - TLV_HDR_SIZE);
|
||||
cmd->vdev_id = vdev_id;
|
||||
cmd->sta_ps_mode = enable;
|
||||
|
||||
ret = ath11k_wmi_cmd_send(wmi, skb, WMI_STA_POWERSAVE_MODE_CMDID);
|
||||
if (ret) {
|
||||
ath11k_warn(ar->ab, "failed to send WMI_PDEV_SET_PARAM cmd\n");
|
||||
dev_kfree_skb(skb);
|
||||
}
|
||||
|
||||
ath11k_dbg(ar->ab, ATH11K_DBG_WMI,
|
||||
"WMI vdev set psmode %d vdev id %d\n",
|
||||
enable, vdev_id);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ath11k_wmi_pdev_suspend(struct ath11k *ar, u32 suspend_opt,
|
||||
u32 pdev_id)
|
||||
{
|
||||
@ -1186,7 +1216,7 @@ int ath11k_wmi_pdev_suspend(struct ath11k *ar, u32 suspend_opt,
|
||||
struct sk_buff *skb;
|
||||
int ret;
|
||||
|
||||
skb = ath11k_wmi_alloc_skb(wmi->wmi_sc, sizeof(*cmd));
|
||||
skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, sizeof(*cmd));
|
||||
if (!skb)
|
||||
return -ENOMEM;
|
||||
|
||||
@ -1217,7 +1247,7 @@ int ath11k_wmi_pdev_resume(struct ath11k *ar, u32 pdev_id)
|
||||
struct sk_buff *skb;
|
||||
int ret;
|
||||
|
||||
skb = ath11k_wmi_alloc_skb(wmi->wmi_sc, sizeof(*cmd));
|
||||
skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, sizeof(*cmd));
|
||||
if (!skb)
|
||||
return -ENOMEM;
|
||||
|
||||
@ -1251,7 +1281,7 @@ int ath11k_wmi_pdev_bss_chan_info_request(struct ath11k *ar,
|
||||
struct sk_buff *skb;
|
||||
int ret;
|
||||
|
||||
skb = ath11k_wmi_alloc_skb(wmi->wmi_sc, sizeof(*cmd));
|
||||
skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, sizeof(*cmd));
|
||||
if (!skb)
|
||||
return -ENOMEM;
|
||||
|
||||
@ -1284,7 +1314,7 @@ int ath11k_wmi_send_set_ap_ps_param_cmd(struct ath11k *ar, u8 *peer_addr,
|
||||
struct sk_buff *skb;
|
||||
int ret;
|
||||
|
||||
skb = ath11k_wmi_alloc_skb(wmi->wmi_sc, sizeof(*cmd));
|
||||
skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, sizeof(*cmd));
|
||||
if (!skb)
|
||||
return -ENOMEM;
|
||||
|
||||
@ -1319,7 +1349,7 @@ int ath11k_wmi_set_sta_ps_param(struct ath11k *ar, u32 vdev_id,
|
||||
struct sk_buff *skb;
|
||||
int ret;
|
||||
|
||||
skb = ath11k_wmi_alloc_skb(wmi->wmi_sc, sizeof(*cmd));
|
||||
skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, sizeof(*cmd));
|
||||
if (!skb)
|
||||
return -ENOMEM;
|
||||
|
||||
@ -1354,7 +1384,7 @@ int ath11k_wmi_force_fw_hang_cmd(struct ath11k *ar, u32 type, u32 delay_time_ms)
|
||||
|
||||
len = sizeof(*cmd);
|
||||
|
||||
skb = ath11k_wmi_alloc_skb(wmi->wmi_sc, len);
|
||||
skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, len);
|
||||
if (!skb)
|
||||
return -ENOMEM;
|
||||
|
||||
@ -1382,7 +1412,7 @@ int ath11k_wmi_vdev_set_param_cmd(struct ath11k *ar, u32 vdev_id,
|
||||
struct sk_buff *skb;
|
||||
int ret;
|
||||
|
||||
skb = ath11k_wmi_alloc_skb(wmi->wmi_sc, sizeof(*cmd));
|
||||
skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, sizeof(*cmd));
|
||||
if (!skb)
|
||||
return -ENOMEM;
|
||||
|
||||
@ -1416,7 +1446,7 @@ int ath11k_wmi_send_stats_request_cmd(struct ath11k *ar,
|
||||
struct sk_buff *skb;
|
||||
int ret;
|
||||
|
||||
skb = ath11k_wmi_alloc_skb(wmi->wmi_sc, sizeof(*cmd));
|
||||
skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, sizeof(*cmd));
|
||||
if (!skb)
|
||||
return -ENOMEM;
|
||||
|
||||
@ -1449,7 +1479,7 @@ int ath11k_wmi_send_bcn_offload_control_cmd(struct ath11k *ar,
|
||||
struct sk_buff *skb;
|
||||
int ret;
|
||||
|
||||
skb = ath11k_wmi_alloc_skb(wmi->wmi_sc, sizeof(*cmd));
|
||||
skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, sizeof(*cmd));
|
||||
if (!skb)
|
||||
return -ENOMEM;
|
||||
|
||||
@ -1490,7 +1520,7 @@ int ath11k_wmi_bcn_tmpl(struct ath11k *ar, u32 vdev_id,
|
||||
|
||||
len = sizeof(*cmd) + sizeof(*bcn_prb_info) + TLV_HDR_SIZE + aligned_len;
|
||||
|
||||
skb = ath11k_wmi_alloc_skb(wmi->wmi_sc, len);
|
||||
skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, len);
|
||||
if (!skb)
|
||||
return -ENOMEM;
|
||||
|
||||
@ -1541,7 +1571,7 @@ int ath11k_wmi_vdev_install_key(struct ath11k *ar,
|
||||
|
||||
len = sizeof(*cmd) + TLV_HDR_SIZE + key_len_aligned;
|
||||
|
||||
skb = ath11k_wmi_alloc_skb(wmi->wmi_sc, len);
|
||||
skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, len);
|
||||
if (!skb)
|
||||
return -ENOMEM;
|
||||
|
||||
@ -1687,7 +1717,7 @@ int ath11k_wmi_send_peer_assoc_cmd(struct ath11k *ar,
|
||||
sizeof(*mcs) + TLV_HDR_SIZE +
|
||||
(sizeof(*he_mcs) * param->peer_he_mcs_count);
|
||||
|
||||
skb = ath11k_wmi_alloc_skb(wmi->wmi_sc, len);
|
||||
skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, len);
|
||||
if (!skb)
|
||||
return -ENOMEM;
|
||||
|
||||
@ -1953,7 +1983,7 @@ int ath11k_wmi_send_scan_start_cmd(struct ath11k *ar,
|
||||
roundup(params->extraie.len, sizeof(u32));
|
||||
len += extraie_len_with_pad;
|
||||
|
||||
skb = ath11k_wmi_alloc_skb(wmi->wmi_sc, len);
|
||||
skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, len);
|
||||
if (!skb)
|
||||
return -ENOMEM;
|
||||
|
||||
@ -2069,7 +2099,7 @@ int ath11k_wmi_send_scan_stop_cmd(struct ath11k *ar,
|
||||
struct sk_buff *skb;
|
||||
int ret;
|
||||
|
||||
skb = ath11k_wmi_alloc_skb(wmi->wmi_sc, sizeof(*cmd));
|
||||
skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, sizeof(*cmd));
|
||||
if (!skb)
|
||||
return -ENOMEM;
|
||||
|
||||
@ -2125,7 +2155,7 @@ int ath11k_wmi_send_scan_chan_list_cmd(struct ath11k *ar,
|
||||
len = sizeof(*cmd) + TLV_HDR_SIZE +
|
||||
sizeof(*chan_info) * chan_list->nallchans;
|
||||
|
||||
skb = ath11k_wmi_alloc_skb(wmi->wmi_sc, len);
|
||||
skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, len);
|
||||
if (!skb)
|
||||
return -ENOMEM;
|
||||
|
||||
@ -2217,7 +2247,7 @@ int ath11k_wmi_send_wmm_update_cmd_tlv(struct ath11k *ar, u32 vdev_id,
|
||||
struct sk_buff *skb;
|
||||
int ret, ac;
|
||||
|
||||
skb = ath11k_wmi_alloc_skb(wmi->wmi_sc, sizeof(*cmd));
|
||||
skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, sizeof(*cmd));
|
||||
if (!skb)
|
||||
return -ENOMEM;
|
||||
|
||||
@ -2284,7 +2314,7 @@ int ath11k_wmi_send_dfs_phyerr_offload_enable_cmd(struct ath11k *ar,
|
||||
struct sk_buff *skb;
|
||||
int ret;
|
||||
|
||||
skb = ath11k_wmi_alloc_skb(wmi->wmi_sc, sizeof(*cmd));
|
||||
skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, sizeof(*cmd));
|
||||
if (!skb)
|
||||
return -ENOMEM;
|
||||
|
||||
@ -2321,7 +2351,7 @@ int ath11k_wmi_pdev_peer_pktlog_filter(struct ath11k *ar, u8 *addr, u8 enable)
|
||||
int ret, len;
|
||||
|
||||
len = sizeof(*cmd) + sizeof(*info) + TLV_HDR_SIZE;
|
||||
skb = ath11k_wmi_alloc_skb(wmi->wmi_sc, len);
|
||||
skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, len);
|
||||
if (!skb)
|
||||
return -ENOMEM;
|
||||
|
||||
@ -2367,7 +2397,7 @@ ath11k_wmi_send_init_country_cmd(struct ath11k *ar,
|
||||
struct sk_buff *skb;
|
||||
int ret;
|
||||
|
||||
skb = ath11k_wmi_alloc_skb(wmi->wmi_sc, sizeof(*cmd));
|
||||
skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, sizeof(*cmd));
|
||||
if (!skb)
|
||||
return -ENOMEM;
|
||||
|
||||
@ -2419,7 +2449,7 @@ int ath11k_wmi_pdev_pktlog_enable(struct ath11k *ar, u32 pktlog_filter)
|
||||
struct sk_buff *skb;
|
||||
int ret;
|
||||
|
||||
skb = ath11k_wmi_alloc_skb(wmi->wmi_sc, sizeof(*cmd));
|
||||
skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, sizeof(*cmd));
|
||||
if (!skb)
|
||||
return -ENOMEM;
|
||||
|
||||
@ -2449,7 +2479,7 @@ int ath11k_wmi_pdev_pktlog_disable(struct ath11k *ar)
|
||||
struct sk_buff *skb;
|
||||
int ret;
|
||||
|
||||
skb = ath11k_wmi_alloc_skb(wmi->wmi_sc, sizeof(*cmd));
|
||||
skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, sizeof(*cmd));
|
||||
if (!skb)
|
||||
return -ENOMEM;
|
||||
|
||||
@ -2474,18 +2504,18 @@ int
|
||||
ath11k_wmi_send_twt_enable_cmd(struct ath11k *ar, u32 pdev_id)
|
||||
{
|
||||
struct ath11k_pdev_wmi *wmi = ar->wmi;
|
||||
struct ath11k_base *ab = wmi->wmi_sc->ab;
|
||||
struct ath11k_base *ab = wmi->wmi_ab->ab;
|
||||
struct wmi_twt_enable_params_cmd *cmd;
|
||||
struct sk_buff *skb;
|
||||
int ret, len;
|
||||
|
||||
len = sizeof(*cmd);
|
||||
|
||||
skb = ath11k_wmi_alloc_skb(wmi->wmi_sc, len);
|
||||
skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, len);
|
||||
if (!skb)
|
||||
return -ENOMEM;
|
||||
|
||||
cmd = (void *)skb->data;
|
||||
cmd = (struct wmi_twt_enable_params_cmd *)skb->data;
|
||||
cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_TWT_ENABLE_CMD) |
|
||||
FIELD_PREP(WMI_TLV_LEN, len - TLV_HDR_SIZE);
|
||||
cmd->pdev_id = pdev_id;
|
||||
@ -2525,18 +2555,18 @@ int
|
||||
ath11k_wmi_send_twt_disable_cmd(struct ath11k *ar, u32 pdev_id)
|
||||
{
|
||||
struct ath11k_pdev_wmi *wmi = ar->wmi;
|
||||
struct ath11k_base *ab = wmi->wmi_sc->ab;
|
||||
struct ath11k_base *ab = wmi->wmi_ab->ab;
|
||||
struct wmi_twt_disable_params_cmd *cmd;
|
||||
struct sk_buff *skb;
|
||||
int ret, len;
|
||||
|
||||
len = sizeof(*cmd);
|
||||
|
||||
skb = ath11k_wmi_alloc_skb(wmi->wmi_sc, len);
|
||||
skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, len);
|
||||
if (!skb)
|
||||
return -ENOMEM;
|
||||
|
||||
cmd = (void *)skb->data;
|
||||
cmd = (struct wmi_twt_disable_params_cmd *)skb->data;
|
||||
cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_TWT_DISABLE_CMD) |
|
||||
FIELD_PREP(WMI_TLV_LEN, len - TLV_HDR_SIZE);
|
||||
cmd->pdev_id = pdev_id;
|
||||
@ -2544,7 +2574,7 @@ ath11k_wmi_send_twt_disable_cmd(struct ath11k *ar, u32 pdev_id)
|
||||
ret = ath11k_wmi_cmd_send(wmi, skb,
|
||||
WMI_TWT_DISABLE_CMDID);
|
||||
if (ret) {
|
||||
ath11k_warn(ab, "Failed to send WMI_TWT_DIeABLE_CMDID");
|
||||
ath11k_warn(ab, "Failed to send WMI_TWT_DISABLE_CMDID");
|
||||
dev_kfree_skb(skb);
|
||||
}
|
||||
return ret;
|
||||
@ -2555,18 +2585,18 @@ ath11k_wmi_send_obss_spr_cmd(struct ath11k *ar, u32 vdev_id,
|
||||
struct ieee80211_he_obss_pd *he_obss_pd)
|
||||
{
|
||||
struct ath11k_pdev_wmi *wmi = ar->wmi;
|
||||
struct ath11k_base *ab = wmi->wmi_sc->ab;
|
||||
struct ath11k_base *ab = wmi->wmi_ab->ab;
|
||||
struct wmi_obss_spatial_reuse_params_cmd *cmd;
|
||||
struct sk_buff *skb;
|
||||
int ret, len;
|
||||
|
||||
len = sizeof(*cmd);
|
||||
|
||||
skb = ath11k_wmi_alloc_skb(wmi->wmi_sc, len);
|
||||
skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, len);
|
||||
if (!skb)
|
||||
return -ENOMEM;
|
||||
|
||||
cmd = (void *)skb->data;
|
||||
cmd = (struct wmi_obss_spatial_reuse_params_cmd *)skb->data;
|
||||
cmd->tlv_header = FIELD_PREP(WMI_TLV_TAG,
|
||||
WMI_TAG_OBSS_SPATIAL_REUSE_SET_CMD) |
|
||||
FIELD_PREP(WMI_TLV_LEN, len - TLV_HDR_SIZE);
|
||||
@ -2684,7 +2714,7 @@ ath11k_wmi_copy_resource_config(struct wmi_resource_config *wmi_cfg,
|
||||
static int ath11k_init_cmd_send(struct ath11k_pdev_wmi *wmi,
|
||||
struct wmi_init_cmd_param *param)
|
||||
{
|
||||
struct ath11k_base *ab = wmi->wmi_sc->ab;
|
||||
struct ath11k_base *ab = wmi->wmi_ab->ab;
|
||||
struct sk_buff *skb;
|
||||
struct wmi_init_cmd *cmd;
|
||||
struct wmi_resource_config *cfg;
|
||||
@ -2704,7 +2734,7 @@ static int ath11k_init_cmd_send(struct ath11k_pdev_wmi *wmi,
|
||||
len = sizeof(*cmd) + TLV_HDR_SIZE + sizeof(*cfg) + hw_mode_len +
|
||||
(sizeof(*host_mem_chunks) * WMI_MAX_MEM_REQS);
|
||||
|
||||
skb = ath11k_wmi_alloc_skb(wmi->wmi_sc, len);
|
||||
skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, len);
|
||||
if (!skb)
|
||||
return -ENOMEM;
|
||||
|
||||
@ -2799,7 +2829,7 @@ int ath11k_wmi_wait_for_service_ready(struct ath11k_base *ab)
|
||||
{
|
||||
unsigned long time_left;
|
||||
|
||||
time_left = wait_for_completion_timeout(&ab->wmi_sc.service_ready,
|
||||
time_left = wait_for_completion_timeout(&ab->wmi_ab.service_ready,
|
||||
WMI_SERVICE_READY_TIMEOUT_HZ);
|
||||
if (!time_left)
|
||||
return -ETIMEDOUT;
|
||||
@ -2811,7 +2841,7 @@ int ath11k_wmi_wait_for_unified_ready(struct ath11k_base *ab)
|
||||
{
|
||||
unsigned long time_left;
|
||||
|
||||
time_left = wait_for_completion_timeout(&ab->wmi_sc.unified_ready,
|
||||
time_left = wait_for_completion_timeout(&ab->wmi_ab.unified_ready,
|
||||
WMI_SERVICE_READY_TIMEOUT_HZ);
|
||||
if (!time_left)
|
||||
return -ETIMEDOUT;
|
||||
@ -2821,7 +2851,7 @@ int ath11k_wmi_wait_for_unified_ready(struct ath11k_base *ab)
|
||||
|
||||
int ath11k_wmi_cmd_init(struct ath11k_base *ab)
|
||||
{
|
||||
struct ath11k_wmi_base *wmi_sc = &ab->wmi_sc;
|
||||
struct ath11k_wmi_base *wmi_sc = &ab->wmi_ab;
|
||||
struct wmi_init_cmd_param init_param;
|
||||
struct target_resource_config config;
|
||||
|
||||
@ -2941,16 +2971,16 @@ static int ath11k_wmi_tlv_hw_mode_caps(struct ath11k_base *soc,
|
||||
while (i < svc_rdy_ext->n_hw_mode_caps) {
|
||||
hw_mode_caps = &svc_rdy_ext->hw_mode_caps[i];
|
||||
mode = hw_mode_caps->hw_mode_id;
|
||||
pref = soc->wmi_sc.preferred_hw_mode;
|
||||
pref = soc->wmi_ab.preferred_hw_mode;
|
||||
|
||||
if (ath11k_hw_mode_pri_map[mode] < ath11k_hw_mode_pri_map[pref]) {
|
||||
svc_rdy_ext->pref_hw_mode_caps = *hw_mode_caps;
|
||||
soc->wmi_sc.preferred_hw_mode = mode;
|
||||
soc->wmi_ab.preferred_hw_mode = mode;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
if (soc->wmi_sc.preferred_hw_mode == WMI_HOST_HW_MODE_MAX)
|
||||
if (soc->wmi_ab.preferred_hw_mode == WMI_HOST_HW_MODE_MAX)
|
||||
return -EINVAL;
|
||||
|
||||
return 0;
|
||||
@ -3000,7 +3030,7 @@ static int ath11k_wmi_tlv_ext_hal_reg_caps_parse(struct ath11k_base *soc,
|
||||
static int ath11k_wmi_tlv_ext_hal_reg_caps(struct ath11k_base *soc,
|
||||
u16 len, const void *ptr, void *data)
|
||||
{
|
||||
struct ath11k_pdev_wmi *wmi_handle = &soc->wmi_sc.wmi[0];
|
||||
struct ath11k_pdev_wmi *wmi_handle = &soc->wmi_ab.wmi[0];
|
||||
struct wmi_tlv_svc_rdy_ext_parse *svc_rdy_ext = data;
|
||||
struct ath11k_hal_reg_capabilities_ext reg_cap;
|
||||
int ret;
|
||||
@ -3036,7 +3066,7 @@ static int ath11k_wmi_tlv_ext_soc_hal_reg_caps_parse(struct ath11k_base *soc,
|
||||
u16 len, const void *ptr,
|
||||
void *data)
|
||||
{
|
||||
struct ath11k_pdev_wmi *wmi_handle = &soc->wmi_sc.wmi[0];
|
||||
struct ath11k_pdev_wmi *wmi_handle = &soc->wmi_ab.wmi[0];
|
||||
struct wmi_tlv_svc_rdy_ext_parse *svc_rdy_ext = data;
|
||||
u8 hw_mode_id = svc_rdy_ext->pref_hw_mode_caps.hw_mode_id;
|
||||
u32 phy_id_map;
|
||||
@ -3074,7 +3104,7 @@ static int ath11k_wmi_tlv_svc_rdy_ext_parse(struct ath11k_base *ab,
|
||||
u16 tag, u16 len,
|
||||
const void *ptr, void *data)
|
||||
{
|
||||
struct ath11k_pdev_wmi *wmi_handle = &ab->wmi_sc.wmi[0];
|
||||
struct ath11k_pdev_wmi *wmi_handle = &ab->wmi_ab.wmi[0];
|
||||
struct wmi_tlv_svc_rdy_ext_parse *svc_rdy_ext = data;
|
||||
int ret;
|
||||
|
||||
@ -3126,7 +3156,7 @@ static int ath11k_wmi_tlv_svc_rdy_ext_parse(struct ath11k_base *ab,
|
||||
return ret;
|
||||
|
||||
svc_rdy_ext->ext_hal_reg_done = true;
|
||||
complete(&ab->wmi_sc.service_ready);
|
||||
complete(&ab->wmi_ab.service_ready);
|
||||
}
|
||||
break;
|
||||
|
||||
@ -4468,7 +4498,7 @@ void ath11k_wmi_fw_stats_fill(struct ath11k *ar,
|
||||
static void ath11k_wmi_op_ep_tx_credits(struct ath11k_base *ab)
|
||||
{
|
||||
/* try to send pending beacons first. they take priority */
|
||||
wake_up(&ab->wmi_sc.tx_credits_wq);
|
||||
wake_up(&ab->wmi_ab.tx_credits_wq);
|
||||
}
|
||||
|
||||
static void ath11k_wmi_htc_tx_complete(struct ath11k_base *ab,
|
||||
@ -4522,7 +4552,7 @@ static int ath11k_reg_chan_list_event(struct ath11k_base *ab, struct sk_buff *sk
|
||||
if (ab->default_regd[pdev_idx] && !ab->new_regd[pdev_idx] &&
|
||||
!memcmp((char *)ab->default_regd[pdev_idx]->alpha2,
|
||||
(char *)reg_info->alpha2, 2))
|
||||
return 0;
|
||||
goto mem_free;
|
||||
|
||||
/* Intersect new rules with default regd if a new country setting was
|
||||
* requested, i.e a default regd was already set during initialization
|
||||
@ -4638,7 +4668,7 @@ static int ath11k_ready_event(struct ath11k_base *ab, struct sk_buff *skb)
|
||||
return ret;
|
||||
}
|
||||
|
||||
complete(&ab->wmi_sc.unified_ready);
|
||||
complete(&ab->wmi_ab.unified_ready);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -5289,7 +5319,7 @@ static void ath11k_service_available_event(struct ath11k_base *ab, struct sk_buf
|
||||
do {
|
||||
if (ev->wmi_service_segment_bitmap[i] &
|
||||
BIT(j % WMI_AVAIL_SERVICE_BITS_IN_SIZE32))
|
||||
set_bit(j, ab->wmi_sc.svc_map);
|
||||
set_bit(j, ab->wmi_ab.svc_map);
|
||||
} while (++j % WMI_AVAIL_SERVICE_BITS_IN_SIZE32);
|
||||
}
|
||||
|
||||
@ -5609,9 +5639,9 @@ static int ath11k_connect_pdev_htc_service(struct ath11k_base *ab,
|
||||
return status;
|
||||
}
|
||||
|
||||
ab->wmi_sc.wmi_endpoint_id[pdev_idx] = conn_resp.eid;
|
||||
ab->wmi_sc.wmi[pdev_idx].eid = conn_resp.eid;
|
||||
ab->wmi_sc.max_msg_len[pdev_idx] = conn_resp.max_msg_len;
|
||||
ab->wmi_ab.wmi_endpoint_id[pdev_idx] = conn_resp.eid;
|
||||
ab->wmi_ab.wmi[pdev_idx].eid = conn_resp.eid;
|
||||
ab->wmi_ab.max_msg_len[pdev_idx] = conn_resp.max_msg_len;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -5634,7 +5664,7 @@ ath11k_wmi_send_unit_test_cmd(struct ath11k *ar,
|
||||
arg_len = sizeof(u32) * ut_cmd.num_args;
|
||||
buf_len = sizeof(ut_cmd) + arg_len + TLV_HDR_SIZE;
|
||||
|
||||
skb = ath11k_wmi_alloc_skb(wmi->wmi_sc, buf_len);
|
||||
skb = ath11k_wmi_alloc_skb(wmi->wmi_ab, buf_len);
|
||||
if (!skb)
|
||||
return -ENOMEM;
|
||||
|
||||
@ -5741,11 +5771,11 @@ int ath11k_wmi_pdev_attach(struct ath11k_base *ab,
|
||||
if (pdev_id >= MAX_RADIOS)
|
||||
return -EINVAL;
|
||||
|
||||
wmi_handle = &ab->wmi_sc.wmi[pdev_id];
|
||||
wmi_handle = &ab->wmi_ab.wmi[pdev_id];
|
||||
|
||||
wmi_handle->wmi_sc = &ab->wmi_sc;
|
||||
wmi_handle->wmi_ab = &ab->wmi_ab;
|
||||
|
||||
ab->wmi_sc.ab = ab;
|
||||
ab->wmi_ab.ab = ab;
|
||||
/* TODO: Init remaining resource specific to pdev */
|
||||
|
||||
return 0;
|
||||
@ -5759,12 +5789,12 @@ int ath11k_wmi_attach(struct ath11k_base *ab)
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ab->wmi_sc.ab = ab;
|
||||
ab->wmi_sc.preferred_hw_mode = WMI_HOST_HW_MODE_MAX;
|
||||
ab->wmi_ab.ab = ab;
|
||||
ab->wmi_ab.preferred_hw_mode = WMI_HOST_HW_MODE_MAX;
|
||||
|
||||
/* TODO: Init remaining wmi soc resources required */
|
||||
init_completion(&ab->wmi_sc.service_ready);
|
||||
init_completion(&ab->wmi_sc.unified_ready);
|
||||
init_completion(&ab->wmi_ab.service_ready);
|
||||
init_completion(&ab->wmi_ab.unified_ready);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -44,7 +44,7 @@ struct wmi_tlv {
|
||||
|
||||
#define WMI_TLV_LEN GENMASK(15, 0)
|
||||
#define WMI_TLV_TAG GENMASK(31, 16)
|
||||
#define TLV_HDR_SIZE FIELD_SIZEOF(struct wmi_tlv, header)
|
||||
#define TLV_HDR_SIZE sizeof_field(struct wmi_tlv, header)
|
||||
|
||||
#define WMI_CMD_HDR_CMD_ID GENMASK(23, 0)
|
||||
#define WMI_MAX_MEM_REQS 32
|
||||
@ -54,6 +54,7 @@ struct wmi_tlv {
|
||||
#define WLAN_SCAN_PARAMS_MAX_BSSID 4
|
||||
#define WLAN_SCAN_PARAMS_MAX_IE_LEN 256
|
||||
|
||||
#define WMI_BA_MODE_BUFFER_SIZE_256 3
|
||||
/*
|
||||
* HW mode config type replicated from FW header
|
||||
* @WMI_HOST_HW_MODE_SINGLE: Only one PHY is active.
|
||||
@ -1003,6 +1004,7 @@ enum wmi_tlv_vdev_param {
|
||||
WMI_VDEV_PARAM_HE_RANGE_EXT,
|
||||
WMI_VDEV_PARAM_ENABLE_BCAST_PROBE_RESPONSE,
|
||||
WMI_VDEV_PARAM_FILS_MAX_CHANNEL_GUARD_TIME,
|
||||
WMI_VDEV_PARAM_BA_MODE = 0x7e,
|
||||
WMI_VDEV_PARAM_SET_HE_SOUNDING_MODE = 0x87,
|
||||
WMI_VDEV_PARAM_PROTOTYPE = 0x8000,
|
||||
WMI_VDEV_PARAM_BSS_COLOR,
|
||||
@ -2354,7 +2356,7 @@ struct wmi_service_available_event {
|
||||
} __packed;
|
||||
|
||||
struct ath11k_pdev_wmi {
|
||||
struct ath11k_wmi_base *wmi_sc;
|
||||
struct ath11k_wmi_base *wmi_ab;
|
||||
enum ath11k_htc_ep_id eid;
|
||||
const struct wmi_peer_flags_map *peer_flags;
|
||||
u32 rx_decap_mode;
|
||||
@ -2567,7 +2569,7 @@ static inline const char *ath11k_wmi_phymode_str(enum wmi_phy_mode mode)
|
||||
/* no default handler to allow compiler to check that the
|
||||
* enum is fully handled
|
||||
*/
|
||||
};
|
||||
}
|
||||
|
||||
return "<unknown>";
|
||||
}
|
||||
@ -2827,6 +2829,12 @@ struct wmi_pdev_set_param_cmd {
|
||||
u32 param_value;
|
||||
} __packed;
|
||||
|
||||
struct wmi_pdev_set_ps_mode_cmd {
|
||||
u32 tlv_header;
|
||||
u32 vdev_id;
|
||||
u32 sta_ps_mode;
|
||||
} __packed;
|
||||
|
||||
struct wmi_pdev_suspend_cmd {
|
||||
u32 tlv_header;
|
||||
u32 pdev_id;
|
||||
@ -2896,15 +2904,6 @@ struct wmi_bcn_offload_ctrl_cmd {
|
||||
u32 bcn_ctrl_op;
|
||||
} __packed;
|
||||
|
||||
enum scan_priority {
|
||||
SCAN_PRIORITY_VERY_LOW,
|
||||
SCAN_PRIORITY_LOW,
|
||||
SCAN_PRIORITY_MEDIUM,
|
||||
SCAN_PRIORITY_HIGH,
|
||||
SCAN_PRIORITY_VERY_HIGH,
|
||||
SCAN_PRIORITY_COUNT,
|
||||
};
|
||||
|
||||
enum scan_dwelltime_adaptive_mode {
|
||||
SCAN_DWELL_MODE_DEFAULT = 0,
|
||||
SCAN_DWELL_MODE_CONSERVATIVE = 1,
|
||||
@ -3056,7 +3055,7 @@ struct scan_req_params {
|
||||
u32 scan_req_id;
|
||||
u32 vdev_id;
|
||||
u32 pdev_id;
|
||||
enum scan_priority scan_priority;
|
||||
enum wmi_scan_priority scan_priority;
|
||||
union {
|
||||
struct {
|
||||
u32 scan_ev_started:1,
|
||||
@ -4556,12 +4555,12 @@ struct wmi_twt_enable_params_cmd {
|
||||
u32 mode_check_interval;
|
||||
u32 add_sta_slot_interval;
|
||||
u32 remove_sta_slot_interval;
|
||||
};
|
||||
} __packed;
|
||||
|
||||
struct wmi_twt_disable_params_cmd {
|
||||
u32 tlv_header;
|
||||
u32 pdev_id;
|
||||
};
|
||||
} __packed;
|
||||
|
||||
struct wmi_obss_spatial_reuse_params_cmd {
|
||||
u32 tlv_header;
|
||||
@ -4570,7 +4569,7 @@ struct wmi_obss_spatial_reuse_params_cmd {
|
||||
s32 obss_min;
|
||||
s32 obss_max;
|
||||
u32 vdev_id;
|
||||
};
|
||||
} __packed;
|
||||
|
||||
struct target_resource_config {
|
||||
u32 num_vdevs;
|
||||
@ -4682,6 +4681,7 @@ int ath11k_wmi_set_peer_param(struct ath11k *ar, const u8 *peer_addr,
|
||||
u32 vdev_id, u32 param_id, u32 param_val);
|
||||
int ath11k_wmi_pdev_set_param(struct ath11k *ar, u32 param_id,
|
||||
u32 param_value, u8 pdev_id);
|
||||
int ath11k_wmi_pdev_set_ps_mode(struct ath11k *ar, int vdev_id, u32 enable);
|
||||
int ath11k_wmi_wait_for_unified_ready(struct ath11k_base *ab);
|
||||
int ath11k_wmi_cmd_init(struct ath11k_base *ab);
|
||||
int ath11k_wmi_wait_for_service_ready(struct ath11k_base *ab);
|
||||
|
@ -1216,7 +1216,7 @@ static void ath9k_hif_usb_firmware_cb(const struct firmware *fw, void *context)
|
||||
static int send_eject_command(struct usb_interface *interface)
|
||||
{
|
||||
struct usb_device *udev = interface_to_usbdev(interface);
|
||||
struct usb_host_interface *iface_desc = &interface->altsetting[0];
|
||||
struct usb_host_interface *iface_desc = interface->cur_altsetting;
|
||||
struct usb_endpoint_descriptor *endpoint;
|
||||
unsigned char *cmd;
|
||||
u8 bulk_out_ep;
|
||||
|
@ -1169,7 +1169,6 @@ static int wcn36xx_init_ieee80211(struct wcn36xx *wcn)
|
||||
|
||||
ieee80211_hw_set(wcn->hw, TIMING_BEACON_ONLY);
|
||||
ieee80211_hw_set(wcn->hw, AMPDU_AGGREGATION);
|
||||
ieee80211_hw_set(wcn->hw, CONNECTION_MONITOR);
|
||||
ieee80211_hw_set(wcn->hw, SUPPORTS_PS);
|
||||
ieee80211_hw_set(wcn->hw, SIGNAL_DBM);
|
||||
ieee80211_hw_set(wcn->hw, HAS_RATE_CONTROL);
|
||||
|
@ -2579,6 +2579,38 @@ wil_cfg80211_update_ft_ies(struct wiphy *wiphy, struct net_device *dev,
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int wil_cfg80211_set_multicast_to_unicast(struct wiphy *wiphy,
|
||||
struct net_device *dev,
|
||||
const bool enabled)
|
||||
{
|
||||
struct wil6210_priv *wil = wiphy_to_wil(wiphy);
|
||||
|
||||
if (wil->multicast_to_unicast == enabled)
|
||||
return 0;
|
||||
|
||||
wil_info(wil, "set multicast to unicast, enabled=%d\n", enabled);
|
||||
wil->multicast_to_unicast = enabled;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int wil_cfg80211_set_cqm_rssi_config(struct wiphy *wiphy,
|
||||
struct net_device *dev,
|
||||
s32 rssi_thold, u32 rssi_hyst)
|
||||
{
|
||||
struct wil6210_priv *wil = wiphy_to_wil(wiphy);
|
||||
int rc;
|
||||
|
||||
wil->cqm_rssi_thold = rssi_thold;
|
||||
|
||||
rc = wmi_set_cqm_rssi_config(wil, rssi_thold, rssi_hyst);
|
||||
if (rc)
|
||||
/* reset stored value upon failure */
|
||||
wil->cqm_rssi_thold = 0;
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static const struct cfg80211_ops wil_cfg80211_ops = {
|
||||
.add_virtual_intf = wil_cfg80211_add_iface,
|
||||
.del_virtual_intf = wil_cfg80211_del_iface,
|
||||
@ -2610,11 +2642,13 @@ static const struct cfg80211_ops wil_cfg80211_ops = {
|
||||
.start_p2p_device = wil_cfg80211_start_p2p_device,
|
||||
.stop_p2p_device = wil_cfg80211_stop_p2p_device,
|
||||
.set_power_mgmt = wil_cfg80211_set_power_mgmt,
|
||||
.set_cqm_rssi_config = wil_cfg80211_set_cqm_rssi_config,
|
||||
.suspend = wil_cfg80211_suspend,
|
||||
.resume = wil_cfg80211_resume,
|
||||
.sched_scan_start = wil_cfg80211_sched_scan_start,
|
||||
.sched_scan_stop = wil_cfg80211_sched_scan_stop,
|
||||
.update_ft_ies = wil_cfg80211_update_ft_ies,
|
||||
.set_multicast_to_unicast = wil_cfg80211_set_multicast_to_unicast,
|
||||
};
|
||||
|
||||
static void wil_wiphy_init(struct wiphy *wiphy)
|
||||
|
@ -1654,6 +1654,8 @@ int wil_reset(struct wil6210_priv *wil, bool load_fw)
|
||||
/* Disable device led before reset*/
|
||||
wmi_led_cfg(wil, false);
|
||||
|
||||
down_write(&wil->mem_lock);
|
||||
|
||||
/* prevent NAPI from being scheduled and prevent wmi commands */
|
||||
mutex_lock(&wil->wmi_mutex);
|
||||
if (test_bit(wil_status_suspending, wil->status))
|
||||
@ -1702,6 +1704,7 @@ int wil_reset(struct wil6210_priv *wil, bool load_fw)
|
||||
|
||||
if (wil->secured_boot) {
|
||||
wil_err(wil, "secured boot is not supported\n");
|
||||
up_write(&wil->mem_lock);
|
||||
return -ENOTSUPP;
|
||||
}
|
||||
|
||||
@ -1737,6 +1740,8 @@ int wil_reset(struct wil6210_priv *wil, bool load_fw)
|
||||
|
||||
clear_bit(wil_status_resetting, wil->status);
|
||||
|
||||
up_write(&wil->mem_lock);
|
||||
|
||||
if (load_fw) {
|
||||
wil_unmask_irq(wil);
|
||||
|
||||
@ -1786,6 +1791,7 @@ int wil_reset(struct wil6210_priv *wil, bool load_fw)
|
||||
return rc;
|
||||
|
||||
out:
|
||||
up_write(&wil->mem_lock);
|
||||
clear_bit(wil_status_resetting, wil->status);
|
||||
return rc;
|
||||
}
|
||||
@ -1811,9 +1817,7 @@ int __wil_up(struct wil6210_priv *wil)
|
||||
|
||||
WARN_ON(!mutex_is_locked(&wil->mutex));
|
||||
|
||||
down_write(&wil->mem_lock);
|
||||
rc = wil_reset(wil, true);
|
||||
up_write(&wil->mem_lock);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
@ -1905,9 +1909,7 @@ int __wil_down(struct wil6210_priv *wil)
|
||||
wil_abort_scan_all_vifs(wil, false);
|
||||
mutex_unlock(&wil->vif_mutex);
|
||||
|
||||
down_write(&wil->mem_lock);
|
||||
rc = wil_reset(wil, false);
|
||||
up_write(&wil->mem_lock);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
@ -10,6 +10,7 @@
|
||||
#include <linux/moduleparam.h>
|
||||
#include <linux/ip.h>
|
||||
#include <linux/ipv6.h>
|
||||
#include <linux/if_vlan.h>
|
||||
#include <net/ipv6.h>
|
||||
#include <linux/prefetch.h>
|
||||
|
||||
@ -1529,6 +1530,35 @@ static struct wil_ring *wil_find_tx_bcast_1(struct wil6210_priv *wil,
|
||||
return v;
|
||||
}
|
||||
|
||||
/* apply multicast to unicast only for ARP and IP packets
|
||||
* (see NL80211_CMD_SET_MULTICAST_TO_UNICAST for more info)
|
||||
*/
|
||||
static bool wil_check_multicast_to_unicast(struct wil6210_priv *wil,
|
||||
struct sk_buff *skb)
|
||||
{
|
||||
const struct ethhdr *eth = (void *)skb->data;
|
||||
const struct vlan_ethhdr *ethvlan = (void *)skb->data;
|
||||
__be16 ethertype;
|
||||
|
||||
if (!wil->multicast_to_unicast)
|
||||
return false;
|
||||
|
||||
/* multicast to unicast conversion only for some payload */
|
||||
ethertype = eth->h_proto;
|
||||
if (ethertype == htons(ETH_P_8021Q) && skb->len >= VLAN_ETH_HLEN)
|
||||
ethertype = ethvlan->h_vlan_encapsulated_proto;
|
||||
switch (ethertype) {
|
||||
case htons(ETH_P_ARP):
|
||||
case htons(ETH_P_IP):
|
||||
case htons(ETH_P_IPV6):
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void wil_set_da_for_vring(struct wil6210_priv *wil,
|
||||
struct sk_buff *skb, int vring_index)
|
||||
{
|
||||
@ -2336,7 +2366,7 @@ netdev_tx_t wil_start_xmit(struct sk_buff *skb, struct net_device *ndev)
|
||||
/* in STA mode (ESS), all to same VRING (to AP) */
|
||||
ring = wil_find_tx_ring_sta(wil, vif, skb);
|
||||
} else if (bcast) {
|
||||
if (vif->pbss)
|
||||
if (vif->pbss || wil_check_multicast_to_unicast(wil, skb))
|
||||
/* in pbss, no bcast VRING - duplicate skb in
|
||||
* all stations VRINGs
|
||||
*/
|
||||
|
@ -903,6 +903,11 @@ static struct sk_buff *wil_sring_reap_rx_edma(struct wil6210_priv *wil,
|
||||
if (unlikely(!wil_val_in_range(buff_id, 1, wil->rx_buff_mgmt.size))) {
|
||||
wil_err(wil, "Corrupt buff_id=%d, sring->swhead=%d\n",
|
||||
buff_id, sring->swhead);
|
||||
print_hex_dump(KERN_ERR, "RxS ", DUMP_PREFIX_OFFSET, 16, 1,
|
||||
msg, wil->use_compressed_rx_status ?
|
||||
sizeof(struct wil_rx_status_compressed) :
|
||||
sizeof(struct wil_rx_status_extended), false);
|
||||
|
||||
wil_rx_status_reset_buff_id(sring);
|
||||
wil_sring_advance_swhead(sring);
|
||||
sring->invalid_buff_id_cnt++;
|
||||
@ -963,6 +968,11 @@ static struct sk_buff *wil_sring_reap_rx_edma(struct wil6210_priv *wil,
|
||||
|
||||
if (unlikely(dmalen > sz)) {
|
||||
wil_err(wil, "Rx size too large: %d bytes!\n", dmalen);
|
||||
print_hex_dump(KERN_ERR, "RxS ", DUMP_PREFIX_OFFSET, 16, 1,
|
||||
msg, wil->use_compressed_rx_status ?
|
||||
sizeof(struct wil_rx_status_compressed) :
|
||||
sizeof(struct wil_rx_status_extended), false);
|
||||
|
||||
stats->rx_large_frame++;
|
||||
rxdata->skipping = true;
|
||||
}
|
||||
|
@ -46,7 +46,7 @@
|
||||
|
||||
#define WIL_RX_EDMA_DLPF_LU_MISS_TID_POS 5
|
||||
|
||||
#define WIL_RX_EDMA_MID_VALID_BIT BIT(22)
|
||||
#define WIL_RX_EDMA_MID_VALID_BIT BIT(20)
|
||||
|
||||
#define WIL_EDMA_DESC_TX_MAC_CFG_0_QID_POS 16
|
||||
#define WIL_EDMA_DESC_TX_MAC_CFG_0_QID_LEN 6
|
||||
@ -244,8 +244,8 @@ struct wil_ring_tx_status {
|
||||
* calculated, Bit1- L4Err - TCP/UDP Checksum Error
|
||||
* bit 7 : Reserved:1
|
||||
* bit 8..19 : Flow ID:12 - MSDU flow ID
|
||||
* bit 20..21 : MID:2 - The MAC ID
|
||||
* bit 22 : MID_V:1 - The MAC ID field is valid
|
||||
* bit 20 : MID_V:1 - The MAC ID field is valid
|
||||
* bit 21..22 : MID:2 - The MAC ID
|
||||
* bit 23 : L3T:1 - IP types: 0-IPv6, 1-IPv4
|
||||
* bit 24 : L4T:1 - Layer 4 Type: 0-UDP, 1-TCP
|
||||
* bit 25 : BC:1 - The received MPDU is broadcast
|
||||
@ -479,7 +479,7 @@ static inline int wil_rx_status_get_mid(void *msg)
|
||||
return 0; /* use the default MID */
|
||||
|
||||
return WIL_GET_BITS(((struct wil_rx_status_compressed *)msg)->d0,
|
||||
20, 21);
|
||||
21, 22);
|
||||
}
|
||||
|
||||
static inline int wil_rx_status_get_error(void *msg)
|
||||
|
@ -1059,6 +1059,8 @@ struct wil6210_priv {
|
||||
|
||||
u32 max_agg_wsize;
|
||||
u32 max_ampdu_size;
|
||||
u8 multicast_to_unicast;
|
||||
s32 cqm_rssi_thold;
|
||||
};
|
||||
|
||||
#define wil_to_wiphy(i) (i->wiphy)
|
||||
@ -1148,7 +1150,7 @@ static inline void wil_c(struct wil6210_priv *wil, u32 reg, u32 val)
|
||||
*/
|
||||
static inline bool wil_cid_valid(struct wil6210_priv *wil, int cid)
|
||||
{
|
||||
return (cid >= 0 && cid < wil->max_assoc_sta);
|
||||
return (cid >= 0 && cid < wil->max_assoc_sta && cid < WIL6210_MAX_CID);
|
||||
}
|
||||
|
||||
void wil_get_board_file(struct wil6210_priv *wil, char *buf, size_t len);
|
||||
@ -1440,4 +1442,6 @@ int wmi_addba_rx_resp_edma(struct wil6210_priv *wil, u8 mid, u8 cid,
|
||||
void update_supported_bands(struct wil6210_priv *wil);
|
||||
|
||||
void wil_clear_fw_log_addr(struct wil6210_priv *wil);
|
||||
int wmi_set_cqm_rssi_config(struct wil6210_priv *wil,
|
||||
s32 rssi_thold, u32 rssi_hyst);
|
||||
#endif /* __WIL6210_H__ */
|
||||
|
@ -46,7 +46,7 @@ static int wil_fw_get_crash_dump_bounds(struct wil6210_priv *wil,
|
||||
|
||||
int wil_fw_copy_crash_dump(struct wil6210_priv *wil, void *dest, u32 size)
|
||||
{
|
||||
int i, rc;
|
||||
int i;
|
||||
const struct fw_map *map;
|
||||
void *data;
|
||||
u32 host_min, dump_size, offset, len;
|
||||
@ -62,9 +62,15 @@ int wil_fw_copy_crash_dump(struct wil6210_priv *wil, void *dest, u32 size)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
rc = wil_mem_access_lock(wil);
|
||||
if (rc)
|
||||
return rc;
|
||||
down_write(&wil->mem_lock);
|
||||
|
||||
if (test_bit(wil_status_suspending, wil->status) ||
|
||||
test_bit(wil_status_suspended, wil->status)) {
|
||||
wil_err(wil,
|
||||
"suspend/resume in progress. cannot copy crash dump\n");
|
||||
up_write(&wil->mem_lock);
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
/* copy to crash dump area */
|
||||
for (i = 0; i < ARRAY_SIZE(fw_mapping); i++) {
|
||||
@ -84,7 +90,8 @@ int wil_fw_copy_crash_dump(struct wil6210_priv *wil, void *dest, u32 size)
|
||||
wil_memcpy_fromio_32((void * __force)(dest + offset),
|
||||
(const void __iomem * __force)data, len);
|
||||
}
|
||||
wil_mem_access_unlock(wil);
|
||||
|
||||
up_write(&wil->mem_lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -196,8 +196,8 @@ const struct fw_map talyn_mb_fw_mapping[] = {
|
||||
{0x8c0000, 0x8c0210, 0x8c0000, "dum_user_rgf", true, true},
|
||||
/* DMA OFU 296b */
|
||||
{0x8c2000, 0x8c2128, 0x8c2000, "dma_ofu", true, true},
|
||||
/* ucode debug 4k */
|
||||
{0x8c3000, 0x8c4000, 0x8c3000, "ucode_debug", true, true},
|
||||
/* ucode debug 256b */
|
||||
{0x8c3000, 0x8c3100, 0x8c3000, "ucode_debug", true, true},
|
||||
/* upper area 1536k */
|
||||
{0x900000, 0xa80000, 0x900000, "upper", true, true},
|
||||
/* UCODE areas - accessible by debugfs blobs but not by
|
||||
@ -476,6 +476,8 @@ static const char *cmdid2name(u16 cmdid)
|
||||
return "WMI_RBUFCAP_CFG_CMD";
|
||||
case WMI_TEMP_SENSE_ALL_CMDID:
|
||||
return "WMI_TEMP_SENSE_ALL_CMDID";
|
||||
case WMI_SET_LINK_MONITOR_CMDID:
|
||||
return "WMI_SET_LINK_MONITOR_CMD";
|
||||
default:
|
||||
return "Untracked CMD";
|
||||
}
|
||||
@ -624,6 +626,10 @@ static const char *eventid2name(u16 eventid)
|
||||
return "WMI_RBUFCAP_CFG_EVENT";
|
||||
case WMI_TEMP_SENSE_ALL_DONE_EVENTID:
|
||||
return "WMI_TEMP_SENSE_ALL_DONE_EVENTID";
|
||||
case WMI_SET_LINK_MONITOR_EVENTID:
|
||||
return "WMI_SET_LINK_MONITOR_EVENT";
|
||||
case WMI_LINK_MONITOR_EVENTID:
|
||||
return "WMI_LINK_MONITOR_EVENT";
|
||||
default:
|
||||
return "Untracked EVENT";
|
||||
}
|
||||
@ -1836,6 +1842,32 @@ wmi_evt_reassoc_status(struct wil6210_vif *vif, int id, void *d, int len)
|
||||
wil6210_disconnect(vif, NULL, WLAN_REASON_PREV_AUTH_NOT_VALID);
|
||||
}
|
||||
|
||||
static void
|
||||
wmi_evt_link_monitor(struct wil6210_vif *vif, int id, void *d, int len)
|
||||
{
|
||||
struct wil6210_priv *wil = vif_to_wil(vif);
|
||||
struct net_device *ndev = vif_to_ndev(vif);
|
||||
struct wmi_link_monitor_event *evt = d;
|
||||
enum nl80211_cqm_rssi_threshold_event event_type;
|
||||
|
||||
if (len < sizeof(*evt)) {
|
||||
wil_err(wil, "link monitor event too short %d\n", len);
|
||||
return;
|
||||
}
|
||||
|
||||
wil_dbg_wmi(wil, "link monitor event, type %d rssi %d (stored %d)\n",
|
||||
evt->type, evt->rssi_level, wil->cqm_rssi_thold);
|
||||
|
||||
if (evt->type != WMI_LINK_MONITOR_NOTIF_RSSI_THRESHOLD_EVT)
|
||||
/* ignore */
|
||||
return;
|
||||
|
||||
event_type = (evt->rssi_level > wil->cqm_rssi_thold ?
|
||||
NL80211_CQM_RSSI_THRESHOLD_EVENT_HIGH :
|
||||
NL80211_CQM_RSSI_THRESHOLD_EVENT_LOW);
|
||||
cfg80211_cqm_rssi_notify(ndev, event_type, evt->rssi_level, GFP_KERNEL);
|
||||
}
|
||||
|
||||
/**
|
||||
* Some events are ignored for purpose; and need not be interpreted as
|
||||
* "unhandled events"
|
||||
@ -1869,6 +1901,7 @@ static const struct {
|
||||
{WMI_LINK_STATS_EVENTID, wmi_evt_link_stats},
|
||||
{WMI_FT_AUTH_STATUS_EVENTID, wmi_evt_auth_status},
|
||||
{WMI_FT_REASSOC_STATUS_EVENTID, wmi_evt_reassoc_status},
|
||||
{WMI_LINK_MONITOR_EVENTID, wmi_evt_link_monitor},
|
||||
};
|
||||
|
||||
/*
|
||||
@ -3981,3 +4014,46 @@ int wmi_link_stats_cfg(struct wil6210_vif *vif, u32 type, u8 cid, u32 interval)
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int wmi_set_cqm_rssi_config(struct wil6210_priv *wil,
|
||||
s32 rssi_thold, u32 rssi_hyst)
|
||||
{
|
||||
struct net_device *ndev = wil->main_ndev;
|
||||
struct wil6210_vif *vif = ndev_to_vif(ndev);
|
||||
int rc;
|
||||
struct {
|
||||
struct wmi_set_link_monitor_cmd cmd;
|
||||
s8 rssi_thold;
|
||||
} __packed cmd = {
|
||||
.cmd = {
|
||||
.rssi_hyst = rssi_hyst,
|
||||
.rssi_thresholds_list_size = 1,
|
||||
},
|
||||
.rssi_thold = rssi_thold,
|
||||
};
|
||||
struct {
|
||||
struct wmi_cmd_hdr hdr;
|
||||
struct wmi_set_link_monitor_event evt;
|
||||
} __packed reply = {
|
||||
.evt = {.status = WMI_FW_STATUS_FAILURE},
|
||||
};
|
||||
|
||||
if (rssi_thold > S8_MAX || rssi_thold < S8_MIN || rssi_hyst > U8_MAX)
|
||||
return -EINVAL;
|
||||
|
||||
rc = wmi_call(wil, WMI_SET_LINK_MONITOR_CMDID, vif->mid, &cmd,
|
||||
sizeof(cmd), WMI_SET_LINK_MONITOR_EVENTID,
|
||||
&reply, sizeof(reply), WIL_WMI_CALL_GENERAL_TO_MS);
|
||||
if (rc) {
|
||||
wil_err(wil, "WMI_SET_LINK_MONITOR_CMDID failed, rc %d\n", rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
if (reply.evt.status != WMI_FW_STATUS_SUCCESS) {
|
||||
wil_err(wil, "WMI_SET_LINK_MONITOR_CMDID failed, status %d\n",
|
||||
reply.evt.status);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -192,6 +192,7 @@ enum wmi_command_id {
|
||||
WMI_RCP_ADDBA_RESP_EDMA_CMDID = 0x83B,
|
||||
WMI_LINK_MAINTAIN_CFG_WRITE_CMDID = 0x842,
|
||||
WMI_LINK_MAINTAIN_CFG_READ_CMDID = 0x843,
|
||||
WMI_SET_LINK_MONITOR_CMDID = 0x845,
|
||||
WMI_SET_SECTORS_CMDID = 0x849,
|
||||
WMI_MAINTAIN_PAUSE_CMDID = 0x850,
|
||||
WMI_MAINTAIN_RESUME_CMDID = 0x851,
|
||||
@ -1973,6 +1974,7 @@ enum wmi_event_id {
|
||||
WMI_REPORT_STATISTICS_EVENTID = 0x100B,
|
||||
WMI_FT_AUTH_STATUS_EVENTID = 0x100C,
|
||||
WMI_FT_REASSOC_STATUS_EVENTID = 0x100D,
|
||||
WMI_LINK_MONITOR_EVENTID = 0x100E,
|
||||
WMI_RADAR_GENERAL_CONFIG_EVENTID = 0x1100,
|
||||
WMI_RADAR_CONFIG_SELECT_EVENTID = 0x1101,
|
||||
WMI_RADAR_PARAMS_CONFIG_EVENTID = 0x1102,
|
||||
@ -2024,6 +2026,7 @@ enum wmi_event_id {
|
||||
WMI_TX_MGMT_PACKET_EVENTID = 0x1841,
|
||||
WMI_LINK_MAINTAIN_CFG_WRITE_DONE_EVENTID = 0x1842,
|
||||
WMI_LINK_MAINTAIN_CFG_READ_DONE_EVENTID = 0x1843,
|
||||
WMI_SET_LINK_MONITOR_EVENTID = 0x1845,
|
||||
WMI_RF_XPM_READ_RESULT_EVENTID = 0x1856,
|
||||
WMI_RF_XPM_WRITE_RESULT_EVENTID = 0x1857,
|
||||
WMI_LED_CFG_DONE_EVENTID = 0x1858,
|
||||
@ -3312,6 +3315,36 @@ struct wmi_link_maintain_cfg_read_cmd {
|
||||
__le32 cid;
|
||||
} __packed;
|
||||
|
||||
/* WMI_SET_LINK_MONITOR_CMDID */
|
||||
struct wmi_set_link_monitor_cmd {
|
||||
u8 rssi_hyst;
|
||||
u8 reserved[12];
|
||||
u8 rssi_thresholds_list_size;
|
||||
s8 rssi_thresholds_list[0];
|
||||
} __packed;
|
||||
|
||||
/* wmi_link_monitor_event_type */
|
||||
enum wmi_link_monitor_event_type {
|
||||
WMI_LINK_MONITOR_NOTIF_RSSI_THRESHOLD_EVT = 0x00,
|
||||
WMI_LINK_MONITOR_NOTIF_TX_ERR_EVT = 0x01,
|
||||
WMI_LINK_MONITOR_NOTIF_THERMAL_EVT = 0x02,
|
||||
};
|
||||
|
||||
/* WMI_SET_LINK_MONITOR_EVENTID */
|
||||
struct wmi_set_link_monitor_event {
|
||||
/* wmi_fw_status */
|
||||
u8 status;
|
||||
u8 reserved[3];
|
||||
} __packed;
|
||||
|
||||
/* WMI_LINK_MONITOR_EVENTID */
|
||||
struct wmi_link_monitor_event {
|
||||
/* link_monitor_event_type */
|
||||
u8 type;
|
||||
s8 rssi_level;
|
||||
u8 reserved[2];
|
||||
} __packed;
|
||||
|
||||
/* WMI_LINK_MAINTAIN_CFG_WRITE_DONE_EVENTID */
|
||||
struct wmi_link_maintain_cfg_write_done_event {
|
||||
/* requested connection ID */
|
||||
|
Loading…
Reference in New Issue
Block a user