xref: /linux/drivers/net/wireless/ath/ath12k/dp_htt.c (revision 8934827db5403eae57d4537114a9ff88b0a8460f)
171a3f92cSHarsh Kumar Bijlani // SPDX-License-Identifier: BSD-3-Clause-Clear
271a3f92cSHarsh Kumar Bijlani /*
371a3f92cSHarsh Kumar Bijlani  * Copyright (c) 2018-2021 The Linux Foundation. All rights reserved.
471a3f92cSHarsh Kumar Bijlani  * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
571a3f92cSHarsh Kumar Bijlani  */
671a3f92cSHarsh Kumar Bijlani 
771a3f92cSHarsh Kumar Bijlani #include "core.h"
871a3f92cSHarsh Kumar Bijlani #include "peer.h"
971a3f92cSHarsh Kumar Bijlani #include "htc.h"
1071a3f92cSHarsh Kumar Bijlani #include "dp_htt.h"
1171a3f92cSHarsh Kumar Bijlani #include "debugfs_htt_stats.h"
12611297eeSHarsh Kumar Bijlani #include "debugfs.h"
1371a3f92cSHarsh Kumar Bijlani 
ath12k_dp_htt_htc_tx_complete(struct ath12k_base * ab,struct sk_buff * skb)14d637c58aSHarsh Kumar Bijlani static void ath12k_dp_htt_htc_tx_complete(struct ath12k_base *ab,
15d637c58aSHarsh Kumar Bijlani 					  struct sk_buff *skb)
16d637c58aSHarsh Kumar Bijlani {
17d637c58aSHarsh Kumar Bijlani 	dev_kfree_skb_any(skb);
18d637c58aSHarsh Kumar Bijlani }
19d637c58aSHarsh Kumar Bijlani 
ath12k_dp_htt_connect(struct ath12k_dp * dp)20d637c58aSHarsh Kumar Bijlani int ath12k_dp_htt_connect(struct ath12k_dp *dp)
21d637c58aSHarsh Kumar Bijlani {
22d637c58aSHarsh Kumar Bijlani 	struct ath12k_htc_svc_conn_req conn_req = {};
23d637c58aSHarsh Kumar Bijlani 	struct ath12k_htc_svc_conn_resp conn_resp = {};
24d637c58aSHarsh Kumar Bijlani 	int status;
25d637c58aSHarsh Kumar Bijlani 
26d637c58aSHarsh Kumar Bijlani 	conn_req.ep_ops.ep_tx_complete = ath12k_dp_htt_htc_tx_complete;
27d637c58aSHarsh Kumar Bijlani 	conn_req.ep_ops.ep_rx_complete = ath12k_dp_htt_htc_t2h_msg_handler;
28d637c58aSHarsh Kumar Bijlani 
29d637c58aSHarsh Kumar Bijlani 	/* connect to control service */
30d637c58aSHarsh Kumar Bijlani 	conn_req.service_id = ATH12K_HTC_SVC_ID_HTT_DATA_MSG;
31d637c58aSHarsh Kumar Bijlani 
32d637c58aSHarsh Kumar Bijlani 	status = ath12k_htc_connect_service(&dp->ab->htc, &conn_req,
33d637c58aSHarsh Kumar Bijlani 					    &conn_resp);
34d637c58aSHarsh Kumar Bijlani 
35d637c58aSHarsh Kumar Bijlani 	if (status)
36d637c58aSHarsh Kumar Bijlani 		return status;
37d637c58aSHarsh Kumar Bijlani 
38d637c58aSHarsh Kumar Bijlani 	dp->eid = conn_resp.eid;
39d637c58aSHarsh Kumar Bijlani 
40d637c58aSHarsh Kumar Bijlani 	return 0;
41d637c58aSHarsh Kumar Bijlani }
42d637c58aSHarsh Kumar Bijlani 
ath12k_get_ppdu_user_index(struct htt_ppdu_stats * ppdu_stats,u16 peer_id)4371a3f92cSHarsh Kumar Bijlani static int ath12k_get_ppdu_user_index(struct htt_ppdu_stats *ppdu_stats,
4471a3f92cSHarsh Kumar Bijlani 				      u16 peer_id)
4571a3f92cSHarsh Kumar Bijlani {
4671a3f92cSHarsh Kumar Bijlani 	int i;
4771a3f92cSHarsh Kumar Bijlani 
4871a3f92cSHarsh Kumar Bijlani 	for (i = 0; i < HTT_PPDU_STATS_MAX_USERS - 1; i++) {
4971a3f92cSHarsh Kumar Bijlani 		if (ppdu_stats->user_stats[i].is_valid_peer_id) {
5071a3f92cSHarsh Kumar Bijlani 			if (peer_id == ppdu_stats->user_stats[i].peer_id)
5171a3f92cSHarsh Kumar Bijlani 				return i;
5271a3f92cSHarsh Kumar Bijlani 		} else {
5371a3f92cSHarsh Kumar Bijlani 			return i;
5471a3f92cSHarsh Kumar Bijlani 		}
5571a3f92cSHarsh Kumar Bijlani 	}
5671a3f92cSHarsh Kumar Bijlani 
5771a3f92cSHarsh Kumar Bijlani 	return -EINVAL;
5871a3f92cSHarsh Kumar Bijlani }
5971a3f92cSHarsh Kumar Bijlani 
ath12k_htt_tlv_ppdu_stats_parse(struct ath12k_base * ab,u16 tag,u16 len,const void * ptr,void * data)6071a3f92cSHarsh Kumar Bijlani static int ath12k_htt_tlv_ppdu_stats_parse(struct ath12k_base *ab,
6171a3f92cSHarsh Kumar Bijlani 					   u16 tag, u16 len, const void *ptr,
6271a3f92cSHarsh Kumar Bijlani 					   void *data)
6371a3f92cSHarsh Kumar Bijlani {
6471a3f92cSHarsh Kumar Bijlani 	const struct htt_ppdu_stats_usr_cmpltn_ack_ba_status *ba_status;
6571a3f92cSHarsh Kumar Bijlani 	const struct htt_ppdu_stats_usr_cmpltn_cmn *cmplt_cmn;
6671a3f92cSHarsh Kumar Bijlani 	const struct htt_ppdu_stats_user_rate *user_rate;
6771a3f92cSHarsh Kumar Bijlani 	struct htt_ppdu_stats_info *ppdu_info;
6871a3f92cSHarsh Kumar Bijlani 	struct htt_ppdu_user_stats *user_stats;
6971a3f92cSHarsh Kumar Bijlani 	int cur_user;
7071a3f92cSHarsh Kumar Bijlani 	u16 peer_id;
7171a3f92cSHarsh Kumar Bijlani 
7271a3f92cSHarsh Kumar Bijlani 	ppdu_info = data;
7371a3f92cSHarsh Kumar Bijlani 
7471a3f92cSHarsh Kumar Bijlani 	switch (tag) {
7571a3f92cSHarsh Kumar Bijlani 	case HTT_PPDU_STATS_TAG_COMMON:
7671a3f92cSHarsh Kumar Bijlani 		if (len < sizeof(struct htt_ppdu_stats_common)) {
7771a3f92cSHarsh Kumar Bijlani 			ath12k_warn(ab, "Invalid len %d for the tag 0x%x\n",
7871a3f92cSHarsh Kumar Bijlani 				    len, tag);
7971a3f92cSHarsh Kumar Bijlani 			return -EINVAL;
8071a3f92cSHarsh Kumar Bijlani 		}
8171a3f92cSHarsh Kumar Bijlani 		memcpy(&ppdu_info->ppdu_stats.common, ptr,
8271a3f92cSHarsh Kumar Bijlani 		       sizeof(struct htt_ppdu_stats_common));
8371a3f92cSHarsh Kumar Bijlani 		break;
8471a3f92cSHarsh Kumar Bijlani 	case HTT_PPDU_STATS_TAG_USR_RATE:
8571a3f92cSHarsh Kumar Bijlani 		if (len < sizeof(struct htt_ppdu_stats_user_rate)) {
8671a3f92cSHarsh Kumar Bijlani 			ath12k_warn(ab, "Invalid len %d for the tag 0x%x\n",
8771a3f92cSHarsh Kumar Bijlani 				    len, tag);
8871a3f92cSHarsh Kumar Bijlani 			return -EINVAL;
8971a3f92cSHarsh Kumar Bijlani 		}
9071a3f92cSHarsh Kumar Bijlani 		user_rate = ptr;
9171a3f92cSHarsh Kumar Bijlani 		peer_id = le16_to_cpu(user_rate->sw_peer_id);
9271a3f92cSHarsh Kumar Bijlani 		cur_user = ath12k_get_ppdu_user_index(&ppdu_info->ppdu_stats,
9371a3f92cSHarsh Kumar Bijlani 						      peer_id);
9471a3f92cSHarsh Kumar Bijlani 		if (cur_user < 0)
9571a3f92cSHarsh Kumar Bijlani 			return -EINVAL;
9671a3f92cSHarsh Kumar Bijlani 		user_stats = &ppdu_info->ppdu_stats.user_stats[cur_user];
9771a3f92cSHarsh Kumar Bijlani 		user_stats->peer_id = peer_id;
9871a3f92cSHarsh Kumar Bijlani 		user_stats->is_valid_peer_id = true;
9971a3f92cSHarsh Kumar Bijlani 		memcpy(&user_stats->rate, ptr,
10071a3f92cSHarsh Kumar Bijlani 		       sizeof(struct htt_ppdu_stats_user_rate));
10171a3f92cSHarsh Kumar Bijlani 		user_stats->tlv_flags |= BIT(tag);
10271a3f92cSHarsh Kumar Bijlani 		break;
10371a3f92cSHarsh Kumar Bijlani 	case HTT_PPDU_STATS_TAG_USR_COMPLTN_COMMON:
10471a3f92cSHarsh Kumar Bijlani 		if (len < sizeof(struct htt_ppdu_stats_usr_cmpltn_cmn)) {
10571a3f92cSHarsh Kumar Bijlani 			ath12k_warn(ab, "Invalid len %d for the tag 0x%x\n",
10671a3f92cSHarsh Kumar Bijlani 				    len, tag);
10771a3f92cSHarsh Kumar Bijlani 			return -EINVAL;
10871a3f92cSHarsh Kumar Bijlani 		}
10971a3f92cSHarsh Kumar Bijlani 
11071a3f92cSHarsh Kumar Bijlani 		cmplt_cmn = ptr;
11171a3f92cSHarsh Kumar Bijlani 		peer_id = le16_to_cpu(cmplt_cmn->sw_peer_id);
11271a3f92cSHarsh Kumar Bijlani 		cur_user = ath12k_get_ppdu_user_index(&ppdu_info->ppdu_stats,
11371a3f92cSHarsh Kumar Bijlani 						      peer_id);
11471a3f92cSHarsh Kumar Bijlani 		if (cur_user < 0)
11571a3f92cSHarsh Kumar Bijlani 			return -EINVAL;
11671a3f92cSHarsh Kumar Bijlani 		user_stats = &ppdu_info->ppdu_stats.user_stats[cur_user];
11771a3f92cSHarsh Kumar Bijlani 		user_stats->peer_id = peer_id;
11871a3f92cSHarsh Kumar Bijlani 		user_stats->is_valid_peer_id = true;
11971a3f92cSHarsh Kumar Bijlani 		memcpy(&user_stats->cmpltn_cmn, ptr,
12071a3f92cSHarsh Kumar Bijlani 		       sizeof(struct htt_ppdu_stats_usr_cmpltn_cmn));
12171a3f92cSHarsh Kumar Bijlani 		user_stats->tlv_flags |= BIT(tag);
12271a3f92cSHarsh Kumar Bijlani 		break;
12371a3f92cSHarsh Kumar Bijlani 	case HTT_PPDU_STATS_TAG_USR_COMPLTN_ACK_BA_STATUS:
12471a3f92cSHarsh Kumar Bijlani 		if (len <
12571a3f92cSHarsh Kumar Bijlani 		    sizeof(struct htt_ppdu_stats_usr_cmpltn_ack_ba_status)) {
12671a3f92cSHarsh Kumar Bijlani 			ath12k_warn(ab, "Invalid len %d for the tag 0x%x\n",
12771a3f92cSHarsh Kumar Bijlani 				    len, tag);
12871a3f92cSHarsh Kumar Bijlani 			return -EINVAL;
12971a3f92cSHarsh Kumar Bijlani 		}
13071a3f92cSHarsh Kumar Bijlani 
13171a3f92cSHarsh Kumar Bijlani 		ba_status = ptr;
13271a3f92cSHarsh Kumar Bijlani 		peer_id = le16_to_cpu(ba_status->sw_peer_id);
13371a3f92cSHarsh Kumar Bijlani 		cur_user = ath12k_get_ppdu_user_index(&ppdu_info->ppdu_stats,
13471a3f92cSHarsh Kumar Bijlani 						      peer_id);
13571a3f92cSHarsh Kumar Bijlani 		if (cur_user < 0)
13671a3f92cSHarsh Kumar Bijlani 			return -EINVAL;
13771a3f92cSHarsh Kumar Bijlani 		user_stats = &ppdu_info->ppdu_stats.user_stats[cur_user];
13871a3f92cSHarsh Kumar Bijlani 		user_stats->peer_id = peer_id;
13971a3f92cSHarsh Kumar Bijlani 		user_stats->is_valid_peer_id = true;
14071a3f92cSHarsh Kumar Bijlani 		memcpy(&user_stats->ack_ba, ptr,
14171a3f92cSHarsh Kumar Bijlani 		       sizeof(struct htt_ppdu_stats_usr_cmpltn_ack_ba_status));
14271a3f92cSHarsh Kumar Bijlani 		user_stats->tlv_flags |= BIT(tag);
14371a3f92cSHarsh Kumar Bijlani 		break;
14471a3f92cSHarsh Kumar Bijlani 	}
14571a3f92cSHarsh Kumar Bijlani 	return 0;
14671a3f92cSHarsh Kumar Bijlani }
14771a3f92cSHarsh Kumar Bijlani 
ath12k_dp_htt_tlv_iter(struct ath12k_base * ab,const void * ptr,size_t len,int (* iter)(struct ath12k_base * ar,u16 tag,u16 len,const void * ptr,void * data),void * data)14871a3f92cSHarsh Kumar Bijlani int ath12k_dp_htt_tlv_iter(struct ath12k_base *ab, const void *ptr, size_t len,
14971a3f92cSHarsh Kumar Bijlani 			   int (*iter)(struct ath12k_base *ar, u16 tag, u16 len,
15071a3f92cSHarsh Kumar Bijlani 				       const void *ptr, void *data),
15171a3f92cSHarsh Kumar Bijlani 			   void *data)
15271a3f92cSHarsh Kumar Bijlani {
15371a3f92cSHarsh Kumar Bijlani 	const struct htt_tlv *tlv;
15471a3f92cSHarsh Kumar Bijlani 	const void *begin = ptr;
15571a3f92cSHarsh Kumar Bijlani 	u16 tlv_tag, tlv_len;
15671a3f92cSHarsh Kumar Bijlani 	int ret = -EINVAL;
15771a3f92cSHarsh Kumar Bijlani 
15871a3f92cSHarsh Kumar Bijlani 	while (len > 0) {
15971a3f92cSHarsh Kumar Bijlani 		if (len < sizeof(*tlv)) {
16071a3f92cSHarsh Kumar Bijlani 			ath12k_err(ab, "htt tlv parse failure at byte %zd (%zu bytes left, %zu expected)\n",
16171a3f92cSHarsh Kumar Bijlani 				   ptr - begin, len, sizeof(*tlv));
16271a3f92cSHarsh Kumar Bijlani 			return -EINVAL;
16371a3f92cSHarsh Kumar Bijlani 		}
16471a3f92cSHarsh Kumar Bijlani 		tlv = (struct htt_tlv *)ptr;
16571a3f92cSHarsh Kumar Bijlani 		tlv_tag = le32_get_bits(tlv->header, HTT_TLV_TAG);
16671a3f92cSHarsh Kumar Bijlani 		tlv_len = le32_get_bits(tlv->header, HTT_TLV_LEN);
16771a3f92cSHarsh Kumar Bijlani 		ptr += sizeof(*tlv);
16871a3f92cSHarsh Kumar Bijlani 		len -= sizeof(*tlv);
16971a3f92cSHarsh Kumar Bijlani 
17071a3f92cSHarsh Kumar Bijlani 		if (tlv_len > len) {
17171a3f92cSHarsh Kumar Bijlani 			ath12k_err(ab, "htt tlv parse failure of tag %u at byte %zd (%zu bytes left, %u expected)\n",
17271a3f92cSHarsh Kumar Bijlani 				   tlv_tag, ptr - begin, len, tlv_len);
17371a3f92cSHarsh Kumar Bijlani 			return -EINVAL;
17471a3f92cSHarsh Kumar Bijlani 		}
17571a3f92cSHarsh Kumar Bijlani 		ret = iter(ab, tlv_tag, tlv_len, ptr, data);
17671a3f92cSHarsh Kumar Bijlani 		if (ret == -ENOMEM)
17771a3f92cSHarsh Kumar Bijlani 			return ret;
17871a3f92cSHarsh Kumar Bijlani 
17971a3f92cSHarsh Kumar Bijlani 		ptr += tlv_len;
18071a3f92cSHarsh Kumar Bijlani 		len -= tlv_len;
18171a3f92cSHarsh Kumar Bijlani 	}
18271a3f92cSHarsh Kumar Bijlani 	return 0;
18371a3f92cSHarsh Kumar Bijlani }
18471a3f92cSHarsh Kumar Bijlani 
18571a3f92cSHarsh Kumar Bijlani static void
ath12k_update_per_peer_tx_stats(struct ath12k_pdev_dp * dp_pdev,struct htt_ppdu_stats * ppdu_stats,u8 user)186c57176c0SRipan Deuri ath12k_update_per_peer_tx_stats(struct ath12k_pdev_dp *dp_pdev,
18771a3f92cSHarsh Kumar Bijlani 				struct htt_ppdu_stats *ppdu_stats, u8 user)
18871a3f92cSHarsh Kumar Bijlani {
189c57176c0SRipan Deuri 	struct ath12k_dp *dp = dp_pdev->dp;
190c57176c0SRipan Deuri 	struct ath12k_base *ab = dp->ab;
1919e0b56a3SHarsh Kumar Bijlani 	struct ath12k_dp_link_peer *peer;
19271a3f92cSHarsh Kumar Bijlani 	struct htt_ppdu_stats_user_rate *user_rate;
193c57176c0SRipan Deuri 	struct ath12k_per_peer_tx_stats *peer_stats = &dp_pdev->peer_tx_stats;
19471a3f92cSHarsh Kumar Bijlani 	struct htt_ppdu_user_stats *usr_stats = &ppdu_stats->user_stats[user];
19571a3f92cSHarsh Kumar Bijlani 	struct htt_ppdu_stats_common *common = &ppdu_stats->common;
19671a3f92cSHarsh Kumar Bijlani 	int ret;
19771a3f92cSHarsh Kumar Bijlani 	u8 flags, mcs, nss, bw, sgi, dcm, ppdu_type, rate_idx = 0;
19871a3f92cSHarsh Kumar Bijlani 	u32 v, succ_bytes = 0;
19971a3f92cSHarsh Kumar Bijlani 	u16 tones, rate = 0, succ_pkts = 0;
20071a3f92cSHarsh Kumar Bijlani 	u32 tx_duration = 0;
20171a3f92cSHarsh Kumar Bijlani 	u8 tid = HTT_PPDU_STATS_NON_QOS_TID;
20271a3f92cSHarsh Kumar Bijlani 	u16 tx_retry_failed = 0, tx_retry_count = 0;
20371a3f92cSHarsh Kumar Bijlani 	bool is_ampdu = false, is_ofdma;
20471a3f92cSHarsh Kumar Bijlani 
20571a3f92cSHarsh Kumar Bijlani 	if (!(usr_stats->tlv_flags & BIT(HTT_PPDU_STATS_TAG_USR_RATE)))
20671a3f92cSHarsh Kumar Bijlani 		return;
20771a3f92cSHarsh Kumar Bijlani 
20871a3f92cSHarsh Kumar Bijlani 	if (usr_stats->tlv_flags & BIT(HTT_PPDU_STATS_TAG_USR_COMPLTN_COMMON)) {
20971a3f92cSHarsh Kumar Bijlani 		is_ampdu =
21071a3f92cSHarsh Kumar Bijlani 			HTT_USR_CMPLTN_IS_AMPDU(usr_stats->cmpltn_cmn.flags);
21171a3f92cSHarsh Kumar Bijlani 		tx_retry_failed =
21271a3f92cSHarsh Kumar Bijlani 			__le16_to_cpu(usr_stats->cmpltn_cmn.mpdu_tried) -
21371a3f92cSHarsh Kumar Bijlani 			__le16_to_cpu(usr_stats->cmpltn_cmn.mpdu_success);
21471a3f92cSHarsh Kumar Bijlani 		tx_retry_count =
21571a3f92cSHarsh Kumar Bijlani 			HTT_USR_CMPLTN_LONG_RETRY(usr_stats->cmpltn_cmn.flags) +
21671a3f92cSHarsh Kumar Bijlani 			HTT_USR_CMPLTN_SHORT_RETRY(usr_stats->cmpltn_cmn.flags);
21771a3f92cSHarsh Kumar Bijlani 	}
21871a3f92cSHarsh Kumar Bijlani 
21971a3f92cSHarsh Kumar Bijlani 	if (usr_stats->tlv_flags &
22071a3f92cSHarsh Kumar Bijlani 	    BIT(HTT_PPDU_STATS_TAG_USR_COMPLTN_ACK_BA_STATUS)) {
22171a3f92cSHarsh Kumar Bijlani 		succ_bytes = le32_to_cpu(usr_stats->ack_ba.success_bytes);
22271a3f92cSHarsh Kumar Bijlani 		succ_pkts = le32_get_bits(usr_stats->ack_ba.info,
22371a3f92cSHarsh Kumar Bijlani 					  HTT_PPDU_STATS_ACK_BA_INFO_NUM_MSDU_M);
22471a3f92cSHarsh Kumar Bijlani 		tid = le32_get_bits(usr_stats->ack_ba.info,
22571a3f92cSHarsh Kumar Bijlani 				    HTT_PPDU_STATS_ACK_BA_INFO_TID_NUM);
22671a3f92cSHarsh Kumar Bijlani 	}
22771a3f92cSHarsh Kumar Bijlani 
22871a3f92cSHarsh Kumar Bijlani 	if (common->fes_duration_us)
22971a3f92cSHarsh Kumar Bijlani 		tx_duration = le32_to_cpu(common->fes_duration_us);
23071a3f92cSHarsh Kumar Bijlani 
23171a3f92cSHarsh Kumar Bijlani 	user_rate = &usr_stats->rate;
23271a3f92cSHarsh Kumar Bijlani 	flags = HTT_USR_RATE_PREAMBLE(user_rate->rate_flags);
23371a3f92cSHarsh Kumar Bijlani 	bw = HTT_USR_RATE_BW(user_rate->rate_flags) - 2;
23471a3f92cSHarsh Kumar Bijlani 	nss = HTT_USR_RATE_NSS(user_rate->rate_flags) + 1;
23571a3f92cSHarsh Kumar Bijlani 	mcs = HTT_USR_RATE_MCS(user_rate->rate_flags);
23671a3f92cSHarsh Kumar Bijlani 	sgi = HTT_USR_RATE_GI(user_rate->rate_flags);
23771a3f92cSHarsh Kumar Bijlani 	dcm = HTT_USR_RATE_DCM(user_rate->rate_flags);
23871a3f92cSHarsh Kumar Bijlani 
23971a3f92cSHarsh Kumar Bijlani 	ppdu_type = HTT_USR_RATE_PPDU_TYPE(user_rate->info1);
24071a3f92cSHarsh Kumar Bijlani 	is_ofdma = (ppdu_type == HTT_PPDU_STATS_PPDU_TYPE_MU_OFDMA) ||
24171a3f92cSHarsh Kumar Bijlani 		   (ppdu_type == HTT_PPDU_STATS_PPDU_TYPE_MU_MIMO_OFDMA);
24271a3f92cSHarsh Kumar Bijlani 
24371a3f92cSHarsh Kumar Bijlani 	/* Note: If host configured fixed rates and in some other special
24471a3f92cSHarsh Kumar Bijlani 	 * cases, the broadcast/management frames are sent in different rates.
24571a3f92cSHarsh Kumar Bijlani 	 * Firmware rate's control to be skipped for this?
24671a3f92cSHarsh Kumar Bijlani 	 */
24771a3f92cSHarsh Kumar Bijlani 
24871a3f92cSHarsh Kumar Bijlani 	if (flags == WMI_RATE_PREAMBLE_HE && mcs > ATH12K_HE_MCS_MAX) {
24971a3f92cSHarsh Kumar Bijlani 		ath12k_warn(ab, "Invalid HE mcs %d peer stats",  mcs);
25071a3f92cSHarsh Kumar Bijlani 		return;
25171a3f92cSHarsh Kumar Bijlani 	}
25271a3f92cSHarsh Kumar Bijlani 
25371a3f92cSHarsh Kumar Bijlani 	if (flags == WMI_RATE_PREAMBLE_VHT && mcs > ATH12K_VHT_MCS_MAX) {
25471a3f92cSHarsh Kumar Bijlani 		ath12k_warn(ab, "Invalid VHT mcs %d peer stats",  mcs);
25571a3f92cSHarsh Kumar Bijlani 		return;
25671a3f92cSHarsh Kumar Bijlani 	}
25771a3f92cSHarsh Kumar Bijlani 
25871a3f92cSHarsh Kumar Bijlani 	if (flags == WMI_RATE_PREAMBLE_HT && (mcs > ATH12K_HT_MCS_MAX || nss < 1)) {
25971a3f92cSHarsh Kumar Bijlani 		ath12k_warn(ab, "Invalid HT mcs %d nss %d peer stats",
26071a3f92cSHarsh Kumar Bijlani 			    mcs, nss);
26171a3f92cSHarsh Kumar Bijlani 		return;
26271a3f92cSHarsh Kumar Bijlani 	}
26371a3f92cSHarsh Kumar Bijlani 
26471a3f92cSHarsh Kumar Bijlani 	if (flags == WMI_RATE_PREAMBLE_CCK || flags == WMI_RATE_PREAMBLE_OFDM) {
26571a3f92cSHarsh Kumar Bijlani 		ret = ath12k_mac_hw_ratecode_to_legacy_rate(mcs,
26671a3f92cSHarsh Kumar Bijlani 							    flags,
26771a3f92cSHarsh Kumar Bijlani 							    &rate_idx,
26871a3f92cSHarsh Kumar Bijlani 							    &rate);
26971a3f92cSHarsh Kumar Bijlani 		if (ret < 0)
27071a3f92cSHarsh Kumar Bijlani 			return;
27171a3f92cSHarsh Kumar Bijlani 	}
27271a3f92cSHarsh Kumar Bijlani 
27371a3f92cSHarsh Kumar Bijlani 	rcu_read_lock();
27411157e09SHarsh Kumar Bijlani 	peer = ath12k_dp_link_peer_find_by_peerid(dp_pdev, usr_stats->peer_id);
27571a3f92cSHarsh Kumar Bijlani 
27671a3f92cSHarsh Kumar Bijlani 	if (!peer || !peer->sta) {
27771a3f92cSHarsh Kumar Bijlani 		rcu_read_unlock();
27871a3f92cSHarsh Kumar Bijlani 		return;
27971a3f92cSHarsh Kumar Bijlani 	}
28071a3f92cSHarsh Kumar Bijlani 
28135fcf4faSHarsh Kumar Bijlani 	spin_lock_bh(&dp->dp_lock);
28271a3f92cSHarsh Kumar Bijlani 
28335fcf4faSHarsh Kumar Bijlani 	memset(&peer->txrate, 0, sizeof(peer->txrate));
28471a3f92cSHarsh Kumar Bijlani 
28535fcf4faSHarsh Kumar Bijlani 	peer->txrate.bw = ath12k_mac_bw_to_mac80211_bw(bw);
28671a3f92cSHarsh Kumar Bijlani 
28771a3f92cSHarsh Kumar Bijlani 	switch (flags) {
28871a3f92cSHarsh Kumar Bijlani 	case WMI_RATE_PREAMBLE_OFDM:
28935fcf4faSHarsh Kumar Bijlani 		peer->txrate.legacy = rate;
29071a3f92cSHarsh Kumar Bijlani 		break;
29171a3f92cSHarsh Kumar Bijlani 	case WMI_RATE_PREAMBLE_CCK:
29235fcf4faSHarsh Kumar Bijlani 		peer->txrate.legacy = rate;
29371a3f92cSHarsh Kumar Bijlani 		break;
29471a3f92cSHarsh Kumar Bijlani 	case WMI_RATE_PREAMBLE_HT:
29535fcf4faSHarsh Kumar Bijlani 		peer->txrate.mcs = mcs + 8 * (nss - 1);
29635fcf4faSHarsh Kumar Bijlani 		peer->txrate.flags = RATE_INFO_FLAGS_MCS;
29771a3f92cSHarsh Kumar Bijlani 		if (sgi)
29835fcf4faSHarsh Kumar Bijlani 			peer->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
29971a3f92cSHarsh Kumar Bijlani 		break;
30071a3f92cSHarsh Kumar Bijlani 	case WMI_RATE_PREAMBLE_VHT:
30135fcf4faSHarsh Kumar Bijlani 		peer->txrate.mcs = mcs;
30235fcf4faSHarsh Kumar Bijlani 		peer->txrate.flags = RATE_INFO_FLAGS_VHT_MCS;
30371a3f92cSHarsh Kumar Bijlani 		if (sgi)
30435fcf4faSHarsh Kumar Bijlani 			peer->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
30571a3f92cSHarsh Kumar Bijlani 		break;
30671a3f92cSHarsh Kumar Bijlani 	case WMI_RATE_PREAMBLE_HE:
30735fcf4faSHarsh Kumar Bijlani 		peer->txrate.mcs = mcs;
30835fcf4faSHarsh Kumar Bijlani 		peer->txrate.flags = RATE_INFO_FLAGS_HE_MCS;
30935fcf4faSHarsh Kumar Bijlani 		peer->txrate.he_dcm = dcm;
31035fcf4faSHarsh Kumar Bijlani 		peer->txrate.he_gi = ath12k_he_gi_to_nl80211_he_gi(sgi);
31171a3f92cSHarsh Kumar Bijlani 		tones = le16_to_cpu(user_rate->ru_end) -
31271a3f92cSHarsh Kumar Bijlani 			le16_to_cpu(user_rate->ru_start) + 1;
31371a3f92cSHarsh Kumar Bijlani 		v = ath12k_he_ru_tones_to_nl80211_he_ru_alloc(tones);
31435fcf4faSHarsh Kumar Bijlani 		peer->txrate.he_ru_alloc = v;
31571a3f92cSHarsh Kumar Bijlani 		if (is_ofdma)
31635fcf4faSHarsh Kumar Bijlani 			peer->txrate.bw = RATE_INFO_BW_HE_RU;
31771a3f92cSHarsh Kumar Bijlani 		break;
31871a3f92cSHarsh Kumar Bijlani 	case WMI_RATE_PREAMBLE_EHT:
31935fcf4faSHarsh Kumar Bijlani 		peer->txrate.mcs = mcs;
32035fcf4faSHarsh Kumar Bijlani 		peer->txrate.flags = RATE_INFO_FLAGS_EHT_MCS;
32135fcf4faSHarsh Kumar Bijlani 		peer->txrate.he_dcm = dcm;
32235fcf4faSHarsh Kumar Bijlani 		peer->txrate.eht_gi = ath12k_mac_eht_gi_to_nl80211_eht_gi(sgi);
32371a3f92cSHarsh Kumar Bijlani 		tones = le16_to_cpu(user_rate->ru_end) -
32471a3f92cSHarsh Kumar Bijlani 			le16_to_cpu(user_rate->ru_start) + 1;
32571a3f92cSHarsh Kumar Bijlani 		v = ath12k_mac_eht_ru_tones_to_nl80211_eht_ru_alloc(tones);
32635fcf4faSHarsh Kumar Bijlani 		peer->txrate.eht_ru_alloc = v;
32771a3f92cSHarsh Kumar Bijlani 		if (is_ofdma)
32835fcf4faSHarsh Kumar Bijlani 			peer->txrate.bw = RATE_INFO_BW_EHT_RU;
32971a3f92cSHarsh Kumar Bijlani 		break;
33071a3f92cSHarsh Kumar Bijlani 	}
33171a3f92cSHarsh Kumar Bijlani 
33235fcf4faSHarsh Kumar Bijlani 	peer->tx_retry_failed += tx_retry_failed;
33335fcf4faSHarsh Kumar Bijlani 	peer->tx_retry_count += tx_retry_count;
33435fcf4faSHarsh Kumar Bijlani 	peer->txrate.nss = nss;
33535fcf4faSHarsh Kumar Bijlani 	peer->tx_duration += tx_duration;
33635fcf4faSHarsh Kumar Bijlani 	memcpy(&peer->last_txrate, &peer->txrate, sizeof(struct rate_info));
33735fcf4faSHarsh Kumar Bijlani 
33835fcf4faSHarsh Kumar Bijlani 	spin_unlock_bh(&dp->dp_lock);
33971a3f92cSHarsh Kumar Bijlani 
34071a3f92cSHarsh Kumar Bijlani 	/* PPDU stats reported for mgmt packet doesn't have valid tx bytes.
34171a3f92cSHarsh Kumar Bijlani 	 * So skip peer stats update for mgmt packets.
34271a3f92cSHarsh Kumar Bijlani 	 */
34371a3f92cSHarsh Kumar Bijlani 	if (tid < HTT_PPDU_STATS_NON_QOS_TID) {
34471a3f92cSHarsh Kumar Bijlani 		memset(peer_stats, 0, sizeof(*peer_stats));
34571a3f92cSHarsh Kumar Bijlani 		peer_stats->succ_pkts = succ_pkts;
34671a3f92cSHarsh Kumar Bijlani 		peer_stats->succ_bytes = succ_bytes;
34771a3f92cSHarsh Kumar Bijlani 		peer_stats->is_ampdu = is_ampdu;
34871a3f92cSHarsh Kumar Bijlani 		peer_stats->duration = tx_duration;
34971a3f92cSHarsh Kumar Bijlani 		peer_stats->ba_fails =
35071a3f92cSHarsh Kumar Bijlani 			HTT_USR_CMPLTN_LONG_RETRY(usr_stats->cmpltn_cmn.flags) +
35171a3f92cSHarsh Kumar Bijlani 			HTT_USR_CMPLTN_SHORT_RETRY(usr_stats->cmpltn_cmn.flags);
35271a3f92cSHarsh Kumar Bijlani 	}
35371a3f92cSHarsh Kumar Bijlani 
35471a3f92cSHarsh Kumar Bijlani 	rcu_read_unlock();
35571a3f92cSHarsh Kumar Bijlani }
35671a3f92cSHarsh Kumar Bijlani 
ath12k_htt_update_ppdu_stats(struct ath12k_pdev_dp * dp_pdev,struct htt_ppdu_stats * ppdu_stats)357c57176c0SRipan Deuri static void ath12k_htt_update_ppdu_stats(struct ath12k_pdev_dp *dp_pdev,
35871a3f92cSHarsh Kumar Bijlani 					 struct htt_ppdu_stats *ppdu_stats)
35971a3f92cSHarsh Kumar Bijlani {
36071a3f92cSHarsh Kumar Bijlani 	u8 user;
36171a3f92cSHarsh Kumar Bijlani 
36271a3f92cSHarsh Kumar Bijlani 	for (user = 0; user < HTT_PPDU_STATS_MAX_USERS - 1; user++)
363c57176c0SRipan Deuri 		ath12k_update_per_peer_tx_stats(dp_pdev, ppdu_stats, user);
36471a3f92cSHarsh Kumar Bijlani }
36571a3f92cSHarsh Kumar Bijlani 
36671a3f92cSHarsh Kumar Bijlani static
ath12k_dp_htt_get_ppdu_desc(struct ath12k_pdev_dp * dp_pdev,u32 ppdu_id)367c57176c0SRipan Deuri struct htt_ppdu_stats_info *ath12k_dp_htt_get_ppdu_desc(struct ath12k_pdev_dp *dp_pdev,
36871a3f92cSHarsh Kumar Bijlani 							u32 ppdu_id)
36971a3f92cSHarsh Kumar Bijlani {
37071a3f92cSHarsh Kumar Bijlani 	struct htt_ppdu_stats_info *ppdu_info;
37171a3f92cSHarsh Kumar Bijlani 
372c57176c0SRipan Deuri 	lockdep_assert_held(&dp_pdev->ppdu_list_lock);
373c57176c0SRipan Deuri 	if (!list_empty(&dp_pdev->ppdu_stats_info)) {
374c57176c0SRipan Deuri 		list_for_each_entry(ppdu_info, &dp_pdev->ppdu_stats_info, list) {
37571a3f92cSHarsh Kumar Bijlani 			if (ppdu_info->ppdu_id == ppdu_id)
37671a3f92cSHarsh Kumar Bijlani 				return ppdu_info;
37771a3f92cSHarsh Kumar Bijlani 		}
37871a3f92cSHarsh Kumar Bijlani 
379c57176c0SRipan Deuri 		if (dp_pdev->ppdu_stat_list_depth > HTT_PPDU_DESC_MAX_DEPTH) {
380c57176c0SRipan Deuri 			ppdu_info = list_first_entry(&dp_pdev->ppdu_stats_info,
38171a3f92cSHarsh Kumar Bijlani 						     typeof(*ppdu_info), list);
38271a3f92cSHarsh Kumar Bijlani 			list_del(&ppdu_info->list);
383c57176c0SRipan Deuri 			dp_pdev->ppdu_stat_list_depth--;
384c57176c0SRipan Deuri 			ath12k_htt_update_ppdu_stats(dp_pdev, &ppdu_info->ppdu_stats);
38571a3f92cSHarsh Kumar Bijlani 			kfree(ppdu_info);
38671a3f92cSHarsh Kumar Bijlani 		}
38771a3f92cSHarsh Kumar Bijlani 	}
38871a3f92cSHarsh Kumar Bijlani 
389*69050f8dSKees Cook 	ppdu_info = kzalloc_obj(*ppdu_info, GFP_ATOMIC);
39071a3f92cSHarsh Kumar Bijlani 	if (!ppdu_info)
39171a3f92cSHarsh Kumar Bijlani 		return NULL;
39271a3f92cSHarsh Kumar Bijlani 
393c57176c0SRipan Deuri 	list_add_tail(&ppdu_info->list, &dp_pdev->ppdu_stats_info);
394c57176c0SRipan Deuri 	dp_pdev->ppdu_stat_list_depth++;
39571a3f92cSHarsh Kumar Bijlani 
39671a3f92cSHarsh Kumar Bijlani 	return ppdu_info;
39771a3f92cSHarsh Kumar Bijlani }
39871a3f92cSHarsh Kumar Bijlani 
ath12k_copy_to_delay_stats(struct ath12k_dp_link_peer * peer,struct htt_ppdu_user_stats * usr_stats)3999e0b56a3SHarsh Kumar Bijlani static void ath12k_copy_to_delay_stats(struct ath12k_dp_link_peer *peer,
40071a3f92cSHarsh Kumar Bijlani 				       struct htt_ppdu_user_stats *usr_stats)
40171a3f92cSHarsh Kumar Bijlani {
40271a3f92cSHarsh Kumar Bijlani 	peer->ppdu_stats_delayba.sw_peer_id = le16_to_cpu(usr_stats->rate.sw_peer_id);
40371a3f92cSHarsh Kumar Bijlani 	peer->ppdu_stats_delayba.info0 = le32_to_cpu(usr_stats->rate.info0);
40471a3f92cSHarsh Kumar Bijlani 	peer->ppdu_stats_delayba.ru_end = le16_to_cpu(usr_stats->rate.ru_end);
40571a3f92cSHarsh Kumar Bijlani 	peer->ppdu_stats_delayba.ru_start = le16_to_cpu(usr_stats->rate.ru_start);
40671a3f92cSHarsh Kumar Bijlani 	peer->ppdu_stats_delayba.info1 = le32_to_cpu(usr_stats->rate.info1);
40771a3f92cSHarsh Kumar Bijlani 	peer->ppdu_stats_delayba.rate_flags = le32_to_cpu(usr_stats->rate.rate_flags);
40871a3f92cSHarsh Kumar Bijlani 	peer->ppdu_stats_delayba.resp_rate_flags =
40971a3f92cSHarsh Kumar Bijlani 		le32_to_cpu(usr_stats->rate.resp_rate_flags);
41071a3f92cSHarsh Kumar Bijlani 
41171a3f92cSHarsh Kumar Bijlani 	peer->delayba_flag = true;
41271a3f92cSHarsh Kumar Bijlani }
41371a3f92cSHarsh Kumar Bijlani 
ath12k_copy_to_bar(struct ath12k_dp_link_peer * peer,struct htt_ppdu_user_stats * usr_stats)4149e0b56a3SHarsh Kumar Bijlani static void ath12k_copy_to_bar(struct ath12k_dp_link_peer *peer,
41571a3f92cSHarsh Kumar Bijlani 			       struct htt_ppdu_user_stats *usr_stats)
41671a3f92cSHarsh Kumar Bijlani {
41771a3f92cSHarsh Kumar Bijlani 	usr_stats->rate.sw_peer_id = cpu_to_le16(peer->ppdu_stats_delayba.sw_peer_id);
41871a3f92cSHarsh Kumar Bijlani 	usr_stats->rate.info0 = cpu_to_le32(peer->ppdu_stats_delayba.info0);
41971a3f92cSHarsh Kumar Bijlani 	usr_stats->rate.ru_end = cpu_to_le16(peer->ppdu_stats_delayba.ru_end);
42071a3f92cSHarsh Kumar Bijlani 	usr_stats->rate.ru_start = cpu_to_le16(peer->ppdu_stats_delayba.ru_start);
42171a3f92cSHarsh Kumar Bijlani 	usr_stats->rate.info1 = cpu_to_le32(peer->ppdu_stats_delayba.info1);
42271a3f92cSHarsh Kumar Bijlani 	usr_stats->rate.rate_flags = cpu_to_le32(peer->ppdu_stats_delayba.rate_flags);
42371a3f92cSHarsh Kumar Bijlani 	usr_stats->rate.resp_rate_flags =
42471a3f92cSHarsh Kumar Bijlani 		cpu_to_le32(peer->ppdu_stats_delayba.resp_rate_flags);
42571a3f92cSHarsh Kumar Bijlani 
42671a3f92cSHarsh Kumar Bijlani 	peer->delayba_flag = false;
42771a3f92cSHarsh Kumar Bijlani }
42871a3f92cSHarsh Kumar Bijlani 
ath12k_htt_pull_ppdu_stats(struct ath12k_base * ab,struct sk_buff * skb)42971a3f92cSHarsh Kumar Bijlani static int ath12k_htt_pull_ppdu_stats(struct ath12k_base *ab,
43071a3f92cSHarsh Kumar Bijlani 				      struct sk_buff *skb)
43171a3f92cSHarsh Kumar Bijlani {
432c57176c0SRipan Deuri 	struct ath12k_dp *dp = ath12k_ab_to_dp(ab);
43371a3f92cSHarsh Kumar Bijlani 	struct ath12k_htt_ppdu_stats_msg *msg;
43471a3f92cSHarsh Kumar Bijlani 	struct htt_ppdu_stats_info *ppdu_info;
4359e0b56a3SHarsh Kumar Bijlani 	struct ath12k_dp_link_peer *peer = NULL;
43671a3f92cSHarsh Kumar Bijlani 	struct htt_ppdu_user_stats *usr_stats = NULL;
43771a3f92cSHarsh Kumar Bijlani 	u32 peer_id = 0;
438c57176c0SRipan Deuri 	struct ath12k_pdev_dp *dp_pdev;
43971a3f92cSHarsh Kumar Bijlani 	int ret, i;
440c57176c0SRipan Deuri 	u8 pdev_id, pdev_idx;
44171a3f92cSHarsh Kumar Bijlani 	u32 ppdu_id, len;
44271a3f92cSHarsh Kumar Bijlani 
44371a3f92cSHarsh Kumar Bijlani 	msg = (struct ath12k_htt_ppdu_stats_msg *)skb->data;
44471a3f92cSHarsh Kumar Bijlani 	len = le32_get_bits(msg->info, HTT_T2H_PPDU_STATS_INFO_PAYLOAD_SIZE);
44571a3f92cSHarsh Kumar Bijlani 	if (len > (skb->len - struct_size(msg, data, 0))) {
44671a3f92cSHarsh Kumar Bijlani 		ath12k_warn(ab,
44771a3f92cSHarsh Kumar Bijlani 			    "HTT PPDU STATS event has unexpected payload size %u, should be smaller than %u\n",
44871a3f92cSHarsh Kumar Bijlani 			    len, skb->len);
44971a3f92cSHarsh Kumar Bijlani 		return -EINVAL;
45071a3f92cSHarsh Kumar Bijlani 	}
45171a3f92cSHarsh Kumar Bijlani 
45271a3f92cSHarsh Kumar Bijlani 	pdev_id = le32_get_bits(msg->info, HTT_T2H_PPDU_STATS_INFO_PDEV_ID);
45371a3f92cSHarsh Kumar Bijlani 	ppdu_id = le32_to_cpu(msg->ppdu_id);
45471a3f92cSHarsh Kumar Bijlani 
455c57176c0SRipan Deuri 	pdev_idx = DP_HW2SW_MACID(pdev_id);
456c57176c0SRipan Deuri 	if (pdev_idx >= MAX_RADIOS) {
457c57176c0SRipan Deuri 		ath12k_warn(ab, "HTT PPDU STATS invalid pdev id %u", pdev_id);
458c57176c0SRipan Deuri 		return -EINVAL;
459c57176c0SRipan Deuri 	}
460c57176c0SRipan Deuri 
46171a3f92cSHarsh Kumar Bijlani 	rcu_read_lock();
462c57176c0SRipan Deuri 
463c57176c0SRipan Deuri 	dp_pdev = ath12k_dp_to_pdev_dp(dp, pdev_idx);
464c57176c0SRipan Deuri 	if (!dp_pdev) {
46571a3f92cSHarsh Kumar Bijlani 		ret = -EINVAL;
46671a3f92cSHarsh Kumar Bijlani 		goto exit;
46771a3f92cSHarsh Kumar Bijlani 	}
46871a3f92cSHarsh Kumar Bijlani 
469c57176c0SRipan Deuri 	spin_lock_bh(&dp_pdev->ppdu_list_lock);
470c57176c0SRipan Deuri 	ppdu_info = ath12k_dp_htt_get_ppdu_desc(dp_pdev, ppdu_id);
47171a3f92cSHarsh Kumar Bijlani 	if (!ppdu_info) {
472c57176c0SRipan Deuri 		spin_unlock_bh(&dp_pdev->ppdu_list_lock);
47371a3f92cSHarsh Kumar Bijlani 		ret = -EINVAL;
47471a3f92cSHarsh Kumar Bijlani 		goto exit;
47571a3f92cSHarsh Kumar Bijlani 	}
47671a3f92cSHarsh Kumar Bijlani 
47771a3f92cSHarsh Kumar Bijlani 	ppdu_info->ppdu_id = ppdu_id;
47871a3f92cSHarsh Kumar Bijlani 	ret = ath12k_dp_htt_tlv_iter(ab, msg->data, len,
47971a3f92cSHarsh Kumar Bijlani 				     ath12k_htt_tlv_ppdu_stats_parse,
48071a3f92cSHarsh Kumar Bijlani 				     (void *)ppdu_info);
48171a3f92cSHarsh Kumar Bijlani 	if (ret) {
482c57176c0SRipan Deuri 		spin_unlock_bh(&dp_pdev->ppdu_list_lock);
48371a3f92cSHarsh Kumar Bijlani 		ath12k_warn(ab, "Failed to parse tlv %d\n", ret);
48471a3f92cSHarsh Kumar Bijlani 		goto exit;
48571a3f92cSHarsh Kumar Bijlani 	}
48671a3f92cSHarsh Kumar Bijlani 
48771a3f92cSHarsh Kumar Bijlani 	if (ppdu_info->ppdu_stats.common.num_users >= HTT_PPDU_STATS_MAX_USERS) {
488c57176c0SRipan Deuri 		spin_unlock_bh(&dp_pdev->ppdu_list_lock);
48971a3f92cSHarsh Kumar Bijlani 		ath12k_warn(ab,
49071a3f92cSHarsh Kumar Bijlani 			    "HTT PPDU STATS event has unexpected num_users %u, should be smaller than %u\n",
49171a3f92cSHarsh Kumar Bijlani 			    ppdu_info->ppdu_stats.common.num_users,
49271a3f92cSHarsh Kumar Bijlani 			    HTT_PPDU_STATS_MAX_USERS);
49371a3f92cSHarsh Kumar Bijlani 		ret = -EINVAL;
49471a3f92cSHarsh Kumar Bijlani 		goto exit;
49571a3f92cSHarsh Kumar Bijlani 	}
49671a3f92cSHarsh Kumar Bijlani 
49771a3f92cSHarsh Kumar Bijlani 	/* back up data rate tlv for all peers */
49871a3f92cSHarsh Kumar Bijlani 	if (ppdu_info->frame_type == HTT_STATS_PPDU_FTYPE_DATA &&
49971a3f92cSHarsh Kumar Bijlani 	    (ppdu_info->tlv_bitmap & (1 << HTT_PPDU_STATS_TAG_USR_COMMON)) &&
50071a3f92cSHarsh Kumar Bijlani 	    ppdu_info->delay_ba) {
50171a3f92cSHarsh Kumar Bijlani 		for (i = 0; i < ppdu_info->ppdu_stats.common.num_users; i++) {
50271a3f92cSHarsh Kumar Bijlani 			peer_id = ppdu_info->ppdu_stats.user_stats[i].peer_id;
50311157e09SHarsh Kumar Bijlani 			peer = ath12k_dp_link_peer_find_by_peerid(dp_pdev, peer_id);
50411157e09SHarsh Kumar Bijlani 			if (!peer)
50571a3f92cSHarsh Kumar Bijlani 				continue;
50671a3f92cSHarsh Kumar Bijlani 
50771a3f92cSHarsh Kumar Bijlani 			usr_stats = &ppdu_info->ppdu_stats.user_stats[i];
50871a3f92cSHarsh Kumar Bijlani 			if (usr_stats->delay_ba)
50971a3f92cSHarsh Kumar Bijlani 				ath12k_copy_to_delay_stats(peer, usr_stats);
51071a3f92cSHarsh Kumar Bijlani 		}
51171a3f92cSHarsh Kumar Bijlani 	}
51271a3f92cSHarsh Kumar Bijlani 
51371a3f92cSHarsh Kumar Bijlani 	/* restore all peers' data rate tlv to mu-bar tlv */
51471a3f92cSHarsh Kumar Bijlani 	if (ppdu_info->frame_type == HTT_STATS_PPDU_FTYPE_BAR &&
51571a3f92cSHarsh Kumar Bijlani 	    (ppdu_info->tlv_bitmap & (1 << HTT_PPDU_STATS_TAG_USR_COMMON))) {
51671a3f92cSHarsh Kumar Bijlani 		for (i = 0; i < ppdu_info->bar_num_users; i++) {
51771a3f92cSHarsh Kumar Bijlani 			peer_id = ppdu_info->ppdu_stats.user_stats[i].peer_id;
51811157e09SHarsh Kumar Bijlani 			peer = ath12k_dp_link_peer_find_by_peerid(dp_pdev, peer_id);
51911157e09SHarsh Kumar Bijlani 			if (!peer)
52071a3f92cSHarsh Kumar Bijlani 				continue;
52171a3f92cSHarsh Kumar Bijlani 
52271a3f92cSHarsh Kumar Bijlani 			usr_stats = &ppdu_info->ppdu_stats.user_stats[i];
52371a3f92cSHarsh Kumar Bijlani 			if (peer->delayba_flag)
52471a3f92cSHarsh Kumar Bijlani 				ath12k_copy_to_bar(peer, usr_stats);
52571a3f92cSHarsh Kumar Bijlani 		}
52671a3f92cSHarsh Kumar Bijlani 	}
52771a3f92cSHarsh Kumar Bijlani 
528c57176c0SRipan Deuri 	spin_unlock_bh(&dp_pdev->ppdu_list_lock);
52971a3f92cSHarsh Kumar Bijlani 
53071a3f92cSHarsh Kumar Bijlani exit:
53171a3f92cSHarsh Kumar Bijlani 	rcu_read_unlock();
53271a3f92cSHarsh Kumar Bijlani 
53371a3f92cSHarsh Kumar Bijlani 	return ret;
53471a3f92cSHarsh Kumar Bijlani }
53571a3f92cSHarsh Kumar Bijlani 
ath12k_htt_mlo_offset_event_handler(struct ath12k_base * ab,struct sk_buff * skb)53671a3f92cSHarsh Kumar Bijlani static void ath12k_htt_mlo_offset_event_handler(struct ath12k_base *ab,
53771a3f92cSHarsh Kumar Bijlani 						struct sk_buff *skb)
53871a3f92cSHarsh Kumar Bijlani {
53971a3f92cSHarsh Kumar Bijlani 	struct ath12k_htt_mlo_offset_msg *msg;
54071a3f92cSHarsh Kumar Bijlani 	struct ath12k_pdev *pdev;
54171a3f92cSHarsh Kumar Bijlani 	struct ath12k *ar;
54271a3f92cSHarsh Kumar Bijlani 	u8 pdev_id;
54371a3f92cSHarsh Kumar Bijlani 
54471a3f92cSHarsh Kumar Bijlani 	msg = (struct ath12k_htt_mlo_offset_msg *)skb->data;
54571a3f92cSHarsh Kumar Bijlani 	pdev_id = u32_get_bits(__le32_to_cpu(msg->info),
54671a3f92cSHarsh Kumar Bijlani 			       HTT_T2H_MLO_OFFSET_INFO_PDEV_ID);
54771a3f92cSHarsh Kumar Bijlani 
54871a3f92cSHarsh Kumar Bijlani 	rcu_read_lock();
54971a3f92cSHarsh Kumar Bijlani 	ar = ath12k_mac_get_ar_by_pdev_id(ab, pdev_id);
55071a3f92cSHarsh Kumar Bijlani 	if (!ar) {
55171a3f92cSHarsh Kumar Bijlani 		/* It is possible that the ar is not yet active (started).
55271a3f92cSHarsh Kumar Bijlani 		 * The above function will only look for the active pdev
55371a3f92cSHarsh Kumar Bijlani 		 * and hence %NULL return is possible. Just silently
55471a3f92cSHarsh Kumar Bijlani 		 * discard this message
55571a3f92cSHarsh Kumar Bijlani 		 */
55671a3f92cSHarsh Kumar Bijlani 		goto exit;
55771a3f92cSHarsh Kumar Bijlani 	}
55871a3f92cSHarsh Kumar Bijlani 
55971a3f92cSHarsh Kumar Bijlani 	spin_lock_bh(&ar->data_lock);
56071a3f92cSHarsh Kumar Bijlani 	pdev = ar->pdev;
56171a3f92cSHarsh Kumar Bijlani 
56271a3f92cSHarsh Kumar Bijlani 	pdev->timestamp.info = __le32_to_cpu(msg->info);
56371a3f92cSHarsh Kumar Bijlani 	pdev->timestamp.sync_timestamp_lo_us = __le32_to_cpu(msg->sync_timestamp_lo_us);
56471a3f92cSHarsh Kumar Bijlani 	pdev->timestamp.sync_timestamp_hi_us = __le32_to_cpu(msg->sync_timestamp_hi_us);
56571a3f92cSHarsh Kumar Bijlani 	pdev->timestamp.mlo_offset_lo = __le32_to_cpu(msg->mlo_offset_lo);
56671a3f92cSHarsh Kumar Bijlani 	pdev->timestamp.mlo_offset_hi = __le32_to_cpu(msg->mlo_offset_hi);
56771a3f92cSHarsh Kumar Bijlani 	pdev->timestamp.mlo_offset_clks = __le32_to_cpu(msg->mlo_offset_clks);
56871a3f92cSHarsh Kumar Bijlani 	pdev->timestamp.mlo_comp_clks = __le32_to_cpu(msg->mlo_comp_clks);
56971a3f92cSHarsh Kumar Bijlani 	pdev->timestamp.mlo_comp_timer = __le32_to_cpu(msg->mlo_comp_timer);
57071a3f92cSHarsh Kumar Bijlani 
57171a3f92cSHarsh Kumar Bijlani 	spin_unlock_bh(&ar->data_lock);
57271a3f92cSHarsh Kumar Bijlani exit:
57371a3f92cSHarsh Kumar Bijlani 	rcu_read_unlock();
57471a3f92cSHarsh Kumar Bijlani }
57571a3f92cSHarsh Kumar Bijlani 
ath12k_dp_htt_htc_t2h_msg_handler(struct ath12k_base * ab,struct sk_buff * skb)57671a3f92cSHarsh Kumar Bijlani void ath12k_dp_htt_htc_t2h_msg_handler(struct ath12k_base *ab,
57771a3f92cSHarsh Kumar Bijlani 				       struct sk_buff *skb)
57871a3f92cSHarsh Kumar Bijlani {
5793a52762bSRipan Deuri 	struct ath12k_dp *dp = ath12k_ab_to_dp(ab);
58071a3f92cSHarsh Kumar Bijlani 	struct htt_resp_msg *resp = (struct htt_resp_msg *)skb->data;
58171a3f92cSHarsh Kumar Bijlani 	enum htt_t2h_msg_type type;
58271a3f92cSHarsh Kumar Bijlani 	u16 peer_id;
58371a3f92cSHarsh Kumar Bijlani 	u8 vdev_id;
58471a3f92cSHarsh Kumar Bijlani 	u8 mac_addr[ETH_ALEN];
58571a3f92cSHarsh Kumar Bijlani 	u16 peer_mac_h16;
58671a3f92cSHarsh Kumar Bijlani 	u16 ast_hash = 0;
58771a3f92cSHarsh Kumar Bijlani 	u16 hw_peer_id;
58871a3f92cSHarsh Kumar Bijlani 
58971a3f92cSHarsh Kumar Bijlani 	type = le32_get_bits(resp->version_msg.version, HTT_T2H_MSG_TYPE);
59071a3f92cSHarsh Kumar Bijlani 
59171a3f92cSHarsh Kumar Bijlani 	ath12k_dbg(ab, ATH12K_DBG_DP_HTT, "dp_htt rx msg type :0x%0x\n", type);
59271a3f92cSHarsh Kumar Bijlani 
59371a3f92cSHarsh Kumar Bijlani 	switch (type) {
59471a3f92cSHarsh Kumar Bijlani 	case HTT_T2H_MSG_TYPE_VERSION_CONF:
59571a3f92cSHarsh Kumar Bijlani 		dp->htt_tgt_ver_major = le32_get_bits(resp->version_msg.version,
59671a3f92cSHarsh Kumar Bijlani 						      HTT_T2H_VERSION_CONF_MAJOR);
59771a3f92cSHarsh Kumar Bijlani 		dp->htt_tgt_ver_minor = le32_get_bits(resp->version_msg.version,
59871a3f92cSHarsh Kumar Bijlani 						      HTT_T2H_VERSION_CONF_MINOR);
59971a3f92cSHarsh Kumar Bijlani 		complete(&dp->htt_tgt_version_received);
60071a3f92cSHarsh Kumar Bijlani 		break;
60171a3f92cSHarsh Kumar Bijlani 	/* TODO: remove unused peer map versions after testing */
60271a3f92cSHarsh Kumar Bijlani 	case HTT_T2H_MSG_TYPE_PEER_MAP:
60371a3f92cSHarsh Kumar Bijlani 		vdev_id = le32_get_bits(resp->peer_map_ev.info,
60471a3f92cSHarsh Kumar Bijlani 					HTT_T2H_PEER_MAP_INFO_VDEV_ID);
60571a3f92cSHarsh Kumar Bijlani 		peer_id = le32_get_bits(resp->peer_map_ev.info,
60671a3f92cSHarsh Kumar Bijlani 					HTT_T2H_PEER_MAP_INFO_PEER_ID);
60771a3f92cSHarsh Kumar Bijlani 		peer_mac_h16 = le32_get_bits(resp->peer_map_ev.info1,
60871a3f92cSHarsh Kumar Bijlani 					     HTT_T2H_PEER_MAP_INFO1_MAC_ADDR_H16);
60971a3f92cSHarsh Kumar Bijlani 		ath12k_dp_get_mac_addr(le32_to_cpu(resp->peer_map_ev.mac_addr_l32),
61071a3f92cSHarsh Kumar Bijlani 				       peer_mac_h16, mac_addr);
6119e0b56a3SHarsh Kumar Bijlani 		ath12k_dp_link_peer_map_event(ab, vdev_id, peer_id, mac_addr, 0, 0);
61271a3f92cSHarsh Kumar Bijlani 		break;
61371a3f92cSHarsh Kumar Bijlani 	case HTT_T2H_MSG_TYPE_PEER_MAP2:
61471a3f92cSHarsh Kumar Bijlani 		vdev_id = le32_get_bits(resp->peer_map_ev.info,
61571a3f92cSHarsh Kumar Bijlani 					HTT_T2H_PEER_MAP_INFO_VDEV_ID);
61671a3f92cSHarsh Kumar Bijlani 		peer_id = le32_get_bits(resp->peer_map_ev.info,
61771a3f92cSHarsh Kumar Bijlani 					HTT_T2H_PEER_MAP_INFO_PEER_ID);
61871a3f92cSHarsh Kumar Bijlani 		peer_mac_h16 = le32_get_bits(resp->peer_map_ev.info1,
61971a3f92cSHarsh Kumar Bijlani 					     HTT_T2H_PEER_MAP_INFO1_MAC_ADDR_H16);
62071a3f92cSHarsh Kumar Bijlani 		ath12k_dp_get_mac_addr(le32_to_cpu(resp->peer_map_ev.mac_addr_l32),
62171a3f92cSHarsh Kumar Bijlani 				       peer_mac_h16, mac_addr);
62271a3f92cSHarsh Kumar Bijlani 		ast_hash = le32_get_bits(resp->peer_map_ev.info2,
62371a3f92cSHarsh Kumar Bijlani 					 HTT_T2H_PEER_MAP_INFO2_AST_HASH_VAL);
62471a3f92cSHarsh Kumar Bijlani 		hw_peer_id = le32_get_bits(resp->peer_map_ev.info1,
62571a3f92cSHarsh Kumar Bijlani 					   HTT_T2H_PEER_MAP_INFO1_HW_PEER_ID);
6269e0b56a3SHarsh Kumar Bijlani 		ath12k_dp_link_peer_map_event(ab, vdev_id, peer_id, mac_addr, ast_hash,
62771a3f92cSHarsh Kumar Bijlani 					      hw_peer_id);
62871a3f92cSHarsh Kumar Bijlani 		break;
62971a3f92cSHarsh Kumar Bijlani 	case HTT_T2H_MSG_TYPE_PEER_MAP3:
63071a3f92cSHarsh Kumar Bijlani 		vdev_id = le32_get_bits(resp->peer_map_ev.info,
63171a3f92cSHarsh Kumar Bijlani 					HTT_T2H_PEER_MAP_INFO_VDEV_ID);
63271a3f92cSHarsh Kumar Bijlani 		peer_id = le32_get_bits(resp->peer_map_ev.info,
63371a3f92cSHarsh Kumar Bijlani 					HTT_T2H_PEER_MAP_INFO_PEER_ID);
63471a3f92cSHarsh Kumar Bijlani 		peer_mac_h16 = le32_get_bits(resp->peer_map_ev.info1,
63571a3f92cSHarsh Kumar Bijlani 					     HTT_T2H_PEER_MAP_INFO1_MAC_ADDR_H16);
63671a3f92cSHarsh Kumar Bijlani 		ath12k_dp_get_mac_addr(le32_to_cpu(resp->peer_map_ev.mac_addr_l32),
63771a3f92cSHarsh Kumar Bijlani 				       peer_mac_h16, mac_addr);
63871a3f92cSHarsh Kumar Bijlani 		ast_hash = le32_get_bits(resp->peer_map_ev.info2,
63971a3f92cSHarsh Kumar Bijlani 					 HTT_T2H_PEER_MAP3_INFO2_AST_HASH_VAL);
64071a3f92cSHarsh Kumar Bijlani 		hw_peer_id = le32_get_bits(resp->peer_map_ev.info2,
64171a3f92cSHarsh Kumar Bijlani 					   HTT_T2H_PEER_MAP3_INFO2_HW_PEER_ID);
6429e0b56a3SHarsh Kumar Bijlani 		ath12k_dp_link_peer_map_event(ab, vdev_id, peer_id, mac_addr, ast_hash,
64371a3f92cSHarsh Kumar Bijlani 					      hw_peer_id);
64471a3f92cSHarsh Kumar Bijlani 		break;
64571a3f92cSHarsh Kumar Bijlani 	case HTT_T2H_MSG_TYPE_PEER_UNMAP:
64671a3f92cSHarsh Kumar Bijlani 	case HTT_T2H_MSG_TYPE_PEER_UNMAP2:
64771a3f92cSHarsh Kumar Bijlani 		peer_id = le32_get_bits(resp->peer_unmap_ev.info,
64871a3f92cSHarsh Kumar Bijlani 					HTT_T2H_PEER_UNMAP_INFO_PEER_ID);
6499e0b56a3SHarsh Kumar Bijlani 		ath12k_dp_link_peer_unmap_event(ab, peer_id);
65071a3f92cSHarsh Kumar Bijlani 		break;
65171a3f92cSHarsh Kumar Bijlani 	case HTT_T2H_MSG_TYPE_PPDU_STATS_IND:
65271a3f92cSHarsh Kumar Bijlani 		ath12k_htt_pull_ppdu_stats(ab, skb);
65371a3f92cSHarsh Kumar Bijlani 		break;
65471a3f92cSHarsh Kumar Bijlani 	case HTT_T2H_MSG_TYPE_EXT_STATS_CONF:
65571a3f92cSHarsh Kumar Bijlani 		ath12k_debugfs_htt_ext_stats_handler(ab, skb);
65671a3f92cSHarsh Kumar Bijlani 		break;
65771a3f92cSHarsh Kumar Bijlani 	case HTT_T2H_MSG_TYPE_MLO_TIMESTAMP_OFFSET_IND:
65871a3f92cSHarsh Kumar Bijlani 		ath12k_htt_mlo_offset_event_handler(ab, skb);
65971a3f92cSHarsh Kumar Bijlani 		break;
66071a3f92cSHarsh Kumar Bijlani 	default:
66171a3f92cSHarsh Kumar Bijlani 		ath12k_dbg(ab, ATH12K_DBG_DP_HTT, "dp_htt event %d not handled\n",
66271a3f92cSHarsh Kumar Bijlani 			   type);
66371a3f92cSHarsh Kumar Bijlani 		break;
66471a3f92cSHarsh Kumar Bijlani 	}
66571a3f92cSHarsh Kumar Bijlani 
66671a3f92cSHarsh Kumar Bijlani 	dev_kfree_skb_any(skb);
66771a3f92cSHarsh Kumar Bijlani }
66871a3f92cSHarsh Kumar Bijlani EXPORT_SYMBOL(ath12k_dp_htt_htc_t2h_msg_handler);
669611297eeSHarsh Kumar Bijlani 
670611297eeSHarsh Kumar Bijlani static int
ath12k_dp_tx_get_ring_id_type(struct ath12k_base * ab,int mac_id,u32 ring_id,enum hal_ring_type ring_type,enum htt_srng_ring_type * htt_ring_type,enum htt_srng_ring_id * htt_ring_id)671611297eeSHarsh Kumar Bijlani ath12k_dp_tx_get_ring_id_type(struct ath12k_base *ab,
672611297eeSHarsh Kumar Bijlani 			      int mac_id, u32 ring_id,
673611297eeSHarsh Kumar Bijlani 			      enum hal_ring_type ring_type,
674611297eeSHarsh Kumar Bijlani 			      enum htt_srng_ring_type *htt_ring_type,
675611297eeSHarsh Kumar Bijlani 			      enum htt_srng_ring_id *htt_ring_id)
676611297eeSHarsh Kumar Bijlani {
677611297eeSHarsh Kumar Bijlani 	int ret = 0;
678611297eeSHarsh Kumar Bijlani 
679611297eeSHarsh Kumar Bijlani 	switch (ring_type) {
680611297eeSHarsh Kumar Bijlani 	case HAL_RXDMA_BUF:
681611297eeSHarsh Kumar Bijlani 		/* for some targets, host fills rx buffer to fw and fw fills to
682611297eeSHarsh Kumar Bijlani 		 * rxbuf ring for each rxdma
683611297eeSHarsh Kumar Bijlani 		 */
684611297eeSHarsh Kumar Bijlani 		if (!ab->hw_params->rx_mac_buf_ring) {
685611297eeSHarsh Kumar Bijlani 			if (!(ring_id == HAL_SRNG_SW2RXDMA_BUF0 ||
686611297eeSHarsh Kumar Bijlani 			      ring_id == HAL_SRNG_SW2RXDMA_BUF1)) {
687611297eeSHarsh Kumar Bijlani 				ret = -EINVAL;
688611297eeSHarsh Kumar Bijlani 			}
689611297eeSHarsh Kumar Bijlani 			*htt_ring_id = HTT_RXDMA_HOST_BUF_RING;
690611297eeSHarsh Kumar Bijlani 			*htt_ring_type = HTT_SW_TO_HW_RING;
691611297eeSHarsh Kumar Bijlani 		} else {
692611297eeSHarsh Kumar Bijlani 			if (ring_id == HAL_SRNG_SW2RXDMA_BUF0) {
693611297eeSHarsh Kumar Bijlani 				*htt_ring_id = HTT_HOST1_TO_FW_RXBUF_RING;
694611297eeSHarsh Kumar Bijlani 				*htt_ring_type = HTT_SW_TO_SW_RING;
695611297eeSHarsh Kumar Bijlani 			} else {
696611297eeSHarsh Kumar Bijlani 				*htt_ring_id = HTT_RXDMA_HOST_BUF_RING;
697611297eeSHarsh Kumar Bijlani 				*htt_ring_type = HTT_SW_TO_HW_RING;
698611297eeSHarsh Kumar Bijlani 			}
699611297eeSHarsh Kumar Bijlani 		}
700611297eeSHarsh Kumar Bijlani 		break;
701611297eeSHarsh Kumar Bijlani 	case HAL_RXDMA_DST:
702611297eeSHarsh Kumar Bijlani 		*htt_ring_id = HTT_RXDMA_NON_MONITOR_DEST_RING;
703611297eeSHarsh Kumar Bijlani 		*htt_ring_type = HTT_HW_TO_SW_RING;
704611297eeSHarsh Kumar Bijlani 		break;
705611297eeSHarsh Kumar Bijlani 	case HAL_RXDMA_MONITOR_BUF:
706611297eeSHarsh Kumar Bijlani 		*htt_ring_id = HTT_RX_MON_HOST2MON_BUF_RING;
707611297eeSHarsh Kumar Bijlani 		*htt_ring_type = HTT_SW_TO_HW_RING;
708611297eeSHarsh Kumar Bijlani 		break;
709611297eeSHarsh Kumar Bijlani 	case HAL_RXDMA_MONITOR_STATUS:
710611297eeSHarsh Kumar Bijlani 		*htt_ring_id = HTT_RXDMA_MONITOR_STATUS_RING;
711611297eeSHarsh Kumar Bijlani 		*htt_ring_type = HTT_SW_TO_HW_RING;
712611297eeSHarsh Kumar Bijlani 		break;
713611297eeSHarsh Kumar Bijlani 	case HAL_RXDMA_MONITOR_DST:
714611297eeSHarsh Kumar Bijlani 		*htt_ring_id = HTT_RX_MON_MON2HOST_DEST_RING;
715611297eeSHarsh Kumar Bijlani 		*htt_ring_type = HTT_HW_TO_SW_RING;
716611297eeSHarsh Kumar Bijlani 		break;
717611297eeSHarsh Kumar Bijlani 	case HAL_RXDMA_MONITOR_DESC:
718611297eeSHarsh Kumar Bijlani 		*htt_ring_id = HTT_RXDMA_MONITOR_DESC_RING;
719611297eeSHarsh Kumar Bijlani 		*htt_ring_type = HTT_SW_TO_HW_RING;
720611297eeSHarsh Kumar Bijlani 		break;
721611297eeSHarsh Kumar Bijlani 	default:
722611297eeSHarsh Kumar Bijlani 		ath12k_warn(ab, "Unsupported ring type in DP :%d\n", ring_type);
723611297eeSHarsh Kumar Bijlani 		ret = -EINVAL;
724611297eeSHarsh Kumar Bijlani 	}
725611297eeSHarsh Kumar Bijlani 	return ret;
726611297eeSHarsh Kumar Bijlani }
727611297eeSHarsh Kumar Bijlani 
ath12k_dp_tx_htt_srng_setup(struct ath12k_base * ab,u32 ring_id,int mac_id,enum hal_ring_type ring_type)728611297eeSHarsh Kumar Bijlani int ath12k_dp_tx_htt_srng_setup(struct ath12k_base *ab, u32 ring_id,
729611297eeSHarsh Kumar Bijlani 				int mac_id, enum hal_ring_type ring_type)
730611297eeSHarsh Kumar Bijlani {
7313a52762bSRipan Deuri 	struct ath12k_dp *dp = ath12k_ab_to_dp(ab);
732611297eeSHarsh Kumar Bijlani 	struct htt_srng_setup_cmd *cmd;
733611297eeSHarsh Kumar Bijlani 	struct hal_srng *srng = &ab->hal.srng_list[ring_id];
734611297eeSHarsh Kumar Bijlani 	struct hal_srng_params params;
735611297eeSHarsh Kumar Bijlani 	struct sk_buff *skb;
736611297eeSHarsh Kumar Bijlani 	u32 ring_entry_sz;
737611297eeSHarsh Kumar Bijlani 	int len = sizeof(*cmd);
738611297eeSHarsh Kumar Bijlani 	dma_addr_t hp_addr, tp_addr;
739611297eeSHarsh Kumar Bijlani 	enum htt_srng_ring_type htt_ring_type;
740611297eeSHarsh Kumar Bijlani 	enum htt_srng_ring_id htt_ring_id;
741611297eeSHarsh Kumar Bijlani 	int ret;
742611297eeSHarsh Kumar Bijlani 
743611297eeSHarsh Kumar Bijlani 	skb = ath12k_htc_alloc_skb(ab, len);
744611297eeSHarsh Kumar Bijlani 	if (!skb)
745611297eeSHarsh Kumar Bijlani 		return -ENOMEM;
746611297eeSHarsh Kumar Bijlani 
747611297eeSHarsh Kumar Bijlani 	memset(&params, 0, sizeof(params));
748611297eeSHarsh Kumar Bijlani 	ath12k_hal_srng_get_params(ab, srng, &params);
749611297eeSHarsh Kumar Bijlani 
750611297eeSHarsh Kumar Bijlani 	hp_addr = ath12k_hal_srng_get_hp_addr(ab, srng);
751611297eeSHarsh Kumar Bijlani 	tp_addr = ath12k_hal_srng_get_tp_addr(ab, srng);
752611297eeSHarsh Kumar Bijlani 
753611297eeSHarsh Kumar Bijlani 	ret = ath12k_dp_tx_get_ring_id_type(ab, mac_id, ring_id,
754611297eeSHarsh Kumar Bijlani 					    ring_type, &htt_ring_type,
755611297eeSHarsh Kumar Bijlani 					    &htt_ring_id);
756611297eeSHarsh Kumar Bijlani 	if (ret)
757611297eeSHarsh Kumar Bijlani 		goto err_free;
758611297eeSHarsh Kumar Bijlani 
759611297eeSHarsh Kumar Bijlani 	skb_put(skb, len);
760611297eeSHarsh Kumar Bijlani 	cmd = (struct htt_srng_setup_cmd *)skb->data;
761611297eeSHarsh Kumar Bijlani 	cmd->info0 = le32_encode_bits(HTT_H2T_MSG_TYPE_SRING_SETUP,
762611297eeSHarsh Kumar Bijlani 				      HTT_SRNG_SETUP_CMD_INFO0_MSG_TYPE);
763611297eeSHarsh Kumar Bijlani 	if (htt_ring_type == HTT_SW_TO_HW_RING ||
764611297eeSHarsh Kumar Bijlani 	    htt_ring_type == HTT_HW_TO_SW_RING)
765611297eeSHarsh Kumar Bijlani 		cmd->info0 |= le32_encode_bits(DP_SW2HW_MACID(mac_id),
766611297eeSHarsh Kumar Bijlani 					       HTT_SRNG_SETUP_CMD_INFO0_PDEV_ID);
767611297eeSHarsh Kumar Bijlani 	else
768611297eeSHarsh Kumar Bijlani 		cmd->info0 |= le32_encode_bits(mac_id,
769611297eeSHarsh Kumar Bijlani 					       HTT_SRNG_SETUP_CMD_INFO0_PDEV_ID);
770611297eeSHarsh Kumar Bijlani 	cmd->info0 |= le32_encode_bits(htt_ring_type,
771611297eeSHarsh Kumar Bijlani 				       HTT_SRNG_SETUP_CMD_INFO0_RING_TYPE);
772611297eeSHarsh Kumar Bijlani 	cmd->info0 |= le32_encode_bits(htt_ring_id,
773611297eeSHarsh Kumar Bijlani 				       HTT_SRNG_SETUP_CMD_INFO0_RING_ID);
774611297eeSHarsh Kumar Bijlani 
775611297eeSHarsh Kumar Bijlani 	cmd->ring_base_addr_lo = cpu_to_le32(params.ring_base_paddr &
776611297eeSHarsh Kumar Bijlani 					     HAL_ADDR_LSB_REG_MASK);
777611297eeSHarsh Kumar Bijlani 
778611297eeSHarsh Kumar Bijlani 	cmd->ring_base_addr_hi = cpu_to_le32((u64)params.ring_base_paddr >>
779611297eeSHarsh Kumar Bijlani 					     HAL_ADDR_MSB_REG_SHIFT);
780611297eeSHarsh Kumar Bijlani 
781611297eeSHarsh Kumar Bijlani 	ret = ath12k_hal_srng_get_entrysize(ab, ring_type);
782611297eeSHarsh Kumar Bijlani 	if (ret < 0)
783611297eeSHarsh Kumar Bijlani 		goto err_free;
784611297eeSHarsh Kumar Bijlani 
785611297eeSHarsh Kumar Bijlani 	ring_entry_sz = ret;
786611297eeSHarsh Kumar Bijlani 
787611297eeSHarsh Kumar Bijlani 	ring_entry_sz >>= 2;
788611297eeSHarsh Kumar Bijlani 	cmd->info1 = le32_encode_bits(ring_entry_sz,
789611297eeSHarsh Kumar Bijlani 				      HTT_SRNG_SETUP_CMD_INFO1_RING_ENTRY_SIZE);
790611297eeSHarsh Kumar Bijlani 	cmd->info1 |= le32_encode_bits(params.num_entries * ring_entry_sz,
791611297eeSHarsh Kumar Bijlani 				       HTT_SRNG_SETUP_CMD_INFO1_RING_SIZE);
792611297eeSHarsh Kumar Bijlani 	cmd->info1 |= le32_encode_bits(!!(params.flags & HAL_SRNG_FLAGS_MSI_SWAP),
793611297eeSHarsh Kumar Bijlani 				       HTT_SRNG_SETUP_CMD_INFO1_RING_FLAGS_MSI_SWAP);
794611297eeSHarsh Kumar Bijlani 	cmd->info1 |= le32_encode_bits(!!(params.flags & HAL_SRNG_FLAGS_DATA_TLV_SWAP),
795611297eeSHarsh Kumar Bijlani 				       HTT_SRNG_SETUP_CMD_INFO1_RING_FLAGS_TLV_SWAP);
796611297eeSHarsh Kumar Bijlani 	cmd->info1 |= le32_encode_bits(!!(params.flags & HAL_SRNG_FLAGS_RING_PTR_SWAP),
797611297eeSHarsh Kumar Bijlani 				       HTT_SRNG_SETUP_CMD_INFO1_RING_FLAGS_HOST_FW_SWAP);
798611297eeSHarsh Kumar Bijlani 	if (htt_ring_type == HTT_SW_TO_HW_RING)
799611297eeSHarsh Kumar Bijlani 		cmd->info1 |= cpu_to_le32(HTT_SRNG_SETUP_CMD_INFO1_RING_LOOP_CNT_DIS);
800611297eeSHarsh Kumar Bijlani 
801611297eeSHarsh Kumar Bijlani 	cmd->ring_head_off32_remote_addr_lo = cpu_to_le32(lower_32_bits(hp_addr));
802611297eeSHarsh Kumar Bijlani 	cmd->ring_head_off32_remote_addr_hi = cpu_to_le32(upper_32_bits(hp_addr));
803611297eeSHarsh Kumar Bijlani 
804611297eeSHarsh Kumar Bijlani 	cmd->ring_tail_off32_remote_addr_lo = cpu_to_le32(lower_32_bits(tp_addr));
805611297eeSHarsh Kumar Bijlani 	cmd->ring_tail_off32_remote_addr_hi = cpu_to_le32(upper_32_bits(tp_addr));
806611297eeSHarsh Kumar Bijlani 
807611297eeSHarsh Kumar Bijlani 	cmd->ring_msi_addr_lo = cpu_to_le32(lower_32_bits(params.msi_addr));
808611297eeSHarsh Kumar Bijlani 	cmd->ring_msi_addr_hi = cpu_to_le32(upper_32_bits(params.msi_addr));
809611297eeSHarsh Kumar Bijlani 	cmd->msi_data = cpu_to_le32(params.msi_data);
810611297eeSHarsh Kumar Bijlani 
811611297eeSHarsh Kumar Bijlani 	cmd->intr_info =
812611297eeSHarsh Kumar Bijlani 		le32_encode_bits(params.intr_batch_cntr_thres_entries * ring_entry_sz,
813611297eeSHarsh Kumar Bijlani 				 HTT_SRNG_SETUP_CMD_INTR_INFO_BATCH_COUNTER_THRESH);
814611297eeSHarsh Kumar Bijlani 	cmd->intr_info |=
815611297eeSHarsh Kumar Bijlani 		le32_encode_bits(params.intr_timer_thres_us >> 3,
816611297eeSHarsh Kumar Bijlani 				 HTT_SRNG_SETUP_CMD_INTR_INFO_INTR_TIMER_THRESH);
817611297eeSHarsh Kumar Bijlani 
818611297eeSHarsh Kumar Bijlani 	cmd->info2 = 0;
819611297eeSHarsh Kumar Bijlani 	if (params.flags & HAL_SRNG_FLAGS_LOW_THRESH_INTR_EN) {
820611297eeSHarsh Kumar Bijlani 		cmd->info2 = le32_encode_bits(params.low_threshold,
821611297eeSHarsh Kumar Bijlani 					      HTT_SRNG_SETUP_CMD_INFO2_INTR_LOW_THRESH);
822611297eeSHarsh Kumar Bijlani 	}
823611297eeSHarsh Kumar Bijlani 
824611297eeSHarsh Kumar Bijlani 	ath12k_dbg(ab, ATH12K_DBG_HAL,
825611297eeSHarsh Kumar Bijlani 		   "%s msi_addr_lo:0x%x, msi_addr_hi:0x%x, msi_data:0x%x\n",
826611297eeSHarsh Kumar Bijlani 		   __func__, cmd->ring_msi_addr_lo, cmd->ring_msi_addr_hi,
827611297eeSHarsh Kumar Bijlani 		   cmd->msi_data);
828611297eeSHarsh Kumar Bijlani 
829611297eeSHarsh Kumar Bijlani 	ath12k_dbg(ab, ATH12K_DBG_HAL,
830611297eeSHarsh Kumar Bijlani 		   "ring_id:%d, ring_type:%d, intr_info:0x%x, flags:0x%x\n",
831611297eeSHarsh Kumar Bijlani 		   ring_id, ring_type, cmd->intr_info, cmd->info2);
832611297eeSHarsh Kumar Bijlani 
8333a52762bSRipan Deuri 	ret = ath12k_htc_send(&ab->htc, dp->eid, skb);
834611297eeSHarsh Kumar Bijlani 	if (ret)
835611297eeSHarsh Kumar Bijlani 		goto err_free;
836611297eeSHarsh Kumar Bijlani 
837611297eeSHarsh Kumar Bijlani 	return 0;
838611297eeSHarsh Kumar Bijlani 
839611297eeSHarsh Kumar Bijlani err_free:
840611297eeSHarsh Kumar Bijlani 	dev_kfree_skb_any(skb);
841611297eeSHarsh Kumar Bijlani 
842611297eeSHarsh Kumar Bijlani 	return ret;
843611297eeSHarsh Kumar Bijlani }
844611297eeSHarsh Kumar Bijlani 
ath12k_dp_tx_htt_h2t_ver_req_msg(struct ath12k_base * ab)845611297eeSHarsh Kumar Bijlani int ath12k_dp_tx_htt_h2t_ver_req_msg(struct ath12k_base *ab)
846611297eeSHarsh Kumar Bijlani {
8473a52762bSRipan Deuri 	struct ath12k_dp *dp = ath12k_ab_to_dp(ab);
848611297eeSHarsh Kumar Bijlani 	struct sk_buff *skb;
849611297eeSHarsh Kumar Bijlani 	struct htt_ver_req_cmd *cmd;
850611297eeSHarsh Kumar Bijlani 	int len = sizeof(*cmd);
851611297eeSHarsh Kumar Bijlani 	u32 metadata_version;
852611297eeSHarsh Kumar Bijlani 	int ret;
853611297eeSHarsh Kumar Bijlani 
854611297eeSHarsh Kumar Bijlani 	init_completion(&dp->htt_tgt_version_received);
855611297eeSHarsh Kumar Bijlani 
856611297eeSHarsh Kumar Bijlani 	skb = ath12k_htc_alloc_skb(ab, len);
857611297eeSHarsh Kumar Bijlani 	if (!skb)
858611297eeSHarsh Kumar Bijlani 		return -ENOMEM;
859611297eeSHarsh Kumar Bijlani 
860611297eeSHarsh Kumar Bijlani 	skb_put(skb, len);
861611297eeSHarsh Kumar Bijlani 	cmd = (struct htt_ver_req_cmd *)skb->data;
862611297eeSHarsh Kumar Bijlani 	cmd->ver_reg_info = le32_encode_bits(HTT_H2T_MSG_TYPE_VERSION_REQ,
863611297eeSHarsh Kumar Bijlani 					     HTT_OPTION_TAG);
864611297eeSHarsh Kumar Bijlani 	metadata_version = ath12k_ftm_mode ? HTT_OPTION_TCL_METADATA_VER_V1 :
865611297eeSHarsh Kumar Bijlani 			   HTT_OPTION_TCL_METADATA_VER_V2;
866611297eeSHarsh Kumar Bijlani 
867611297eeSHarsh Kumar Bijlani 	cmd->tcl_metadata_version = le32_encode_bits(HTT_TAG_TCL_METADATA_VERSION,
868611297eeSHarsh Kumar Bijlani 						     HTT_OPTION_TAG) |
869611297eeSHarsh Kumar Bijlani 				    le32_encode_bits(HTT_TCL_METADATA_VER_SZ,
870611297eeSHarsh Kumar Bijlani 						     HTT_OPTION_LEN) |
871611297eeSHarsh Kumar Bijlani 				    le32_encode_bits(metadata_version,
872611297eeSHarsh Kumar Bijlani 						     HTT_OPTION_VALUE);
873611297eeSHarsh Kumar Bijlani 
874611297eeSHarsh Kumar Bijlani 	ret = ath12k_htc_send(&ab->htc, dp->eid, skb);
875611297eeSHarsh Kumar Bijlani 	if (ret) {
876611297eeSHarsh Kumar Bijlani 		dev_kfree_skb_any(skb);
877611297eeSHarsh Kumar Bijlani 		return ret;
878611297eeSHarsh Kumar Bijlani 	}
879611297eeSHarsh Kumar Bijlani 
880611297eeSHarsh Kumar Bijlani 	ret = wait_for_completion_timeout(&dp->htt_tgt_version_received,
881611297eeSHarsh Kumar Bijlani 					  HTT_TARGET_VERSION_TIMEOUT_HZ);
882611297eeSHarsh Kumar Bijlani 	if (ret == 0) {
883611297eeSHarsh Kumar Bijlani 		ath12k_warn(ab, "htt target version request timed out\n");
884611297eeSHarsh Kumar Bijlani 		return -ETIMEDOUT;
885611297eeSHarsh Kumar Bijlani 	}
886611297eeSHarsh Kumar Bijlani 
887611297eeSHarsh Kumar Bijlani 	if (dp->htt_tgt_ver_major != HTT_TARGET_VERSION_MAJOR) {
888611297eeSHarsh Kumar Bijlani 		ath12k_err(ab, "unsupported htt major version %d supported version is %d\n",
889611297eeSHarsh Kumar Bijlani 			   dp->htt_tgt_ver_major, HTT_TARGET_VERSION_MAJOR);
890611297eeSHarsh Kumar Bijlani 		return -EOPNOTSUPP;
891611297eeSHarsh Kumar Bijlani 	}
892611297eeSHarsh Kumar Bijlani 
893611297eeSHarsh Kumar Bijlani 	return 0;
894611297eeSHarsh Kumar Bijlani }
895611297eeSHarsh Kumar Bijlani 
ath12k_dp_tx_htt_h2t_ppdu_stats_req(struct ath12k * ar,u32 mask)896611297eeSHarsh Kumar Bijlani int ath12k_dp_tx_htt_h2t_ppdu_stats_req(struct ath12k *ar, u32 mask)
897611297eeSHarsh Kumar Bijlani {
898611297eeSHarsh Kumar Bijlani 	struct ath12k_base *ab = ar->ab;
8993a52762bSRipan Deuri 	struct ath12k_dp *dp = ath12k_ab_to_dp(ab);
900611297eeSHarsh Kumar Bijlani 	struct sk_buff *skb;
901611297eeSHarsh Kumar Bijlani 	struct htt_ppdu_stats_cfg_cmd *cmd;
902611297eeSHarsh Kumar Bijlani 	int len = sizeof(*cmd);
903611297eeSHarsh Kumar Bijlani 	u8 pdev_mask;
904611297eeSHarsh Kumar Bijlani 	int ret;
905611297eeSHarsh Kumar Bijlani 	int i;
906611297eeSHarsh Kumar Bijlani 
907611297eeSHarsh Kumar Bijlani 	for (i = 0; i < ab->hw_params->num_rxdma_per_pdev; i++) {
908611297eeSHarsh Kumar Bijlani 		skb = ath12k_htc_alloc_skb(ab, len);
909611297eeSHarsh Kumar Bijlani 		if (!skb)
910611297eeSHarsh Kumar Bijlani 			return -ENOMEM;
911611297eeSHarsh Kumar Bijlani 
912611297eeSHarsh Kumar Bijlani 		skb_put(skb, len);
913611297eeSHarsh Kumar Bijlani 		cmd = (struct htt_ppdu_stats_cfg_cmd *)skb->data;
914611297eeSHarsh Kumar Bijlani 		cmd->msg = le32_encode_bits(HTT_H2T_MSG_TYPE_PPDU_STATS_CFG,
915611297eeSHarsh Kumar Bijlani 					    HTT_PPDU_STATS_CFG_MSG_TYPE);
916611297eeSHarsh Kumar Bijlani 
917611297eeSHarsh Kumar Bijlani 		pdev_mask = 1 << (i + ar->pdev_idx);
918611297eeSHarsh Kumar Bijlani 		cmd->msg |= le32_encode_bits(pdev_mask, HTT_PPDU_STATS_CFG_PDEV_ID);
919611297eeSHarsh Kumar Bijlani 		cmd->msg |= le32_encode_bits(mask, HTT_PPDU_STATS_CFG_TLV_TYPE_BITMASK);
920611297eeSHarsh Kumar Bijlani 
921611297eeSHarsh Kumar Bijlani 		ret = ath12k_htc_send(&ab->htc, dp->eid, skb);
922611297eeSHarsh Kumar Bijlani 		if (ret) {
923611297eeSHarsh Kumar Bijlani 			dev_kfree_skb_any(skb);
924611297eeSHarsh Kumar Bijlani 			return ret;
925611297eeSHarsh Kumar Bijlani 		}
926611297eeSHarsh Kumar Bijlani 	}
927611297eeSHarsh Kumar Bijlani 
928611297eeSHarsh Kumar Bijlani 	return 0;
929611297eeSHarsh Kumar Bijlani }
930611297eeSHarsh Kumar Bijlani 
ath12k_dp_tx_htt_rx_filter_setup(struct ath12k_base * ab,u32 ring_id,int mac_id,enum hal_ring_type ring_type,int rx_buf_size,struct htt_rx_ring_tlv_filter * tlv_filter)931611297eeSHarsh Kumar Bijlani int ath12k_dp_tx_htt_rx_filter_setup(struct ath12k_base *ab, u32 ring_id,
932611297eeSHarsh Kumar Bijlani 				     int mac_id, enum hal_ring_type ring_type,
933611297eeSHarsh Kumar Bijlani 				     int rx_buf_size,
934611297eeSHarsh Kumar Bijlani 				     struct htt_rx_ring_tlv_filter *tlv_filter)
935611297eeSHarsh Kumar Bijlani {
9363a52762bSRipan Deuri 	struct ath12k_dp *dp = ath12k_ab_to_dp(ab);
937611297eeSHarsh Kumar Bijlani 	struct htt_rx_ring_selection_cfg_cmd *cmd;
938611297eeSHarsh Kumar Bijlani 	struct hal_srng *srng = &ab->hal.srng_list[ring_id];
939611297eeSHarsh Kumar Bijlani 	struct hal_srng_params params;
940611297eeSHarsh Kumar Bijlani 	struct sk_buff *skb;
941611297eeSHarsh Kumar Bijlani 	int len = sizeof(*cmd);
942611297eeSHarsh Kumar Bijlani 	enum htt_srng_ring_type htt_ring_type;
943611297eeSHarsh Kumar Bijlani 	enum htt_srng_ring_id htt_ring_id;
944611297eeSHarsh Kumar Bijlani 	int ret;
945611297eeSHarsh Kumar Bijlani 
946611297eeSHarsh Kumar Bijlani 	skb = ath12k_htc_alloc_skb(ab, len);
947611297eeSHarsh Kumar Bijlani 	if (!skb)
948611297eeSHarsh Kumar Bijlani 		return -ENOMEM;
949611297eeSHarsh Kumar Bijlani 
950611297eeSHarsh Kumar Bijlani 	memset(&params, 0, sizeof(params));
951611297eeSHarsh Kumar Bijlani 	ath12k_hal_srng_get_params(ab, srng, &params);
952611297eeSHarsh Kumar Bijlani 
953611297eeSHarsh Kumar Bijlani 	ret = ath12k_dp_tx_get_ring_id_type(ab, mac_id, ring_id,
954611297eeSHarsh Kumar Bijlani 					    ring_type, &htt_ring_type,
955611297eeSHarsh Kumar Bijlani 					    &htt_ring_id);
956611297eeSHarsh Kumar Bijlani 	if (ret)
957611297eeSHarsh Kumar Bijlani 		goto err_free;
958611297eeSHarsh Kumar Bijlani 
959611297eeSHarsh Kumar Bijlani 	skb_put(skb, len);
960611297eeSHarsh Kumar Bijlani 	cmd = (struct htt_rx_ring_selection_cfg_cmd *)skb->data;
961611297eeSHarsh Kumar Bijlani 	cmd->info0 = le32_encode_bits(HTT_H2T_MSG_TYPE_RX_RING_SELECTION_CFG,
962611297eeSHarsh Kumar Bijlani 				      HTT_RX_RING_SELECTION_CFG_CMD_INFO0_MSG_TYPE);
963611297eeSHarsh Kumar Bijlani 	if (htt_ring_type == HTT_SW_TO_HW_RING ||
964611297eeSHarsh Kumar Bijlani 	    htt_ring_type == HTT_HW_TO_SW_RING)
965611297eeSHarsh Kumar Bijlani 		cmd->info0 |=
966611297eeSHarsh Kumar Bijlani 			le32_encode_bits(DP_SW2HW_MACID(mac_id),
967611297eeSHarsh Kumar Bijlani 					 HTT_RX_RING_SELECTION_CFG_CMD_INFO0_PDEV_ID);
968611297eeSHarsh Kumar Bijlani 	else
969611297eeSHarsh Kumar Bijlani 		cmd->info0 |=
970611297eeSHarsh Kumar Bijlani 			le32_encode_bits(mac_id,
971611297eeSHarsh Kumar Bijlani 					 HTT_RX_RING_SELECTION_CFG_CMD_INFO0_PDEV_ID);
972611297eeSHarsh Kumar Bijlani 	cmd->info0 |= le32_encode_bits(htt_ring_id,
973611297eeSHarsh Kumar Bijlani 				       HTT_RX_RING_SELECTION_CFG_CMD_INFO0_RING_ID);
974611297eeSHarsh Kumar Bijlani 	cmd->info0 |= le32_encode_bits(!!(params.flags & HAL_SRNG_FLAGS_MSI_SWAP),
975611297eeSHarsh Kumar Bijlani 				       HTT_RX_RING_SELECTION_CFG_CMD_INFO0_SS);
976611297eeSHarsh Kumar Bijlani 	cmd->info0 |= le32_encode_bits(!!(params.flags & HAL_SRNG_FLAGS_DATA_TLV_SWAP),
977611297eeSHarsh Kumar Bijlani 				       HTT_RX_RING_SELECTION_CFG_CMD_INFO0_PS);
978611297eeSHarsh Kumar Bijlani 	cmd->info0 |= le32_encode_bits(tlv_filter->offset_valid,
979611297eeSHarsh Kumar Bijlani 				       HTT_RX_RING_SELECTION_CFG_CMD_INFO0_OFFSET_VALID);
980611297eeSHarsh Kumar Bijlani 	cmd->info0 |=
981611297eeSHarsh Kumar Bijlani 		le32_encode_bits(tlv_filter->drop_threshold_valid,
982611297eeSHarsh Kumar Bijlani 				 HTT_RX_RING_SELECTION_CFG_CMD_INFO0_DROP_THRES_VAL);
983611297eeSHarsh Kumar Bijlani 	cmd->info0 |= le32_encode_bits(!tlv_filter->rxmon_disable,
984611297eeSHarsh Kumar Bijlani 				       HTT_RX_RING_SELECTION_CFG_CMD_INFO0_EN_RXMON);
985611297eeSHarsh Kumar Bijlani 
986611297eeSHarsh Kumar Bijlani 	cmd->info1 = le32_encode_bits(rx_buf_size,
987611297eeSHarsh Kumar Bijlani 				      HTT_RX_RING_SELECTION_CFG_CMD_INFO1_BUF_SIZE);
988611297eeSHarsh Kumar Bijlani 	cmd->info1 |= le32_encode_bits(tlv_filter->conf_len_mgmt,
989611297eeSHarsh Kumar Bijlani 				       HTT_RX_RING_SELECTION_CFG_CMD_INFO1_CONF_LEN_MGMT);
990611297eeSHarsh Kumar Bijlani 	cmd->info1 |= le32_encode_bits(tlv_filter->conf_len_ctrl,
991611297eeSHarsh Kumar Bijlani 				       HTT_RX_RING_SELECTION_CFG_CMD_INFO1_CONF_LEN_CTRL);
992611297eeSHarsh Kumar Bijlani 	cmd->info1 |= le32_encode_bits(tlv_filter->conf_len_data,
993611297eeSHarsh Kumar Bijlani 				       HTT_RX_RING_SELECTION_CFG_CMD_INFO1_CONF_LEN_DATA);
994611297eeSHarsh Kumar Bijlani 	cmd->pkt_type_en_flags0 = cpu_to_le32(tlv_filter->pkt_filter_flags0);
995611297eeSHarsh Kumar Bijlani 	cmd->pkt_type_en_flags1 = cpu_to_le32(tlv_filter->pkt_filter_flags1);
996611297eeSHarsh Kumar Bijlani 	cmd->pkt_type_en_flags2 = cpu_to_le32(tlv_filter->pkt_filter_flags2);
997611297eeSHarsh Kumar Bijlani 	cmd->pkt_type_en_flags3 = cpu_to_le32(tlv_filter->pkt_filter_flags3);
998611297eeSHarsh Kumar Bijlani 	cmd->rx_filter_tlv = cpu_to_le32(tlv_filter->rx_filter);
999611297eeSHarsh Kumar Bijlani 
1000611297eeSHarsh Kumar Bijlani 	cmd->info2 = le32_encode_bits(tlv_filter->rx_drop_threshold,
1001611297eeSHarsh Kumar Bijlani 				      HTT_RX_RING_SELECTION_CFG_CMD_INFO2_DROP_THRESHOLD);
1002611297eeSHarsh Kumar Bijlani 	cmd->info2 |=
1003611297eeSHarsh Kumar Bijlani 		le32_encode_bits(tlv_filter->enable_log_mgmt_type,
1004611297eeSHarsh Kumar Bijlani 				 HTT_RX_RING_SELECTION_CFG_CMD_INFO2_EN_LOG_MGMT_TYPE);
1005611297eeSHarsh Kumar Bijlani 	cmd->info2 |=
1006611297eeSHarsh Kumar Bijlani 		le32_encode_bits(tlv_filter->enable_log_ctrl_type,
1007611297eeSHarsh Kumar Bijlani 				 HTT_RX_RING_SELECTION_CFG_CMD_INFO2_EN_CTRL_TYPE);
1008611297eeSHarsh Kumar Bijlani 	cmd->info2 |=
1009611297eeSHarsh Kumar Bijlani 		le32_encode_bits(tlv_filter->enable_log_data_type,
1010611297eeSHarsh Kumar Bijlani 				 HTT_RX_RING_SELECTION_CFG_CMD_INFO2_EN_LOG_DATA_TYPE);
1011611297eeSHarsh Kumar Bijlani 
1012611297eeSHarsh Kumar Bijlani 	cmd->info3 =
1013611297eeSHarsh Kumar Bijlani 		le32_encode_bits(tlv_filter->enable_rx_tlv_offset,
1014611297eeSHarsh Kumar Bijlani 				 HTT_RX_RING_SELECTION_CFG_CMD_INFO3_EN_TLV_PKT_OFFSET);
1015611297eeSHarsh Kumar Bijlani 	cmd->info3 |=
1016611297eeSHarsh Kumar Bijlani 		le32_encode_bits(tlv_filter->rx_tlv_offset,
1017611297eeSHarsh Kumar Bijlani 				 HTT_RX_RING_SELECTION_CFG_CMD_INFO3_PKT_TLV_OFFSET);
1018611297eeSHarsh Kumar Bijlani 
1019611297eeSHarsh Kumar Bijlani 	if (tlv_filter->offset_valid) {
1020611297eeSHarsh Kumar Bijlani 		cmd->rx_packet_offset =
1021611297eeSHarsh Kumar Bijlani 			le32_encode_bits(tlv_filter->rx_packet_offset,
1022611297eeSHarsh Kumar Bijlani 					 HTT_RX_RING_SELECTION_CFG_RX_PACKET_OFFSET);
1023611297eeSHarsh Kumar Bijlani 
1024611297eeSHarsh Kumar Bijlani 		cmd->rx_packet_offset |=
1025611297eeSHarsh Kumar Bijlani 			le32_encode_bits(tlv_filter->rx_header_offset,
1026611297eeSHarsh Kumar Bijlani 					 HTT_RX_RING_SELECTION_CFG_RX_HEADER_OFFSET);
1027611297eeSHarsh Kumar Bijlani 
1028611297eeSHarsh Kumar Bijlani 		cmd->rx_mpdu_offset =
1029611297eeSHarsh Kumar Bijlani 			le32_encode_bits(tlv_filter->rx_mpdu_end_offset,
1030611297eeSHarsh Kumar Bijlani 					 HTT_RX_RING_SELECTION_CFG_RX_MPDU_END_OFFSET);
1031611297eeSHarsh Kumar Bijlani 
1032611297eeSHarsh Kumar Bijlani 		cmd->rx_mpdu_offset |=
1033611297eeSHarsh Kumar Bijlani 			le32_encode_bits(tlv_filter->rx_mpdu_start_offset,
1034611297eeSHarsh Kumar Bijlani 					 HTT_RX_RING_SELECTION_CFG_RX_MPDU_START_OFFSET);
1035611297eeSHarsh Kumar Bijlani 
1036611297eeSHarsh Kumar Bijlani 		cmd->rx_msdu_offset =
1037611297eeSHarsh Kumar Bijlani 			le32_encode_bits(tlv_filter->rx_msdu_end_offset,
1038611297eeSHarsh Kumar Bijlani 					 HTT_RX_RING_SELECTION_CFG_RX_MSDU_END_OFFSET);
1039611297eeSHarsh Kumar Bijlani 
1040611297eeSHarsh Kumar Bijlani 		cmd->rx_msdu_offset |=
1041611297eeSHarsh Kumar Bijlani 			le32_encode_bits(tlv_filter->rx_msdu_start_offset,
1042611297eeSHarsh Kumar Bijlani 					 HTT_RX_RING_SELECTION_CFG_RX_MSDU_START_OFFSET);
1043611297eeSHarsh Kumar Bijlani 
1044611297eeSHarsh Kumar Bijlani 		cmd->rx_attn_offset =
1045611297eeSHarsh Kumar Bijlani 			le32_encode_bits(tlv_filter->rx_attn_offset,
1046611297eeSHarsh Kumar Bijlani 					 HTT_RX_RING_SELECTION_CFG_RX_ATTENTION_OFFSET);
1047611297eeSHarsh Kumar Bijlani 	}
1048611297eeSHarsh Kumar Bijlani 
1049611297eeSHarsh Kumar Bijlani 	if (tlv_filter->rx_mpdu_start_wmask > 0 &&
1050611297eeSHarsh Kumar Bijlani 	    tlv_filter->rx_msdu_end_wmask > 0) {
1051611297eeSHarsh Kumar Bijlani 		cmd->info2 |=
1052611297eeSHarsh Kumar Bijlani 			le32_encode_bits(true,
1053611297eeSHarsh Kumar Bijlani 					 HTT_RX_RING_SELECTION_CFG_WORD_MASK_COMPACT_SET);
1054611297eeSHarsh Kumar Bijlani 		cmd->rx_mpdu_start_end_mask =
1055611297eeSHarsh Kumar Bijlani 			le32_encode_bits(tlv_filter->rx_mpdu_start_wmask,
1056611297eeSHarsh Kumar Bijlani 					 HTT_RX_RING_SELECTION_CFG_RX_MPDU_START_MASK);
1057611297eeSHarsh Kumar Bijlani 		/* mpdu_end is not used for any hardwares so far
1058611297eeSHarsh Kumar Bijlani 		 * please assign it in future if any chip is
1059611297eeSHarsh Kumar Bijlani 		 * using through hal ops
1060611297eeSHarsh Kumar Bijlani 		 */
1061611297eeSHarsh Kumar Bijlani 		cmd->rx_mpdu_start_end_mask |=
1062611297eeSHarsh Kumar Bijlani 			le32_encode_bits(tlv_filter->rx_mpdu_end_wmask,
1063611297eeSHarsh Kumar Bijlani 					 HTT_RX_RING_SELECTION_CFG_RX_MPDU_END_MASK);
1064611297eeSHarsh Kumar Bijlani 		cmd->rx_msdu_end_word_mask =
1065611297eeSHarsh Kumar Bijlani 			le32_encode_bits(tlv_filter->rx_msdu_end_wmask,
1066611297eeSHarsh Kumar Bijlani 					 HTT_RX_RING_SELECTION_CFG_RX_MSDU_END_MASK);
1067611297eeSHarsh Kumar Bijlani 	}
1068611297eeSHarsh Kumar Bijlani 
10693a52762bSRipan Deuri 	ret = ath12k_htc_send(&ab->htc, dp->eid, skb);
1070611297eeSHarsh Kumar Bijlani 	if (ret)
1071611297eeSHarsh Kumar Bijlani 		goto err_free;
1072611297eeSHarsh Kumar Bijlani 
1073611297eeSHarsh Kumar Bijlani 	return 0;
1074611297eeSHarsh Kumar Bijlani 
1075611297eeSHarsh Kumar Bijlani err_free:
1076611297eeSHarsh Kumar Bijlani 	dev_kfree_skb_any(skb);
1077611297eeSHarsh Kumar Bijlani 
1078611297eeSHarsh Kumar Bijlani 	return ret;
1079611297eeSHarsh Kumar Bijlani }
1080219dd149SPavankumar Nandeshwar EXPORT_SYMBOL(ath12k_dp_tx_htt_rx_filter_setup);
1081611297eeSHarsh Kumar Bijlani 
1082611297eeSHarsh Kumar Bijlani int
ath12k_dp_tx_htt_h2t_ext_stats_req(struct ath12k * ar,u8 type,struct htt_ext_stats_cfg_params * cfg_params,u64 cookie)1083611297eeSHarsh Kumar Bijlani ath12k_dp_tx_htt_h2t_ext_stats_req(struct ath12k *ar, u8 type,
1084611297eeSHarsh Kumar Bijlani 				   struct htt_ext_stats_cfg_params *cfg_params,
1085611297eeSHarsh Kumar Bijlani 				   u64 cookie)
1086611297eeSHarsh Kumar Bijlani {
1087611297eeSHarsh Kumar Bijlani 	struct ath12k_base *ab = ar->ab;
10883a52762bSRipan Deuri 	struct ath12k_dp *dp = ath12k_ab_to_dp(ab);
1089611297eeSHarsh Kumar Bijlani 	struct sk_buff *skb;
1090611297eeSHarsh Kumar Bijlani 	struct htt_ext_stats_cfg_cmd *cmd;
1091611297eeSHarsh Kumar Bijlani 	int len = sizeof(*cmd);
1092611297eeSHarsh Kumar Bijlani 	int ret;
1093611297eeSHarsh Kumar Bijlani 	u32 pdev_id;
1094611297eeSHarsh Kumar Bijlani 
1095611297eeSHarsh Kumar Bijlani 	skb = ath12k_htc_alloc_skb(ab, len);
1096611297eeSHarsh Kumar Bijlani 	if (!skb)
1097611297eeSHarsh Kumar Bijlani 		return -ENOMEM;
1098611297eeSHarsh Kumar Bijlani 
1099611297eeSHarsh Kumar Bijlani 	skb_put(skb, len);
1100611297eeSHarsh Kumar Bijlani 
1101611297eeSHarsh Kumar Bijlani 	cmd = (struct htt_ext_stats_cfg_cmd *)skb->data;
1102611297eeSHarsh Kumar Bijlani 	memset(cmd, 0, sizeof(*cmd));
1103611297eeSHarsh Kumar Bijlani 	cmd->hdr.msg_type = HTT_H2T_MSG_TYPE_EXT_STATS_CFG;
1104611297eeSHarsh Kumar Bijlani 
1105611297eeSHarsh Kumar Bijlani 	pdev_id = ath12k_mac_get_target_pdev_id(ar);
1106611297eeSHarsh Kumar Bijlani 	cmd->hdr.pdev_mask = 1 << pdev_id;
1107611297eeSHarsh Kumar Bijlani 
1108611297eeSHarsh Kumar Bijlani 	cmd->hdr.stats_type = type;
1109611297eeSHarsh Kumar Bijlani 	cmd->cfg_param0 = cpu_to_le32(cfg_params->cfg0);
1110611297eeSHarsh Kumar Bijlani 	cmd->cfg_param1 = cpu_to_le32(cfg_params->cfg1);
1111611297eeSHarsh Kumar Bijlani 	cmd->cfg_param2 = cpu_to_le32(cfg_params->cfg2);
1112611297eeSHarsh Kumar Bijlani 	cmd->cfg_param3 = cpu_to_le32(cfg_params->cfg3);
1113611297eeSHarsh Kumar Bijlani 	cmd->cookie_lsb = cpu_to_le32(lower_32_bits(cookie));
1114611297eeSHarsh Kumar Bijlani 	cmd->cookie_msb = cpu_to_le32(upper_32_bits(cookie));
1115611297eeSHarsh Kumar Bijlani 
1116611297eeSHarsh Kumar Bijlani 	ret = ath12k_htc_send(&ab->htc, dp->eid, skb);
1117611297eeSHarsh Kumar Bijlani 	if (ret) {
1118611297eeSHarsh Kumar Bijlani 		ath12k_warn(ab, "failed to send htt type stats request: %d",
1119611297eeSHarsh Kumar Bijlani 			    ret);
1120611297eeSHarsh Kumar Bijlani 		dev_kfree_skb_any(skb);
1121611297eeSHarsh Kumar Bijlani 		return ret;
1122611297eeSHarsh Kumar Bijlani 	}
1123611297eeSHarsh Kumar Bijlani 
1124611297eeSHarsh Kumar Bijlani 	return 0;
1125611297eeSHarsh Kumar Bijlani }
1126611297eeSHarsh Kumar Bijlani 
ath12k_dp_tx_htt_monitor_mode_ring_config(struct ath12k * ar,bool reset)1127611297eeSHarsh Kumar Bijlani int ath12k_dp_tx_htt_monitor_mode_ring_config(struct ath12k *ar, bool reset)
1128611297eeSHarsh Kumar Bijlani {
1129611297eeSHarsh Kumar Bijlani 	struct ath12k_base *ab = ar->ab;
1130611297eeSHarsh Kumar Bijlani 	int ret;
1131611297eeSHarsh Kumar Bijlani 
1132611297eeSHarsh Kumar Bijlani 	ret = ath12k_dp_tx_htt_rx_monitor_mode_ring_config(ar, reset);
1133611297eeSHarsh Kumar Bijlani 	if (ret) {
1134611297eeSHarsh Kumar Bijlani 		ath12k_err(ab, "failed to setup rx monitor filter %d\n", ret);
1135611297eeSHarsh Kumar Bijlani 		return ret;
1136611297eeSHarsh Kumar Bijlani 	}
1137611297eeSHarsh Kumar Bijlani 
1138611297eeSHarsh Kumar Bijlani 	return 0;
1139611297eeSHarsh Kumar Bijlani }
1140611297eeSHarsh Kumar Bijlani 
ath12k_dp_tx_htt_rx_monitor_mode_ring_config(struct ath12k * ar,bool reset)1141611297eeSHarsh Kumar Bijlani int ath12k_dp_tx_htt_rx_monitor_mode_ring_config(struct ath12k *ar, bool reset)
1142611297eeSHarsh Kumar Bijlani {
1143611297eeSHarsh Kumar Bijlani 	struct ath12k_base *ab = ar->ab;
11443a52762bSRipan Deuri 	struct ath12k_dp *dp = ath12k_ab_to_dp(ab);
1145611297eeSHarsh Kumar Bijlani 	struct htt_rx_ring_tlv_filter tlv_filter = {};
1146611297eeSHarsh Kumar Bijlani 	int ret, ring_id, i;
1147611297eeSHarsh Kumar Bijlani 
1148611297eeSHarsh Kumar Bijlani 	tlv_filter.offset_valid = false;
1149611297eeSHarsh Kumar Bijlani 
1150611297eeSHarsh Kumar Bijlani 	if (!reset) {
1151611297eeSHarsh Kumar Bijlani 		tlv_filter.rx_filter = HTT_RX_MON_FILTER_TLV_FLAGS_MON_DEST_RING;
1152611297eeSHarsh Kumar Bijlani 
1153611297eeSHarsh Kumar Bijlani 		tlv_filter.drop_threshold_valid = true;
1154611297eeSHarsh Kumar Bijlani 		tlv_filter.rx_drop_threshold = HTT_RX_RING_TLV_DROP_THRESHOLD_VALUE;
1155611297eeSHarsh Kumar Bijlani 
1156611297eeSHarsh Kumar Bijlani 		tlv_filter.enable_log_mgmt_type = true;
1157611297eeSHarsh Kumar Bijlani 		tlv_filter.enable_log_ctrl_type = true;
1158611297eeSHarsh Kumar Bijlani 		tlv_filter.enable_log_data_type = true;
1159611297eeSHarsh Kumar Bijlani 
1160611297eeSHarsh Kumar Bijlani 		tlv_filter.conf_len_ctrl = HTT_RX_RING_DEFAULT_DMA_LENGTH;
1161611297eeSHarsh Kumar Bijlani 		tlv_filter.conf_len_mgmt = HTT_RX_RING_DEFAULT_DMA_LENGTH;
1162611297eeSHarsh Kumar Bijlani 		tlv_filter.conf_len_data = HTT_RX_RING_DEFAULT_DMA_LENGTH;
1163611297eeSHarsh Kumar Bijlani 
1164611297eeSHarsh Kumar Bijlani 		tlv_filter.enable_rx_tlv_offset = true;
1165611297eeSHarsh Kumar Bijlani 		tlv_filter.rx_tlv_offset = HTT_RX_RING_PKT_TLV_OFFSET;
1166611297eeSHarsh Kumar Bijlani 
1167611297eeSHarsh Kumar Bijlani 		tlv_filter.pkt_filter_flags0 =
1168611297eeSHarsh Kumar Bijlani 					HTT_RX_MON_FP_MGMT_FILTER_FLAGS0 |
1169611297eeSHarsh Kumar Bijlani 					HTT_RX_MON_MO_MGMT_FILTER_FLAGS0;
1170611297eeSHarsh Kumar Bijlani 		tlv_filter.pkt_filter_flags1 =
1171611297eeSHarsh Kumar Bijlani 					HTT_RX_MON_FP_MGMT_FILTER_FLAGS1 |
1172611297eeSHarsh Kumar Bijlani 					HTT_RX_MON_MO_MGMT_FILTER_FLAGS1;
1173611297eeSHarsh Kumar Bijlani 		tlv_filter.pkt_filter_flags2 =
1174611297eeSHarsh Kumar Bijlani 					HTT_RX_MON_FP_CTRL_FILTER_FLASG2 |
1175611297eeSHarsh Kumar Bijlani 					HTT_RX_MON_MO_CTRL_FILTER_FLASG2;
1176611297eeSHarsh Kumar Bijlani 		tlv_filter.pkt_filter_flags3 =
1177611297eeSHarsh Kumar Bijlani 					HTT_RX_MON_FP_CTRL_FILTER_FLASG3 |
1178611297eeSHarsh Kumar Bijlani 					HTT_RX_MON_MO_CTRL_FILTER_FLASG3 |
1179611297eeSHarsh Kumar Bijlani 					HTT_RX_MON_FP_DATA_FILTER_FLASG3 |
1180611297eeSHarsh Kumar Bijlani 					HTT_RX_MON_MO_DATA_FILTER_FLASG3;
1181611297eeSHarsh Kumar Bijlani 	} else {
1182611297eeSHarsh Kumar Bijlani 		tlv_filter = ath12k_mac_mon_status_filter_default;
1183611297eeSHarsh Kumar Bijlani 
1184611297eeSHarsh Kumar Bijlani 		if (ath12k_debugfs_is_extd_rx_stats_enabled(ar))
1185611297eeSHarsh Kumar Bijlani 			tlv_filter.rx_filter = ath12k_debugfs_rx_filter(ar);
1186611297eeSHarsh Kumar Bijlani 	}
1187611297eeSHarsh Kumar Bijlani 
1188611297eeSHarsh Kumar Bijlani 	if (ab->hw_params->rxdma1_enable) {
1189611297eeSHarsh Kumar Bijlani 		for (i = 0; i < ab->hw_params->num_rxdma_per_pdev; i++) {
1190611297eeSHarsh Kumar Bijlani 			ring_id = ar->dp.rxdma_mon_dst_ring[i].ring_id;
1191611297eeSHarsh Kumar Bijlani 			ret = ath12k_dp_tx_htt_rx_filter_setup(ar->ab, ring_id,
1192611297eeSHarsh Kumar Bijlani 							       ar->dp.mac_id + i,
1193611297eeSHarsh Kumar Bijlani 							       HAL_RXDMA_MONITOR_DST,
1194611297eeSHarsh Kumar Bijlani 							       DP_RXDMA_REFILL_RING_SIZE,
1195611297eeSHarsh Kumar Bijlani 							       &tlv_filter);
1196611297eeSHarsh Kumar Bijlani 			if (ret) {
1197611297eeSHarsh Kumar Bijlani 				ath12k_err(ab,
1198611297eeSHarsh Kumar Bijlani 					   "failed to setup filter for monitor buf %d\n",
1199611297eeSHarsh Kumar Bijlani 					   ret);
1200611297eeSHarsh Kumar Bijlani 				return ret;
1201611297eeSHarsh Kumar Bijlani 			}
1202611297eeSHarsh Kumar Bijlani 		}
1203611297eeSHarsh Kumar Bijlani 		return 0;
1204611297eeSHarsh Kumar Bijlani 	}
1205611297eeSHarsh Kumar Bijlani 
1206611297eeSHarsh Kumar Bijlani 	if (!reset) {
1207611297eeSHarsh Kumar Bijlani 		for (i = 0; i < ab->hw_params->num_rxdma_per_pdev; i++) {
12083a52762bSRipan Deuri 			ring_id = dp->rx_mac_buf_ring[i].ring_id;
1209611297eeSHarsh Kumar Bijlani 			ret = ath12k_dp_tx_htt_rx_filter_setup(ar->ab, ring_id,
1210611297eeSHarsh Kumar Bijlani 							       i,
1211611297eeSHarsh Kumar Bijlani 							       HAL_RXDMA_BUF,
1212611297eeSHarsh Kumar Bijlani 							       DP_RXDMA_REFILL_RING_SIZE,
1213611297eeSHarsh Kumar Bijlani 							       &tlv_filter);
1214611297eeSHarsh Kumar Bijlani 			if (ret) {
1215611297eeSHarsh Kumar Bijlani 				ath12k_err(ab,
1216611297eeSHarsh Kumar Bijlani 					   "failed to setup filter for mon rx buf %d\n",
1217611297eeSHarsh Kumar Bijlani 					   ret);
1218611297eeSHarsh Kumar Bijlani 				return ret;
1219611297eeSHarsh Kumar Bijlani 			}
1220611297eeSHarsh Kumar Bijlani 		}
1221611297eeSHarsh Kumar Bijlani 	}
1222611297eeSHarsh Kumar Bijlani 
1223611297eeSHarsh Kumar Bijlani 	for (i = 0; i < ab->hw_params->num_rxdma_per_pdev; i++) {
12243a52762bSRipan Deuri 		ring_id = dp->rx_mon_status_refill_ring[i].refill_buf_ring.ring_id;
1225611297eeSHarsh Kumar Bijlani 		if (!reset) {
1226611297eeSHarsh Kumar Bijlani 			tlv_filter.rx_filter =
1227611297eeSHarsh Kumar Bijlani 				HTT_RX_MON_FILTER_TLV_FLAGS_MON_STATUS_RING;
1228611297eeSHarsh Kumar Bijlani 		}
1229611297eeSHarsh Kumar Bijlani 
1230611297eeSHarsh Kumar Bijlani 		ret = ath12k_dp_tx_htt_rx_filter_setup(ab, ring_id,
1231611297eeSHarsh Kumar Bijlani 						       i,
1232611297eeSHarsh Kumar Bijlani 						       HAL_RXDMA_MONITOR_STATUS,
1233611297eeSHarsh Kumar Bijlani 						       RX_MON_STATUS_BUF_SIZE,
1234611297eeSHarsh Kumar Bijlani 						       &tlv_filter);
1235611297eeSHarsh Kumar Bijlani 		if (ret) {
1236611297eeSHarsh Kumar Bijlani 			ath12k_err(ab,
1237611297eeSHarsh Kumar Bijlani 				   "failed to setup filter for mon status buf %d\n",
1238611297eeSHarsh Kumar Bijlani 				   ret);
1239611297eeSHarsh Kumar Bijlani 			return ret;
1240611297eeSHarsh Kumar Bijlani 		}
1241611297eeSHarsh Kumar Bijlani 	}
1242611297eeSHarsh Kumar Bijlani 
1243611297eeSHarsh Kumar Bijlani 	return 0;
1244611297eeSHarsh Kumar Bijlani }
1245611297eeSHarsh Kumar Bijlani 
ath12k_dp_tx_htt_tx_filter_setup(struct ath12k_base * ab,u32 ring_id,int mac_id,enum hal_ring_type ring_type,int tx_buf_size,struct htt_tx_ring_tlv_filter * htt_tlv_filter)1246611297eeSHarsh Kumar Bijlani int ath12k_dp_tx_htt_tx_filter_setup(struct ath12k_base *ab, u32 ring_id,
1247611297eeSHarsh Kumar Bijlani 				     int mac_id, enum hal_ring_type ring_type,
1248611297eeSHarsh Kumar Bijlani 				     int tx_buf_size,
1249611297eeSHarsh Kumar Bijlani 				     struct htt_tx_ring_tlv_filter *htt_tlv_filter)
1250611297eeSHarsh Kumar Bijlani {
12513a52762bSRipan Deuri 	struct ath12k_dp *dp = ath12k_ab_to_dp(ab);
1252611297eeSHarsh Kumar Bijlani 	struct htt_tx_ring_selection_cfg_cmd *cmd;
1253611297eeSHarsh Kumar Bijlani 	struct hal_srng *srng = &ab->hal.srng_list[ring_id];
1254611297eeSHarsh Kumar Bijlani 	struct hal_srng_params params;
1255611297eeSHarsh Kumar Bijlani 	struct sk_buff *skb;
1256611297eeSHarsh Kumar Bijlani 	int len = sizeof(*cmd);
1257611297eeSHarsh Kumar Bijlani 	enum htt_srng_ring_type htt_ring_type;
1258611297eeSHarsh Kumar Bijlani 	enum htt_srng_ring_id htt_ring_id;
1259611297eeSHarsh Kumar Bijlani 	int ret;
1260611297eeSHarsh Kumar Bijlani 
1261611297eeSHarsh Kumar Bijlani 	skb = ath12k_htc_alloc_skb(ab, len);
1262611297eeSHarsh Kumar Bijlani 	if (!skb)
1263611297eeSHarsh Kumar Bijlani 		return -ENOMEM;
1264611297eeSHarsh Kumar Bijlani 
1265611297eeSHarsh Kumar Bijlani 	memset(&params, 0, sizeof(params));
1266611297eeSHarsh Kumar Bijlani 	ath12k_hal_srng_get_params(ab, srng, &params);
1267611297eeSHarsh Kumar Bijlani 
1268611297eeSHarsh Kumar Bijlani 	ret = ath12k_dp_tx_get_ring_id_type(ab, mac_id, ring_id,
1269611297eeSHarsh Kumar Bijlani 					    ring_type, &htt_ring_type,
1270611297eeSHarsh Kumar Bijlani 					    &htt_ring_id);
1271611297eeSHarsh Kumar Bijlani 
1272611297eeSHarsh Kumar Bijlani 	if (ret)
1273611297eeSHarsh Kumar Bijlani 		goto err_free;
1274611297eeSHarsh Kumar Bijlani 
1275611297eeSHarsh Kumar Bijlani 	skb_put(skb, len);
1276611297eeSHarsh Kumar Bijlani 	cmd = (struct htt_tx_ring_selection_cfg_cmd *)skb->data;
1277611297eeSHarsh Kumar Bijlani 	cmd->info0 = le32_encode_bits(HTT_H2T_MSG_TYPE_TX_MONITOR_CFG,
1278611297eeSHarsh Kumar Bijlani 				      HTT_TX_RING_SELECTION_CFG_CMD_INFO0_MSG_TYPE);
1279611297eeSHarsh Kumar Bijlani 	if (htt_ring_type == HTT_SW_TO_HW_RING ||
1280611297eeSHarsh Kumar Bijlani 	    htt_ring_type == HTT_HW_TO_SW_RING)
1281611297eeSHarsh Kumar Bijlani 		cmd->info0 |=
1282611297eeSHarsh Kumar Bijlani 			le32_encode_bits(DP_SW2HW_MACID(mac_id),
1283611297eeSHarsh Kumar Bijlani 					 HTT_TX_RING_SELECTION_CFG_CMD_INFO0_PDEV_ID);
1284611297eeSHarsh Kumar Bijlani 	else
1285611297eeSHarsh Kumar Bijlani 		cmd->info0 |=
1286611297eeSHarsh Kumar Bijlani 			le32_encode_bits(mac_id,
1287611297eeSHarsh Kumar Bijlani 					 HTT_TX_RING_SELECTION_CFG_CMD_INFO0_PDEV_ID);
1288611297eeSHarsh Kumar Bijlani 	cmd->info0 |= le32_encode_bits(htt_ring_id,
1289611297eeSHarsh Kumar Bijlani 				       HTT_TX_RING_SELECTION_CFG_CMD_INFO0_RING_ID);
1290611297eeSHarsh Kumar Bijlani 	cmd->info0 |= le32_encode_bits(!!(params.flags & HAL_SRNG_FLAGS_MSI_SWAP),
1291611297eeSHarsh Kumar Bijlani 				       HTT_TX_RING_SELECTION_CFG_CMD_INFO0_SS);
1292611297eeSHarsh Kumar Bijlani 	cmd->info0 |= le32_encode_bits(!!(params.flags & HAL_SRNG_FLAGS_DATA_TLV_SWAP),
1293611297eeSHarsh Kumar Bijlani 				       HTT_TX_RING_SELECTION_CFG_CMD_INFO0_PS);
1294611297eeSHarsh Kumar Bijlani 
1295611297eeSHarsh Kumar Bijlani 	cmd->info1 |=
1296611297eeSHarsh Kumar Bijlani 		le32_encode_bits(tx_buf_size,
1297611297eeSHarsh Kumar Bijlani 				 HTT_TX_RING_SELECTION_CFG_CMD_INFO1_RING_BUFF_SIZE);
1298611297eeSHarsh Kumar Bijlani 
1299611297eeSHarsh Kumar Bijlani 	if (htt_tlv_filter->tx_mon_mgmt_filter) {
1300611297eeSHarsh Kumar Bijlani 		cmd->info1 |=
1301611297eeSHarsh Kumar Bijlani 			le32_encode_bits(HTT_STATS_FRAME_CTRL_TYPE_MGMT,
1302611297eeSHarsh Kumar Bijlani 					 HTT_TX_RING_SELECTION_CFG_CMD_INFO1_PKT_TYPE);
1303611297eeSHarsh Kumar Bijlani 		cmd->info1 |=
1304611297eeSHarsh Kumar Bijlani 		le32_encode_bits(htt_tlv_filter->tx_mon_pkt_dma_len,
1305611297eeSHarsh Kumar Bijlani 				 HTT_TX_RING_SELECTION_CFG_CMD_INFO1_CONF_LEN_MGMT);
1306611297eeSHarsh Kumar Bijlani 		cmd->info2 |=
1307611297eeSHarsh Kumar Bijlani 		le32_encode_bits(HTT_STATS_FRAME_CTRL_TYPE_MGMT,
1308611297eeSHarsh Kumar Bijlani 				 HTT_TX_RING_SELECTION_CFG_CMD_INFO2_PKT_TYPE_EN_FLAG);
1309611297eeSHarsh Kumar Bijlani 	}
1310611297eeSHarsh Kumar Bijlani 
1311611297eeSHarsh Kumar Bijlani 	if (htt_tlv_filter->tx_mon_data_filter) {
1312611297eeSHarsh Kumar Bijlani 		cmd->info1 |=
1313611297eeSHarsh Kumar Bijlani 			le32_encode_bits(HTT_STATS_FRAME_CTRL_TYPE_CTRL,
1314611297eeSHarsh Kumar Bijlani 					 HTT_TX_RING_SELECTION_CFG_CMD_INFO1_PKT_TYPE);
1315611297eeSHarsh Kumar Bijlani 		cmd->info1 |=
1316611297eeSHarsh Kumar Bijlani 		le32_encode_bits(htt_tlv_filter->tx_mon_pkt_dma_len,
1317611297eeSHarsh Kumar Bijlani 				 HTT_TX_RING_SELECTION_CFG_CMD_INFO1_CONF_LEN_CTRL);
1318611297eeSHarsh Kumar Bijlani 		cmd->info2 |=
1319611297eeSHarsh Kumar Bijlani 		le32_encode_bits(HTT_STATS_FRAME_CTRL_TYPE_CTRL,
1320611297eeSHarsh Kumar Bijlani 				 HTT_TX_RING_SELECTION_CFG_CMD_INFO2_PKT_TYPE_EN_FLAG);
1321611297eeSHarsh Kumar Bijlani 	}
1322611297eeSHarsh Kumar Bijlani 
1323611297eeSHarsh Kumar Bijlani 	if (htt_tlv_filter->tx_mon_ctrl_filter) {
1324611297eeSHarsh Kumar Bijlani 		cmd->info1 |=
1325611297eeSHarsh Kumar Bijlani 			le32_encode_bits(HTT_STATS_FRAME_CTRL_TYPE_DATA,
1326611297eeSHarsh Kumar Bijlani 					 HTT_TX_RING_SELECTION_CFG_CMD_INFO1_PKT_TYPE);
1327611297eeSHarsh Kumar Bijlani 		cmd->info1 |=
1328611297eeSHarsh Kumar Bijlani 		le32_encode_bits(htt_tlv_filter->tx_mon_pkt_dma_len,
1329611297eeSHarsh Kumar Bijlani 				 HTT_TX_RING_SELECTION_CFG_CMD_INFO1_CONF_LEN_DATA);
1330611297eeSHarsh Kumar Bijlani 		cmd->info2 |=
1331611297eeSHarsh Kumar Bijlani 		le32_encode_bits(HTT_STATS_FRAME_CTRL_TYPE_DATA,
1332611297eeSHarsh Kumar Bijlani 				 HTT_TX_RING_SELECTION_CFG_CMD_INFO2_PKT_TYPE_EN_FLAG);
1333611297eeSHarsh Kumar Bijlani 	}
1334611297eeSHarsh Kumar Bijlani 
1335611297eeSHarsh Kumar Bijlani 	cmd->tlv_filter_mask_in0 =
1336611297eeSHarsh Kumar Bijlani 		cpu_to_le32(htt_tlv_filter->tx_mon_downstream_tlv_flags);
1337611297eeSHarsh Kumar Bijlani 	cmd->tlv_filter_mask_in1 =
1338611297eeSHarsh Kumar Bijlani 		cpu_to_le32(htt_tlv_filter->tx_mon_upstream_tlv_flags0);
1339611297eeSHarsh Kumar Bijlani 	cmd->tlv_filter_mask_in2 =
1340611297eeSHarsh Kumar Bijlani 		cpu_to_le32(htt_tlv_filter->tx_mon_upstream_tlv_flags1);
1341611297eeSHarsh Kumar Bijlani 	cmd->tlv_filter_mask_in3 =
1342611297eeSHarsh Kumar Bijlani 		cpu_to_le32(htt_tlv_filter->tx_mon_upstream_tlv_flags2);
1343611297eeSHarsh Kumar Bijlani 
13443a52762bSRipan Deuri 	ret = ath12k_htc_send(&ab->htc, dp->eid, skb);
1345611297eeSHarsh Kumar Bijlani 	if (ret)
1346611297eeSHarsh Kumar Bijlani 		goto err_free;
1347611297eeSHarsh Kumar Bijlani 
1348611297eeSHarsh Kumar Bijlani 	return 0;
1349611297eeSHarsh Kumar Bijlani 
1350611297eeSHarsh Kumar Bijlani err_free:
1351611297eeSHarsh Kumar Bijlani 	dev_kfree_skb_any(skb);
1352611297eeSHarsh Kumar Bijlani 	return ret;
1353611297eeSHarsh Kumar Bijlani }
1354