ATH11K Archive on lore.kernel.org
 help / color / mirror / Atom feed
From: Kalle Valo <kvalo@codeaurora.org>
To: Wen Gong <quic_wgong@quicinc.com>
Cc: <ath11k@lists.infradead.org>,  <linux-wireless@vger.kernel.org>
Subject: Re: [PATCH v2] ath11k: report rssi of each chain to mac80211
Date: Fri, 26 Nov 2021 12:16:40 +0200	[thread overview]
Message-ID: <871r335iif.fsf@codeaurora.org> (raw)
In-Reply-To: <20211118102331.10726-1-quic_wgong@quicinc.com> (Wen Gong's message of "Thu, 18 Nov 2021 05:23:31 -0500")

Wen Gong <quic_wgong@quicinc.com> writes:

> 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.

A bit more information about the design would be nice. With mon status I
guess you mean ath11k_hal_rx_parse_mon_status()? How is performance and
power consumption affected here? Especially I'm worried how often this
new WMI command is sent, is it only when ath11k_mac_op_sta_statistics()
is called?

And I think this only works when CONFIG_ATH11K_DEBUGFS is enabled,
right?

> --- a/drivers/net/wireless/ath/ath11k/core.h
> +++ b/drivers/net/wireless/ath/ath11k/core.h
> @@ -382,6 +382,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;
>  
> @@ -412,6 +413,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

The comment is really providing any value, please remove.

> +/* signed value, 10000000h, it is empty value, invalid */
> +#define ATH11K_INVALID_RSSI_EMPTY -128

Same here.

> --- a/drivers/net/wireless/ath/ath11k/debugfs.h
> +++ b/drivers/net/wireless/ath/ath11k/debugfs.h
> @@ -117,6 +117,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);

ath11k_debugfs_get_fw_stats

> --- a/drivers/net/wireless/ath/ath11k/hal_rx.c
> +++ b/drivers/net/wireless/ath/ath11k/hal_rx.c
> @@ -1080,6 +1080,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;
>  
> @@ -1090,6 +1093,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);

le32_get_bits() makes the code simpler.

