diff options
author | Kalle Valo <kvalo@codeaurora.org> | 2019-12-19 18:27:36 +0200 |
---|---|---|
committer | Kalle Valo <kvalo@codeaurora.org> | 2019-12-19 18:27:36 +0200 |
commit | ae0a723c4cfd89dad31ce238f47ccfbe81b35b84 (patch) | |
tree | 5d485700086b25cd6a5bc230c604d3115598ae06 /drivers/net/wireless | |
parent | c705f9fc6a1736dcf6ec01f8206707c108dca824 (diff) | |
parent | ca0e477931c5a725bb887c764a49eb5d69ab7a67 (diff) |
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
Diffstat (limited to 'drivers/net/wireless')
30 files changed, 568 insertions, 302 deletions
diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c index 767c7bf16975..0969e9bf5d5e 100644 --- a/drivers/net/wireless/ath/ath10k/mac.c +++ b/drivers/net/wireless/ath/ath10k/mac.c @@ -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); diff --git a/drivers/net/wireless/ath/ath10k/testmode.c b/drivers/net/wireless/ath/ath10k/testmode.c index 1bffe3fbea3f..7a9b9bbcdbfc 100644 --- a/drivers/net/wireless/ath/ath10k/testmode.c +++ b/drivers/net/wireless/ath/ath10k/testmode.c @@ -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; diff --git a/drivers/net/wireless/ath/ath11k/ce.c b/drivers/net/wireless/ath/ath11k/ce.c index a6572b414303..cdd40c8fc867 100644 --- a/drivers/net/wireless/ath/ath11k/ce.c +++ b/drivers/net/wireless/ath/ath11k/ce.c @@ -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; diff --git a/drivers/net/wireless/ath/ath11k/core.c b/drivers/net/wireless/ath/ath11k/core.c index 5cdc9b2aee51..9e823056e673 100644 --- a/drivers/net/wireless/ath/ath11k/core.c +++ b/drivers/net/wireless/ath/ath11k/core.c @@ -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; diff --git a/drivers/net/wireless/ath/ath11k/core.h b/drivers/net/wireless/ath/ath11k/core.h index 06482a5c102d..25cdcf71d0c4 100644 --- a/drivers/net/wireless/ath/ath11k/core.h +++ b/drivers/net/wireless/ath/ath11k/core.h @@ -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; diff --git a/drivers/net/wireless/ath/ath11k/debug.c b/drivers/net/wireless/ath/ath11k/debug.c index c27fffd13a5d..f48daf17f2d2 100644 --- a/drivers/net/wireless/ath/ath11k/debug.c +++ b/drivers/net/wireless/ath/ath11k/debug.c @@ -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; } diff --git a/drivers/net/wireless/ath/ath11k/debug_htt_stats.c b/drivers/net/wireless/ath/ath11k/debug_htt_stats.c index 27b301bc1a1b..090fffa5e53c 100644 --- a/drivers/net/wireless/ath/ath11k/debug_htt_stats.c +++ b/drivers/net/wireless/ath/ath11k/debug_htt_stats.c @@ -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; } diff --git a/drivers/net/wireless/ath/ath11k/debugfs_sta.c b/drivers/net/wireless/ath/ath11k/debugfs_sta.c index 3c5f931e22a9..743760c9bcae 100644 --- a/drivers/net/wireless/ath/ath11k/debugfs_sta.c +++ b/drivers/net/wireless/ath/ath11k/debugfs_sta.c @@ -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)); - - 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, + 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 (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(); } diff --git a/drivers/net/wireless/ath/ath11k/dp.c b/drivers/net/wireless/ath/ath11k/dp.c index b966a16a930f..b112825a52ed 100644 --- a/drivers/net/wireless/ath/ath11k/dp.c +++ b/drivers/net/wireless/ath/ath11k/dp.c @@ -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; } diff --git a/drivers/net/wireless/ath/ath11k/dp.h b/drivers/net/wireless/ath/ath11k/dp.h index f7e53509ae07..2f0980f2c762 100644 --- a/drivers/net/wireless/ath/ath11k/dp.h +++ b/drivers/net/wireless/ath/ath11k/dp.h @@ -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 { diff --git a/drivers/net/wireless/ath/ath11k/dp_rx.c b/drivers/net/wireless/ath/ath11k/dp_rx.c index 1b3b65c0038c..3a3dc7680622 100644 --- a/drivers/net/wireless/ath/ath11k/dp_rx.c +++ b/drivers/net/wireless/ath/ath11k/dp_rx.c @@ -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; } diff --git a/drivers/net/wireless/ath/ath11k/dp_tx.c b/drivers/net/wireless/ath/ath11k/dp_tx.c index a8b9557c2346..918305dda106 100644 --- a/drivers/net/wireless/ath/ath11k/dp_tx.c +++ b/drivers/net/wireless/ath/ath11k/dp_tx.c @@ -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 @@ exit: 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; + + 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); - 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); + 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; diff --git a/drivers/net/wireless/ath/ath11k/hal_tx.c b/drivers/net/wireless/ath/ath11k/hal_tx.c index cbe549798762..e4aa7e8a1284 100644 --- a/drivers/net/wireless/ath/ath11k/hal_tx.c +++ b/drivers/net/wireless/ath/ath11k/hal_tx.c @@ -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) diff --git a/drivers/net/wireless/ath/ath11k/hal_tx.h b/drivers/net/wireless/ath/ath11k/hal_tx.h index 5217eaf9da50..ce48a61bfb66 100644 --- a/drivers/net/wireless/ath/ath11k/hal_tx.h +++ b/drivers/net/wireless/ath/ath11k/hal_tx.h @@ -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, diff --git a/drivers/net/wireless/ath/ath11k/htc.c b/drivers/net/wireless/ath/ath11k/htc.c index 9d4115f25ceb..8f54f58b83e6 100644 --- a/drivers/net/wireless/ath/ath11k/htc.c +++ b/drivers/net/wireless/ath/ath11k/htc.c @@ -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; diff --git a/drivers/net/wireless/ath/ath11k/mac.c b/drivers/net/wireless/ath/ath11k/mac.c index 978d8768d68a..556eef9881a7 100644 --- a/drivers/net/wireless/ath/ath11k/mac.c +++ b/drivers/net/wireless/ath/ath11k/mac.c @@ -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 |