ath11k: report rssi of each chain to mac80211
PATCH 1/1 ath11k: report rssi of each chain to mac80211
Command "iw wls1 station dump" does not show each chain's rssi currently.
This patch is to change like this:
If the rssi of each chain from mon status is invalid, then ath11k send wmi cmd WMI_REQUEST_STATS_CMDID with flag WMI_REQUEST_RSSI_PER_CHAIN_STAT to firmware, and parse the rssi of chain in wmi WMI_UPDATE_STATS_EVENTID, then report them to mac80211.
Tested-on: QCA6390 hw2.0 PCI WLAN.HST.1.0.1-01230-QCAHSTSWPLZ_V2_TO_X86-1
Signed-off-by Wen Gong <[email protected]>
--- drivers/net/wireless/ath/ath11k/core.h | 7 ++ drivers/net/wireless/ath/ath11k/debugfs.c | 36 ++++++++ drivers/net/wireless/ath/ath11k/debugfs.h | 7 ++ drivers/net/wireless/ath/ath11k/dp_rx.c | 8 ++ drivers/net/wireless/ath/ath11k/hal_rx.c | 13 +++ drivers/net/wireless/ath/ath11k/hal_rx.h | 12 ++- drivers/net/wireless/ath/ath11k/mac.c | 38 ++++++++ drivers/net/wireless/ath/ath11k/wmi.c | 107 +++++++++++++++++++++- drivers/net/wireless/ath/ath11k/wmi.h | 14 +++ 9 files changed, 240 insertions(+), 2 deletions(-)
drivers/net/wireless/ath/ath11k/core.h +7 -0
@@ -410,6 +410,7 @@ struct ath11k_sta {u64 rx_duration;u64 tx_duration;u8 rssi_comb; +s8 chain_signal[IEEE80211_MAX_CHAINS ];struct ath11k_htt_tx_stats *tx_stats;struct ath11k_rx_peer_stats *rx_stats;
@@ -438,6 +439,12 @@ enum ath11k_state {/* Antenna noise floor */ #define ATH11K_DEFAULT_NOISE_FLOOR -95 +/* signed value, 11111111h, it is full bit value, invalid */ +#define ATH11K_INVALID_RSSI_FULL -1 + +/* signed value, 10000000h, it is empty value, invalid */ +#define ATH11K_INVALID_RSSI_EMPTY -128 +struct ath11k_ftm_event_obj {u32 data_pos;u32 expected_seq;
drivers/net/wireless/ath/ath11k/debugfs.c +36 -0
@@ -126,6 +126,11 @@ void ath11k_debugfs_fw_stats_process(struct ath11k_base *ab, struct sk_buff *skb goto complete; } +if (stats.stats_id ==WMI_REQUEST_RSSI_PER_CHAIN_STAT ) { + ar->debug.fw_stats_done = true; + goto complete; + } +if (stats.stats_id ==WMI_REQUEST_VDEV_STAT ) {if (list_empty (&stats.vdevs)) {ath11k_warn (ab,"empty vdev stats" );
@@ -229,6 +234,37 @@ static int ath11k_debugfs_fw_stats_request(struct ath11k *ar,return 0 ; } +int ath11k_debug_get_fw_stats (struct ath11k *ar,u32 pdev_id,u32 vdev_id,u32 stats_id) +{ +struct ath11k_base *ab = ar->ab; +struct stats_request_params req_param; +int ret; + +mutex_lock (&ar->conf_mutex); + +if (ar->state !=ATH11K_STATE_ON ) { + ret = -ENETDOWN ; + goto err_unlock; + } + + req_param.pdev_id = pdev_id; + req_param.vdev_id = vdev_id; + req_param.stats_id = stats_id; + + ret =ath11k_debugfs_fw_stats_request (ar, &req_param); +if (ret) +ath11k_warn (ab,"failed to request fw stats: %d\n" , ret); + +ath11k_dbg (ab,ATH11K_DBG_WMI , +"debug get fw stat pdev id %d vdev id %d stats id 0x%x\n" , + pdev_id, vdev_id, stats_id); + +err_unlock: +mutex_unlock (&ar->conf_mutex); + +return ret; +} +static int ath11k_open_pdev_stats (struct inode *inode,struct file *file) {struct ath11k *ar = inode->i_private;
drivers/net/wireless/ath/ath11k/debugfs.h +7 -0
@@ -113,6 +113,7 @@ void ath11k_debugfs_unregister(struct ath11k *ar);void ath11k_debugfs_fw_stats_process (struct ath11k_base *ab,struct sk_buff *skb);void ath11k_debugfs_fw_stats_init (struct ath11k *ar); +int ath11k_debug_get_fw_stats (struct ath11k *ar,u32 pdev_id,u32 vdev_id,u32 stats_id);static inline bool ath11k_debugfs_is_pktlog_lite_mode_enabled (struct ath11k *ar) {
@@ -212,6 +213,12 @@ static inline int ath11k_debugfs_rx_filter(struct ath11k *ar)return 0 ; } +static inline int ath11k_debug_get_fw_stats (struct ath11k *ar, +u32 pdev_id,u32 vdev_id,u32 stats_id) +{ +return 0 ; +} +#endif /* CONFIG_MAC80211_DEBUGFS*/ #endif /* _ATH11K_DEBUGFS_H_ */
drivers/net/wireless/ath/ath11k/dp_rx.c +8 -0
@@ -2696,6 +2696,7 @@ static void ath11k_dp_rx_update_peer_stats(struct ath11k_sta *arsta, {struct ath11k_rx_peer_stats *rx_stats = arsta->rx_stats;u32 num_msdu; +int i;if (!rx_stats)return ;
@@ -2757,6 +2758,13 @@ static void ath11k_dp_rx_update_peer_stats(struct ath11k_sta *arsta, rx_stats->ru_alloc_cnt[ppdu_info->ru_alloc] += num_msdu; arsta->rssi_comb = ppdu_info->rssi_comb; + +BUILD_BUG_ON (ARRAY_SIZE (arsta->chain_signal) > +ARRAY_SIZE (ppdu_info->rssi_chain_pri20)); + +for (i =0 ; i <ARRAY_SIZE (arsta->chain_signal); i++) + arsta->chain_signal[i] = ppdu_info->rssi_chain_pri20[i]; + rx_stats->rx_duration += ppdu_info->rx_duration; arsta->rx_duration = rx_stats->rx_duration; }
drivers/net/wireless/ath/ath11k/hal_rx.c +13 -0
@@ -1078,6 +1078,9 @@ ath11k_hal_rx_parse_mon_status_tlv(struct ath11k_base *ab,break ; }case HAL_PHYRX_RSSI_LEGACY : { +int i; +bool db2dbm =test_bit (WMI_TLV_SERVICE_HW_DB2DBM_CONVERSION_SUPPORT , + ab->wmi_ab.svc_map);struct hal_rx_phyrx_rssi_legacy_info *rssi = (struct hal_rx_phyrx_rssi_legacy_info *)tlv_data;
@@ -1088,6 +1091,16 @@ ath11k_hal_rx_parse_mon_status_tlv(struct ath11k_base *ab, ppdu_info->rssi_comb =FIELD_GET (HAL_RX_PHYRX_RSSI_LEGACY_INFO_INFO1_RSSI_COMB ,__le32_to_cpu (rssi->info0)); + +if (db2dbm) { +for (i =0 ; i <ARRAY_SIZE (rssi->preamble); i++) { +u32 rssi2040 =__le32_to_cpu (rssi->preamble[i].rssi_2040); + + ppdu_info->rssi_chain_pri20[i] = +FIELD_GET (HAL_RX_PHYRX_RSSI_PREAMBLE_PRI20 , + rssi2040); + } + }break ; }case HAL_RX_MPDU_START : {
drivers/net/wireless/ath/ath11k/hal_rx.h +11 -1
@@ -98,6 +98,7 @@ struct hal_rx_mon_ppdu_info {u8 ldpc;u8 beamformed;u8 rssi_comb; +u8 rssi_chain_pri20[HAL_RX_MAX_NSS ];u8 tid;u8 dcm;u8 ru_alloc;
@@ -248,8 +249,17 @@ struct hal_rx_he_sig_b2_ofdma_info {#define HAL_RX_PHYRX_RSSI_LEGACY_INFO_INFO1_RSSI_COMB GENMASK(15, 8) +#define HAL_RX_PHYRX_RSSI_PREAMBLE_PRI20 GENMASK(7, 0) + +struct hal_rx_phyrx_chain_rssi { +__le32 rssi_2040; +__le32 rssi_80; +} __packed; +struct hal_rx_phyrx_rssi_legacy_info { -__le32 rsvd[35 ]; +__le32 rsvd[3 ]; +struct hal_rx_phyrx_chain_rssi pre_rssi[HAL_RX_MAX_NSS ]; +struct hal_rx_phyrx_chain_rssi preamble[HAL_RX_MAX_NSS ];__le32 info0; } __packed;
drivers/net/wireless/ath/ath11k/mac.c +38 -0
@@ -6952,12 +6952,42 @@ static int ath11k_mac_op_get_survey(struct ieee80211_hw *hw, int idx,return ret; } +static void ath11k_mac_put_chain_rssi (struct station_info *sinfo, +struct ath11k_sta *arsta, +char *pre, +bool clear) +{ +struct ath11k *ar = arsta->arvif->ar; +int i; +s8 rssi; + +for (i =0 ; i <ARRAY_SIZE (sinfo->chain_signal); i++) { + sinfo->chains &= ~BIT (i); + rssi = arsta->chain_signal[i]; +if (clear) + arsta->chain_signal[i] =ATH11K_INVALID_RSSI_FULL ; + +ath11k_dbg (ar->ab,ATH11K_DBG_MAC , +"mac sta statistics %s rssi[%d] %d\n" , pre, i, rssi); + +if (rssi !=ATH11K_DEFAULT_NOISE_FLOOR && + rssi !=ATH11K_INVALID_RSSI_FULL && + rssi !=ATH11K_INVALID_RSSI_EMPTY && + rssi !=0 ) { + sinfo->chain_signal[i] = rssi; + sinfo->chains |=BIT (i); + sinfo->filled |=BIT_ULL (NL80211_STA_INFO_CHAIN_SIGNAL ); + } + } +} +static void ath11k_mac_op_sta_statistics (struct ieee80211_hw *hw,struct ieee80211_vif *vif,struct ieee80211_sta *sta,struct station_info *sinfo) {struct ath11k_sta *arsta = (struct ath11k_sta *)sta->drv_priv; +struct ath11k *ar = arsta->arvif->ar; sinfo->rx_duration = arsta->rx_duration; sinfo->filled |=BIT_ULL (NL80211_STA_INFO_RX_DURATION );
@@ -6980,6 +7010,14 @@ static void ath11k_mac_op_sta_statistics(struct ieee80211_hw *hw, sinfo->filled |=BIT_ULL (NL80211_STA_INFO_TX_BITRATE ); } +ath11k_mac_put_chain_rssi (sinfo, arsta,"ppdu" , false); + +if (!(sinfo->filled &BIT_ULL (NL80211_STA_INFO_CHAIN_SIGNAL )) && + !ath11k_debug_get_fw_stats (ar, ar->pdev->pdev_id,0 , +WMI_REQUEST_RSSI_PER_CHAIN_STAT )) { +ath11k_mac_put_chain_rssi (sinfo, arsta,"fw stats" , true); + } +/* TODO: Use real NF instead of default one. */ sinfo->signal = arsta->rssi_comb +ATH11K_DEFAULT_NOISE_FLOOR ; sinfo->filled |=BIT_ULL (NL80211_STA_INFO_SIGNAL );
drivers/net/wireless/ath/ath11k/wmi.c +106 -1
140 lines not on this page · raw message
drivers/net/wireless/ath/ath11k/wmi.h +14 -0
@@ -4547,6 +4547,20 @@ struct wmi_stats_event {u32 num_peer_extd2_stats; } __packed; +#define WMI_MAX_CHAINS 8 + +struct wmi_rssi_stats { +u32 tlv_header; +u32 vdev_id; +u32 rssi_avg_beacon[WMI_MAX_CHAINS ]; +u32 rssi_avg_data[WMI_MAX_CHAINS ]; +struct wmi_mac_addr peer_macaddr; +} __packed; + +struct wmi_per_chain_rssi_stats { +u32 num_per_chain_rssi_stats; +} __packed; +struct wmi_pdev_ctl_failsafe_chk_event {u32 pdev_id;u32 ctl_failsafe_status;
Signature · 7 lines
2.31.1 -- ath11k mailing list [email protected] http://lists.infradead.org/mailman/listinfo/ath11k