--- a/drivers/net/wireless/ath/ath11k/mac.c +++ b/drivers/net/wireless/ath/ath11k/mac.c @@ -6278,6 +6278,8 @@ static int __ath11k_mac_register(struct ar->hw->wiphy->max_ap_assoc_sta = ar->max_num_stations; + wiphy_ext_feature_set(ar->hw->wiphy, NL80211_EXT_FEATURE_ACK_SIGNAL_SUPPORT); + ar->hw->queues = ATH11K_HW_MAX_QUEUES; ar->hw->wiphy->tx_queue_len = ATH11K_QUEUE_LEN; ar->hw->offchannel_tx_hw_queue = ATH11K_HW_MAX_QUEUES - 1; --- a/drivers/net/wireless/ath/ath11k/wmi.c +++ b/drivers/net/wireless/ath/ath11k/wmi.c @@ -3143,7 +3143,8 @@ ath11k_wmi_copy_resource_config(struct w wmi_cfg->bpf_instruction_size = tg_cfg->bpf_instruction_size; wmi_cfg->max_bssid_rx_filters = tg_cfg->max_bssid_rx_filters; wmi_cfg->use_pdev_id = tg_cfg->use_pdev_id; - wmi_cfg->flag1 |= WMI_RSRC_CFG_FLAG1_BSS_CHANNEL_INFO_64; + wmi_cfg->flag1 |= WMI_RSRC_CFG_FLAG1_BSS_CHANNEL_INFO_64 | + WMI_RSRC_CFG_FLAG1_ACK_RSSI; wmi_cfg->peer_map_unmap_v2_support = tg_cfg->peer_map_unmap_v2_support; wmi_cfg->sched_params = tg_cfg->sched_params; wmi_cfg->twt_ap_pdev_count = tg_cfg->twt_ap_pdev_count; @@ -4344,32 +4345,35 @@ static int ath11k_pull_mgmt_rx_params_tl return 0; } -static int wmi_process_mgmt_tx_comp(struct ath11k *ar, u32 desc_id, - u32 status) +static int wmi_process_mgmt_tx_comp(struct ath11k *ar, struct wmi_mgmt_tx_compl_event *tx_compl_param) { struct sk_buff *msdu; struct ieee80211_tx_info *info; struct ath11k_skb_cb *skb_cb; spin_lock_bh(&ar->txmgmt_idr_lock); - msdu = idr_find(&ar->txmgmt_idr, desc_id); + msdu = idr_find(&ar->txmgmt_idr, tx_compl_param->desc_id); if (!msdu) { ath11k_warn(ar->ab, "received mgmt tx compl for invalid msdu_id: %d\n", - desc_id); + tx_compl_param->desc_id); spin_unlock_bh(&ar->txmgmt_idr_lock); return -ENOENT; } - idr_remove(&ar->txmgmt_idr, desc_id); + idr_remove(&ar->txmgmt_idr, tx_compl_param->desc_id); spin_unlock_bh(&ar->txmgmt_idr_lock); skb_cb = ATH11K_SKB_CB(msdu); dma_unmap_single(ar->ab->dev, skb_cb->paddr, msdu->len, DMA_TO_DEVICE); info = IEEE80211_SKB_CB(msdu); - if ((!(info->flags & IEEE80211_TX_CTL_NO_ACK)) && !status) + if ((!(info->flags & IEEE80211_TX_CTL_NO_ACK)) && !tx_compl_param->status) + { info->flags |= IEEE80211_TX_STAT_ACK; + info->status.ack_signal = tx_compl_param->ack_rssi; + info->status.is_valid_ack_signal = true; + } ieee80211_tx_status_irqsafe(ar->hw, msdu); @@ -4405,6 +4409,7 @@ static int ath11k_pull_mgmt_tx_compl_par param->pdev_id = ev->pdev_id; param->desc_id = ev->desc_id; param->status = ev->status; + param->ack_rssi = ev->ack_rssi; kfree(tb); return 0; @@ -5798,8 +5803,7 @@ static void ath11k_mgmt_tx_compl_event(s goto exit; } - wmi_process_mgmt_tx_comp(ar, tx_compl_param.desc_id, - tx_compl_param.status); + wmi_process_mgmt_tx_comp(ar, &tx_compl_param); ath11k_dbg(ab, ATH11K_DBG_MGMT, "mgmt tx compl ev pdev_id %d, desc_id %d, status %d", --- a/drivers/net/wireless/ath/ath11k/wmi.h +++ b/drivers/net/wireless/ath/ath11k/wmi.h @@ -2220,6 +2220,7 @@ struct wmi_init_cmd { } __packed; #define WMI_RSRC_CFG_FLAG1_BSS_CHANNEL_INFO_64 BIT(5) +#define WMI_RSRC_CFG_FLAG1_ACK_RSSI BIT(18) struct wmi_resource_config { u32 tlv_header; @@ -4337,6 +4338,8 @@ struct wmi_mgmt_tx_compl_event { u32 desc_id; u32 status; u32 pdev_id; + u32 ppdu_id; + u32 ack_rssi; } __packed; struct wmi_scan_event {