>  int ath11k_wmi_pull_fw_stats(struct ath11k_base *ab, struct sk_buff *skb,
>  			     struct ath11k_fw_stats *stats)
>  {
> +	struct ath11k *ar;
>  	const void **tb;
>  	const struct wmi_stats_event *ev;
> +	const struct wmi_per_chain_rssi_stats *rssi;
> +	const struct wmi_rssi_stats *stats_rssi;
> +	struct ieee80211_sta *sta;
> +	struct ath11k_sta *arsta;
>  	const void *data;
> -	int i, ret;
> +	const struct wmi_tlv *tlv;
> +	u16 tlv_tag, tlv_len;
> +	int i, ret, rssi_num = 0;
>  	u32 len = skb->len;
>  
>  	tb = ath11k_wmi_tlv_parse_alloc(ab, skb->data, len, GFP_ATOMIC);
> @@ -5447,12 +5456,18 @@ int ath11k_wmi_pull_fw_stats(struct ath11k_base *ab, struct sk_buff *skb,
>  
>  	ev = tb[WMI_TAG_STATS_EVENT];
>  	data = tb[WMI_TAG_ARRAY_BYTE];
> +	rssi = tb[WMI_TAG_PER_CHAIN_RSSI_STATS];
>  	if (!ev || !data) {
>  		ath11k_warn(ab, "failed to fetch update stats ev");
>  		kfree(tb);
>  		return -EPROTO;
>  	}
>  
> +	if (rssi && (ev->stats_id & WMI_REQUEST_RSSI_PER_CHAIN_STAT))
> +		rssi_num = rssi->num_per_chain_rssi_stats;
> +
> +	ar = ath11k_mac_get_ar_by_pdev_id(ab, ev->pdev_id);
> +
>  	ath11k_dbg(ab, ATH11K_DBG_WMI,
>  		   "wmi stats update ev pdev_id %d pdev %i vdev %i bcn %i\n",
>  		   ev->pdev_id,
> @@ -5533,6 +5548,96 @@ int ath11k_wmi_pull_fw_stats(struct ath11k_base *ab, struct sk_buff *skb,
>  		list_add_tail(&dst->list, &stats->bcn);
>  	}
>  
> +	ath11k_dbg(ab, ATH11K_DBG_WMI,
> +		   "wmi stats id 0x%x num chain %d\n",
> +		   ev->stats_id,
> +		   rssi_num);
> +
> +	if (rssi_num) {
> +		/* This TLV of WMI_TAG_PER_CHAIN_RSSI_STATS is followed by
> +		 * another TLV of array of structs
> +		 * wmi_rssi_stats rssi_stats[num_per_chain_rssi_stats].
> +		 * So add check integrity for the TLVs.
> +		 * rssi is behind the TLV of WMI_TAG_PER_CHAIN_RSSI_STATS.
> +		 */
> +		tlv = (struct wmi_tlv *)((u8 *)rssi - sizeof(*tlv));
> +		tlv_len = FIELD_GET(WMI_TLV_LEN, tlv->header);
> +
> +		/* Skip wmi_per_chain_rssi_stats to get the TLV of array structs */
> +		tlv = (struct wmi_tlv *)((u8 *)rssi + tlv_len);
> +		if (((u8 *)tlv - skb->data) >= skb->len)
> +			goto fin;
> +
> +		tlv_tag = FIELD_GET(WMI_TLV_TAG, tlv->header);
> +		if (tlv_tag != WMI_TAG_ARRAY_STRUCT)
> +			rssi_num = 0;
> +
> +		/* Skip array struct TLV to get the array of structs */
> +		tlv++;
> +		if (((u8 *)tlv - skb->data) >= skb->len)
> +			goto fin;
> +
> +		tlv_len = FIELD_GET(WMI_TLV_LEN, tlv->header);
> +	}
> +
> +	for (i = 0; i < rssi_num; i++) {
> +		struct ath11k_vif *arvif;
> +		int j;
> +
> +		stats_rssi = (struct wmi_rssi_stats *)((u8 *)tlv + i *
> +			(sizeof(*tlv) + tlv_len));
> +		if (((u8 *)stats_rssi - skb->data) >= skb->len)
> +			goto fin;
> +
> +		tlv_tag = FIELD_GET(WMI_TLV_TAG, stats_rssi->tlv_header);
> +		if (tlv_tag != WMI_TAG_RSSI_STATS) {
> +			ath11k_warn(ab, "invalid rssi stats TLV data\n");
> +			break;
> +		}

In this function there's a lot of pointer arithmetic and casting, can't
you use ath11k_wmi_tlv_parse_alloc() & friends for parsing the TLVs?

> --- a/drivers/net/wireless/ath/ath11k/wmi.h
> +++ b/drivers/net/wireless/ath/ath11k/wmi.h
> @@ -4394,6 +4394,20 @@ struct wmi_stats_event {
>  	u32 num_peer_extd2_stats;
>  } __packed;
>  
> +#define WMI_MAX_CHAINS 8

This is already defined on line 27.

-- 
https://patchwork.kernel.org/project/linux-wireless/list/

https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches

-- 
ath11k mailing list
ath11k@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/ath11k

  reply	other threads:[~2021-11-26 10:16 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-11-18 10:23 [PATCH v2] ath11k: report rssi of each chain to mac80211 Wen Gong
2021-11-26 10:16 ` Kalle Valo [this message]
2021-12-06 10:39   ` Wen Gong

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=871r335iif.fsf@codeaurora.org \
    --to=kvalo@codeaurora.org \
    --cc=ath11k@lists.infradead.org \
    --cc=linux-wireless@vger.kernel.org \
    --cc=quic_wgong@quicinc.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox