--- a/drivers/net/wireless/ath/ath11k/mac.c +++ b/drivers/net/wireless/ath/ath11k/mac.c @@ -7137,6 +7137,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 @@ -3460,7 +3460,7 @@ ath11k_wmi_copy_resource_config(struct w 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_EAPOL_REKEY_MINRATE | - WMI_RSRC_CFG_FLAG1_BSS_CHANNEL_INFO_64; + 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; @@ -4711,8 +4711,7 @@ 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; @@ -4725,24 +4724,28 @@ static int wmi_process_mgmt_tx_comp(stru u16 frm_type; 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; + } hdr = (struct ieee80211_hdr *)msdu->data; frm_type = FIELD_GET(IEEE80211_FCTL_STYPE, hdr->frame_control); @@ -4762,7 +4765,7 @@ static int wmi_process_mgmt_tx_comp(stru arvif = ath11k_vif_to_arvif(vif); mgmt_stats = &arvif->mgmt_stats; - if (!status) + if (!tx_compl_param->status) mgmt_stats->tx_compl_succ[frm_type]++; else mgmt_stats->tx_compl_fail[frm_type]++; @@ -4803,6 +4806,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; @@ -6266,8 +6270,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 @@ -2244,6 +2244,7 @@ struct wmi_init_cmd { #define WMI_RSRC_CFG_FLAG1_EAPOL_REKEY_MINRATE BIT(14) #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; @@ -4402,6 +4403,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 { --- a/net/mac80211/status.c +++ b/net/mac80211/status.c @@ -1244,6 +1244,13 @@ void ieee80211_tx_status_8023(struct iee ieee80211_sta_reset_conn_monitor(sdata); sta->status_stats.last_ack = jiffies; + if (info->status.is_valid_ack_signal) { + sta->status_stats.last_ack_signal = + (s8)info->status.ack_signal; + sta->status_stats.ack_signal_filled = true; + ewma_avg_signal_add(&sta->status_stats.avg_ack_signal, + -info->status.ack_signal); + } if (info->flags & IEEE80211_TX_STAT_ACK) { if (sta->status_stats.lost_packets) sta->status_stats.lost_packets = 0;