xref: /wlan-driver/qca-wifi-host-cmn/dp/wifi3.0/dp_htt.c (revision 5113495b16420b49004c444715d2daae2066e7dc)
1*5113495bSYour Name /*
2*5113495bSYour Name  * Copyright (c) 2016-2021 The Linux Foundation. All rights reserved.
3*5113495bSYour Name  * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
4*5113495bSYour Name  *
5*5113495bSYour Name  * Permission to use, copy, modify, and/or distribute this software for
6*5113495bSYour Name  * any purpose with or without fee is hereby granted, provided that the
7*5113495bSYour Name  * above copyright notice and this permission notice appear in all
8*5113495bSYour Name  * copies.
9*5113495bSYour Name  *
10*5113495bSYour Name  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
11*5113495bSYour Name  * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
12*5113495bSYour Name  * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
13*5113495bSYour Name  * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
14*5113495bSYour Name  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
15*5113495bSYour Name  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
16*5113495bSYour Name  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17*5113495bSYour Name  * PERFORMANCE OF THIS SOFTWARE.
18*5113495bSYour Name  */
19*5113495bSYour Name 
20*5113495bSYour Name #include <htt.h>
21*5113495bSYour Name #include <hal_hw_headers.h>
22*5113495bSYour Name #include <hal_api.h>
23*5113495bSYour Name #include "dp_peer.h"
24*5113495bSYour Name #include "dp_types.h"
25*5113495bSYour Name #include "dp_internal.h"
26*5113495bSYour Name #include "dp_ipa.h"
27*5113495bSYour Name #include "dp_rx.h"
28*5113495bSYour Name #include "htt_stats.h"
29*5113495bSYour Name #include "htt_ppdu_stats.h"
30*5113495bSYour Name #include "dp_htt.h"
31*5113495bSYour Name #ifdef WIFI_MONITOR_SUPPORT
32*5113495bSYour Name #include <dp_mon.h>
33*5113495bSYour Name #endif
34*5113495bSYour Name #include "qdf_mem.h"   /* qdf_mem_malloc,free */
35*5113495bSYour Name #include "cdp_txrx_cmn_struct.h"
36*5113495bSYour Name #ifdef IPA_OPT_WIFI_DP
37*5113495bSYour Name #include "cdp_txrx_ipa.h"
38*5113495bSYour Name #endif
39*5113495bSYour Name #ifdef FEATURE_PERPKT_INFO
40*5113495bSYour Name #include "dp_ratetable.h"
41*5113495bSYour Name #endif
42*5113495bSYour Name #include <qdf_module.h>
43*5113495bSYour Name #ifdef CONFIG_SAWF_DEF_QUEUES
44*5113495bSYour Name #include <dp_sawf_htt.h>
45*5113495bSYour Name #endif
46*5113495bSYour Name #include <wbuff.h>
47*5113495bSYour Name 
48*5113495bSYour Name #define HTT_TLV_HDR_LEN HTT_T2H_EXT_STATS_CONF_TLV_HDR_SIZE
49*5113495bSYour Name 
50*5113495bSYour Name #define HTT_HTC_PKT_POOL_INIT_SIZE 64
51*5113495bSYour Name 
52*5113495bSYour Name #define HTT_MSG_BUF_SIZE(msg_bytes) \
53*5113495bSYour Name 	((msg_bytes) + HTC_HEADER_LEN + HTC_HDR_ALIGNMENT_PADDING)
54*5113495bSYour Name 
55*5113495bSYour Name #define HTT_PID_BIT_MASK 0x3
56*5113495bSYour Name 
57*5113495bSYour Name #define DP_EXT_MSG_LENGTH 2048
58*5113495bSYour Name #define HTT_HEADER_LEN 16
59*5113495bSYour Name #define HTT_MGMT_CTRL_TLV_HDR_RESERVERD_LEN 16
60*5113495bSYour Name 
61*5113495bSYour Name #define HTT_SHIFT_UPPER_TIMESTAMP 32
62*5113495bSYour Name #define HTT_MASK_UPPER_TIMESTAMP 0xFFFFFFFF00000000
63*5113495bSYour Name #define HTT_BKP_STATS_MAX_QUEUE_DEPTH 16
64*5113495bSYour Name 
65*5113495bSYour Name struct dp_htt_htc_pkt *
htt_htc_pkt_alloc(struct htt_soc * soc)66*5113495bSYour Name htt_htc_pkt_alloc(struct htt_soc *soc)
67*5113495bSYour Name {
68*5113495bSYour Name 	struct dp_htt_htc_pkt_union *pkt = NULL;
69*5113495bSYour Name 
70*5113495bSYour Name 	HTT_TX_MUTEX_ACQUIRE(&soc->htt_tx_mutex);
71*5113495bSYour Name 	if (soc->htt_htc_pkt_freelist) {
72*5113495bSYour Name 		pkt = soc->htt_htc_pkt_freelist;
73*5113495bSYour Name 		soc->htt_htc_pkt_freelist = soc->htt_htc_pkt_freelist->u.next;
74*5113495bSYour Name 	}
75*5113495bSYour Name 	HTT_TX_MUTEX_RELEASE(&soc->htt_tx_mutex);
76*5113495bSYour Name 
77*5113495bSYour Name 	if (!pkt)
78*5113495bSYour Name 		pkt = qdf_mem_malloc(sizeof(*pkt));
79*5113495bSYour Name 
80*5113495bSYour Name 	if (!pkt)
81*5113495bSYour Name 		return NULL;
82*5113495bSYour Name 
83*5113495bSYour Name 	htc_packet_set_magic_cookie(&(pkt->u.pkt.htc_pkt), 0);
84*5113495bSYour Name 
85*5113495bSYour Name 	return &pkt->u.pkt; /* not actually a dereference */
86*5113495bSYour Name }
87*5113495bSYour Name 
88*5113495bSYour Name qdf_export_symbol(htt_htc_pkt_alloc);
89*5113495bSYour Name 
90*5113495bSYour Name void
htt_htc_pkt_free(struct htt_soc * soc,struct dp_htt_htc_pkt * pkt)91*5113495bSYour Name htt_htc_pkt_free(struct htt_soc *soc, struct dp_htt_htc_pkt *pkt)
92*5113495bSYour Name {
93*5113495bSYour Name 	struct dp_htt_htc_pkt_union *u_pkt =
94*5113495bSYour Name 		(struct dp_htt_htc_pkt_union *)pkt;
95*5113495bSYour Name 
96*5113495bSYour Name 	HTT_TX_MUTEX_ACQUIRE(&soc->htt_tx_mutex);
97*5113495bSYour Name 	htc_packet_set_magic_cookie(&(u_pkt->u.pkt.htc_pkt), 0);
98*5113495bSYour Name 	u_pkt->u.next = soc->htt_htc_pkt_freelist;
99*5113495bSYour Name 	soc->htt_htc_pkt_freelist = u_pkt;
100*5113495bSYour Name 	HTT_TX_MUTEX_RELEASE(&soc->htt_tx_mutex);
101*5113495bSYour Name }
102*5113495bSYour Name 
103*5113495bSYour Name qdf_export_symbol(htt_htc_pkt_free);
104*5113495bSYour Name 
105*5113495bSYour Name void
htt_htc_pkt_pool_free(struct htt_soc * soc)106*5113495bSYour Name htt_htc_pkt_pool_free(struct htt_soc *soc)
107*5113495bSYour Name {
108*5113495bSYour Name 	struct dp_htt_htc_pkt_union *pkt, *next;
109*5113495bSYour Name 	pkt = soc->htt_htc_pkt_freelist;
110*5113495bSYour Name 	while (pkt) {
111*5113495bSYour Name 		next = pkt->u.next;
112*5113495bSYour Name 		qdf_mem_free(pkt);
113*5113495bSYour Name 		pkt = next;
114*5113495bSYour Name 	}
115*5113495bSYour Name 	soc->htt_htc_pkt_freelist = NULL;
116*5113495bSYour Name }
117*5113495bSYour Name 
118*5113495bSYour Name 
119*5113495bSYour Name #ifndef ENABLE_CE4_COMP_DISABLE_HTT_HTC_MISC_LIST
120*5113495bSYour Name 
121*5113495bSYour Name /**
122*5113495bSYour Name  * htt_htc_misc_pkt_list_trim() - trim misc list
123*5113495bSYour Name  * @soc: HTT SOC handle
124*5113495bSYour Name  * @level: max no. of pkts in list
125*5113495bSYour Name  */
126*5113495bSYour Name static void
htt_htc_misc_pkt_list_trim(struct htt_soc * soc,int level)127*5113495bSYour Name htt_htc_misc_pkt_list_trim(struct htt_soc *soc, int level)
128*5113495bSYour Name {
129*5113495bSYour Name 	struct dp_htt_htc_pkt_union *pkt, *next, *prev = NULL;
130*5113495bSYour Name 	int i = 0;
131*5113495bSYour Name 	qdf_nbuf_t netbuf;
132*5113495bSYour Name 
133*5113495bSYour Name 	HTT_TX_MUTEX_ACQUIRE(&soc->htt_tx_mutex);
134*5113495bSYour Name 	pkt = soc->htt_htc_pkt_misclist;
135*5113495bSYour Name 	while (pkt) {
136*5113495bSYour Name 		next = pkt->u.next;
137*5113495bSYour Name 		/* trim the out grown list*/
138*5113495bSYour Name 		if (++i > level) {
139*5113495bSYour Name 			netbuf =
140*5113495bSYour Name 				(qdf_nbuf_t)(pkt->u.pkt.htc_pkt.pNetBufContext);
141*5113495bSYour Name 			qdf_nbuf_unmap(soc->osdev, netbuf, QDF_DMA_TO_DEVICE);
142*5113495bSYour Name 			qdf_nbuf_free(netbuf);
143*5113495bSYour Name 			qdf_mem_free(pkt);
144*5113495bSYour Name 			pkt = NULL;
145*5113495bSYour Name 			if (prev)
146*5113495bSYour Name 				prev->u.next = NULL;
147*5113495bSYour Name 		}
148*5113495bSYour Name 		prev = pkt;
149*5113495bSYour Name 		pkt = next;
150*5113495bSYour Name 	}
151*5113495bSYour Name 	HTT_TX_MUTEX_RELEASE(&soc->htt_tx_mutex);
152*5113495bSYour Name }
153*5113495bSYour Name 
154*5113495bSYour Name void
htt_htc_misc_pkt_list_add(struct htt_soc * soc,struct dp_htt_htc_pkt * pkt)155*5113495bSYour Name htt_htc_misc_pkt_list_add(struct htt_soc *soc, struct dp_htt_htc_pkt *pkt)
156*5113495bSYour Name {
157*5113495bSYour Name 	struct dp_htt_htc_pkt_union *u_pkt =
158*5113495bSYour Name 				(struct dp_htt_htc_pkt_union *)pkt;
159*5113495bSYour Name 	int misclist_trim_level = htc_get_tx_queue_depth(soc->htc_soc,
160*5113495bSYour Name 							pkt->htc_pkt.Endpoint)
161*5113495bSYour Name 				+ DP_HTT_HTC_PKT_MISCLIST_SIZE;
162*5113495bSYour Name 
163*5113495bSYour Name 	HTT_TX_MUTEX_ACQUIRE(&soc->htt_tx_mutex);
164*5113495bSYour Name 	if (soc->htt_htc_pkt_misclist) {
165*5113495bSYour Name 		u_pkt->u.next = soc->htt_htc_pkt_misclist;
166*5113495bSYour Name 		soc->htt_htc_pkt_misclist = u_pkt;
167*5113495bSYour Name 	} else {
168*5113495bSYour Name 		soc->htt_htc_pkt_misclist = u_pkt;
169*5113495bSYour Name 	}
170*5113495bSYour Name 	HTT_TX_MUTEX_RELEASE(&soc->htt_tx_mutex);
171*5113495bSYour Name 
172*5113495bSYour Name 	/* only ce pipe size + tx_queue_depth could possibly be in use
173*5113495bSYour Name 	 * free older packets in the misclist
174*5113495bSYour Name 	 */
175*5113495bSYour Name 	htt_htc_misc_pkt_list_trim(soc, misclist_trim_level);
176*5113495bSYour Name }
177*5113495bSYour Name 
178*5113495bSYour Name qdf_export_symbol(htt_htc_misc_pkt_list_add);
179*5113495bSYour Name #endif  /* ENABLE_CE4_COMP_DISABLE_HTT_HTC_MISC_LIST */
180*5113495bSYour Name 
181*5113495bSYour Name /**
182*5113495bSYour Name  * htt_htc_misc_pkt_pool_free() - free pkts in misc list
183*5113495bSYour Name  * @soc:	HTT SOC handle
184*5113495bSYour Name  */
185*5113495bSYour Name static void
htt_htc_misc_pkt_pool_free(struct htt_soc * soc)186*5113495bSYour Name htt_htc_misc_pkt_pool_free(struct htt_soc *soc)
187*5113495bSYour Name {
188*5113495bSYour Name 	struct dp_htt_htc_pkt_union *pkt, *next;
189*5113495bSYour Name 	qdf_nbuf_t netbuf;
190*5113495bSYour Name 
191*5113495bSYour Name 	HTT_TX_MUTEX_ACQUIRE(&soc->htt_tx_mutex);
192*5113495bSYour Name 	pkt = soc->htt_htc_pkt_misclist;
193*5113495bSYour Name 
194*5113495bSYour Name 	while (pkt) {
195*5113495bSYour Name 		next = pkt->u.next;
196*5113495bSYour Name 		if (htc_packet_get_magic_cookie(&(pkt->u.pkt.htc_pkt)) !=
197*5113495bSYour Name 		    HTC_PACKET_MAGIC_COOKIE) {
198*5113495bSYour Name 			pkt = next;
199*5113495bSYour Name 			soc->stats.skip_count++;
200*5113495bSYour Name 			continue;
201*5113495bSYour Name 		}
202*5113495bSYour Name 		netbuf = (qdf_nbuf_t) (pkt->u.pkt.htc_pkt.pNetBufContext);
203*5113495bSYour Name 		qdf_nbuf_unmap(soc->osdev, netbuf, QDF_DMA_TO_DEVICE);
204*5113495bSYour Name 
205*5113495bSYour Name 		soc->stats.htc_pkt_free++;
206*5113495bSYour Name 		dp_htt_info("%pK: Pkt free count %d",
207*5113495bSYour Name 			    soc->dp_soc, soc->stats.htc_pkt_free);
208*5113495bSYour Name 
209*5113495bSYour Name 		qdf_nbuf_free(netbuf);
210*5113495bSYour Name 		qdf_mem_free(pkt);
211*5113495bSYour Name 		pkt = next;
212*5113495bSYour Name 	}
213*5113495bSYour Name 	soc->htt_htc_pkt_misclist = NULL;
214*5113495bSYour Name 	HTT_TX_MUTEX_RELEASE(&soc->htt_tx_mutex);
215*5113495bSYour Name 	dp_info("HTC Packets, fail count = %d, skip count = %d",
216*5113495bSYour Name 		soc->stats.fail_count, soc->stats.skip_count);
217*5113495bSYour Name }
218*5113495bSYour Name 
219*5113495bSYour Name /**
220*5113495bSYour Name  * htt_t2h_mac_addr_deswizzle() - Swap MAC addr bytes if FW endianness differ
221*5113495bSYour Name  * @tgt_mac_addr:	Target MAC
222*5113495bSYour Name  * @buffer:		Output buffer
223*5113495bSYour Name  */
224*5113495bSYour Name static u_int8_t *
htt_t2h_mac_addr_deswizzle(u_int8_t * tgt_mac_addr,u_int8_t * buffer)225*5113495bSYour Name htt_t2h_mac_addr_deswizzle(u_int8_t *tgt_mac_addr, u_int8_t *buffer)
226*5113495bSYour Name {
227*5113495bSYour Name #ifdef BIG_ENDIAN_HOST
228*5113495bSYour Name 	/*
229*5113495bSYour Name 	 * The host endianness is opposite of the target endianness.
230*5113495bSYour Name 	 * To make u_int32_t elements come out correctly, the target->host
231*5113495bSYour Name 	 * upload has swizzled the bytes in each u_int32_t element of the
232*5113495bSYour Name 	 * message.
233*5113495bSYour Name 	 * For byte-array message fields like the MAC address, this
234*5113495bSYour Name 	 * upload swizzling puts the bytes in the wrong order, and needs
235*5113495bSYour Name 	 * to be undone.
236*5113495bSYour Name 	 */
237*5113495bSYour Name 	buffer[0] = tgt_mac_addr[3];
238*5113495bSYour Name 	buffer[1] = tgt_mac_addr[2];
239*5113495bSYour Name 	buffer[2] = tgt_mac_addr[1];
240*5113495bSYour Name 	buffer[3] = tgt_mac_addr[0];
241*5113495bSYour Name 	buffer[4] = tgt_mac_addr[7];
242*5113495bSYour Name 	buffer[5] = tgt_mac_addr[6];
243*5113495bSYour Name 	return buffer;
244*5113495bSYour Name #else
245*5113495bSYour Name 	/*
246*5113495bSYour Name 	 * The host endianness matches the target endianness -
247*5113495bSYour Name 	 * we can use the mac addr directly from the message buffer.
248*5113495bSYour Name 	 */
249*5113495bSYour Name 	return tgt_mac_addr;
250*5113495bSYour Name #endif
251*5113495bSYour Name }
252*5113495bSYour Name 
253*5113495bSYour Name /**
254*5113495bSYour Name  * dp_htt_h2t_send_complete_free_netbuf() - Free completed buffer
255*5113495bSYour Name  * @soc:	SOC handle
256*5113495bSYour Name  * @status:	Completion status
257*5113495bSYour Name  * @netbuf:	HTT buffer
258*5113495bSYour Name  */
259*5113495bSYour Name static void
dp_htt_h2t_send_complete_free_netbuf(void * soc,A_STATUS status,qdf_nbuf_t netbuf)260*5113495bSYour Name dp_htt_h2t_send_complete_free_netbuf(
261*5113495bSYour Name 	void *soc, A_STATUS status, qdf_nbuf_t netbuf)
262*5113495bSYour Name {
263*5113495bSYour Name 	qdf_nbuf_free(netbuf);
264*5113495bSYour Name }
265*5113495bSYour Name 
266*5113495bSYour Name #ifdef ENABLE_CE4_COMP_DISABLE_HTT_HTC_MISC_LIST
267*5113495bSYour Name void
dp_htt_h2t_send_complete(void * context,HTC_PACKET * htc_pkt)268*5113495bSYour Name dp_htt_h2t_send_complete(void *context, HTC_PACKET *htc_pkt)
269*5113495bSYour Name {
270*5113495bSYour Name 	struct htt_soc *soc =  (struct htt_soc *) context;
271*5113495bSYour Name 	struct dp_htt_htc_pkt *htt_pkt;
272*5113495bSYour Name 	qdf_nbuf_t netbuf;
273*5113495bSYour Name 
274*5113495bSYour Name 	htt_pkt = container_of(htc_pkt, struct dp_htt_htc_pkt, htc_pkt);
275*5113495bSYour Name 
276*5113495bSYour Name 	/* process (free or keep) the netbuf that held the message */
277*5113495bSYour Name 	netbuf = (qdf_nbuf_t) htc_pkt->pNetBufContext;
278*5113495bSYour Name 	/*
279*5113495bSYour Name 	 * adf sendcomplete is required for windows only
280*5113495bSYour Name 	 */
281*5113495bSYour Name 	/* qdf_nbuf_set_sendcompleteflag(netbuf, TRUE); */
282*5113495bSYour Name 	/* free the htt_htc_pkt / HTC_PACKET object */
283*5113495bSYour Name 	qdf_nbuf_free(netbuf);
284*5113495bSYour Name 	htt_htc_pkt_free(soc, htt_pkt);
285*5113495bSYour Name }
286*5113495bSYour Name 
287*5113495bSYour Name #else /* ENABLE_CE4_COMP_DISABLE_HTT_HTC_MISC_LIST */
288*5113495bSYour Name 
289*5113495bSYour Name void
dp_htt_h2t_send_complete(void * context,HTC_PACKET * htc_pkt)290*5113495bSYour Name dp_htt_h2t_send_complete(void *context, HTC_PACKET *htc_pkt)
291*5113495bSYour Name {
292*5113495bSYour Name 	void (*send_complete_part2)(
293*5113495bSYour Name 	     void *soc, QDF_STATUS status, qdf_nbuf_t msdu);
294*5113495bSYour Name 	struct htt_soc *soc =  (struct htt_soc *) context;
295*5113495bSYour Name 	struct dp_htt_htc_pkt *htt_pkt;
296*5113495bSYour Name 	qdf_nbuf_t netbuf;
297*5113495bSYour Name 
298*5113495bSYour Name 	send_complete_part2 = htc_pkt->pPktContext;
299*5113495bSYour Name 
300*5113495bSYour Name 	htt_pkt = container_of(htc_pkt, struct dp_htt_htc_pkt, htc_pkt);
301*5113495bSYour Name 
302*5113495bSYour Name 	/* process (free or keep) the netbuf that held the message */
303*5113495bSYour Name 	netbuf = (qdf_nbuf_t) htc_pkt->pNetBufContext;
304*5113495bSYour Name 	/*
305*5113495bSYour Name 	 * adf sendcomplete is required for windows only
306*5113495bSYour Name 	 */
307*5113495bSYour Name 	/* qdf_nbuf_set_sendcompleteflag(netbuf, TRUE); */
308*5113495bSYour Name 	if (send_complete_part2){
309*5113495bSYour Name 		send_complete_part2(
310*5113495bSYour Name 		    htt_pkt->soc_ctxt, htc_pkt->Status, netbuf);
311*5113495bSYour Name 	}
312*5113495bSYour Name 	/* free the htt_htc_pkt / HTC_PACKET object */
313*5113495bSYour Name 	htt_htc_pkt_free(soc, htt_pkt);
314*5113495bSYour Name }
315*5113495bSYour Name 
316*5113495bSYour Name #endif /* ENABLE_CE4_COMP_DISABLE_HTT_HTC_MISC_LIST */
317*5113495bSYour Name 
318*5113495bSYour Name /**
319*5113495bSYour Name  * dp_htt_h2t_add_tcl_metadata_ver_v1() - Add tcl_metadata version V1
320*5113495bSYour Name  * @soc:	HTT SOC handle
321*5113495bSYour Name  * @msg:	Pointer to nbuf
322*5113495bSYour Name  *
323*5113495bSYour Name  * Return: 0 on success; error code on failure
324*5113495bSYour Name  */
dp_htt_h2t_add_tcl_metadata_ver_v1(struct htt_soc * soc,qdf_nbuf_t * msg)325*5113495bSYour Name static int dp_htt_h2t_add_tcl_metadata_ver_v1(struct htt_soc *soc,
326*5113495bSYour Name 					      qdf_nbuf_t *msg)
327*5113495bSYour Name {
328*5113495bSYour Name 	uint32_t *msg_word;
329*5113495bSYour Name 
330*5113495bSYour Name 	*msg = qdf_nbuf_alloc(
331*5113495bSYour Name 		soc->osdev,
332*5113495bSYour Name 		HTT_MSG_BUF_SIZE(HTT_VER_REQ_BYTES),
333*5113495bSYour Name 		/* reserve room for the HTC header */
334*5113495bSYour Name 		HTC_HEADER_LEN + HTC_HDR_ALIGNMENT_PADDING, 4, TRUE);
335*5113495bSYour Name 	if (!*msg)
336*5113495bSYour Name 		return QDF_STATUS_E_NOMEM;
337*5113495bSYour Name 
338*5113495bSYour Name 	/*
339*5113495bSYour Name 	 * Set the length of the message.
340*5113495bSYour Name 	 * The contribution from the HTC_HDR_ALIGNMENT_PADDING is added
341*5113495bSYour Name 	 * separately during the below call to qdf_nbuf_push_head.
342*5113495bSYour Name 	 * The contribution from the HTC header is added separately inside HTC.
343*5113495bSYour Name 	 */
344*5113495bSYour Name 	if (!qdf_nbuf_put_tail(*msg, HTT_VER_REQ_BYTES)) {
345*5113495bSYour Name 		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
346*5113495bSYour Name 			  "%s: Failed to expand head for HTT_H2T_MSG_TYPE_VERSION_REQ msg",
347*5113495bSYour Name 			  __func__);
348*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
349*5113495bSYour Name 	}
350*5113495bSYour Name 
351*5113495bSYour Name 	/* fill in the message contents */
352*5113495bSYour Name 	msg_word = (u_int32_t *)qdf_nbuf_data(*msg);
353*5113495bSYour Name 
354*5113495bSYour Name 	/* rewind beyond alignment pad to get to the HTC header reserved area */
355*5113495bSYour Name 	qdf_nbuf_push_head(*msg, HTC_HDR_ALIGNMENT_PADDING);
356*5113495bSYour Name 
357*5113495bSYour Name 	*msg_word = 0;
358*5113495bSYour Name 	HTT_H2T_MSG_TYPE_SET(*msg_word, HTT_H2T_MSG_TYPE_VERSION_REQ);
359*5113495bSYour Name 
360*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
361*5113495bSYour Name }
362*5113495bSYour Name 
363*5113495bSYour Name #ifdef QCA_DP_TX_FW_METADATA_V2
364*5113495bSYour Name /**
365*5113495bSYour Name  * dp_htt_h2t_add_tcl_metadata_ver_v2() - Add tcl_metadata version V2
366*5113495bSYour Name  * @soc:	HTT SOC handle
367*5113495bSYour Name  * @msg:	Pointer to nbuf
368*5113495bSYour Name  *
369*5113495bSYour Name  * Return: 0 on success; error code on failure
370*5113495bSYour Name  */
dp_htt_h2t_add_tcl_metadata_ver_v2(struct htt_soc * soc,qdf_nbuf_t * msg)371*5113495bSYour Name static int dp_htt_h2t_add_tcl_metadata_ver_v2(struct htt_soc *soc,
372*5113495bSYour Name 					      qdf_nbuf_t *msg)
373*5113495bSYour Name {
374*5113495bSYour Name 	uint32_t *msg_word;
375*5113495bSYour Name 
376*5113495bSYour Name 	*msg = qdf_nbuf_alloc(
377*5113495bSYour Name 		soc->osdev,
378*5113495bSYour Name 		HTT_MSG_BUF_SIZE(HTT_VER_REQ_BYTES + HTT_TCL_METADATA_VER_SZ),
379*5113495bSYour Name 		/* reserve room for the HTC header */
380*5113495bSYour Name 		HTC_HEADER_LEN + HTC_HDR_ALIGNMENT_PADDING, 4, TRUE);
381*5113495bSYour Name 	if (!*msg)
382*5113495bSYour Name 		return QDF_STATUS_E_NOMEM;
383*5113495bSYour Name 
384*5113495bSYour Name 	/*
385*5113495bSYour Name 	 * Set the length of the message.
386*5113495bSYour Name 	 * The contribution from the HTC_HDR_ALIGNMENT_PADDING is added
387*5113495bSYour Name 	 * separately during the below call to qdf_nbuf_push_head.
388*5113495bSYour Name 	 * The contribution from the HTC header is added separately inside HTC.
389*5113495bSYour Name 	 */
390*5113495bSYour Name 	if (!qdf_nbuf_put_tail(*msg,
391*5113495bSYour Name 			       HTT_VER_REQ_BYTES + HTT_TCL_METADATA_VER_SZ)) {
392*5113495bSYour Name 		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
393*5113495bSYour Name 			  "%s: Failed to expand head for HTT_H2T_MSG_TYPE_VERSION_REQ msg",
394*5113495bSYour Name 			  __func__);
395*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
396*5113495bSYour Name 	}
397*5113495bSYour Name 
398*5113495bSYour Name 	/* fill in the message contents */
399*5113495bSYour Name 	msg_word = (u_int32_t *)qdf_nbuf_data(*msg);
400*5113495bSYour Name 
401*5113495bSYour Name 	/* rewind beyond alignment pad to get to the HTC header reserved area */
402*5113495bSYour Name 	qdf_nbuf_push_head(*msg, HTC_HDR_ALIGNMENT_PADDING);
403*5113495bSYour Name 
404*5113495bSYour Name 	*msg_word = 0;
405*5113495bSYour Name 	HTT_H2T_MSG_TYPE_SET(*msg_word, HTT_H2T_MSG_TYPE_VERSION_REQ);
406*5113495bSYour Name 
407*5113495bSYour Name 	/* word 1 */
408*5113495bSYour Name 	msg_word++;
409*5113495bSYour Name 	*msg_word = 0;
410*5113495bSYour Name 	HTT_OPTION_TLV_TAG_SET(*msg_word, HTT_OPTION_TLV_TAG_TCL_METADATA_VER);
411*5113495bSYour Name 	HTT_OPTION_TLV_LENGTH_SET(*msg_word, HTT_TCL_METADATA_VER_SZ);
412*5113495bSYour Name 	HTT_OPTION_TLV_TCL_METADATA_VER_SET(*msg_word,
413*5113495bSYour Name 					    HTT_OPTION_TLV_TCL_METADATA_V21);
414*5113495bSYour Name 
415*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
416*5113495bSYour Name }
417*5113495bSYour Name 
418*5113495bSYour Name /**
419*5113495bSYour Name  * dp_htt_h2t_add_tcl_metadata_ver() - Add tcl_metadata version
420*5113495bSYour Name  * @soc:	HTT SOC handle
421*5113495bSYour Name  * @msg:	Pointer to nbuf
422*5113495bSYour Name  *
423*5113495bSYour Name  * Return: 0 on success; error code on failure
424*5113495bSYour Name  */
dp_htt_h2t_add_tcl_metadata_ver(struct htt_soc * soc,qdf_nbuf_t * msg)425*5113495bSYour Name static int dp_htt_h2t_add_tcl_metadata_ver(struct htt_soc *soc, qdf_nbuf_t *msg)
426*5113495bSYour Name {
427*5113495bSYour Name 	/* Use tcl_metadata_v1 when NSS offload is enabled */
428*5113495bSYour Name 	if (wlan_cfg_get_dp_soc_nss_cfg(soc->dp_soc->wlan_cfg_ctx) ||
429*5113495bSYour Name 	    soc->dp_soc->cdp_soc.ol_ops->get_con_mode() == QDF_GLOBAL_FTM_MODE)
430*5113495bSYour Name 		return dp_htt_h2t_add_tcl_metadata_ver_v1(soc, msg);
431*5113495bSYour Name 	else
432*5113495bSYour Name 		return dp_htt_h2t_add_tcl_metadata_ver_v2(soc, msg);
433*5113495bSYour Name }
434*5113495bSYour Name #else
dp_htt_h2t_add_tcl_metadata_ver(struct htt_soc * soc,qdf_nbuf_t * msg)435*5113495bSYour Name static int dp_htt_h2t_add_tcl_metadata_ver(struct htt_soc *soc, qdf_nbuf_t *msg)
436*5113495bSYour Name {
437*5113495bSYour Name 	return dp_htt_h2t_add_tcl_metadata_ver_v1(soc, msg);
438*5113495bSYour Name }
439*5113495bSYour Name #endif
440*5113495bSYour Name 
441*5113495bSYour Name /**
442*5113495bSYour Name  * htt_h2t_ver_req_msg() - Send HTT version request message to target
443*5113495bSYour Name  * @soc:	HTT SOC handle
444*5113495bSYour Name  *
445*5113495bSYour Name  * Return: 0 on success; error code on failure
446*5113495bSYour Name  */
htt_h2t_ver_req_msg(struct htt_soc * soc)447*5113495bSYour Name static int htt_h2t_ver_req_msg(struct htt_soc *soc)
448*5113495bSYour Name {
449*5113495bSYour Name 	struct dp_htt_htc_pkt *pkt;
450*5113495bSYour Name 	qdf_nbuf_t msg = NULL;
451*5113495bSYour Name 	QDF_STATUS status;
452*5113495bSYour Name 
453*5113495bSYour Name 	status = dp_htt_h2t_add_tcl_metadata_ver(soc, &msg);
454*5113495bSYour Name 	if (status != QDF_STATUS_SUCCESS)
455*5113495bSYour Name 		return status;
456*5113495bSYour Name 
457*5113495bSYour Name 	pkt = htt_htc_pkt_alloc(soc);
458*5113495bSYour Name 	if (!pkt) {
459*5113495bSYour Name 		qdf_nbuf_free(msg);
460*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
461*5113495bSYour Name 	}
462*5113495bSYour Name 	pkt->soc_ctxt = NULL; /* not used during send-done callback */
463*5113495bSYour Name 
464*5113495bSYour Name 	SET_HTC_PACKET_INFO_TX(&pkt->htc_pkt,
465*5113495bSYour Name 		dp_htt_h2t_send_complete_free_netbuf, qdf_nbuf_data(msg),
466*5113495bSYour Name 		qdf_nbuf_len(msg), soc->htc_endpoint,
467*5113495bSYour Name 		HTC_TX_PACKET_TAG_RTPM_PUT_RC);
468*5113495bSYour Name 
469*5113495bSYour Name 	SET_HTC_PACKET_NET_BUF_CONTEXT(&pkt->htc_pkt, msg);
470*5113495bSYour Name 	status = DP_HTT_SEND_HTC_PKT(soc, pkt, HTT_H2T_MSG_TYPE_VERSION_REQ,
471*5113495bSYour Name 				     NULL);
472*5113495bSYour Name 
473*5113495bSYour Name 	if (status != QDF_STATUS_SUCCESS) {
474*5113495bSYour Name 		qdf_nbuf_free(msg);
475*5113495bSYour Name 		htt_htc_pkt_free(soc, pkt);
476*5113495bSYour Name 	}
477*5113495bSYour Name 
478*5113495bSYour Name 	return status;
479*5113495bSYour Name }
480*5113495bSYour Name 
481*5113495bSYour Name #ifdef IPA_OPT_WIFI_DP
htt_h2t_rx_cce_super_rule_setup(struct htt_soc * soc,void * param)482*5113495bSYour Name QDF_STATUS htt_h2t_rx_cce_super_rule_setup(struct htt_soc *soc, void *param)
483*5113495bSYour Name {
484*5113495bSYour Name 	struct wifi_dp_flt_setup *flt_params =
485*5113495bSYour Name 			(struct wifi_dp_flt_setup *)param;
486*5113495bSYour Name 	struct dp_htt_htc_pkt *pkt;
487*5113495bSYour Name 	qdf_nbuf_t msg;
488*5113495bSYour Name 	uint32_t *msg_word;
489*5113495bSYour Name 	uint8_t *htt_logger_bufp;
490*5113495bSYour Name 	uint16_t ver = 0;
491*5113495bSYour Name 	uint8_t i, valid = 0;
492*5113495bSYour Name 	uint8_t num_filters = flt_params->num_filters;
493*5113495bSYour Name 	uint8_t pdev_id = flt_params->pdev_id;
494*5113495bSYour Name 	uint8_t op = flt_params->op;
495*5113495bSYour Name 	uint16_t ipv4 = qdf_ntohs(QDF_NBUF_TRAC_IPV4_ETH_TYPE);
496*5113495bSYour Name 	uint16_t ipv6 = qdf_ntohs(QDF_NBUF_TRAC_IPV6_ETH_TYPE);
497*5113495bSYour Name 	QDF_STATUS status;
498*5113495bSYour Name 
499*5113495bSYour Name 	if (num_filters > RX_CCE_SUPER_RULE_SETUP_NUM) {
500*5113495bSYour Name 		dp_htt_err("Wrong filter count %d", num_filters);
501*5113495bSYour Name 		return QDF_STATUS_FILT_REQ_ERROR;
502*5113495bSYour Name 	}
503*5113495bSYour Name 
504*5113495bSYour Name 	msg = qdf_nbuf_alloc(soc->osdev,
505*5113495bSYour Name 			     HTT_MSG_BUF_SIZE(HTT_RX_CCE_SUPER_RULE_SETUP_SZ),
506*5113495bSYour Name 			     HTC_HEADER_LEN + HTC_HDR_ALIGNMENT_PADDING, 4,
507*5113495bSYour Name 			     true);
508*5113495bSYour Name 	if (!msg) {
509*5113495bSYour Name 		dp_htt_err("Fail to allocate SUPER_RULE_SETUP msg ");
510*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
511*5113495bSYour Name 	}
512*5113495bSYour Name 
513*5113495bSYour Name 	qdf_nbuf_put_tail(msg, HTT_RX_CCE_SUPER_RULE_SETUP_SZ);
514*5113495bSYour Name 	msg_word = (uint32_t *)qdf_nbuf_data(msg);
515*5113495bSYour Name 	memset(msg_word, 0, HTT_RX_CCE_SUPER_RULE_SETUP_SZ);
516*5113495bSYour Name 
517*5113495bSYour Name 	qdf_nbuf_push_head(msg, HTC_HDR_ALIGNMENT_PADDING);
518*5113495bSYour Name 	htt_logger_bufp = (uint8_t *)msg_word;
519*5113495bSYour Name 
520*5113495bSYour Name 	*msg_word = 0;
521*5113495bSYour Name 	HTT_H2T_MSG_TYPE_SET(*msg_word,
522*5113495bSYour Name 			     HTT_H2T_MSG_TYPE_RX_CCE_SUPER_RULE_SETUP);
523*5113495bSYour Name 	HTT_RX_CCE_SUPER_RULE_SETUP_PDEV_ID_SET(*msg_word, pdev_id);
524*5113495bSYour Name 	HTT_RX_CCE_SUPER_RULE_SETUP_OPERATION_SET(*msg_word, op);
525*5113495bSYour Name 
526*5113495bSYour Name 	/* Set cce_super_rule_params */
527*5113495bSYour Name 	for (i = 0; i < RX_CCE_SUPER_RULE_SETUP_NUM; i++) {
528*5113495bSYour Name 		valid = flt_params->flt_addr_params[i].valid;
529*5113495bSYour Name 		ver = flt_params->flt_addr_params[i].l3_type;
530*5113495bSYour Name 		msg_word++;
531*5113495bSYour Name 
532*5113495bSYour Name 		if (ver == ipv4) {
533*5113495bSYour Name 			HTT_RX_CCE_SUPER_RULE_SETUP_IPV4_ADDR_ARRAY_SET(
534*5113495bSYour Name 				msg_word,
535*5113495bSYour Name 				flt_params->flt_addr_params[i].src_ipv4_addr);
536*5113495bSYour Name 		} else if (ver == ipv6) {
537*5113495bSYour Name 			HTT_RX_CCE_SUPER_RULE_SETUP_IPV6_ADDR_ARRAY_SET(
538*5113495bSYour Name 				msg_word,
539*5113495bSYour Name 				flt_params->flt_addr_params[i].src_ipv6_addr);
540*5113495bSYour Name 		} else {
541*5113495bSYour Name 			dp_htt_debug("Filter %d not in use.", i);
542*5113495bSYour Name 		}
543*5113495bSYour Name 
544*5113495bSYour Name 		/* move uint32_t *msg_word by IPV6 addr size */
545*5113495bSYour Name 		msg_word += (QDF_IPV6_ADDR_SIZE / 4);
546*5113495bSYour Name 
547*5113495bSYour Name 		if (ver == ipv4) {
548*5113495bSYour Name 			HTT_RX_CCE_SUPER_RULE_SETUP_IPV4_ADDR_ARRAY_SET(
549*5113495bSYour Name 				msg_word,
550*5113495bSYour Name 				flt_params->flt_addr_params[i].dst_ipv4_addr);
551*5113495bSYour Name 		} else if (ver == ipv6) {
552*5113495bSYour Name 			HTT_RX_CCE_SUPER_RULE_SETUP_IPV6_ADDR_ARRAY_SET(
553*5113495bSYour Name 				msg_word,
554*5113495bSYour Name 				flt_params->flt_addr_params[i].dst_ipv6_addr);
555*5113495bSYour Name 		} else {
556*5113495bSYour Name 			dp_htt_debug("Filter %d not in use.", i);
557*5113495bSYour Name 		}
558*5113495bSYour Name 
559*5113495bSYour Name 		/* move uint32_t *msg_word by IPV6 addr size */
560*5113495bSYour Name 		msg_word += (QDF_IPV6_ADDR_SIZE / 4);
561*5113495bSYour Name 		HTT_RX_CCE_SUPER_RULE_SETUP_L3_TYPE_SET(*msg_word, ver);
562*5113495bSYour Name 		HTT_RX_CCE_SUPER_RULE_SETUP_L4_TYPE_SET(
563*5113495bSYour Name 					*msg_word,
564*5113495bSYour Name 					flt_params->flt_addr_params[i].l4_type);
565*5113495bSYour Name 		HTT_RX_CCE_SUPER_RULE_SETUP_IS_VALID_SET(*msg_word, valid);
566*5113495bSYour Name 		msg_word++;
567*5113495bSYour Name 		HTT_RX_CCE_SUPER_RULE_SETUP_L4_SRC_PORT_SET(
568*5113495bSYour Name 				*msg_word,
569*5113495bSYour Name 				flt_params->flt_addr_params[i].src_port);
570*5113495bSYour Name 		HTT_RX_CCE_SUPER_RULE_SETUP_L4_DST_PORT_SET(
571*5113495bSYour Name 				*msg_word,
572*5113495bSYour Name 				flt_params->flt_addr_params[i].dst_port);
573*5113495bSYour Name 
574*5113495bSYour Name 		dp_info("opt_dp:: pdev: %u ver %u, flt_num %u, op %u",
575*5113495bSYour Name 			pdev_id, ver, i, op);
576*5113495bSYour Name 		dp_info("valid %u", valid);
577*5113495bSYour Name 	}
578*5113495bSYour Name 
579*5113495bSYour Name 	pkt = htt_htc_pkt_alloc(soc);
580*5113495bSYour Name 	if (!pkt) {
581*5113495bSYour Name 		dp_htt_err("Fail to allocate dp_htt_htc_pkt buffer");
582*5113495bSYour Name 		qdf_assert(0);
583*5113495bSYour Name 		qdf_nbuf_free(msg);
584*5113495bSYour Name 		return QDF_STATUS_E_NOMEM;
585*5113495bSYour Name 	}
586*5113495bSYour Name 
587*5113495bSYour Name 	pkt->soc_ctxt = NULL; /*not used during send-done callback */
588*5113495bSYour Name 	SET_HTC_PACKET_INFO_TX(&pkt->htc_pkt,
589*5113495bSYour Name 			       dp_htt_h2t_send_complete_free_netbuf,
590*5113495bSYour Name 			       qdf_nbuf_data(msg), qdf_nbuf_len(msg),
591*5113495bSYour Name 			       soc->htc_endpoint,
592*5113495bSYour Name 			       HTC_TX_PACKET_TAG_RUNTIME_PUT);
593*5113495bSYour Name 
594*5113495bSYour Name 	SET_HTC_PACKET_NET_BUF_CONTEXT(&pkt->htc_pkt, msg);
595*5113495bSYour Name 	status = DP_HTT_SEND_HTC_PKT(soc, pkt,
596*5113495bSYour Name 				     HTT_H2T_MSG_TYPE_RX_CCE_SUPER_RULE_SETUP,
597*5113495bSYour Name 				     htt_logger_bufp);
598*5113495bSYour Name 
599*5113495bSYour Name 	if (status != QDF_STATUS_SUCCESS) {
600*5113495bSYour Name 		qdf_nbuf_free(msg);
601*5113495bSYour Name 		htt_htc_pkt_free(soc, pkt);
602*5113495bSYour Name 	}
603*5113495bSYour Name 	return status;
604*5113495bSYour Name }
605*5113495bSYour Name #endif /* IPA_OPT_WIFI_DP */
606*5113495bSYour Name 
htt_srng_setup(struct htt_soc * soc,int mac_id,hal_ring_handle_t hal_ring_hdl,int hal_ring_type)607*5113495bSYour Name int htt_srng_setup(struct htt_soc *soc, int mac_id,
608*5113495bSYour Name 		   hal_ring_handle_t hal_ring_hdl,
609*5113495bSYour Name 		   int hal_ring_type)
610*5113495bSYour Name {
611*5113495bSYour Name 	struct dp_htt_htc_pkt *pkt;
612*5113495bSYour Name 	qdf_nbuf_t htt_msg;
613*5113495bSYour Name 	uint32_t *msg_word;
614*5113495bSYour Name 	struct hal_srng_params srng_params;
615*5113495bSYour Name 	qdf_dma_addr_t hp_addr, tp_addr;
616*5113495bSYour Name 	uint32_t ring_entry_size =
617*5113495bSYour Name 		hal_srng_get_entrysize(soc->hal_soc, hal_ring_type);
618*5113495bSYour Name 	int htt_ring_type, htt_ring_id;
619*5113495bSYour Name 	uint8_t *htt_logger_bufp;
620*5113495bSYour Name 	int target_pdev_id;
621*5113495bSYour Name 	int lmac_id = dp_get_lmac_id_for_pdev_id(soc->dp_soc, 0, mac_id);
622*5113495bSYour Name 	QDF_STATUS status;
623*5113495bSYour Name 
624*5113495bSYour Name 	/* Sizes should be set in 4-byte words */
625*5113495bSYour Name 	ring_entry_size = ring_entry_size >> 2;
626*5113495bSYour Name 
627*5113495bSYour Name 	htt_msg = qdf_nbuf_alloc(soc->osdev,
628*5113495bSYour Name 		HTT_MSG_BUF_SIZE(HTT_SRING_SETUP_SZ),
629*5113495bSYour Name 		/* reserve room for the HTC header */
630*5113495bSYour Name 		HTC_HEADER_LEN + HTC_HDR_ALIGNMENT_PADDING, 4, TRUE);
631*5113495bSYour Name 	if (!htt_msg) {
632*5113495bSYour Name 		dp_err("htt_msg alloc failed ring type %d", hal_ring_type);
633*5113495bSYour Name 		goto fail0;
634*5113495bSYour Name 	}
635*5113495bSYour Name 
636*5113495bSYour Name 	hal_get_srng_params(soc->hal_soc, hal_ring_hdl, &srng_params);
637*5113495bSYour Name 	hp_addr = hal_srng_get_hp_addr(soc->hal_soc, hal_ring_hdl);
638*5113495bSYour Name 	tp_addr = hal_srng_get_tp_addr(soc->hal_soc, hal_ring_hdl);
639*5113495bSYour Name 
640*5113495bSYour Name 	switch (hal_ring_type) {
641*5113495bSYour Name 	case RXDMA_BUF:
642*5113495bSYour Name #ifdef QCA_HOST2FW_RXBUF_RING
643*5113495bSYour Name 		if (srng_params.ring_id ==
644*5113495bSYour Name 		    (HAL_SRNG_WMAC1_SW2RXDMA0_BUF0 +
645*5113495bSYour Name 		    (lmac_id * HAL_MAX_RINGS_PER_LMAC))) {
646*5113495bSYour Name 			htt_ring_id = HTT_HOST1_TO_FW_RXBUF_RING;
647*5113495bSYour Name 			htt_ring_type = HTT_SW_TO_SW_RING;
648*5113495bSYour Name #ifdef IPA_OFFLOAD
649*5113495bSYour Name 		} else if (srng_params.ring_id ==
650*5113495bSYour Name 		    (HAL_SRNG_WMAC1_SW2RXDMA0_BUF1 +
651*5113495bSYour Name 		    (lmac_id * HAL_MAX_RINGS_PER_LMAC))) {
652*5113495bSYour Name 			htt_ring_id = HTT_HOST2_TO_FW_RXBUF_RING;
653*5113495bSYour Name 			htt_ring_type = HTT_SW_TO_SW_RING;
654*5113495bSYour Name #ifdef IPA_WDI3_VLAN_SUPPORT
655*5113495bSYour Name 		} else if (srng_params.ring_id ==
656*5113495bSYour Name 		    (HAL_SRNG_WMAC1_SW2RXDMA0_BUF2 +
657*5113495bSYour Name 		    (lmac_id * HAL_MAX_RINGS_PER_LMAC))) {
658*5113495bSYour Name 			htt_ring_id = HTT_HOST3_TO_FW_RXBUF_RING;
659*5113495bSYour Name 			htt_ring_type = HTT_SW_TO_SW_RING;
660*5113495bSYour Name #endif
661*5113495bSYour Name #endif
662*5113495bSYour Name #else
663*5113495bSYour Name 		if (srng_params.ring_id ==
664*5113495bSYour Name 			(HAL_SRNG_WMAC1_SW2RXDMA0_BUF0 +
665*5113495bSYour Name 			(lmac_id * HAL_MAX_RINGS_PER_LMAC))) {
666*5113495bSYour Name 			htt_ring_id = HTT_RXDMA_HOST_BUF_RING;
667*5113495bSYour Name 			htt_ring_type = HTT_SW_TO_HW_RING;
668*5113495bSYour Name #endif
669*5113495bSYour Name 		} else if (srng_params.ring_id ==
670*5113495bSYour Name 			 (HAL_SRNG_WMAC1_SW2RXDMA1_BUF +
671*5113495bSYour Name 			(lmac_id * HAL_MAX_RINGS_PER_LMAC))) {
672*5113495bSYour Name 			htt_ring_id = HTT_RXDMA_HOST_BUF_RING;
673*5113495bSYour Name 			htt_ring_type = HTT_SW_TO_HW_RING;
674*5113495bSYour Name #ifdef FEATURE_DIRECT_LINK
675*5113495bSYour Name 		} else if (srng_params.ring_id ==
676*5113495bSYour Name 			   (HAL_SRNG_WMAC1_RX_DIRECT_LINK_SW_REFILL_RING +
677*5113495bSYour Name 			    (lmac_id * HAL_MAX_RINGS_PER_LMAC))) {
678*5113495bSYour Name 			htt_ring_id = HTT_LPASS_TO_FW_RXBUF_RING;
679*5113495bSYour Name 			htt_ring_type = HTT_SW_TO_SW_RING;
680*5113495bSYour Name #endif
681*5113495bSYour Name 		} else {
682*5113495bSYour Name 			QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
683*5113495bSYour Name 				   "%s: Ring %d currently not supported",
684*5113495bSYour Name 				   __func__, srng_params.ring_id);
685*5113495bSYour Name 			goto fail1;
686*5113495bSYour Name 		}
687*5113495bSYour Name 
688*5113495bSYour Name 		break;
689*5113495bSYour Name 	case RXDMA_MONITOR_BUF:
690*5113495bSYour Name 		htt_ring_id = dp_htt_get_mon_htt_ring_id(soc->dp_soc,
691*5113495bSYour Name 							 RXDMA_MONITOR_BUF);
692*5113495bSYour Name 		htt_ring_type = HTT_SW_TO_HW_RING;
693*5113495bSYour Name 		break;
694*5113495bSYour Name 	case RXDMA_MONITOR_STATUS:
695*5113495bSYour Name 		htt_ring_id = HTT_RXDMA_MONITOR_STATUS_RING;
696*5113495bSYour Name 		htt_ring_type = HTT_SW_TO_HW_RING;
697*5113495bSYour Name 		break;
698*5113495bSYour Name 	case RXDMA_MONITOR_DST:
699*5113495bSYour Name 		htt_ring_id = dp_htt_get_mon_htt_ring_id(soc->dp_soc,
700*5113495bSYour Name 							 RXDMA_MONITOR_DST);
701*5113495bSYour Name 		htt_ring_type = HTT_HW_TO_SW_RING;
702*5113495bSYour Name 		break;
703*5113495bSYour Name 	case RXDMA_MONITOR_DESC:
704*5113495bSYour Name 		htt_ring_id = HTT_RXDMA_MONITOR_DESC_RING;
705*5113495bSYour Name 		htt_ring_type = HTT_SW_TO_HW_RING;
706*5113495bSYour Name 		break;
707*5113495bSYour Name 	case RXDMA_DST:
708*5113495bSYour Name 		htt_ring_id = HTT_RXDMA_NON_MONITOR_DEST_RING;
709*5113495bSYour Name 		htt_ring_type = HTT_HW_TO_SW_RING;
710*5113495bSYour Name 		break;
711*5113495bSYour Name 	case TX_MONITOR_BUF:
712*5113495bSYour Name 		htt_ring_id = HTT_TX_MON_HOST2MON_BUF_RING;
713*5113495bSYour Name 		htt_ring_type = HTT_SW_TO_HW_RING;
714*5113495bSYour Name 		break;
715*5113495bSYour Name 	case TX_MONITOR_DST:
716*5113495bSYour Name 		htt_ring_id = HTT_TX_MON_MON2HOST_DEST_RING;
717*5113495bSYour Name 		htt_ring_type = HTT_HW_TO_SW_RING;
718*5113495bSYour Name 		break;
719*5113495bSYour Name 	case SW2RXDMA_LINK_RELEASE:
720*5113495bSYour Name 		htt_ring_id = HTT_RXDMA_MONITOR_DESC_RING;
721*5113495bSYour Name 		htt_ring_type = HTT_SW_TO_HW_RING;
722*5113495bSYour Name 		break;
723*5113495bSYour Name 
724*5113495bSYour Name 	default:
725*5113495bSYour Name 		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
726*5113495bSYour Name 			"%s: Ring currently not supported", __func__);
727*5113495bSYour Name 			goto fail1;
728*5113495bSYour Name 	}
729*5113495bSYour Name 
730*5113495bSYour Name 	dp_info("ring_type %d ring_id %d htt_ring_id %d hp_addr 0x%llx tp_addr 0x%llx",
731*5113495bSYour Name 		hal_ring_type, srng_params.ring_id, htt_ring_id,
732*5113495bSYour Name 		(uint64_t)hp_addr,
733*5113495bSYour Name 		(uint64_t)tp_addr);
734*5113495bSYour Name 	/*
735*5113495bSYour Name 	 * Set the length of the message.
736*5113495bSYour Name 	 * The contribution from the HTC_HDR_ALIGNMENT_PADDING is added
737*5113495bSYour Name 	 * separately during the below call to qdf_nbuf_push_head.
738*5113495bSYour Name 	 * The contribution from the HTC header is added separately inside HTC.
739*5113495bSYour Name 	 */
740*5113495bSYour Name 	if (qdf_nbuf_put_tail(htt_msg, HTT_SRING_SETUP_SZ) == NULL) {
741*5113495bSYour Name 		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
742*5113495bSYour Name 			"%s: Failed to expand head for SRING_SETUP msg",
743*5113495bSYour Name 			__func__);
744*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
745*5113495bSYour Name 	}
746*5113495bSYour Name 
747*5113495bSYour Name 	msg_word = (uint32_t *)qdf_nbuf_data(htt_msg);
748*5113495bSYour Name 
749*5113495bSYour Name 	/* rewind beyond alignment pad to get to the HTC header reserved area */
750*5113495bSYour Name 	qdf_nbuf_push_head(htt_msg, HTC_HDR_ALIGNMENT_PADDING);
751*5113495bSYour Name 
752*5113495bSYour Name 	/* word 0 */
753*5113495bSYour Name 	*msg_word = 0;
754*5113495bSYour Name 	htt_logger_bufp = (uint8_t *)msg_word;
755*5113495bSYour Name 	HTT_H2T_MSG_TYPE_SET(*msg_word, HTT_H2T_MSG_TYPE_SRING_SETUP);
756*5113495bSYour Name 	target_pdev_id =
757*5113495bSYour Name 	dp_get_target_pdev_id_for_host_pdev_id(soc->dp_soc, mac_id);
758*5113495bSYour Name 
759*5113495bSYour Name 	if ((htt_ring_type == HTT_SW_TO_HW_RING) ||
760*5113495bSYour Name 			(htt_ring_type == HTT_HW_TO_SW_RING))
761*5113495bSYour Name 		HTT_SRING_SETUP_PDEV_ID_SET(*msg_word, target_pdev_id);
762*5113495bSYour Name 	else
763*5113495bSYour Name 		HTT_SRING_SETUP_PDEV_ID_SET(*msg_word, mac_id);
764*5113495bSYour Name 
765*5113495bSYour Name 	dp_info("mac_id %d", mac_id);
766*5113495bSYour Name 	HTT_SRING_SETUP_RING_TYPE_SET(*msg_word, htt_ring_type);
767*5113495bSYour Name 	/* TODO: Discuss with FW on changing this to unique ID and using
768*5113495bSYour Name 	 * htt_ring_type to send the type of ring
769*5113495bSYour Name 	 */
770*5113495bSYour Name 	HTT_SRING_SETUP_RING_ID_SET(*msg_word, htt_ring_id);
771*5113495bSYour Name 
772*5113495bSYour Name 	/* word 1 */
773*5113495bSYour Name 	msg_word++;
774*5113495bSYour Name 	*msg_word = 0;
775*5113495bSYour Name 	HTT_SRING_SETUP_RING_BASE_ADDR_LO_SET(*msg_word,
776*5113495bSYour Name 		srng_params.ring_base_paddr & 0xffffffff);
777*5113495bSYour Name 
778*5113495bSYour Name 	/* word 2 */
779*5113495bSYour Name 	msg_word++;
780*5113495bSYour Name 	*msg_word = 0;
781*5113495bSYour Name 	HTT_SRING_SETUP_RING_BASE_ADDR_HI_SET(*msg_word,
782*5113495bSYour Name 		(uint64_t)srng_params.ring_base_paddr >> 32);
783*5113495bSYour Name 
784*5113495bSYour Name 	/* word 3 */
785*5113495bSYour Name 	msg_word++;
786*5113495bSYour Name 	*msg_word = 0;
787*5113495bSYour Name 	HTT_SRING_SETUP_ENTRY_SIZE_SET(*msg_word, ring_entry_size);
788*5113495bSYour Name 	HTT_SRING_SETUP_RING_SIZE_SET(*msg_word,
789*5113495bSYour Name 		(ring_entry_size * srng_params.num_entries));
790*5113495bSYour Name 	dp_info("entry_size %d", ring_entry_size);
791*5113495bSYour Name 	dp_info("num_entries %d", srng_params.num_entries);
792*5113495bSYour Name 	dp_info("ring_size %d", (ring_entry_size * srng_params.num_entries));
793*5113495bSYour Name 	if (htt_ring_type == HTT_SW_TO_HW_RING)
794*5113495bSYour Name 		HTT_SRING_SETUP_RING_MISC_CFG_FLAG_LOOPCOUNT_DISABLE_SET(
795*5113495bSYour Name 						*msg_word, 1);
796*5113495bSYour Name 	HTT_SRING_SETUP_RING_MISC_CFG_FLAG_MSI_SWAP_SET(*msg_word,
797*5113495bSYour Name 		!!(srng_params.flags & HAL_SRNG_MSI_SWAP));
798*5113495bSYour Name 	HTT_SRING_SETUP_RING_MISC_CFG_FLAG_TLV_SWAP_SET(*msg_word,
799*5113495bSYour Name 		!!(srng_params.flags & HAL_SRNG_DATA_TLV_SWAP));
800*5113495bSYour Name 	HTT_SRING_SETUP_RING_MISC_CFG_FLAG_HOST_FW_SWAP_SET(*msg_word,
801*5113495bSYour Name 		!!(srng_params.flags & HAL_SRNG_RING_PTR_SWAP));
802*5113495bSYour Name 
803*5113495bSYour Name 	/* word 4 */
804*5113495bSYour Name 	msg_word++;
805*5113495bSYour Name 	*msg_word = 0;
806*5113495bSYour Name 	HTT_SRING_SETUP_HEAD_OFFSET32_REMOTE_BASE_ADDR_LO_SET(*msg_word,
807*5113495bSYour Name 		hp_addr & 0xffffffff);
808*5113495bSYour Name 
809*5113495bSYour Name 	/* word 5 */
810*5113495bSYour Name 	msg_word++;
811*5113495bSYour Name 	*msg_word = 0;
812*5113495bSYour Name 	HTT_SRING_SETUP_HEAD_OFFSET32_REMOTE_BASE_ADDR_HI_SET(*msg_word,
813*5113495bSYour Name 		(uint64_t)hp_addr >> 32);
814*5113495bSYour Name 
815*5113495bSYour Name 	/* word 6 */
816*5113495bSYour Name 	msg_word++;
817*5113495bSYour Name 	*msg_word = 0;
818*5113495bSYour Name 	HTT_SRING_SETUP_TAIL_OFFSET32_REMOTE_BASE_ADDR_LO_SET(*msg_word,
819*5113495bSYour Name 		tp_addr & 0xffffffff);
820*5113495bSYour Name 
821*5113495bSYour Name 	/* word 7 */
822*5113495bSYour Name 	msg_word++;
823*5113495bSYour Name 	*msg_word = 0;
824*5113495bSYour Name 	HTT_SRING_SETUP_TAIL_OFFSET32_REMOTE_BASE_ADDR_HI_SET(*msg_word,
825*5113495bSYour Name 		(uint64_t)tp_addr >> 32);
826*5113495bSYour Name 
827*5113495bSYour Name 	/* word 8 */
828*5113495bSYour Name 	msg_word++;
829*5113495bSYour Name 	*msg_word = 0;
830*5113495bSYour Name 	HTT_SRING_SETUP_RING_MSI_ADDR_LO_SET(*msg_word,
831*5113495bSYour Name 		srng_params.msi_addr & 0xffffffff);
832*5113495bSYour Name 
833*5113495bSYour Name 	/* word 9 */
834*5113495bSYour Name 	msg_word++;
835*5113495bSYour Name 	*msg_word = 0;
836*5113495bSYour Name 	HTT_SRING_SETUP_RING_MSI_ADDR_HI_SET(*msg_word,
837*5113495bSYour Name 		(uint64_t)(srng_params.msi_addr) >> 32);
838*5113495bSYour Name 
839*5113495bSYour Name 	/* word 10 */
840*5113495bSYour Name 	msg_word++;
841*5113495bSYour Name 	*msg_word = 0;
842*5113495bSYour Name 	HTT_SRING_SETUP_RING_MSI_DATA_SET(*msg_word,
843*5113495bSYour Name 		qdf_cpu_to_le32(srng_params.msi_data));
844*5113495bSYour Name 
845*5113495bSYour Name 	/* word 11 */
846*5113495bSYour Name 	msg_word++;
847*5113495bSYour Name 	*msg_word = 0;
848*5113495bSYour Name 	HTT_SRING_SETUP_INTR_BATCH_COUNTER_TH_SET(*msg_word,
849*5113495bSYour Name 		srng_params.intr_batch_cntr_thres_entries *
850*5113495bSYour Name 		ring_entry_size);
851*5113495bSYour Name 	HTT_SRING_SETUP_INTR_TIMER_TH_SET(*msg_word,
852*5113495bSYour Name 		srng_params.intr_timer_thres_us >> 3);
853*5113495bSYour Name 
854*5113495bSYour Name 	/* word 12 */
855*5113495bSYour Name 	msg_word++;
856*5113495bSYour Name 	*msg_word = 0;
857*5113495bSYour Name 	if (srng_params.flags & HAL_SRNG_LOW_THRES_INTR_ENABLE) {
858*5113495bSYour Name 		/* TODO: Setting low threshold to 1/8th of ring size - see
859*5113495bSYour Name 		 * if this needs to be configurable
860*5113495bSYour Name 		 */
861*5113495bSYour Name 		HTT_SRING_SETUP_INTR_LOW_TH_SET(*msg_word,
862*5113495bSYour Name 			srng_params.low_threshold);
863*5113495bSYour Name 	}
864*5113495bSYour Name 	/* "response_required" field should be set if a HTT response message is
865*5113495bSYour Name 	 * required after setting up the ring.
866*5113495bSYour Name 	 */
867*5113495bSYour Name 	pkt = htt_htc_pkt_alloc(soc);
868*5113495bSYour Name 	if (!pkt) {
869*5113495bSYour Name 		dp_err("pkt alloc failed, ring_type %d ring_id %d htt_ring_id %d",
870*5113495bSYour Name 		       hal_ring_type, srng_params.ring_id, htt_ring_id);
871*5113495bSYour Name 		goto fail1;
872*5113495bSYour Name 	}
873*5113495bSYour Name 
874*5113495bSYour Name 	pkt->soc_ctxt = NULL; /* not used during send-done callback */
875*5113495bSYour Name 
876*5113495bSYour Name 	SET_HTC_PACKET_INFO_TX(
877*5113495bSYour Name 		&pkt->htc_pkt,
878*5113495bSYour Name 		dp_htt_h2t_send_complete_free_netbuf,
879*5113495bSYour Name 		qdf_nbuf_data(htt_msg),
880*5113495bSYour Name 		qdf_nbuf_len(htt_msg),
881*5113495bSYour Name 		soc->htc_endpoint,
882*5113495bSYour Name 		HTC_TX_PACKET_TAG_RUNTIME_PUT); /* tag for no FW response msg */
883*5113495bSYour Name 
884*5113495bSYour Name 	SET_HTC_PACKET_NET_BUF_CONTEXT(&pkt->htc_pkt, htt_msg);
885*5113495bSYour Name 	status = DP_HTT_SEND_HTC_PKT(soc, pkt, HTT_H2T_MSG_TYPE_SRING_SETUP,
886*5113495bSYour Name 				     htt_logger_bufp);
887*5113495bSYour Name 
888*5113495bSYour Name 	if (status != QDF_STATUS_SUCCESS) {
889*5113495bSYour Name 		qdf_nbuf_free(htt_msg);
890*5113495bSYour Name 		htt_htc_pkt_free(soc, pkt);
891*5113495bSYour Name 	}
892*5113495bSYour Name 
893*5113495bSYour Name 	return status;
894*5113495bSYour Name 
895*5113495bSYour Name fail1:
896*5113495bSYour Name 	qdf_nbuf_free(htt_msg);
897*5113495bSYour Name fail0:
898*5113495bSYour Name 	return QDF_STATUS_E_FAILURE;
899*5113495bSYour Name }
900*5113495bSYour Name 
901*5113495bSYour Name qdf_export_symbol(htt_srng_setup);
902*5113495bSYour Name 
903*5113495bSYour Name #ifdef QCA_SUPPORT_FULL_MON
904*5113495bSYour Name /**
905*5113495bSYour Name  * htt_h2t_full_mon_cfg() - Send full monitor configuration msg to FW
906*5113495bSYour Name  *
907*5113495bSYour Name  * @htt_soc: HTT Soc handle
908*5113495bSYour Name  * @pdev_id: Radio id
909*5113495bSYour Name  * @config: enabled/disable configuration
910*5113495bSYour Name  *
911*5113495bSYour Name  * Return: Success when HTT message is sent, error on failure
912*5113495bSYour Name  */
913*5113495bSYour Name int htt_h2t_full_mon_cfg(struct htt_soc *htt_soc,
914*5113495bSYour Name 			 uint8_t pdev_id,
915*5113495bSYour Name 			 enum dp_full_mon_config config)
916*5113495bSYour Name {
917*5113495bSYour Name 	struct htt_soc *soc = (struct htt_soc *)htt_soc;
918*5113495bSYour Name 	struct dp_htt_htc_pkt *pkt;
919*5113495bSYour Name 	qdf_nbuf_t htt_msg;
920*5113495bSYour Name 	uint32_t *msg_word;
921*5113495bSYour Name 	uint8_t *htt_logger_bufp;
922*5113495bSYour Name 	QDF_STATUS status;
923*5113495bSYour Name 
924*5113495bSYour Name 	htt_msg = qdf_nbuf_alloc(soc->osdev,
925*5113495bSYour Name 				 HTT_MSG_BUF_SIZE(
926*5113495bSYour Name 				 HTT_RX_FULL_MONITOR_MODE_SETUP_SZ),
927*5113495bSYour Name 				 /* reserve room for the HTC header */
928*5113495bSYour Name 				 HTC_HEADER_LEN + HTC_HDR_ALIGNMENT_PADDING,
929*5113495bSYour Name 				 4,
930*5113495bSYour Name 				 TRUE);
931*5113495bSYour Name 	if (!htt_msg)
932*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
933*5113495bSYour Name 
934*5113495bSYour Name 	/*
935*5113495bSYour Name 	 * Set the length of the message.
936*5113495bSYour Name 	 * The contribution from the HTC_HDR_ALIGNMENT_PADDING is added
937*5113495bSYour Name 	 * separately during the below call to qdf_nbuf_push_head.
938*5113495bSYour Name 	 * The contribution from the HTC header is added separately inside HTC.
939*5113495bSYour Name 	 */
940*5113495bSYour Name 	if (!qdf_nbuf_put_tail(htt_msg, HTT_RX_FULL_MONITOR_MODE_SETUP_SZ)) {
941*5113495bSYour Name 		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
942*5113495bSYour Name 			  "%s: Failed to expand head for RX Ring Cfg msg",
943*5113495bSYour Name 			  __func__);
944*5113495bSYour Name 		goto fail1;
945*5113495bSYour Name 	}
946*5113495bSYour Name 
947*5113495bSYour Name 	msg_word = (uint32_t *)qdf_nbuf_data(htt_msg);
948*5113495bSYour Name 
949*5113495bSYour Name 	/* rewind beyond alignment pad to get to the HTC header reserved area */
950*5113495bSYour Name 	qdf_nbuf_push_head(htt_msg, HTC_HDR_ALIGNMENT_PADDING);
951*5113495bSYour Name 
952*5113495bSYour Name 	/* word 0 */
953*5113495bSYour Name 	*msg_word = 0;
954*5113495bSYour Name 	htt_logger_bufp = (uint8_t *)msg_word;
955*5113495bSYour Name 	HTT_H2T_MSG_TYPE_SET(*msg_word, HTT_H2T_MSG_TYPE_RX_FULL_MONITOR_MODE);
956*5113495bSYour Name 	HTT_RX_FULL_MONITOR_MODE_OPERATION_PDEV_ID_SET(
957*5113495bSYour Name 			*msg_word, DP_SW2HW_MACID(pdev_id));
958*5113495bSYour Name 
959*5113495bSYour Name 	msg_word++;
960*5113495bSYour Name 	*msg_word = 0;
961*5113495bSYour Name 	/* word 1 */
962*5113495bSYour Name 	if (config == DP_FULL_MON_ENABLE) {
963*5113495bSYour Name 		HTT_RX_FULL_MONITOR_MODE_ENABLE_SET(*msg_word, true);
964*5113495bSYour Name 		HTT_RX_FULL_MONITOR_MODE_ZERO_MPDU_SET(*msg_word, true);
965*5113495bSYour Name 		HTT_RX_FULL_MONITOR_MODE_NON_ZERO_MPDU_SET(*msg_word, true);
966*5113495bSYour Name 		HTT_RX_FULL_MONITOR_MODE_RELEASE_RINGS_SET(*msg_word, 0x2);
967*5113495bSYour Name 	} else if (config == DP_FULL_MON_DISABLE) {
968*5113495bSYour Name 		/* As per MAC team's suggestion, While disabling full monitor
969*5113495bSYour Name 		 * mode, Set 'en' bit to true in full monitor mode register.
970*5113495bSYour Name 		 */
971*5113495bSYour Name 		HTT_RX_FULL_MONITOR_MODE_ENABLE_SET(*msg_word, true);
972*5113495bSYour Name 		HTT_RX_FULL_MONITOR_MODE_ZERO_MPDU_SET(*msg_word, false);
973*5113495bSYour Name 		HTT_RX_FULL_MONITOR_MODE_NON_ZERO_MPDU_SET(*msg_word, false);
974*5113495bSYour Name 		HTT_RX_FULL_MONITOR_MODE_RELEASE_RINGS_SET(*msg_word, 0x2);
975*5113495bSYour Name 	}
976*5113495bSYour Name 
977*5113495bSYour Name 	pkt = htt_htc_pkt_alloc(soc);
978*5113495bSYour Name 	if (!pkt) {
979*5113495bSYour Name 		qdf_err("HTC packet allocation failed");
980*5113495bSYour Name 		goto fail1;
981*5113495bSYour Name 	}
982*5113495bSYour Name 
983*5113495bSYour Name 	pkt->soc_ctxt = NULL; /* not used during send-done callback */
984*5113495bSYour Name 
985*5113495bSYour Name 	SET_HTC_PACKET_INFO_TX(
986*5113495bSYour Name 		&pkt->htc_pkt,
987*5113495bSYour Name 		dp_htt_h2t_send_complete_free_netbuf,
988*5113495bSYour Name 		qdf_nbuf_data(htt_msg),
989*5113495bSYour Name 		qdf_nbuf_len(htt_msg),
990*5113495bSYour Name 		soc->htc_endpoint,
991*5113495bSYour Name 		HTC_TX_PACKET_TAG_RUNTIME_PUT); /* tag for no FW response msg */
992*5113495bSYour Name 
993*5113495bSYour Name 	SET_HTC_PACKET_NET_BUF_CONTEXT(&pkt->htc_pkt, htt_msg);
994*5113495bSYour Name 	qdf_debug("config: %d", config);
995*5113495bSYour Name 	status = DP_HTT_SEND_HTC_PKT(soc, pkt,
996*5113495bSYour Name 				     HTT_H2T_MSG_TYPE_RX_FULL_MONITOR_MODE,
997*5113495bSYour Name 				     htt_logger_bufp);
998*5113495bSYour Name 
999*5113495bSYour Name 	if (status != QDF_STATUS_SUCCESS) {
1000*5113495bSYour Name 		qdf_nbuf_free(htt_msg);
1001*5113495bSYour Name 		htt_htc_pkt_free(soc, pkt);
1002*5113495bSYour Name 	}
1003*5113495bSYour Name 
1004*5113495bSYour Name 	return status;
1005*5113495bSYour Name fail1:
1006*5113495bSYour Name 	qdf_nbuf_free(htt_msg);
1007*5113495bSYour Name 	return QDF_STATUS_E_FAILURE;
1008*5113495bSYour Name }
1009*5113495bSYour Name 
1010*5113495bSYour Name qdf_export_symbol(htt_h2t_full_mon_cfg);
1011*5113495bSYour Name #else
1012*5113495bSYour Name int htt_h2t_full_mon_cfg(struct htt_soc *htt_soc,
1013*5113495bSYour Name 			 uint8_t pdev_id,
1014*5113495bSYour Name 			 enum dp_full_mon_config config)
1015*5113495bSYour Name {
1016*5113495bSYour Name 	return 0;
1017*5113495bSYour Name }
1018*5113495bSYour Name 
1019*5113495bSYour Name qdf_export_symbol(htt_h2t_full_mon_cfg);
1020*5113495bSYour Name #endif
1021*5113495bSYour Name 
1022*5113495bSYour Name #ifdef QCA_UNDECODED_METADATA_SUPPORT
1023*5113495bSYour Name static inline void
1024*5113495bSYour Name dp_mon_rx_enable_phy_errors(uint32_t *msg_word,
1025*5113495bSYour Name 			    struct htt_rx_ring_tlv_filter *htt_tlv_filter)
1026*5113495bSYour Name {
1027*5113495bSYour Name 	if (htt_tlv_filter->phy_err_filter_valid) {
1028*5113495bSYour Name 		HTT_RX_RING_SELECTION_CFG_FP_PHY_ERR_SET
1029*5113495bSYour Name 			(*msg_word, htt_tlv_filter->fp_phy_err);
1030*5113495bSYour Name 		HTT_RX_RING_SELECTION_CFG_FP_PHY_ERR_BUF_SRC_SET
1031*5113495bSYour Name 			(*msg_word, htt_tlv_filter->fp_phy_err_buf_src);
1032*5113495bSYour Name 		HTT_RX_RING_SELECTION_CFG_FP_PHY_ERR_BUF_DEST_SET
1033*5113495bSYour Name 			(*msg_word, htt_tlv_filter->fp_phy_err_buf_dest);
1034*5113495bSYour Name 
1035*5113495bSYour Name 		/* word 12*/
1036*5113495bSYour Name 		msg_word++;
1037*5113495bSYour Name 		*msg_word = 0;
1038*5113495bSYour Name 		HTT_RX_RING_SELECTION_CFG_PHY_ERR_MASK_SET
1039*5113495bSYour Name 			(*msg_word, htt_tlv_filter->phy_err_mask);
1040*5113495bSYour Name 
1041*5113495bSYour Name 		/* word 13*/
1042*5113495bSYour Name 		msg_word++;
1043*5113495bSYour Name 		*msg_word = 0;
1044*5113495bSYour Name 		HTT_RX_RING_SELECTION_CFG_PHY_ERR_MASK_CONT_SET
1045*5113495bSYour Name 			(*msg_word, htt_tlv_filter->phy_err_mask_cont);
1046*5113495bSYour Name 	}
1047*5113495bSYour Name }
1048*5113495bSYour Name #else
1049*5113495bSYour Name static inline void
1050*5113495bSYour Name dp_mon_rx_enable_phy_errors(uint32_t *msg_word,
1051*5113495bSYour Name 			    struct htt_rx_ring_tlv_filter *htt_tlv_filter)
1052*5113495bSYour Name {
1053*5113495bSYour Name }
1054*5113495bSYour Name #endif
1055*5113495bSYour Name 
1056*5113495bSYour Name int htt_h2t_rx_ring_cfg(struct htt_soc *htt_soc, int pdev_id,
1057*5113495bSYour Name 			hal_ring_handle_t hal_ring_hdl,
1058*5113495bSYour Name 			int hal_ring_type, int ring_buf_size,
1059*5113495bSYour Name 			struct htt_rx_ring_tlv_filter *htt_tlv_filter)
1060*5113495bSYour Name {
1061*5113495bSYour Name 	struct htt_soc *soc = (struct htt_soc *)htt_soc;
1062*5113495bSYour Name 	struct dp_htt_htc_pkt *pkt;
1063*5113495bSYour Name 	qdf_nbuf_t htt_msg;
1064*5113495bSYour Name 	uint32_t *msg_word;
1065*5113495bSYour Name 	uint32_t *msg_word_data;
1066*5113495bSYour Name 	struct hal_srng_params srng_params;
1067*5113495bSYour Name 	uint32_t htt_ring_type, htt_ring_id;
1068*5113495bSYour Name 	uint32_t tlv_filter;
1069*5113495bSYour Name 	uint8_t *htt_logger_bufp;
1070*5113495bSYour Name 	struct wlan_cfg_dp_soc_ctxt *wlan_cfg_ctx = soc->dp_soc->wlan_cfg_ctx;
1071*5113495bSYour Name 	uint32_t mon_drop_th = wlan_cfg_get_mon_drop_thresh(wlan_cfg_ctx);
1072*5113495bSYour Name 	int target_pdev_id;
1073*5113495bSYour Name 	QDF_STATUS status;
1074*5113495bSYour Name 
1075*5113495bSYour Name 	htt_msg = qdf_nbuf_alloc(soc->osdev,
1076*5113495bSYour Name 		HTT_MSG_BUF_SIZE(HTT_RX_RING_SELECTION_CFG_SZ),
1077*5113495bSYour Name 	/* reserve room for the HTC header */
1078*5113495bSYour Name 	HTC_HEADER_LEN + HTC_HDR_ALIGNMENT_PADDING, 4, TRUE);
1079*5113495bSYour Name 	if (!htt_msg) {
1080*5113495bSYour Name 		dp_err("htt_msg alloc failed ring type %d", hal_ring_type);
1081*5113495bSYour Name 		goto fail0;
1082*5113495bSYour Name 	}
1083*5113495bSYour Name 
1084*5113495bSYour Name 	hal_get_srng_params(soc->hal_soc, hal_ring_hdl, &srng_params);
1085*5113495bSYour Name 
1086*5113495bSYour Name 	switch (hal_ring_type) {
1087*5113495bSYour Name 	case RXDMA_BUF:
1088*5113495bSYour Name 		htt_ring_id = HTT_RXDMA_HOST_BUF_RING;
1089*5113495bSYour Name 		htt_ring_type = HTT_SW_TO_HW_RING;
1090*5113495bSYour Name 		break;
1091*5113495bSYour Name 	case RXDMA_MONITOR_BUF:
1092*5113495bSYour Name 		htt_ring_id = dp_htt_get_mon_htt_ring_id(soc->dp_soc,
1093*5113495bSYour Name 							 RXDMA_MONITOR_BUF);
1094*5113495bSYour Name 		htt_ring_type = HTT_SW_TO_HW_RING;
1095*5113495bSYour Name 		break;
1096*5113495bSYour Name 	case RXDMA_MONITOR_STATUS:
1097*5113495bSYour Name 		htt_ring_id = HTT_RXDMA_MONITOR_STATUS_RING;
1098*5113495bSYour Name 		htt_ring_type = HTT_SW_TO_HW_RING;
1099*5113495bSYour Name 		break;
1100*5113495bSYour Name 	case RXDMA_MONITOR_DST:
1101*5113495bSYour Name 		htt_ring_id = dp_htt_get_mon_htt_ring_id(soc->dp_soc,
1102*5113495bSYour Name 							 RXDMA_MONITOR_DST);
1103*5113495bSYour Name 		htt_ring_type = HTT_HW_TO_SW_RING;
1104*5113495bSYour Name 		break;
1105*5113495bSYour Name 	case RXDMA_MONITOR_DESC:
1106*5113495bSYour Name 		htt_ring_id = HTT_RXDMA_MONITOR_DESC_RING;
1107*5113495bSYour Name 		htt_ring_type = HTT_SW_TO_HW_RING;
1108*5113495bSYour Name 		break;
1109*5113495bSYour Name 	case RXDMA_DST:
1110*5113495bSYour Name 		htt_ring_id = HTT_RXDMA_NON_MONITOR_DEST_RING;
1111*5113495bSYour Name 		htt_ring_type = HTT_HW_TO_SW_RING;
1112*5113495bSYour Name 		break;
1113*5113495bSYour Name 
1114*5113495bSYour Name 	default:
1115*5113495bSYour Name 		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
1116*5113495bSYour Name 			"%s: Ring currently not supported", __func__);
1117*5113495bSYour Name 		goto fail1;
1118*5113495bSYour Name 	}
1119*5113495bSYour Name 
1120*5113495bSYour Name 	dp_info("ring_type %d ring_id %d htt_ring_id %d",
1121*5113495bSYour Name 		hal_ring_type, srng_params.ring_id, htt_ring_id);
1122*5113495bSYour Name 
1123*5113495bSYour Name 	/*
1124*5113495bSYour Name 	 * Set the length of the message.
1125*5113495bSYour Name 	 * The contribution from the HTC_HDR_ALIGNMENT_PADDING is added
1126*5113495bSYour Name 	 * separately during the below call to qdf_nbuf_push_head.
1127*5113495bSYour Name 	 * The contribution from the HTC header is added separately inside HTC.
1128*5113495bSYour Name 	 */
1129*5113495bSYour Name 	if (qdf_nbuf_put_tail(htt_msg, HTT_RX_RING_SELECTION_CFG_SZ) == NULL) {
1130*5113495bSYour Name 		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
1131*5113495bSYour Name 			"%s: Failed to expand head for RX Ring Cfg msg",
1132*5113495bSYour Name 			__func__);
1133*5113495bSYour Name 		goto fail1; /* failure */
1134*5113495bSYour Name 	}
1135*5113495bSYour Name 
1136*5113495bSYour Name 	msg_word = (uint32_t *)qdf_nbuf_data(htt_msg);
1137*5113495bSYour Name 
1138*5113495bSYour Name 	/* rewind beyond alignment pad to get to the HTC header reserved area */
1139*5113495bSYour Name 	qdf_nbuf_push_head(htt_msg, HTC_HDR_ALIGNMENT_PADDING);
1140*5113495bSYour Name 
1141*5113495bSYour Name 	/* word 0 */
1142*5113495bSYour Name 	htt_logger_bufp = (uint8_t *)msg_word;
1143*5113495bSYour Name 	*msg_word = 0;
1144*5113495bSYour Name 	HTT_H2T_MSG_TYPE_SET(*msg_word, HTT_H2T_MSG_TYPE_RX_RING_SELECTION_CFG);
1145*5113495bSYour Name 
1146*5113495bSYour Name 	/* applicable only for post Li */
1147*5113495bSYour Name 	dp_rx_mon_enable(soc->dp_soc, msg_word, htt_tlv_filter);
1148*5113495bSYour Name 
1149*5113495bSYour Name 	/*
1150*5113495bSYour Name 	 * pdev_id is indexed from 0 whereas mac_id is indexed from 1
1151*5113495bSYour Name 	 * SW_TO_SW and SW_TO_HW rings are unaffected by this
1152*5113495bSYour Name 	 */
1153*5113495bSYour Name 	target_pdev_id =
1154*5113495bSYour Name 	dp_get_target_pdev_id_for_host_pdev_id(soc->dp_soc, pdev_id);
1155*5113495bSYour Name 
1156*5113495bSYour Name 	if (htt_ring_type == HTT_SW_TO_SW_RING ||
1157*5113495bSYour Name 			htt_ring_type == HTT_SW_TO_HW_RING ||
1158*5113495bSYour Name 			htt_ring_type == HTT_HW_TO_SW_RING)
1159*5113495bSYour Name 		HTT_RX_RING_SELECTION_CFG_PDEV_ID_SET(*msg_word,
1160*5113495bSYour Name 						      target_pdev_id);
1161*5113495bSYour Name 
1162*5113495bSYour Name 	/* TODO: Discuss with FW on changing this to unique ID and using
1163*5113495bSYour Name 	 * htt_ring_type to send the type of ring
1164*5113495bSYour Name 	 */
1165*5113495bSYour Name 	HTT_RX_RING_SELECTION_CFG_RING_ID_SET(*msg_word, htt_ring_id);
1166*5113495bSYour Name 
1167*5113495bSYour Name 	HTT_RX_RING_SELECTION_CFG_STATUS_TLV_SET(*msg_word,
1168*5113495bSYour Name 		!!(srng_params.flags & HAL_SRNG_MSI_SWAP));
1169*5113495bSYour Name 
1170*5113495bSYour Name 	HTT_RX_RING_SELECTION_CFG_RX_OFFSETS_VALID_SET(*msg_word,
1171*5113495bSYour Name 						htt_tlv_filter->offset_valid);
1172*5113495bSYour Name 
1173*5113495bSYour Name 	if (mon_drop_th > 0)
1174*5113495bSYour Name 		HTT_RX_RING_SELECTION_CFG_DROP_THRESHOLD_VALID_SET(*msg_word,
1175*5113495bSYour Name 								   1);
1176*5113495bSYour Name 	else
1177*5113495bSYour Name 		HTT_RX_RING_SELECTION_CFG_DROP_THRESHOLD_VALID_SET(*msg_word,
1178*5113495bSYour Name 								   0);
1179*5113495bSYour Name 
1180*5113495bSYour Name 	/* word 1 */
1181*5113495bSYour Name 	msg_word++;
1182*5113495bSYour Name 	*msg_word = 0;
1183*5113495bSYour Name 	HTT_RX_RING_SELECTION_CFG_RING_BUFFER_SIZE_SET(*msg_word,
1184*5113495bSYour Name 		ring_buf_size);
1185*5113495bSYour Name 
1186*5113495bSYour Name 	dp_mon_rx_packet_length_set(soc->dp_soc, msg_word, htt_tlv_filter);
1187*5113495bSYour Name 	dp_mon_rx_hdr_length_set(soc->dp_soc, msg_word, htt_tlv_filter);
1188*5113495bSYour Name 	dp_mon_rx_mac_filter_set(soc->dp_soc, msg_word, htt_tlv_filter);
1189*5113495bSYour Name 
1190*5113495bSYour Name 	/* word 2 */
1191*5113495bSYour Name 	msg_word++;
1192*5113495bSYour Name 	*msg_word = 0;
1193*5113495bSYour Name 
1194*5113495bSYour Name 	if (htt_tlv_filter->enable_fp) {
1195*5113495bSYour Name 		/* TYPE: MGMT */
1196*5113495bSYour Name 		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG0,
1197*5113495bSYour Name 			FP, MGMT, 0000,
1198*5113495bSYour Name 			(htt_tlv_filter->fp_mgmt_filter &
1199*5113495bSYour Name 			FILTER_MGMT_ASSOC_REQ) ? 1 : 0);
1200*5113495bSYour Name 		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG0,
1201*5113495bSYour Name 			FP, MGMT, 0001,
1202*5113495bSYour Name 			(htt_tlv_filter->fp_mgmt_filter &
1203*5113495bSYour Name 			FILTER_MGMT_ASSOC_RES) ? 1 : 0);
1204*5113495bSYour Name 		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG0,
1205*5113495bSYour Name 			FP, MGMT, 0010,
1206*5113495bSYour Name 			(htt_tlv_filter->fp_mgmt_filter &
1207*5113495bSYour Name 			FILTER_MGMT_REASSOC_REQ) ? 1 : 0);
1208*5113495bSYour Name 		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG0,
1209*5113495bSYour Name 			FP, MGMT, 0011,
1210*5113495bSYour Name 			(htt_tlv_filter->fp_mgmt_filter &
1211*5113495bSYour Name 			FILTER_MGMT_REASSOC_RES) ? 1 : 0);
1212*5113495bSYour Name 		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG0,
1213*5113495bSYour Name 			FP, MGMT, 0100,
1214*5113495bSYour Name 			(htt_tlv_filter->fp_mgmt_filter &
1215*5113495bSYour Name 			FILTER_MGMT_PROBE_REQ) ? 1 : 0);
1216*5113495bSYour Name 		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG0,
1217*5113495bSYour Name 			FP, MGMT, 0101,
1218*5113495bSYour Name 			(htt_tlv_filter->fp_mgmt_filter &
1219*5113495bSYour Name 			FILTER_MGMT_PROBE_RES) ? 1 : 0);
1220*5113495bSYour Name 		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG0,
1221*5113495bSYour Name 			FP, MGMT, 0110,
1222*5113495bSYour Name 			(htt_tlv_filter->fp_mgmt_filter &
1223*5113495bSYour Name 			FILTER_MGMT_TIM_ADVT) ? 1 : 0);
1224*5113495bSYour Name 		/* reserved */
1225*5113495bSYour Name 		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG0, FP,
1226*5113495bSYour Name 			MGMT, 0111,
1227*5113495bSYour Name 			(htt_tlv_filter->fp_mgmt_filter &
1228*5113495bSYour Name 			FILTER_MGMT_RESERVED_7) ? 1 : 0);
1229*5113495bSYour Name 		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG0,
1230*5113495bSYour Name 			FP, MGMT, 1000,
1231*5113495bSYour Name 			(htt_tlv_filter->fp_mgmt_filter &
1232*5113495bSYour Name 			FILTER_MGMT_BEACON) ? 1 : 0);
1233*5113495bSYour Name 		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG0,
1234*5113495bSYour Name 			FP, MGMT, 1001,
1235*5113495bSYour Name 			(htt_tlv_filter->fp_mgmt_filter &
1236*5113495bSYour Name 			FILTER_MGMT_ATIM) ? 1 : 0);
1237*5113495bSYour Name 	}
1238*5113495bSYour Name 
1239*5113495bSYour Name 	if (htt_tlv_filter->enable_md) {
1240*5113495bSYour Name 			/* TYPE: MGMT */
1241*5113495bSYour Name 		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG0,
1242*5113495bSYour Name 			MD, MGMT, 0000,
1243*5113495bSYour Name 			(htt_tlv_filter->md_mgmt_filter &
1244*5113495bSYour Name 			FILTER_MGMT_ASSOC_REQ) ? 1 : 0);
1245*5113495bSYour Name 		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG0,
1246*5113495bSYour Name 			MD, MGMT, 0001,
1247*5113495bSYour Name 			(htt_tlv_filter->md_mgmt_filter &
1248*5113495bSYour Name 			FILTER_MGMT_ASSOC_RES) ? 1 : 0);
1249*5113495bSYour Name 		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG0,
1250*5113495bSYour Name 			MD, MGMT, 0010,
1251*5113495bSYour Name 			(htt_tlv_filter->md_mgmt_filter &
1252*5113495bSYour Name 			FILTER_MGMT_REASSOC_REQ) ? 1 : 0);
1253*5113495bSYour Name 		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG0,
1254*5113495bSYour Name 			MD, MGMT, 0011,
1255*5113495bSYour Name 			(htt_tlv_filter->md_mgmt_filter &
1256*5113495bSYour Name 			FILTER_MGMT_REASSOC_RES) ? 1 : 0);
1257*5113495bSYour Name 		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG0,
1258*5113495bSYour Name 			MD, MGMT, 0100,
1259*5113495bSYour Name 			(htt_tlv_filter->md_mgmt_filter &
1260*5113495bSYour Name 			FILTER_MGMT_PROBE_REQ) ? 1 : 0);
1261*5113495bSYour Name 		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG0,
1262*5113495bSYour Name 			MD, MGMT, 0101,
1263*5113495bSYour Name 			(htt_tlv_filter->md_mgmt_filter &
1264*5113495bSYour Name 			FILTER_MGMT_PROBE_RES) ? 1 : 0);
1265*5113495bSYour Name 		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG0,
1266*5113495bSYour Name 			MD, MGMT, 0110,
1267*5113495bSYour Name 			(htt_tlv_filter->md_mgmt_filter &
1268*5113495bSYour Name 			FILTER_MGMT_TIM_ADVT) ? 1 : 0);
1269*5113495bSYour Name 		/* reserved */
1270*5113495bSYour Name 		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG0, MD,
1271*5113495bSYour Name 			MGMT, 0111,
1272*5113495bSYour Name 			(htt_tlv_filter->md_mgmt_filter &
1273*5113495bSYour Name 			FILTER_MGMT_RESERVED_7) ? 1 : 0);
1274*5113495bSYour Name 		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG0,
1275*5113495bSYour Name 			MD, MGMT, 1000,
1276*5113495bSYour Name 			(htt_tlv_filter->md_mgmt_filter &
1277*5113495bSYour Name 			FILTER_MGMT_BEACON) ? 1 : 0);
1278*5113495bSYour Name 		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG0,
1279*5113495bSYour Name 			MD, MGMT, 1001,
1280*5113495bSYour Name 			(htt_tlv_filter->md_mgmt_filter &
1281*5113495bSYour Name 			FILTER_MGMT_ATIM) ? 1 : 0);
1282*5113495bSYour Name 	}
1283*5113495bSYour Name 
1284*5113495bSYour Name 	if (htt_tlv_filter->enable_mo) {
1285*5113495bSYour Name 		/* TYPE: MGMT */
1286*5113495bSYour Name 		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG0,
1287*5113495bSYour Name 			MO, MGMT, 0000,
1288*5113495bSYour Name 			(htt_tlv_filter->mo_mgmt_filter &
1289*5113495bSYour Name 			FILTER_MGMT_ASSOC_REQ) ? 1 : 0);
1290*5113495bSYour Name 		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG0,
1291*5113495bSYour Name 			MO, MGMT, 0001,
1292*5113495bSYour Name 			(htt_tlv_filter->mo_mgmt_filter &
1293*5113495bSYour Name 			FILTER_MGMT_ASSOC_RES) ? 1 : 0);
1294*5113495bSYour Name 		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG0,
1295*5113495bSYour Name 			MO, MGMT, 0010,
1296*5113495bSYour Name 			(htt_tlv_filter->mo_mgmt_filter &
1297*5113495bSYour Name 			FILTER_MGMT_REASSOC_REQ) ? 1 : 0);
1298*5113495bSYour Name 		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG0,
1299*5113495bSYour Name 			MO, MGMT, 0011,
1300*5113495bSYour Name 			(htt_tlv_filter->mo_mgmt_filter &
1301*5113495bSYour Name 			FILTER_MGMT_REASSOC_RES) ? 1 : 0);
1302*5113495bSYour Name 		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG0,
1303*5113495bSYour Name 			MO, MGMT, 0100,
1304*5113495bSYour Name 			(htt_tlv_filter->mo_mgmt_filter &
1305*5113495bSYour Name 			FILTER_MGMT_PROBE_REQ) ? 1 : 0);
1306*5113495bSYour Name 		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG0,
1307*5113495bSYour Name 			MO, MGMT, 0101,
1308*5113495bSYour Name 			(htt_tlv_filter->mo_mgmt_filter &
1309*5113495bSYour Name 			FILTER_MGMT_PROBE_RES) ? 1 : 0);
1310*5113495bSYour Name 		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG0,
1311*5113495bSYour Name 			MO, MGMT, 0110,
1312*5113495bSYour Name 			(htt_tlv_filter->mo_mgmt_filter &
1313*5113495bSYour Name 			FILTER_MGMT_TIM_ADVT) ? 1 : 0);
1314*5113495bSYour Name 		/* reserved */
1315*5113495bSYour Name 		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG0, MO,
1316*5113495bSYour Name 			MGMT, 0111,
1317*5113495bSYour Name 			(htt_tlv_filter->mo_mgmt_filter &
1318*5113495bSYour Name 			FILTER_MGMT_RESERVED_7) ? 1 : 0);
1319*5113495bSYour Name 		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG0,
1320*5113495bSYour Name 			MO, MGMT, 1000,
1321*5113495bSYour Name 			(htt_tlv_filter->mo_mgmt_filter &
1322*5113495bSYour Name 			FILTER_MGMT_BEACON) ? 1 : 0);
1323*5113495bSYour Name 		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG0,
1324*5113495bSYour Name 			MO, MGMT, 1001,
1325*5113495bSYour Name 			(htt_tlv_filter->mo_mgmt_filter &
1326*5113495bSYour Name 			FILTER_MGMT_ATIM) ? 1 : 0);
1327*5113495bSYour Name 	}
1328*5113495bSYour Name 
1329*5113495bSYour Name 	/* word 3 */
1330*5113495bSYour Name 	msg_word++;
1331*5113495bSYour Name 	*msg_word = 0;
1332*5113495bSYour Name 
1333*5113495bSYour Name 	if (htt_tlv_filter->enable_fp) {
1334*5113495bSYour Name 		/* TYPE: MGMT */
1335*5113495bSYour Name 		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG1,
1336*5113495bSYour Name 			FP, MGMT, 1010,
1337*5113495bSYour Name 			(htt_tlv_filter->fp_mgmt_filter &
1338*5113495bSYour Name 			FILTER_MGMT_DISASSOC) ? 1 : 0);
1339*5113495bSYour Name 		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG1,
1340*5113495bSYour Name 			FP, MGMT, 1011,
1341*5113495bSYour Name 			(htt_tlv_filter->fp_mgmt_filter &
1342*5113495bSYour Name 			FILTER_MGMT_AUTH) ? 1 : 0);
1343*5113495bSYour Name 		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG1,
1344*5113495bSYour Name 			FP, MGMT, 1100,
1345*5113495bSYour Name 			(htt_tlv_filter->fp_mgmt_filter &
1346*5113495bSYour Name 			FILTER_MGMT_DEAUTH) ? 1 : 0);
1347*5113495bSYour Name 		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG1,
1348*5113495bSYour Name 			FP, MGMT, 1101,
1349*5113495bSYour Name 			(htt_tlv_filter->fp_mgmt_filter &
1350*5113495bSYour Name 			FILTER_MGMT_ACTION) ? 1 : 0);
1351*5113495bSYour Name 		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG1,
1352*5113495bSYour Name 			FP, MGMT, 1110,
1353*5113495bSYour Name 			(htt_tlv_filter->fp_mgmt_filter &
1354*5113495bSYour Name 			FILTER_MGMT_ACT_NO_ACK) ? 1 : 0);
1355*5113495bSYour Name 		/* reserved*/
1356*5113495bSYour Name 		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG1, FP,
1357*5113495bSYour Name 			MGMT, 1111,
1358*5113495bSYour Name 			(htt_tlv_filter->fp_mgmt_filter &
1359*5113495bSYour Name 			FILTER_MGMT_RESERVED_15) ? 1 : 0);
1360*5113495bSYour Name 	}
1361*5113495bSYour Name 
1362*5113495bSYour Name 	if (htt_tlv_filter->enable_md) {
1363*5113495bSYour Name 			/* TYPE: MGMT */
1364*5113495bSYour Name 		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG1,
1365*5113495bSYour Name 			MD, MGMT, 1010,
1366*5113495bSYour Name 			(htt_tlv_filter->md_mgmt_filter &
1367*5113495bSYour Name 			FILTER_MGMT_DISASSOC) ? 1 : 0);
1368*5113495bSYour Name 		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG1,
1369*5113495bSYour Name 			MD, MGMT, 1011,
1370*5113495bSYour Name 			(htt_tlv_filter->md_mgmt_filter &
1371*5113495bSYour Name 			FILTER_MGMT_AUTH) ? 1 : 0);
1372*5113495bSYour Name 		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG1,
1373*5113495bSYour Name 			MD, MGMT, 1100,
1374*5113495bSYour Name 			(htt_tlv_filter->md_mgmt_filter &
1375*5113495bSYour Name 			FILTER_MGMT_DEAUTH) ? 1 : 0);
1376*5113495bSYour Name 		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG1,
1377*5113495bSYour Name 			MD, MGMT, 1101,
1378*5113495bSYour Name 			(htt_tlv_filter->md_mgmt_filter &
1379*5113495bSYour Name 			FILTER_MGMT_ACTION) ? 1 : 0);
1380*5113495bSYour Name 		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG1,
1381*5113495bSYour Name 			MD, MGMT, 1110,
1382*5113495bSYour Name 			(htt_tlv_filter->md_mgmt_filter &
1383*5113495bSYour Name 			FILTER_MGMT_ACT_NO_ACK) ? 1 : 0);
1384*5113495bSYour Name 	}
1385*5113495bSYour Name 
1386*5113495bSYour Name 	if (htt_tlv_filter->enable_mo) {
1387*5113495bSYour Name 		/* TYPE: MGMT */
1388*5113495bSYour Name 		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG1,
1389*5113495bSYour Name 			MO, MGMT, 1010,
1390*5113495bSYour Name 			(htt_tlv_filter->mo_mgmt_filter &
1391*5113495bSYour Name 			FILTER_MGMT_DISASSOC) ? 1 : 0);
1392*5113495bSYour Name 		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG1,
1393*5113495bSYour Name 			MO, MGMT, 1011,
1394*5113495bSYour Name 			(htt_tlv_filter->mo_mgmt_filter &
1395*5113495bSYour Name 			FILTER_MGMT_AUTH) ? 1 : 0);
1396*5113495bSYour Name 		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG1,
1397*5113495bSYour Name 			MO, MGMT, 1100,
1398*5113495bSYour Name 			(htt_tlv_filter->mo_mgmt_filter &
1399*5113495bSYour Name 			FILTER_MGMT_DEAUTH) ? 1 : 0);
1400*5113495bSYour Name 		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG1,
1401*5113495bSYour Name 			MO, MGMT, 1101,
1402*5113495bSYour Name 			(htt_tlv_filter->mo_mgmt_filter &
1403*5113495bSYour Name 			FILTER_MGMT_ACTION) ? 1 : 0);
1404*5113495bSYour Name 		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG1,
1405*5113495bSYour Name 			MO, MGMT, 1110,
1406*5113495bSYour Name 			(htt_tlv_filter->mo_mgmt_filter &
1407*5113495bSYour Name 			FILTER_MGMT_ACT_NO_ACK) ? 1 : 0);
1408*5113495bSYour Name 		/* reserved*/
1409*5113495bSYour Name 		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG1, MO,
1410*5113495bSYour Name 			MGMT, 1111,
1411*5113495bSYour Name 			(htt_tlv_filter->mo_mgmt_filter &
1412*5113495bSYour Name 			FILTER_MGMT_RESERVED_15) ? 1 : 0);
1413*5113495bSYour Name 	}
1414*5113495bSYour Name 
1415*5113495bSYour Name 	/* word 4 */
1416*5113495bSYour Name 	msg_word++;
1417*5113495bSYour Name 	*msg_word = 0;
1418*5113495bSYour Name 
1419*5113495bSYour Name 	if (htt_tlv_filter->enable_fp) {
1420*5113495bSYour Name 		/* TYPE: CTRL */
1421*5113495bSYour Name 		/* reserved */
1422*5113495bSYour Name 		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG2, FP,
1423*5113495bSYour Name 			CTRL, 0000,
1424*5113495bSYour Name 			(htt_tlv_filter->fp_ctrl_filter &
1425*5113495bSYour Name 			FILTER_CTRL_RESERVED_1) ? 1 : 0);
1426*5113495bSYour Name 		/* reserved */
1427*5113495bSYour Name 		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG2, FP,
1428*5113495bSYour Name 			CTRL, 0001,
1429*5113495bSYour Name 			(htt_tlv_filter->fp_ctrl_filter &
1430*5113495bSYour Name 			FILTER_CTRL_RESERVED_2) ? 1 : 0);
1431*5113495bSYour Name 		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG2, FP,
1432*5113495bSYour Name 			CTRL, 0010,
1433*5113495bSYour Name 			(htt_tlv_filter->fp_ctrl_filter &
1434*5113495bSYour Name 			FILTER_CTRL_TRIGGER) ? 1 : 0);
1435*5113495bSYour Name 		/* reserved */
1436*5113495bSYour Name 		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG2, FP,
1437*5113495bSYour Name 			CTRL, 0011,
1438*5113495bSYour Name 			(htt_tlv_filter->fp_ctrl_filter &
1439*5113495bSYour Name 			FILTER_CTRL_RESERVED_4) ? 1 : 0);
1440*5113495bSYour Name 		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG2, FP,
1441*5113495bSYour Name 			CTRL, 0100,
1442*5113495bSYour Name 			(htt_tlv_filter->fp_ctrl_filter &
1443*5113495bSYour Name 			FILTER_CTRL_BF_REP_POLL) ? 1 : 0);
1444*5113495bSYour Name 		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG2, FP,
1445*5113495bSYour Name 			CTRL, 0101,
1446*5113495bSYour Name 			(htt_tlv_filter->fp_ctrl_filter &
1447*5113495bSYour Name 			FILTER_CTRL_VHT_NDP) ? 1 : 0);
1448*5113495bSYour Name 		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG2, FP,
1449*5113495bSYour Name 			CTRL, 0110,
1450*5113495bSYour Name 			(htt_tlv_filter->fp_ctrl_filter &
1451*5113495bSYour Name 			FILTER_CTRL_FRAME_EXT) ? 1 : 0);
1452*5113495bSYour Name 		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG2, FP,
1453*5113495bSYour Name 			CTRL, 0111,
1454*5113495bSYour Name 			(htt_tlv_filter->fp_ctrl_filter &
1455*5113495bSYour Name 			FILTER_CTRL_CTRLWRAP) ? 1 : 0);
1456*5113495bSYour Name 		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG2, FP,
1457*5113495bSYour Name 			CTRL, 1000,
1458*5113495bSYour Name 			(htt_tlv_filter->fp_ctrl_filter &
1459*5113495bSYour Name 			FILTER_CTRL_BA_REQ) ? 1 : 0);
1460*5113495bSYour Name 		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG2, FP,
1461*5113495bSYour Name 			CTRL, 1001,
1462*5113495bSYour Name 			(htt_tlv_filter->fp_ctrl_filter &
1463*5113495bSYour Name 			FILTER_CTRL_BA) ? 1 : 0);
1464*5113495bSYour Name 	}
1465*5113495bSYour Name 
1466*5113495bSYour Name 	if (htt_tlv_filter->enable_md) {
1467*5113495bSYour Name 		/* TYPE: CTRL */
1468*5113495bSYour Name 		/* reserved */
1469*5113495bSYour Name 		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG2, MD,
1470*5113495bSYour Name 			CTRL, 0000,
1471*5113495bSYour Name 			(htt_tlv_filter->md_ctrl_filter &
1472*5113495bSYour Name 			FILTER_CTRL_RESERVED_1) ? 1 : 0);
1473*5113495bSYour Name 		/* reserved */
1474*5113495bSYour Name 		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG2, MD,
1475*5113495bSYour Name 			CTRL, 0001,
1476*5113495bSYour Name 			(htt_tlv_filter->md_ctrl_filter &
1477*5113495bSYour Name 			FILTER_CTRL_RESERVED_2) ? 1 : 0);
1478*5113495bSYour Name 		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG2, MD,
1479*5113495bSYour Name 			CTRL, 0010,
1480*5113495bSYour Name 			(htt_tlv_filter->md_ctrl_filter &
1481*5113495bSYour Name 			FILTER_CTRL_TRIGGER) ? 1 : 0);
1482*5113495bSYour Name 		/* reserved */
1483*5113495bSYour Name 		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG2, MD,
1484*5113495bSYour Name 			CTRL, 0011,
1485*5113495bSYour Name 			(htt_tlv_filter->md_ctrl_filter &
1486*5113495bSYour Name 			FILTER_CTRL_RESERVED_4) ? 1 : 0);
1487*5113495bSYour Name 		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG2, MD,
1488*5113495bSYour Name 			CTRL, 0100,
1489*5113495bSYour Name 			(htt_tlv_filter->md_ctrl_filter &
1490*5113495bSYour Name 			FILTER_CTRL_BF_REP_POLL) ? 1 : 0);
1491*5113495bSYour Name 		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG2, MD,
1492*5113495bSYour Name 			CTRL, 0101,
1493*5113495bSYour Name 			(htt_tlv_filter->md_ctrl_filter &
1494*5113495bSYour Name 			FILTER_CTRL_VHT_NDP) ? 1 : 0);
1495*5113495bSYour Name 		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG2, MD,
1496*5113495bSYour Name 			CTRL, 0110,
1497*5113495bSYour Name 			(htt_tlv_filter->md_ctrl_filter &
1498*5113495bSYour Name 			FILTER_CTRL_FRAME_EXT) ? 1 : 0);
1499*5113495bSYour Name 		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG2, MD,
1500*5113495bSYour Name 			CTRL, 0111,
1501*5113495bSYour Name 			(htt_tlv_filter->md_ctrl_filter &
1502*5113495bSYour Name 			FILTER_CTRL_CTRLWRAP) ? 1 : 0);
1503*5113495bSYour Name 		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG2, MD,
1504*5113495bSYour Name 			CTRL, 1000,
1505*5113495bSYour Name 			(htt_tlv_filter->md_ctrl_filter &
1506*5113495bSYour Name 			FILTER_CTRL_BA_REQ) ? 1 : 0);
1507*5113495bSYour Name 		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG2, MD,
1508*5113495bSYour Name 			CTRL, 1001,
1509*5113495bSYour Name 			(htt_tlv_filter->md_ctrl_filter &
1510*5113495bSYour Name 			FILTER_CTRL_BA) ? 1 : 0);
1511*5113495bSYour Name 	}
1512*5113495bSYour Name 
1513*5113495bSYour Name 	if (htt_tlv_filter->enable_mo) {
1514*5113495bSYour Name 		/* TYPE: CTRL */
1515*5113495bSYour Name 		/* reserved */
1516*5113495bSYour Name 		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG2, MO,
1517*5113495bSYour Name 			CTRL, 0000,
1518*5113495bSYour Name 			(htt_tlv_filter->mo_ctrl_filter &
1519*5113495bSYour Name 			FILTER_CTRL_RESERVED_1) ? 1 : 0);
1520*5113495bSYour Name 		/* reserved */
1521*5113495bSYour Name 		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG2, MO,
1522*5113495bSYour Name 			CTRL, 0001,
1523*5113495bSYour Name 			(htt_tlv_filter->mo_ctrl_filter &
1524*5113495bSYour Name 			FILTER_CTRL_RESERVED_2) ? 1 : 0);
1525*5113495bSYour Name 		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG2, MO,
1526*5113495bSYour Name 			CTRL, 0010,
1527*5113495bSYour Name 			(htt_tlv_filter->mo_ctrl_filter &
1528*5113495bSYour Name 			FILTER_CTRL_TRIGGER) ? 1 : 0);
1529*5113495bSYour Name 		/* reserved */
1530*5113495bSYour Name 		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG2, MO,
1531*5113495bSYour Name 			CTRL, 0011,
1532*5113495bSYour Name 			(htt_tlv_filter->mo_ctrl_filter &
1533*5113495bSYour Name 			FILTER_CTRL_RESERVED_4) ? 1 : 0);
1534*5113495bSYour Name 		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG2, MO,
1535*5113495bSYour Name 			CTRL, 0100,
1536*5113495bSYour Name 			(htt_tlv_filter->mo_ctrl_filter &
1537*5113495bSYour Name 			FILTER_CTRL_BF_REP_POLL) ? 1 : 0);
1538*5113495bSYour Name 		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG2, MO,
1539*5113495bSYour Name 			CTRL, 0101,
1540*5113495bSYour Name 			(htt_tlv_filter->mo_ctrl_filter &
1541*5113495bSYour Name 			FILTER_CTRL_VHT_NDP) ? 1 : 0);
1542*5113495bSYour Name 		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG2, MO,
1543*5113495bSYour Name 			CTRL, 0110,
1544*5113495bSYour Name 			(htt_tlv_filter->mo_ctrl_filter &
1545*5113495bSYour Name 			FILTER_CTRL_FRAME_EXT) ? 1 : 0);
1546*5113495bSYour Name 		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG2, MO,
1547*5113495bSYour Name 			CTRL, 0111,
1548*5113495bSYour Name 			(htt_tlv_filter->mo_ctrl_filter &
1549*5113495bSYour Name 			FILTER_CTRL_CTRLWRAP) ? 1 : 0);
1550*5113495bSYour Name 		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG2, MO,
1551*5113495bSYour Name 			CTRL, 1000,
1552*5113495bSYour Name 			(htt_tlv_filter->mo_ctrl_filter &
1553*5113495bSYour Name 			FILTER_CTRL_BA_REQ) ? 1 : 0);
1554*5113495bSYour Name 		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG2, MO,
1555*5113495bSYour Name 			CTRL, 1001,
1556*5113495bSYour Name 			(htt_tlv_filter->mo_ctrl_filter &
1557*5113495bSYour Name 			FILTER_CTRL_BA) ? 1 : 0);
1558*5113495bSYour Name 	}
1559*5113495bSYour Name 
1560*5113495bSYour Name 	/* word 5 */
1561*5113495bSYour Name 	msg_word++;
1562*5113495bSYour Name 	*msg_word = 0;
1563*5113495bSYour Name 	if (htt_tlv_filter->enable_fp) {
1564*5113495bSYour Name 		/* TYPE: CTRL */
1565*5113495bSYour Name 		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG3, FP,
1566*5113495bSYour Name 			CTRL, 1010,
1567*5113495bSYour Name 			(htt_tlv_filter->fp_ctrl_filter &
1568*5113495bSYour Name 			FILTER_CTRL_PSPOLL) ? 1 : 0);
1569*5113495bSYour Name 		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG3, FP,
1570*5113495bSYour Name 			CTRL, 1011,
1571*5113495bSYour Name 			(htt_tlv_filter->fp_ctrl_filter &
1572*5113495bSYour Name 			FILTER_CTRL_RTS) ? 1 : 0);
1573*5113495bSYour Name 		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG3, FP,
1574*5113495bSYour Name 			CTRL, 1100,
1575*5113495bSYour Name 			(htt_tlv_filter->fp_ctrl_filter &
1576*5113495bSYour Name 			FILTER_CTRL_CTS) ? 1 : 0);
1577*5113495bSYour Name 		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG3, FP,
1578*5113495bSYour Name 			CTRL, 1101,
1579*5113495bSYour Name 			(htt_tlv_filter->fp_ctrl_filter &
1580*5113495bSYour Name 			FILTER_CTRL_ACK) ? 1 : 0);
1581*5113495bSYour Name 		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG3, FP,
1582*5113495bSYour Name 			CTRL, 1110,
1583*5113495bSYour Name 			(htt_tlv_filter->fp_ctrl_filter &
1584*5113495bSYour Name 			FILTER_CTRL_CFEND) ? 1 : 0);
1585*5113495bSYour Name 		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG3, FP,
1586*5113495bSYour Name 			CTRL, 1111,
1587*5113495bSYour Name 			(htt_tlv_filter->fp_ctrl_filter &
1588*5113495bSYour Name 			FILTER_CTRL_CFEND_CFACK) ? 1 : 0);
1589*5113495bSYour Name 		/* TYPE: DATA */
1590*5113495bSYour Name 		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG3, FP,
1591*5113495bSYour Name 			DATA, MCAST,
1592*5113495bSYour Name 			(htt_tlv_filter->fp_data_filter &
1593*5113495bSYour Name 			FILTER_DATA_MCAST) ? 1 : 0);
1594*5113495bSYour Name 		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG3, FP,
1595*5113495bSYour Name 			DATA, UCAST,
1596*5113495bSYour Name 			(htt_tlv_filter->fp_data_filter &
1597*5113495bSYour Name 			FILTER_DATA_UCAST) ? 1 : 0);
1598*5113495bSYour Name 		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG3, FP,
1599*5113495bSYour Name 			DATA, NULL,
1600*5113495bSYour Name 			(htt_tlv_filter->fp_data_filter &
1601*5113495bSYour Name 			FILTER_DATA_NULL) ? 1 : 0);
1602*5113495bSYour Name 	}
1603*5113495bSYour Name 
1604*5113495bSYour Name 	if (htt_tlv_filter->enable_md) {
1605*5113495bSYour Name 		/* TYPE: CTRL */
1606*5113495bSYour Name 		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG3, MD,
1607*5113495bSYour Name 			CTRL, 1010,
1608*5113495bSYour Name 			(htt_tlv_filter->md_ctrl_filter &
1609*5113495bSYour Name 			FILTER_CTRL_PSPOLL) ? 1 : 0);
1610*5113495bSYour Name 		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG3, MD,
1611*5113495bSYour Name 			CTRL, 1011,
1612*5113495bSYour Name 			(htt_tlv_filter->md_ctrl_filter &
1613*5113495bSYour Name 			FILTER_CTRL_RTS) ? 1 : 0);
1614*5113495bSYour Name 		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG3, MD,
1615*5113495bSYour Name 			CTRL, 1100,
1616*5113495bSYour Name 			(htt_tlv_filter->md_ctrl_filter &
1617*5113495bSYour Name 			FILTER_CTRL_CTS) ? 1 : 0);
1618*5113495bSYour Name 		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG3, MD,
1619*5113495bSYour Name 			CTRL, 1101,
1620*5113495bSYour Name 			(htt_tlv_filter->md_ctrl_filter &
1621*5113495bSYour Name 			FILTER_CTRL_ACK) ? 1 : 0);
1622*5113495bSYour Name 		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG3, MD,
1623*5113495bSYour Name 			CTRL, 1110,
1624*5113495bSYour Name 			(htt_tlv_filter->md_ctrl_filter &
1625*5113495bSYour Name 			FILTER_CTRL_CFEND) ? 1 : 0);
1626*5113495bSYour Name 		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG3, MD,
1627*5113495bSYour Name 			CTRL, 1111,
1628*5113495bSYour Name 			(htt_tlv_filter->md_ctrl_filter &
1629*5113495bSYour Name 			FILTER_CTRL_CFEND_CFACK) ? 1 : 0);
1630*5113495bSYour Name 		/* TYPE: DATA */
1631*5113495bSYour Name 		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG3, MD,
1632*5113495bSYour Name 			DATA, MCAST,
1633*5113495bSYour Name 			(htt_tlv_filter->md_data_filter &
1634*5113495bSYour Name 			FILTER_DATA_MCAST) ? 1 : 0);
1635*5113495bSYour Name 		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG3, MD,
1636*5113495bSYour Name 			DATA, UCAST,
1637*5113495bSYour Name 			(htt_tlv_filter->md_data_filter &
1638*5113495bSYour Name 			FILTER_DATA_UCAST) ? 1 : 0);
1639*5113495bSYour Name 		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG3, MD,
1640*5113495bSYour Name 			DATA, NULL,
1641*5113495bSYour Name 			(htt_tlv_filter->md_data_filter &
1642*5113495bSYour Name 			FILTER_DATA_NULL) ? 1 : 0);
1643*5113495bSYour Name 	}
1644*5113495bSYour Name 
1645*5113495bSYour Name 	if (htt_tlv_filter->enable_mo) {
1646*5113495bSYour Name 		/* TYPE: CTRL */
1647*5113495bSYour Name 		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG3, MO,
1648*5113495bSYour Name 			CTRL, 1010,
1649*5113495bSYour Name 			(htt_tlv_filter->mo_ctrl_filter &
1650*5113495bSYour Name 			FILTER_CTRL_PSPOLL) ? 1 : 0);
1651*5113495bSYour Name 		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG3, MO,
1652*5113495bSYour Name 			CTRL, 1011,
1653*5113495bSYour Name 			(htt_tlv_filter->mo_ctrl_filter &
1654*5113495bSYour Name 			FILTER_CTRL_RTS) ? 1 : 0);
1655*5113495bSYour Name 		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG3, MO,
1656*5113495bSYour Name 			CTRL, 1100,
1657*5113495bSYour Name 			(htt_tlv_filter->mo_ctrl_filter &
1658*5113495bSYour Name 			FILTER_CTRL_CTS) ? 1 : 0);
1659*5113495bSYour Name 		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG3, MO,
1660*5113495bSYour Name 			CTRL, 1101,
1661*5113495bSYour Name 			(htt_tlv_filter->mo_ctrl_filter &
1662*5113495bSYour Name 			FILTER_CTRL_ACK) ? 1 : 0);
1663*5113495bSYour Name 		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG3, MO,
1664*5113495bSYour Name 			CTRL, 1110,
1665*5113495bSYour Name 			(htt_tlv_filter->mo_ctrl_filter &
1666*5113495bSYour Name 			FILTER_CTRL_CFEND) ? 1 : 0);
1667*5113495bSYour Name 		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG3, MO,
1668*5113495bSYour Name 			CTRL, 1111,
1669*5113495bSYour Name 			(htt_tlv_filter->mo_ctrl_filter &
1670*5113495bSYour Name 			FILTER_CTRL_CFEND_CFACK) ? 1 : 0);
1671*5113495bSYour Name 		/* TYPE: DATA */
1672*5113495bSYour Name 		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG3, MO,
1673*5113495bSYour Name 			DATA, MCAST,
1674*5113495bSYour Name 			(htt_tlv_filter->mo_data_filter &
1675*5113495bSYour Name 			FILTER_DATA_MCAST) ? 1 : 0);
1676*5113495bSYour Name 		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG3, MO,
1677*5113495bSYour Name 			DATA, UCAST,
1678*5113495bSYour Name 			(htt_tlv_filter->mo_data_filter &
1679*5113495bSYour Name 			FILTER_DATA_UCAST) ? 1 : 0);
1680*5113495bSYour Name 		htt_rx_ring_pkt_enable_subtype_set(*msg_word, FLAG3, MO,
1681*5113495bSYour Name 			DATA, NULL,
1682*5113495bSYour Name 			(htt_tlv_filter->mo_data_filter &
1683*5113495bSYour Name 			FILTER_DATA_NULL) ? 1 : 0);
1684*5113495bSYour Name 	}
1685*5113495bSYour Name 
1686*5113495bSYour Name 	/* word 6 */
1687*5113495bSYour Name 	msg_word++;
1688*5113495bSYour Name 	*msg_word = 0;
1689*5113495bSYour Name 	tlv_filter = 0;
1690*5113495bSYour Name 	htt_rx_ring_tlv_filter_in_enable_set(tlv_filter, MPDU_START,
1691*5113495bSYour Name 		htt_tlv_filter->mpdu_start);
1692*5113495bSYour Name 	htt_rx_ring_tlv_filter_in_enable_set(tlv_filter, MSDU_START,
1693*5113495bSYour Name 		htt_tlv_filter->msdu_start);
1694*5113495bSYour Name 	htt_rx_ring_tlv_filter_in_enable_set(tlv_filter, PACKET,
1695*5113495bSYour Name 		htt_tlv_filter->packet);
1696*5113495bSYour Name 	htt_rx_ring_tlv_filter_in_enable_set(tlv_filter, MSDU_END,
1697*5113495bSYour Name 		htt_tlv_filter->msdu_end);
1698*5113495bSYour Name 	htt_rx_ring_tlv_filter_in_enable_set(tlv_filter, MPDU_END,
1699*5113495bSYour Name 		htt_tlv_filter->mpdu_end);
1700*5113495bSYour Name 	htt_rx_ring_tlv_filter_in_enable_set(tlv_filter, PACKET_HEADER,
1701*5113495bSYour Name 		htt_tlv_filter->packet_header);
1702*5113495bSYour Name 	htt_rx_ring_tlv_filter_in_enable_set(tlv_filter, ATTENTION,
1703*5113495bSYour Name 		htt_tlv_filter->attention);
1704*5113495bSYour Name 	htt_rx_ring_tlv_filter_in_enable_set(tlv_filter, PPDU_START,
1705*5113495bSYour Name 		htt_tlv_filter->ppdu_start);
1706*5113495bSYour Name 	htt_rx_ring_tlv_filter_in_enable_set(tlv_filter, PPDU_END,
1707*5113495bSYour Name 		htt_tlv_filter->ppdu_end);
1708*5113495bSYour Name 	htt_rx_ring_tlv_filter_in_enable_set(tlv_filter, PPDU_END_USER_STATS,
1709*5113495bSYour Name 		htt_tlv_filter->ppdu_end_user_stats);
1710*5113495bSYour Name 	htt_rx_ring_tlv_filter_in_enable_set(tlv_filter,
1711*5113495bSYour Name 		PPDU_END_USER_STATS_EXT,
1712*5113495bSYour Name 		htt_tlv_filter->ppdu_end_user_stats_ext);
1713*5113495bSYour Name 	htt_rx_ring_tlv_filter_in_enable_set(tlv_filter, PPDU_END_STATUS_DONE,
1714*5113495bSYour Name 		htt_tlv_filter->ppdu_end_status_done);
1715*5113495bSYour Name 	htt_rx_ring_tlv_filter_in_enable_set(tlv_filter, PPDU_START_USER_INFO,
1716*5113495bSYour Name 		htt_tlv_filter->ppdu_start_user_info);
1717*5113495bSYour Name 	/* RESERVED bit maps to header_per_msdu in htt_tlv_filter*/
1718*5113495bSYour Name 	 htt_rx_ring_tlv_filter_in_enable_set(tlv_filter, RESERVED,
1719*5113495bSYour Name 		 htt_tlv_filter->header_per_msdu);
1720*5113495bSYour Name 
1721*5113495bSYour Name 	HTT_RX_RING_SELECTION_CFG_TLV_FILTER_IN_FLAG_SET(*msg_word, tlv_filter);
1722*5113495bSYour Name 
1723*5113495bSYour Name 	msg_word_data = (uint32_t *)qdf_nbuf_data(htt_msg);
1724*5113495bSYour Name 	dp_info("config_data: [0x%x][0x%x][0x%x][0x%x][0x%x][0x%x][0x%x]",
1725*5113495bSYour Name 		msg_word_data[0], msg_word_data[1], msg_word_data[2],
1726*5113495bSYour Name 		msg_word_data[3], msg_word_data[4], msg_word_data[5],
1727*5113495bSYour Name 		msg_word_data[6]);
1728*5113495bSYour Name 
1729*5113495bSYour Name 	/* word 7 */
1730*5113495bSYour Name 	msg_word++;
1731*5113495bSYour Name 	*msg_word = 0;
1732*5113495bSYour Name 	if (htt_tlv_filter->offset_valid) {
1733*5113495bSYour Name 		HTT_RX_RING_SELECTION_CFG_RX_PACKET_OFFSET_SET(*msg_word,
1734*5113495bSYour Name 					htt_tlv_filter->rx_packet_offset);
1735*5113495bSYour Name 		HTT_RX_RING_SELECTION_CFG_RX_HEADER_OFFSET_SET(*msg_word,
1736*5113495bSYour Name 					htt_tlv_filter->rx_header_offset);
1737*5113495bSYour Name 
1738*5113495bSYour Name 		/* word 8 */
1739*5113495bSYour Name 		msg_word++;
1740*5113495bSYour Name 		*msg_word = 0;
1741*5113495bSYour Name 		HTT_RX_RING_SELECTION_CFG_RX_MPDU_END_OFFSET_SET(*msg_word,
1742*5113495bSYour Name 					htt_tlv_filter->rx_mpdu_end_offset);
1743*5113495bSYour Name 		HTT_RX_RING_SELECTION_CFG_RX_MPDU_START_OFFSET_SET(*msg_word,
1744*5113495bSYour Name 					htt_tlv_filter->rx_mpdu_start_offset);
1745*5113495bSYour Name 
1746*5113495bSYour Name 		/* word 9 */
1747*5113495bSYour Name 		msg_word++;
1748*5113495bSYour Name 		*msg_word = 0;
1749*5113495bSYour Name 		HTT_RX_RING_SELECTION_CFG_RX_MSDU_END_OFFSET_SET(*msg_word,
1750*5113495bSYour Name 					htt_tlv_filter->rx_msdu_end_offset);
1751*5113495bSYour Name 		HTT_RX_RING_SELECTION_CFG_RX_MSDU_START_OFFSET_SET(*msg_word,
1752*5113495bSYour Name 					htt_tlv_filter->rx_msdu_start_offset);
1753*5113495bSYour Name 
1754*5113495bSYour Name 		/* word 10 */
1755*5113495bSYour Name 		msg_word++;
1756*5113495bSYour Name 		*msg_word = 0;
1757*5113495bSYour Name 		HTT_RX_RING_SELECTION_CFG_RX_ATTENTION_OFFSET_SET(*msg_word,
1758*5113495bSYour Name 					htt_tlv_filter->rx_attn_offset);
1759*5113495bSYour Name 
1760*5113495bSYour Name 		/* word 11 */
1761*5113495bSYour Name 		msg_word++;
1762*5113495bSYour Name 		*msg_word = 0;
1763*5113495bSYour Name 	} else {
1764*5113495bSYour Name 		/* word 11 */
1765*5113495bSYour Name 		msg_word += 4;
1766*5113495bSYour Name 		*msg_word = 0;
1767*5113495bSYour Name 	}
1768*5113495bSYour Name 
1769*5113495bSYour Name 	soc->dp_soc->arch_ops.dp_rx_word_mask_subscribe(
1770*5113495bSYour Name 						soc->dp_soc,
1771*5113495bSYour Name 						msg_word,
1772*5113495bSYour Name 						(void *)htt_tlv_filter);
1773*5113495bSYour Name 
1774*5113495bSYour Name 	dp_mon_rx_wmask_subscribe(soc->dp_soc, msg_word,
1775*5113495bSYour Name 				  pdev_id, htt_tlv_filter);
1776*5113495bSYour Name 
1777*5113495bSYour Name 	if (mon_drop_th > 0)
1778*5113495bSYour Name 		HTT_RX_RING_SELECTION_CFG_RX_DROP_THRESHOLD_SET(*msg_word,
1779*5113495bSYour Name 				mon_drop_th);
1780*5113495bSYour Name 
1781*5113495bSYour Name 	dp_mon_rx_enable_mpdu_logging(soc->dp_soc, msg_word, htt_tlv_filter);
1782*5113495bSYour Name 
1783*5113495bSYour Name 	dp_mon_rx_enable_phy_errors(msg_word, htt_tlv_filter);
1784*5113495bSYour Name 
1785*5113495bSYour Name 	/* word 14*/
1786*5113495bSYour Name 	msg_word += 3;
1787*5113495bSYour Name 
1788*5113495bSYour Name 	/* word 15*/
1789*5113495bSYour Name 	msg_word++;
1790*5113495bSYour Name 
1791*5113495bSYour Name 	/* word 16*/
1792*5113495bSYour Name 	msg_word++;
1793*5113495bSYour Name 	*msg_word = 0;
1794*5113495bSYour Name 
1795*5113495bSYour Name 	dp_mon_rx_enable_pkt_tlv_offset(soc->dp_soc, msg_word, htt_tlv_filter);
1796*5113495bSYour Name 
1797*5113495bSYour Name 	/* word 20 and 21*/
1798*5113495bSYour Name 	msg_word += 4;
1799*5113495bSYour Name 	*msg_word = 0;
1800*5113495bSYour Name 
1801*5113495bSYour Name 	dp_mon_rx_enable_fpmo(soc->dp_soc, msg_word, htt_tlv_filter);
1802*5113495bSYour Name 
1803*5113495bSYour Name 	/* "response_required" field should be set if a HTT response message is
1804*5113495bSYour Name 	 * required after setting up the ring.
1805*5113495bSYour Name 	 */
1806*5113495bSYour Name 	pkt = htt_htc_pkt_alloc(soc);
1807*5113495bSYour Name 	if (!pkt) {
1808*5113495bSYour Name 		dp_err("pkt alloc failed, ring_type %d ring_id %d htt_ring_id %d",
1809*5113495bSYour Name 		       hal_ring_type, srng_params.ring_id, htt_ring_id);
1810*5113495bSYour Name 		goto fail1;
1811*5113495bSYour Name 	}
1812*5113495bSYour Name 
1813*5113495bSYour Name 	pkt->soc_ctxt = NULL; /* not used during send-done callback */
1814*5113495bSYour Name 
1815*5113495bSYour Name 	SET_HTC_PACKET_INFO_TX(
1816*5113495bSYour Name 		&pkt->htc_pkt,
1817*5113495bSYour Name 		dp_htt_h2t_send_complete_free_netbuf,
1818*5113495bSYour Name 		qdf_nbuf_data(htt_msg),
1819*5113495bSYour Name 		qdf_nbuf_len(htt_msg),
1820*5113495bSYour Name 		soc->htc_endpoint,
1821*5113495bSYour Name 		HTC_TX_PACKET_TAG_RUNTIME_PUT); /* tag for no FW response msg */
1822*5113495bSYour Name 
1823*5113495bSYour Name 	SET_HTC_PACKET_NET_BUF_CONTEXT(&pkt->htc_pkt, htt_msg);
1824*5113495bSYour Name 	status = DP_HTT_SEND_HTC_PKT(soc, pkt,
1825*5113495bSYour Name 				     HTT_H2T_MSG_TYPE_RX_RING_SELECTION_CFG,
1826*5113495bSYour Name 				     htt_logger_bufp);
1827*5113495bSYour Name 
1828*5113495bSYour Name 	if (status != QDF_STATUS_SUCCESS) {
1829*5113495bSYour Name 		qdf_nbuf_free(htt_msg);
1830*5113495bSYour Name 		htt_htc_pkt_free(soc, pkt);
1831*5113495bSYour Name 	}
1832*5113495bSYour Name 
1833*5113495bSYour Name 	return status;
1834*5113495bSYour Name 
1835*5113495bSYour Name fail1:
1836*5113495bSYour Name 	qdf_nbuf_free(htt_msg);
1837*5113495bSYour Name fail0:
1838*5113495bSYour Name 	return QDF_STATUS_E_FAILURE;
1839*5113495bSYour Name }
1840*5113495bSYour Name 
1841*5113495bSYour Name qdf_export_symbol(htt_h2t_rx_ring_cfg);
1842*5113495bSYour Name 
1843*5113495bSYour Name #if defined(HTT_STATS_ENABLE)
1844*5113495bSYour Name static inline QDF_STATUS dp_send_htt_stat_resp(struct htt_stats_context *htt_stats,
1845*5113495bSYour Name 					struct dp_soc *soc, qdf_nbuf_t htt_msg)
1846*5113495bSYour Name 
1847*5113495bSYour Name {
1848*5113495bSYour Name 	uint32_t pdev_id;
1849*5113495bSYour Name 	uint32_t *msg_word = NULL;
1850*5113495bSYour Name 	uint32_t msg_remain_len = 0;
1851*5113495bSYour Name 
1852*5113495bSYour Name 	msg_word = (uint32_t *) qdf_nbuf_data(htt_msg);
1853*5113495bSYour Name 
1854*5113495bSYour Name 	/*COOKIE MSB*/
1855*5113495bSYour Name 	pdev_id = *(msg_word + 2) & HTT_PID_BIT_MASK;
1856*5113495bSYour Name 
1857*5113495bSYour Name 	/* stats message length + 16 size of HTT header*/
1858*5113495bSYour Name 	msg_remain_len = qdf_min(htt_stats->msg_len + 16,
1859*5113495bSYour Name 				(uint32_t)DP_EXT_MSG_LENGTH);
1860*5113495bSYour Name 
1861*5113495bSYour Name 	dp_wdi_event_handler(WDI_EVENT_HTT_STATS, soc,
1862*5113495bSYour Name 			msg_word,  msg_remain_len,
1863*5113495bSYour Name 			WDI_NO_VAL, pdev_id);
1864*5113495bSYour Name 
1865*5113495bSYour Name 	if (htt_stats->msg_len >= DP_EXT_MSG_LENGTH) {
1866*5113495bSYour Name 		htt_stats->msg_len -= DP_EXT_MSG_LENGTH;
1867*5113495bSYour Name 	}
1868*5113495bSYour Name 	/* Need to be freed here as WDI handler will
1869*5113495bSYour Name 	 * make a copy of pkt to send data to application
1870*5113495bSYour Name 	 */
1871*5113495bSYour Name 	qdf_nbuf_free(htt_msg);
1872*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
1873*5113495bSYour Name }
1874*5113495bSYour Name #else
1875*5113495bSYour Name static inline QDF_STATUS
1876*5113495bSYour Name dp_send_htt_stat_resp(struct htt_stats_context *htt_stats,
1877*5113495bSYour Name 		      struct dp_soc *soc, qdf_nbuf_t htt_msg)
1878*5113495bSYour Name {
1879*5113495bSYour Name 	return QDF_STATUS_E_NOSUPPORT;
1880*5113495bSYour Name }
1881*5113495bSYour Name #endif
1882*5113495bSYour Name 
1883*5113495bSYour Name #ifdef HTT_STATS_DEBUGFS_SUPPORT
1884*5113495bSYour Name /* dp_send_htt_stats_dbgfs_msg() - Function to send htt data to upper layer.
1885*5113495bSYour Name  * @pdev: dp pdev handle
1886*5113495bSYour Name  * @msg_word: HTT msg
1887*5113495bSYour Name  * @msg_len: Length of HTT msg sent
1888*5113495bSYour Name  *
1889*5113495bSYour Name  * Return: none
1890*5113495bSYour Name  */
1891*5113495bSYour Name static inline void
1892*5113495bSYour Name dp_htt_stats_dbgfs_send_msg(struct dp_pdev *pdev, uint32_t *msg_word,
1893*5113495bSYour Name 			    uint32_t msg_len)
1894*5113495bSYour Name {
1895*5113495bSYour Name 	struct htt_dbgfs_cfg dbgfs_cfg;
1896*5113495bSYour Name 	int done = 0;
1897*5113495bSYour Name 
1898*5113495bSYour Name 	/* send 5th word of HTT msg to upper layer */
1899*5113495bSYour Name 	dbgfs_cfg.msg_word = (msg_word + 4);
1900*5113495bSYour Name 	dbgfs_cfg.m = pdev->dbgfs_cfg->m;
1901*5113495bSYour Name 
1902*5113495bSYour Name 	/* stats message length + 16 size of HTT header*/
1903*5113495bSYour Name 	msg_len = qdf_min(msg_len + HTT_HEADER_LEN, (uint32_t)DP_EXT_MSG_LENGTH);
1904*5113495bSYour Name 
1905*5113495bSYour Name 	if (pdev->dbgfs_cfg->htt_stats_dbgfs_msg_process)
1906*5113495bSYour Name 		pdev->dbgfs_cfg->htt_stats_dbgfs_msg_process(&dbgfs_cfg,
1907*5113495bSYour Name 							     (msg_len - HTT_HEADER_LEN));
1908*5113495bSYour Name 
1909*5113495bSYour Name 	/* Get TLV Done bit from 4th msg word */
1910*5113495bSYour Name 	done = HTT_T2H_EXT_STATS_CONF_TLV_DONE_GET(*(msg_word + 3));
1911*5113495bSYour Name 	if (done) {
1912*5113495bSYour Name 		if (qdf_event_set(&pdev->dbgfs_cfg->htt_stats_dbgfs_event))
1913*5113495bSYour Name 			dp_htt_err("%pK: Failed to set event for debugfs htt stats"
1914*5113495bSYour Name 				   , pdev->soc);
1915*5113495bSYour Name 	}
1916*5113495bSYour Name }
1917*5113495bSYour Name #else
1918*5113495bSYour Name static inline void
1919*5113495bSYour Name dp_htt_stats_dbgfs_send_msg(struct dp_pdev *pdev, uint32_t *msg_word,
1920*5113495bSYour Name 			    uint32_t msg_len)
1921*5113495bSYour Name {
1922*5113495bSYour Name }
1923*5113495bSYour Name #endif /* HTT_STATS_DEBUGFS_SUPPORT */
1924*5113495bSYour Name 
1925*5113495bSYour Name #ifdef WLAN_SYSFS_DP_STATS
1926*5113495bSYour Name /* dp_htt_stats_sysfs_update_config() - Function to send htt data to upper layer.
1927*5113495bSYour Name  * @pdev: dp pdev handle
1928*5113495bSYour Name  *
1929*5113495bSYour Name  * This function sets the process id and printing mode within the sysfs config
1930*5113495bSYour Name  * struct. which enables DP_PRINT statements within this process to write to the
1931*5113495bSYour Name  * console buffer provided by the user space.
1932*5113495bSYour Name  *
1933*5113495bSYour Name  * Return: None
1934*5113495bSYour Name  */
1935*5113495bSYour Name static inline void
1936*5113495bSYour Name dp_htt_stats_sysfs_update_config(struct dp_pdev *pdev)
1937*5113495bSYour Name {
1938*5113495bSYour Name 	struct dp_soc *soc = pdev->soc;
1939*5113495bSYour Name 
1940*5113495bSYour Name 	if (!soc) {
1941*5113495bSYour Name 		dp_htt_err("soc is null");
1942*5113495bSYour Name 		return;
1943*5113495bSYour Name 	}
1944*5113495bSYour Name 
1945*5113495bSYour Name 	if (!soc->sysfs_config) {
1946*5113495bSYour Name 		dp_htt_err("soc->sysfs_config is NULL");
1947*5113495bSYour Name 		return;
1948*5113495bSYour Name 	}
1949*5113495bSYour Name 
1950*5113495bSYour Name 	/* set sysfs config parameters */
1951*5113495bSYour Name 	soc->sysfs_config->process_id = qdf_get_current_pid();
1952*5113495bSYour Name 	soc->sysfs_config->printing_mode = PRINTING_MODE_ENABLED;
1953*5113495bSYour Name }
1954*5113495bSYour Name 
1955*5113495bSYour Name /**
1956*5113495bSYour Name  * dp_htt_stats_sysfs_set_event() - Set sysfs stats event.
1957*5113495bSYour Name  * @soc: soc handle.
1958*5113495bSYour Name  * @msg_word: Pointer to htt msg word.
1959*5113495bSYour Name  *
1960*5113495bSYour Name  * Return: void
1961*5113495bSYour Name  */
1962*5113495bSYour Name static inline void
1963*5113495bSYour Name dp_htt_stats_sysfs_set_event(struct dp_soc *soc, uint32_t *msg_word)
1964*5113495bSYour Name {
1965*5113495bSYour Name 	int done = 0;
1966*5113495bSYour Name 
1967*5113495bSYour Name 	done = HTT_T2H_EXT_STATS_CONF_TLV_DONE_GET(*(msg_word + 3));
1968*5113495bSYour Name 	if (done) {
1969*5113495bSYour Name 		if (qdf_event_set(&soc->sysfs_config->sysfs_txrx_fw_request_done))
1970*5113495bSYour Name 			dp_htt_err("%pK:event compl Fail to set event ",
1971*5113495bSYour Name 				   soc);
1972*5113495bSYour Name 	}
1973*5113495bSYour Name }
1974*5113495bSYour Name #else /* WLAN_SYSFS_DP_STATS */
1975*5113495bSYour Name static inline void
1976*5113495bSYour Name dp_htt_stats_sysfs_update_config(struct dp_pdev *pdev)
1977*5113495bSYour Name {
1978*5113495bSYour Name }
1979*5113495bSYour Name 
1980*5113495bSYour Name static inline void
1981*5113495bSYour Name dp_htt_stats_sysfs_set_event(struct dp_soc *dp_soc, uint32_t *msg_word)
1982*5113495bSYour Name {
1983*5113495bSYour Name }
1984*5113495bSYour Name #endif /* WLAN_SYSFS_DP_STATS */
1985*5113495bSYour Name 
1986*5113495bSYour Name /* dp_htt_set_pdev_obss_stats() - Function to set pdev obss stats.
1987*5113495bSYour Name  * @pdev: dp pdev handle
1988*5113495bSYour Name  * @tag_type: HTT TLV tag type
1989*5113495bSYour Name  * @tag_buf: TLV buffer pointer
1990*5113495bSYour Name  *
1991*5113495bSYour Name  * Return: None
1992*5113495bSYour Name  */
1993*5113495bSYour Name static inline void
1994*5113495bSYour Name dp_htt_set_pdev_obss_stats(struct dp_pdev *pdev, uint32_t tag_type,
1995*5113495bSYour Name 			   uint32_t *tag_buf)
1996*5113495bSYour Name {
1997*5113495bSYour Name 	if (tag_type != HTT_STATS_PDEV_OBSS_PD_TAG) {
1998*5113495bSYour Name 		dp_err("Tag mismatch");
1999*5113495bSYour Name 		return;
2000*5113495bSYour Name 	}
2001*5113495bSYour Name 	qdf_mem_copy(&pdev->stats.htt_tx_pdev_stats.obss_pd_stats_tlv,
2002*5113495bSYour Name 		     tag_buf, sizeof(struct cdp_pdev_obss_pd_stats_tlv));
2003*5113495bSYour Name 	qdf_event_set(&pdev->fw_obss_stats_event);
2004*5113495bSYour Name }
2005*5113495bSYour Name 
2006*5113495bSYour Name /**
2007*5113495bSYour Name  * dp_process_htt_stat_msg(): Process the list of buffers of HTT EXT stats
2008*5113495bSYour Name  * @htt_stats: htt stats info
2009*5113495bSYour Name  * @soc: dp_soc
2010*5113495bSYour Name  *
2011*5113495bSYour Name  * The FW sends the HTT EXT STATS as a stream of T2H messages. Each T2H message
2012*5113495bSYour Name  * contains sub messages which are identified by a TLV header.
2013*5113495bSYour Name  * In this function we will process the stream of T2H messages and read all the
2014*5113495bSYour Name  * TLV contained in the message.
2015*5113495bSYour Name  *
2016*5113495bSYour Name  * The following cases have been taken care of
2017*5113495bSYour Name  * Case 1: When the tlv_remain_length <= msg_remain_length of HTT MSG buffer
2018*5113495bSYour Name  *		In this case the buffer will contain multiple tlvs.
2019*5113495bSYour Name  * Case 2: When the tlv_remain_length > msg_remain_length of HTT MSG buffer.
2020*5113495bSYour Name  *		Only one tlv will be contained in the HTT message and this tag
2021*5113495bSYour Name  *		will extend onto the next buffer.
2022*5113495bSYour Name  * Case 3: When the buffer is the continuation of the previous message
2023*5113495bSYour Name  * Case 4: tlv length is 0. which will indicate the end of message
2024*5113495bSYour Name  *
2025*5113495bSYour Name  * Return: void
2026*5113495bSYour Name  */
2027*5113495bSYour Name static inline void dp_process_htt_stat_msg(struct htt_stats_context *htt_stats,
2028*5113495bSYour Name 					struct dp_soc *soc)
2029*5113495bSYour Name {
2030*5113495bSYour Name 	htt_tlv_tag_t tlv_type = 0xff;
2031*5113495bSYour Name 	qdf_nbuf_t htt_msg = NULL;
2032*5113495bSYour Name 	uint32_t *msg_word;
2033*5113495bSYour Name 	uint8_t *tlv_buf_head = NULL;
2034*5113495bSYour Name 	uint8_t *tlv_buf_tail = NULL;
2035*5113495bSYour Name 	uint32_t msg_remain_len = 0;
2036*5113495bSYour Name 	uint32_t tlv_remain_len = 0;
2037*5113495bSYour Name 	uint32_t *tlv_start;
2038*5113495bSYour Name 	int cookie_val = 0;
2039*5113495bSYour Name 	int cookie_msb = 0;
2040*5113495bSYour Name 	int pdev_id;
2041*5113495bSYour Name 	bool copy_stats = false;
2042*5113495bSYour Name 	struct dp_pdev *pdev;
2043*5113495bSYour Name 
2044*5113495bSYour Name 	/* Process node in the HTT message queue */
2045*5113495bSYour Name 	while ((htt_msg = qdf_nbuf_queue_remove(&htt_stats->msg))
2046*5113495bSYour Name 		!= NULL) {
2047*5113495bSYour Name 		msg_word = (uint32_t *) qdf_nbuf_data(htt_msg);
2048*5113495bSYour Name 		cookie_val = *(msg_word + 1);
2049*5113495bSYour Name 		htt_stats->msg_len = HTT_T2H_EXT_STATS_CONF_TLV_LENGTH_GET(
2050*5113495bSYour Name 					*(msg_word +
2051*5113495bSYour Name 					HTT_T2H_EXT_STATS_TLV_START_OFFSET));
2052*5113495bSYour Name 
2053*5113495bSYour Name 		if (cookie_val) {
2054*5113495bSYour Name 			if (dp_send_htt_stat_resp(htt_stats, soc, htt_msg)
2055*5113495bSYour Name 					== QDF_STATUS_SUCCESS) {
2056*5113495bSYour Name 				continue;
2057*5113495bSYour Name 			}
2058*5113495bSYour Name 		}
2059*5113495bSYour Name 
2060*5113495bSYour Name 		cookie_msb = *(msg_word + 2);
2061*5113495bSYour Name 		pdev_id = *(msg_word + 2) & HTT_PID_BIT_MASK;
2062*5113495bSYour Name 		pdev = soc->pdev_list[pdev_id];
2063*5113495bSYour Name 
2064*5113495bSYour Name 		if (!cookie_val && (cookie_msb & DBG_STATS_COOKIE_HTT_DBGFS)) {
2065*5113495bSYour Name 			dp_htt_stats_dbgfs_send_msg(pdev, msg_word,
2066*5113495bSYour Name 						    htt_stats->msg_len);
2067*5113495bSYour Name 			qdf_nbuf_free(htt_msg);
2068*5113495bSYour Name 			continue;
2069*5113495bSYour Name 		}
2070*5113495bSYour Name 
2071*5113495bSYour Name 		if (!cookie_val && (cookie_msb & DBG_SYSFS_STATS_COOKIE))
2072*5113495bSYour Name 			dp_htt_stats_sysfs_update_config(pdev);
2073*5113495bSYour Name 
2074*5113495bSYour Name 		if (cookie_msb & DBG_STATS_COOKIE_DP_STATS)
2075*5113495bSYour Name 			copy_stats = true;
2076*5113495bSYour Name 
2077*5113495bSYour Name 		/* read 5th word */
2078*5113495bSYour Name 		msg_word = msg_word + 4;
2079*5113495bSYour Name 		msg_remain_len = qdf_min(htt_stats->msg_len,
2080*5113495bSYour Name 				(uint32_t) DP_EXT_MSG_LENGTH);
2081*5113495bSYour Name 		/* Keep processing the node till node length is 0 */
2082*5113495bSYour Name 		while (msg_remain_len) {
2083*5113495bSYour Name 			/*
2084*5113495bSYour Name 			 * if message is not a continuation of previous message
2085*5113495bSYour Name 			 * read the tlv type and tlv length
2086*5113495bSYour Name 			 */
2087*5113495bSYour Name 			if (!tlv_buf_head) {
2088*5113495bSYour Name 				tlv_type = HTT_STATS_TLV_TAG_GET(
2089*5113495bSYour Name 						*msg_word);
2090*5113495bSYour Name 				tlv_remain_len = HTT_STATS_TLV_LENGTH_GET(
2091*5113495bSYour Name 						*msg_word);
2092*5113495bSYour Name 			}
2093*5113495bSYour Name 
2094*5113495bSYour Name 			if (tlv_remain_len == 0) {
2095*5113495bSYour Name 				msg_remain_len = 0;
2096*5113495bSYour Name 
2097*5113495bSYour Name 				if (tlv_buf_head) {
2098*5113495bSYour Name 					qdf_mem_free(tlv_buf_head);
2099*5113495bSYour Name 					tlv_buf_head = NULL;
2100*5113495bSYour Name 					tlv_buf_tail = NULL;
2101*5113495bSYour Name 				}
2102*5113495bSYour Name 
2103*5113495bSYour Name 				goto error;
2104*5113495bSYour Name 			}
2105*5113495bSYour Name 
2106*5113495bSYour Name 			if (!tlv_buf_head)
2107*5113495bSYour Name 				tlv_remain_len += HTT_TLV_HDR_LEN;
2108*5113495bSYour Name 
2109*5113495bSYour Name 			if ((tlv_remain_len <= msg_remain_len)) {
2110*5113495bSYour Name 				/* Case 3 */
2111*5113495bSYour Name 				if (tlv_buf_head) {
2112*5113495bSYour Name 					qdf_mem_copy(tlv_buf_tail,
2113*5113495bSYour Name 							(uint8_t *)msg_word,
2114*5113495bSYour Name 							tlv_remain_len);
2115*5113495bSYour Name 					tlv_start = (uint32_t *)tlv_buf_head;
2116*5113495bSYour Name 				} else {
2117*5113495bSYour Name 					/* Case 1 */
2118*5113495bSYour Name 					tlv_start = msg_word;
2119*5113495bSYour Name 				}
2120*5113495bSYour Name 
2121*5113495bSYour Name 				if (copy_stats)
2122*5113495bSYour Name 					dp_htt_stats_copy_tag(pdev,
2123*5113495bSYour Name 							      tlv_type,
2124*5113495bSYour Name 							      tlv_start);
2125*5113495bSYour Name 				else
2126*5113495bSYour Name 					dp_htt_stats_print_tag(pdev,
2127*5113495bSYour Name 							       tlv_type,
2128*5113495bSYour Name 							       tlv_start);
2129*5113495bSYour Name 
2130*5113495bSYour Name 				if (tlv_type == HTT_STATS_PEER_DETAILS_TAG ||
2131*5113495bSYour Name 				    tlv_type == HTT_STATS_PEER_STATS_CMN_TAG)
2132*5113495bSYour Name 					dp_peer_update_inactive_time(pdev,
2133*5113495bSYour Name 								     tlv_type,
2134*5113495bSYour Name 								     tlv_start);
2135*5113495bSYour Name 
2136*5113495bSYour Name 				if (cookie_msb & DBG_STATS_COOKIE_HTT_OBSS)
2137*5113495bSYour Name 					dp_htt_set_pdev_obss_stats(pdev,
2138*5113495bSYour Name 								   tlv_type,
2139*5113495bSYour Name 								   tlv_start);
2140*5113495bSYour Name 
2141*5113495bSYour Name 				msg_remain_len -= tlv_remain_len;
2142*5113495bSYour Name 
2143*5113495bSYour Name 				msg_word = (uint32_t *)
2144*5113495bSYour Name 					(((uint8_t *)msg_word) +
2145*5113495bSYour Name 					tlv_remain_len);
2146*5113495bSYour Name 
2147*5113495bSYour Name 				tlv_remain_len = 0;
2148*5113495bSYour Name 
2149*5113495bSYour Name 				if (tlv_buf_head) {
2150*5113495bSYour Name 					qdf_mem_free(tlv_buf_head);
2151*5113495bSYour Name 					tlv_buf_head = NULL;
2152*5113495bSYour Name 					tlv_buf_tail = NULL;
2153*5113495bSYour Name 				}
2154*5113495bSYour Name 
2155*5113495bSYour Name 			} else { /* tlv_remain_len > msg_remain_len */
2156*5113495bSYour Name 				/* Case 2 & 3 */
2157*5113495bSYour Name 				if (!tlv_buf_head) {
2158*5113495bSYour Name 					tlv_buf_head = qdf_mem_malloc(
2159*5113495bSYour Name 							tlv_remain_len);
2160*5113495bSYour Name 
2161*5113495bSYour Name 					if (!tlv_buf_head) {
2162*5113495bSYour Name 						QDF_TRACE(QDF_MODULE_ID_TXRX,
2163*5113495bSYour Name 								QDF_TRACE_LEVEL_ERROR,
2164*5113495bSYour Name 								"Alloc failed");
2165*5113495bSYour Name 						goto error;
2166*5113495bSYour Name 					}
2167*5113495bSYour Name 
2168*5113495bSYour Name 					tlv_buf_tail = tlv_buf_head;
2169*5113495bSYour Name 				}
2170*5113495bSYour Name 
2171*5113495bSYour Name 				qdf_mem_copy(tlv_buf_tail, (uint8_t *)msg_word,
2172*5113495bSYour Name 						msg_remain_len);
2173*5113495bSYour Name 				tlv_remain_len -= msg_remain_len;
2174*5113495bSYour Name 				tlv_buf_tail += msg_remain_len;
2175*5113495bSYour Name 			}
2176*5113495bSYour Name 		}
2177*5113495bSYour Name 
2178*5113495bSYour Name 		if (htt_stats->msg_len >= DP_EXT_MSG_LENGTH) {
2179*5113495bSYour Name 			htt_stats->msg_len -= DP_EXT_MSG_LENGTH;
2180*5113495bSYour Name 		}
2181*5113495bSYour Name 
2182*5113495bSYour Name 		/* indicate event completion in case the event is done */
2183*5113495bSYour Name 		if (!cookie_val && (cookie_msb & DBG_SYSFS_STATS_COOKIE))
2184*5113495bSYour Name 			dp_htt_stats_sysfs_set_event(soc, msg_word);
2185*5113495bSYour Name 
2186*5113495bSYour Name 		qdf_nbuf_free(htt_msg);
2187*5113495bSYour Name 	}
2188*5113495bSYour Name 	return;
2189*5113495bSYour Name 
2190*5113495bSYour Name error:
2191*5113495bSYour Name 	qdf_nbuf_free(htt_msg);
2192*5113495bSYour Name 	while ((htt_msg = qdf_nbuf_queue_remove(&htt_stats->msg))
2193*5113495bSYour Name 			!= NULL)
2194*5113495bSYour Name 		qdf_nbuf_free(htt_msg);
2195*5113495bSYour Name }
2196*5113495bSYour Name 
2197*5113495bSYour Name void htt_t2h_stats_handler(void *context)
2198*5113495bSYour Name {
2199*5113495bSYour Name 	struct dp_soc *soc = (struct dp_soc *)context;
2200*5113495bSYour Name 	struct htt_stats_context htt_stats;
2201*5113495bSYour Name 	uint32_t *msg_word;
2202*5113495bSYour Name 	qdf_nbuf_t htt_msg = NULL;
2203*5113495bSYour Name 	uint8_t done;
2204*5113495bSYour Name 	uint32_t rem_stats;
2205*5113495bSYour Name 
2206*5113495bSYour Name 	if (!soc) {
2207*5113495bSYour Name 		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
2208*5113495bSYour Name 			  "soc is NULL");
2209*5113495bSYour Name 		return;
2210*5113495bSYour Name 	}
2211*5113495bSYour Name 
2212*5113495bSYour Name 	if (!qdf_atomic_read(&soc->cmn_init_done)) {
2213*5113495bSYour Name 		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
2214*5113495bSYour Name 			  "soc: 0x%pK, init_done: %d", soc,
2215*5113495bSYour Name 			  qdf_atomic_read(&soc->cmn_init_done));
2216*5113495bSYour Name 		return;
2217*5113495bSYour Name 	}
2218*5113495bSYour Name 
2219*5113495bSYour Name 	qdf_mem_zero(&htt_stats, sizeof(htt_stats));
2220*5113495bSYour Name 	qdf_nbuf_queue_init(&htt_stats.msg);
2221*5113495bSYour Name 
2222*5113495bSYour Name 	/* pull one completed stats from soc->htt_stats_msg and process */
2223*5113495bSYour Name 	qdf_spin_lock_bh(&soc->htt_stats.lock);
2224*5113495bSYour Name 	if (!soc->htt_stats.num_stats) {
2225*5113495bSYour Name 		qdf_spin_unlock_bh(&soc->htt_stats.lock);
2226*5113495bSYour Name 		return;
2227*5113495bSYour Name 	}
2228*5113495bSYour Name 	while ((htt_msg = qdf_nbuf_queue_remove(&soc->htt_stats.msg)) != NULL) {
2229*5113495bSYour Name 		msg_word = (uint32_t *) qdf_nbuf_data(htt_msg);
2230*5113495bSYour Name 		msg_word = msg_word + HTT_T2H_EXT_STATS_TLV_START_OFFSET;
2231*5113495bSYour Name 		done = HTT_T2H_EXT_STATS_CONF_TLV_DONE_GET(*msg_word);
2232*5113495bSYour Name 		qdf_nbuf_queue_add(&htt_stats.msg, htt_msg);
2233*5113495bSYour Name 		/*
2234*5113495bSYour Name 		 * Done bit signifies that this is the last T2H buffer in the
2235*5113495bSYour Name 		 * stream of HTT EXT STATS message
2236*5113495bSYour Name 		 */
2237*5113495bSYour Name 		if (done)
2238*5113495bSYour Name 			break;
2239*5113495bSYour Name 	}
2240*5113495bSYour Name 	rem_stats = --soc->htt_stats.num_stats;
2241*5113495bSYour Name 	qdf_spin_unlock_bh(&soc->htt_stats.lock);
2242*5113495bSYour Name 
2243*5113495bSYour Name 	/* If there are more stats to process, schedule stats work again.
2244*5113495bSYour Name 	 * Scheduling prior to processing ht_stats to queue with early
2245*5113495bSYour Name 	 * index
2246*5113495bSYour Name 	 */
2247*5113495bSYour Name 	if (rem_stats)
2248*5113495bSYour Name 		qdf_sched_work(0, &soc->htt_stats.work);
2249*5113495bSYour Name 
2250*5113495bSYour Name 	dp_process_htt_stat_msg(&htt_stats, soc);
2251*5113495bSYour Name }
2252*5113495bSYour Name 
2253*5113495bSYour Name /**
2254*5113495bSYour Name  * dp_txrx_fw_stats_handler() - Function to process HTT EXT stats
2255*5113495bSYour Name  * @soc: DP SOC handle
2256*5113495bSYour Name  * @htt_t2h_msg: HTT message nbuf
2257*5113495bSYour Name  *
2258*5113495bSYour Name  * return:void
2259*5113495bSYour Name  */
2260*5113495bSYour Name static inline void dp_txrx_fw_stats_handler(struct dp_soc *soc,
2261*5113495bSYour Name 					    qdf_nbuf_t htt_t2h_msg)
2262*5113495bSYour Name {
2263*5113495bSYour Name 	uint8_t done;
2264*5113495bSYour Name 	qdf_nbuf_t msg_copy;
2265*5113495bSYour Name 	uint32_t *msg_word;
2266*5113495bSYour Name 
2267*5113495bSYour Name 	msg_word = (uint32_t *)qdf_nbuf_data(htt_t2h_msg);
2268*5113495bSYour Name 	msg_word = msg_word + 3;
2269*5113495bSYour Name 	done = HTT_T2H_EXT_STATS_CONF_TLV_DONE_GET(*msg_word);
2270*5113495bSYour Name 
2271*5113495bSYour Name 	/*
2272*5113495bSYour Name 	 * HTT EXT stats response comes as stream of TLVs which span over
2273*5113495bSYour Name 	 * multiple T2H messages.
2274*5113495bSYour Name 	 * The first message will carry length of the response.
2275*5113495bSYour Name 	 * For rest of the messages length will be zero.
2276*5113495bSYour Name 	 *
2277*5113495bSYour Name 	 * Clone the T2H message buffer and store it in a list to process
2278*5113495bSYour Name 	 * it later.
2279*5113495bSYour Name 	 *
2280*5113495bSYour Name 	 * The original T2H message buffers gets freed in the T2H HTT event
2281*5113495bSYour Name 	 * handler
2282*5113495bSYour Name 	 */
2283*5113495bSYour Name 	msg_copy = qdf_nbuf_clone(htt_t2h_msg);
2284*5113495bSYour Name 
2285*5113495bSYour Name 	if (!msg_copy) {
2286*5113495bSYour Name 		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_INFO,
2287*5113495bSYour Name 			  "T2H message clone failed for HTT EXT STATS");
2288*5113495bSYour Name 		goto error;
2289*5113495bSYour Name 	}
2290*5113495bSYour Name 
2291*5113495bSYour Name 	qdf_spin_lock_bh(&soc->htt_stats.lock);
2292*5113495bSYour Name 	qdf_nbuf_queue_add(&soc->htt_stats.msg, msg_copy);
2293*5113495bSYour Name 	/*
2294*5113495bSYour Name 	 * Done bit signifies that this is the last T2H buffer in the stream of
2295*5113495bSYour Name 	 * HTT EXT STATS message
2296*5113495bSYour Name 	 */
2297*5113495bSYour Name 	if (done) {
2298*5113495bSYour Name 		soc->htt_stats.num_stats++;
2299*5113495bSYour Name 		qdf_sched_work(0, &soc->htt_stats.work);
2300*5113495bSYour Name 	}
2301*5113495bSYour Name 	qdf_spin_unlock_bh(&soc->htt_stats.lock);
2302*5113495bSYour Name 
2303*5113495bSYour Name 	return;
2304*5113495bSYour Name 
2305*5113495bSYour Name error:
2306*5113495bSYour Name 	qdf_spin_lock_bh(&soc->htt_stats.lock);
2307*5113495bSYour Name 	while ((msg_copy = qdf_nbuf_queue_remove(&soc->htt_stats.msg))
2308*5113495bSYour Name 			!= NULL) {
2309*5113495bSYour Name 		qdf_nbuf_free(msg_copy);
2310*5113495bSYour Name 	}
2311*5113495bSYour Name 	soc->htt_stats.num_stats = 0;
2312*5113495bSYour Name 	qdf_spin_unlock_bh(&soc->htt_stats.lock);
2313*5113495bSYour Name 	return;
2314*5113495bSYour Name }
2315*5113495bSYour Name 
2316*5113495bSYour Name int htt_soc_attach_target(struct htt_soc *htt_soc)
2317*5113495bSYour Name {
2318*5113495bSYour Name 	struct htt_soc *soc = (struct htt_soc *)htt_soc;
2319*5113495bSYour Name 
2320*5113495bSYour Name 	return htt_h2t_ver_req_msg(soc);
2321*5113495bSYour Name }
2322*5113495bSYour Name 
2323*5113495bSYour Name void htt_set_htc_handle(struct htt_soc *htt_soc, HTC_HANDLE htc_soc)
2324*5113495bSYour Name {
2325*5113495bSYour Name 	htt_soc->htc_soc = htc_soc;
2326*5113495bSYour Name }
2327*5113495bSYour Name 
2328*5113495bSYour Name HTC_HANDLE htt_get_htc_handle(struct htt_soc *htt_soc)
2329*5113495bSYour Name {
2330*5113495bSYour Name 	return htt_soc->htc_soc;
2331*5113495bSYour Name }
2332*5113495bSYour Name 
2333*5113495bSYour Name struct htt_soc *htt_soc_attach(struct dp_soc *soc, HTC_HANDLE htc_handle)
2334*5113495bSYour Name {
2335*5113495bSYour Name 	int i;
2336*5113495bSYour Name 	int j;
2337*5113495bSYour Name 	int umac_alloc_size = HTT_SW_UMAC_RING_IDX_MAX *
2338*5113495bSYour Name 			      sizeof(struct bp_handler);
2339*5113495bSYour Name 	int lmac_alloc_size = HTT_SW_LMAC_RING_IDX_MAX *
2340*5113495bSYour Name 			      sizeof(struct bp_handler);
2341*5113495bSYour Name 	struct htt_soc *htt_soc = NULL;
2342*5113495bSYour Name 
2343*5113495bSYour Name 	htt_soc = qdf_mem_malloc(sizeof(*htt_soc));
2344*5113495bSYour Name 	if (!htt_soc) {
2345*5113495bSYour Name 		dp_err("HTT attach failed");
2346*5113495bSYour Name 		return NULL;
2347*5113495bSYour Name 	}
2348*5113495bSYour Name 
2349*5113495bSYour Name 	for (i = 0; i < MAX_PDEV_CNT; i++) {
2350*5113495bSYour Name 		htt_soc->pdevid_tt[i].umac_path =
2351*5113495bSYour Name 			qdf_mem_malloc(umac_alloc_size);
2352*5113495bSYour Name 		if (!htt_soc->pdevid_tt[i].umac_path)
2353*5113495bSYour Name 			break;
2354*5113495bSYour Name 		for (j = 0; j < HTT_SW_UMAC_RING_IDX_MAX; j++)
2355*5113495bSYour Name 			htt_soc->pdevid_tt[i].umac_path[j].bp_start_tt = -1;
2356*5113495bSYour Name 		htt_soc->pdevid_tt[i].lmac_path =
2357*5113495bSYour Name 			qdf_mem_malloc(lmac_alloc_size);
2358*5113495bSYour Name 		if (!htt_soc->pdevid_tt[i].lmac_path) {
2359*5113495bSYour Name 			qdf_mem_free(htt_soc->pdevid_tt[i].umac_path);
2360*5113495bSYour Name 			break;
2361*5113495bSYour Name 		}
2362*5113495bSYour Name 		for (j = 0; j < HTT_SW_LMAC_RING_IDX_MAX ; j++)
2363*5113495bSYour Name 			htt_soc->pdevid_tt[i].lmac_path[j].bp_start_tt = -1;
2364*5113495bSYour Name 	}
2365*5113495bSYour Name 
2366*5113495bSYour Name 	if (i != MAX_PDEV_CNT) {
2367*5113495bSYour Name 		for (j = 0; j < i; j++) {
2368*5113495bSYour Name 			qdf_mem_free(htt_soc->pdevid_tt[j].umac_path);
2369*5113495bSYour Name 			qdf_mem_free(htt_soc->pdevid_tt[j].lmac_path);
2370*5113495bSYour Name 		}
2371*5113495bSYour Name 		qdf_mem_free(htt_soc);
2372*5113495bSYour Name 		return NULL;
2373*5113495bSYour Name 	}
2374*5113495bSYour Name 
2375*5113495bSYour Name 	htt_soc->dp_soc = soc;
2376*5113495bSYour Name 	htt_soc->htc_soc = htc_handle;
2377*5113495bSYour Name 	HTT_TX_MUTEX_INIT(&htt_soc->htt_tx_mutex);
2378*5113495bSYour Name 
2379*5113495bSYour Name 	return htt_soc;
2380*5113495bSYour Name }
2381*5113495bSYour Name 
2382*5113495bSYour Name #if defined(WDI_EVENT_ENABLE) && \
2383*5113495bSYour Name 	!defined(REMOVE_PKT_LOG)
2384*5113495bSYour Name /**
2385*5113495bSYour Name  * dp_pktlog_msg_handler() - Pktlog msg handler
2386*5113495bSYour Name  * @soc:	 HTT SOC handle
2387*5113495bSYour Name  * @msg_word:    Pointer to payload
2388*5113495bSYour Name  *
2389*5113495bSYour Name  * Return: None
2390*5113495bSYour Name  */
2391*5113495bSYour Name static void
2392*5113495bSYour Name dp_pktlog_msg_handler(struct htt_soc *soc,
2393*5113495bSYour Name 		      uint32_t *msg_word)
2394*5113495bSYour Name {
2395*5113495bSYour Name 	uint8_t pdev_id;
2396*5113495bSYour Name 	uint8_t target_pdev_id;
2397*5113495bSYour Name 	uint32_t *pl_hdr;
2398*5113495bSYour Name 
2399*5113495bSYour Name 	target_pdev_id = HTT_T2H_PKTLOG_PDEV_ID_GET(*msg_word);
2400*5113495bSYour Name 	pdev_id = dp_get_host_pdev_id_for_target_pdev_id(soc->dp_soc,
2401*5113495bSYour Name 							 target_pdev_id);
2402*5113495bSYour Name 	pl_hdr = (msg_word + 1);
2403*5113495bSYour Name 	dp_wdi_event_handler(WDI_EVENT_OFFLOAD_ALL, soc->dp_soc,
2404*5113495bSYour Name 		pl_hdr, HTT_INVALID_PEER, WDI_NO_VAL,
2405*5113495bSYour Name 		pdev_id);
2406*5113495bSYour Name }
2407*5113495bSYour Name #else
2408*5113495bSYour Name static void
2409*5113495bSYour Name dp_pktlog_msg_handler(struct htt_soc *soc,
2410*5113495bSYour Name 		      uint32_t *msg_word)
2411*5113495bSYour Name {
2412*5113495bSYour Name }
2413*5113495bSYour Name #endif
2414*5113495bSYour Name 
2415*5113495bSYour Name #ifdef QCA_SUPPORT_PRIMARY_LINK_MIGRATE
2416*5113495bSYour Name QDF_STATUS
2417*5113495bSYour Name dp_h2t_ptqm_migration_msg_send(struct dp_soc *dp_soc, uint16_t vdev_id,
2418*5113495bSYour Name 			       uint8_t pdev_id,
2419*5113495bSYour Name 			       uint8_t chip_id, uint16_t peer_id,
2420*5113495bSYour Name 			       uint16_t ml_peer_id, uint16_t src_info,
2421*5113495bSYour Name 			       QDF_STATUS status)
2422*5113495bSYour Name {
2423*5113495bSYour Name 	struct htt_soc *soc = dp_soc->htt_handle;
2424*5113495bSYour Name 	struct dp_htt_htc_pkt *pkt;
2425*5113495bSYour Name 	uint8_t *htt_logger_bufp;
2426*5113495bSYour Name 	qdf_nbuf_t msg;
2427*5113495bSYour Name 	uint32_t *msg_word;
2428*5113495bSYour Name 	QDF_STATUS ret = QDF_STATUS_SUCCESS;
2429*5113495bSYour Name 	bool src_info_valid = false;
2430*5113495bSYour Name 
2431*5113495bSYour Name 	msg = qdf_nbuf_alloc(
2432*5113495bSYour Name 			soc->osdev,
2433*5113495bSYour Name 			HTT_MSG_BUF_SIZE(sizeof(htt_h2t_primary_link_peer_migrate_resp_t)),
2434*5113495bSYour Name 			HTC_HEADER_LEN + HTC_HDR_ALIGNMENT_PADDING, 4, TRUE);
2435*5113495bSYour Name 
2436*5113495bSYour Name 	if (!msg)
2437*5113495bSYour Name 		return QDF_STATUS_E_NOMEM;
2438*5113495bSYour Name 
2439*5113495bSYour Name 	/*
2440*5113495bSYour Name 	 * Set the length of the message.
2441*5113495bSYour Name 	 * The contribution from the HTC_HDR_ALIGNMENT_PADDING is added
2442*5113495bSYour Name 	 * separately during the below call to qdf_nbuf_push_head.
2443*5113495bSYour Name 	 * The contribution from the HTC header is added separately inside HTC.
2444*5113495bSYour Name 	 */
2445*5113495bSYour Name 	if (qdf_nbuf_put_tail(msg, sizeof(htt_h2t_primary_link_peer_migrate_resp_t))
2446*5113495bSYour Name 			      == NULL) {
2447*5113495bSYour Name 		dp_htt_err("Failed to expand head for"
2448*5113495bSYour Name 			   "HTT_H2T_MSG_TYPE_PRIMARY_LINK_PEER_MIGRATE_RESP");
2449*5113495bSYour Name 		qdf_nbuf_free(msg);
2450*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
2451*5113495bSYour Name 	}
2452*5113495bSYour Name 
2453*5113495bSYour Name 	msg_word = (uint32_t *)qdf_nbuf_data(msg);
2454*5113495bSYour Name 	memset(msg_word, 0, sizeof(htt_h2t_primary_link_peer_migrate_resp_t));
2455*5113495bSYour Name 
2456*5113495bSYour Name 	qdf_nbuf_push_head(msg, HTC_HDR_ALIGNMENT_PADDING);
2457*5113495bSYour Name 	htt_logger_bufp = (uint8_t *)msg_word;
2458*5113495bSYour Name 	*msg_word = 0;
2459*5113495bSYour Name 	HTT_H2T_MSG_TYPE_SET(*msg_word,
2460*5113495bSYour Name 			     HTT_H2T_MSG_TYPE_PRIMARY_LINK_PEER_MIGRATE_RESP);
2461*5113495bSYour Name 	HTT_H2T_PRIMARY_LINK_PEER_MIGRATE_PDEV_ID_SET(*msg_word, pdev_id);
2462*5113495bSYour Name 	HTT_H2T_PRIMARY_LINK_PEER_MIGRATE_CHIP_ID_SET(*msg_word, chip_id);
2463*5113495bSYour Name 	HTT_H2T_PRIMARY_LINK_PEER_MIGRATE_VDEV_ID_SET(*msg_word, vdev_id);
2464*5113495bSYour Name 
2465*5113495bSYour Name 	/* word 1 */
2466*5113495bSYour Name 	msg_word++;
2467*5113495bSYour Name 	*msg_word = 0;
2468*5113495bSYour Name 	HTT_H2T_PRIMARY_LINK_PEER_MIGRATE_SW_LINK_PEER_ID_SET(*msg_word,
2469*5113495bSYour Name 							      peer_id);
2470*5113495bSYour Name 	HTT_H2T_PRIMARY_LINK_PEER_MIGRATE_ML_PEER_ID_SET(*msg_word,
2471*5113495bSYour Name 							 ml_peer_id);
2472*5113495bSYour Name 
2473*5113495bSYour Name 	/* word 1 */
2474*5113495bSYour Name 	msg_word++;
2475*5113495bSYour Name 	*msg_word = 0;
2476*5113495bSYour Name 
2477*5113495bSYour Name 	if (src_info != 0)
2478*5113495bSYour Name 		src_info_valid = true;
2479*5113495bSYour Name 
2480*5113495bSYour Name 	HTT_H2T_PRIMARY_LINK_PEER_MIGRATE_SRC_INFO_VALID_SET(*msg_word,
2481*5113495bSYour Name 							     src_info_valid);
2482*5113495bSYour Name 	HTT_H2T_PRIMARY_LINK_PEER_MIGRATE_SRC_INFO_SET(*msg_word,
2483*5113495bSYour Name 						       src_info);
2484*5113495bSYour Name 	HTT_H2T_PRIMARY_LINK_PEER_MIGRATE_STATUS_SET(*msg_word,
2485*5113495bSYour Name 						     status);
2486*5113495bSYour Name 
2487*5113495bSYour Name 	pkt = htt_htc_pkt_alloc(soc);
2488*5113495bSYour Name 	if (!pkt) {
2489*5113495bSYour Name 		dp_htt_err("Fail to allocate dp_htt_htc_pkt buffer");
2490*5113495bSYour Name 		qdf_nbuf_free(msg);
2491*5113495bSYour Name 		return QDF_STATUS_E_NOMEM;
2492*5113495bSYour Name 	}
2493*5113495bSYour Name 
2494*5113495bSYour Name 	pkt->soc_ctxt = NULL;
2495*5113495bSYour Name 
2496*5113495bSYour Name 	/* macro to set packet parameters for TX */
2497*5113495bSYour Name 	SET_HTC_PACKET_INFO_TX(
2498*5113495bSYour Name 			&pkt->htc_pkt,
2499*5113495bSYour Name 			dp_htt_h2t_send_complete_free_netbuf,
2500*5113495bSYour Name 			qdf_nbuf_data(msg),
2501*5113495bSYour Name 			qdf_nbuf_len(msg),
2502*5113495bSYour Name 			soc->htc_endpoint,
2503*5113495bSYour Name 			HTC_TX_PACKET_TAG_RUNTIME_PUT);
2504*5113495bSYour Name 
2505*5113495bSYour Name 	SET_HTC_PACKET_NET_BUF_CONTEXT(&pkt->htc_pkt, msg);
2506*5113495bSYour Name 
2507*5113495bSYour Name 	ret = DP_HTT_SEND_HTC_PKT(
2508*5113495bSYour Name 			soc, pkt,
2509*5113495bSYour Name 			HTT_H2T_MSG_TYPE_PRIMARY_LINK_PEER_MIGRATE_RESP,
2510*5113495bSYour Name 			htt_logger_bufp);
2511*5113495bSYour Name 
2512*5113495bSYour Name 	if (ret != QDF_STATUS_SUCCESS) {
2513*5113495bSYour Name 		qdf_nbuf_free(msg);
2514*5113495bSYour Name 		htt_htc_pkt_free(soc, pkt);
2515*5113495bSYour Name 	}
2516*5113495bSYour Name 
2517*5113495bSYour Name 	return ret;
2518*5113495bSYour Name }
2519*5113495bSYour Name #endif
2520*5113495bSYour Name 
2521*5113495bSYour Name #ifdef QCA_VDEV_STATS_HW_OFFLOAD_SUPPORT
2522*5113495bSYour Name /**
2523*5113495bSYour Name  * dp_vdev_txrx_hw_stats_handler - Handle vdev stats received from FW
2524*5113495bSYour Name  * @soc: htt soc handle
2525*5113495bSYour Name  * @msg_word: buffer containing stats
2526*5113495bSYour Name  *
2527*5113495bSYour Name  * Return: void
2528*5113495bSYour Name  */
2529*5113495bSYour Name static void dp_vdev_txrx_hw_stats_handler(struct htt_soc *soc,
2530*5113495bSYour Name 					  uint32_t *msg_word)
2531*5113495bSYour Name {
2532*5113495bSYour Name 	struct dp_soc *dpsoc = (struct dp_soc *)soc->dp_soc;
2533*5113495bSYour Name 	uint8_t pdev_id;
2534*5113495bSYour Name 	uint8_t vdev_id;
2535*5113495bSYour Name 	uint8_t target_pdev_id;
2536*5113495bSYour Name 	uint16_t payload_size;
2537*5113495bSYour Name 	struct dp_pdev *pdev;
2538*5113495bSYour Name 	struct dp_vdev *vdev;
2539*5113495bSYour Name 	uint8_t *tlv_buf;
2540*5113495bSYour Name 	uint32_t *tlv_buf_temp;
2541*5113495bSYour Name 	uint32_t *tag_buf;
2542*5113495bSYour Name 	htt_tlv_tag_t tlv_type;
2543*5113495bSYour Name 	uint16_t tlv_length;
2544*5113495bSYour Name 	uint64_t pkt_count = 0;
2545*5113495bSYour Name 	uint64_t byte_count = 0;
2546*5113495bSYour Name 	uint64_t soc_drop_cnt = 0;
2547*5113495bSYour Name 	struct cdp_pkt_info tx_comp = { 0 };
2548*5113495bSYour Name 	struct cdp_pkt_info tx_failed =  { 0 };
2549*5113495bSYour Name 
2550*5113495bSYour Name 	target_pdev_id =
2551*5113495bSYour Name 		HTT_T2H_VDEVS_TXRX_STATS_PERIODIC_IND_PDEV_ID_GET(*msg_word);
2552*5113495bSYour Name 	pdev_id = dp_get_host_pdev_id_for_target_pdev_id(dpsoc,
2553*5113495bSYour Name 							 target_pdev_id);
2554*5113495bSYour Name 
2555*5113495bSYour Name 	if (pdev_id >= MAX_PDEV_CNT)
2556*5113495bSYour Name 		return;
2557*5113495bSYour Name 
2558*5113495bSYour Name 	pdev = dpsoc->pdev_list[pdev_id];
2559*5113495bSYour Name 	if (!pdev) {
2560*5113495bSYour Name 		dp_err("PDEV is NULL for pdev_id:%d", pdev_id);
2561*5113495bSYour Name 		return;
2562*5113495bSYour Name 	}
2563*5113495bSYour Name 
2564*5113495bSYour Name 	payload_size =
2565*5113495bSYour Name 	HTT_T2H_VDEVS_TXRX_STATS_PERIODIC_IND_PAYLOAD_SIZE_GET(*msg_word);
2566*5113495bSYour Name 
2567*5113495bSYour Name 	qdf_trace_hex_dump(QDF_MODULE_ID_DP_HTT, QDF_TRACE_LEVEL_INFO,
2568*5113495bSYour Name 			   (void *)msg_word, payload_size + 16);
2569*5113495bSYour Name 
2570*5113495bSYour Name 	/* Adjust msg_word to point to the first TLV in buffer */
2571*5113495bSYour Name 	msg_word = msg_word + 4;
2572*5113495bSYour Name 
2573*5113495bSYour Name 	/* Parse the received buffer till payload size reaches 0 */
2574*5113495bSYour Name 	while (payload_size > 0) {
2575*5113495bSYour Name 		tlv_buf = (uint8_t *)msg_word;
2576*5113495bSYour Name 		tlv_buf_temp = msg_word;
2577*5113495bSYour Name 		tlv_type = HTT_STATS_TLV_TAG_GET(*msg_word);
2578*5113495bSYour Name 		tlv_length = HTT_STATS_TLV_LENGTH_GET(*msg_word);
2579*5113495bSYour Name 
2580*5113495bSYour Name 		/* Add header size to tlv length*/
2581*5113495bSYour Name 		tlv_length += 4;
2582*5113495bSYour Name 
2583*5113495bSYour Name 		switch (tlv_type) {
2584*5113495bSYour Name 		case HTT_STATS_SOC_TXRX_STATS_COMMON_TAG:
2585*5113495bSYour Name 		{
2586*5113495bSYour Name 			tag_buf = tlv_buf_temp +
2587*5113495bSYour Name 					HTT_VDEV_STATS_GET_INDEX(SOC_DROP_CNT);
2588*5113495bSYour Name 			soc_drop_cnt = HTT_VDEV_GET_STATS_U64(tag_buf);
2589*5113495bSYour Name 			DP_STATS_UPD(dpsoc, tx.tqm_drop_no_peer, soc_drop_cnt);
2590*5113495bSYour Name 			break;
2591*5113495bSYour Name 		}
2592*5113495bSYour Name 		case HTT_STATS_VDEV_TXRX_STATS_HW_STATS_TAG:
2593*5113495bSYour Name 		{
2594*5113495bSYour Name 			tag_buf = tlv_buf_temp +
2595*5113495bSYour Name 					HTT_VDEV_STATS_GET_INDEX(VDEV_ID);
2596*5113495bSYour Name 			vdev_id = (uint8_t)(*tag_buf);
2597*5113495bSYour Name 			vdev = dp_vdev_get_ref_by_id(dpsoc, vdev_id,
2598*5113495bSYour Name 						     DP_MOD_ID_HTT);
2599*5113495bSYour Name 
2600*5113495bSYour Name 			if (!vdev)
2601*5113495bSYour Name 				goto invalid_vdev;
2602*5113495bSYour Name 
2603*5113495bSYour Name 			/* Extract received packet count from buffer */
2604*5113495bSYour Name 			tag_buf = tlv_buf_temp +
2605*5113495bSYour Name 					HTT_VDEV_STATS_GET_INDEX(RX_PKT_CNT);
2606*5113495bSYour Name 			pkt_count = HTT_VDEV_GET_STATS_U64(tag_buf);
2607*5113495bSYour Name 			DP_STATS_UPD(vdev, rx_i.reo_rcvd_pkt.num, pkt_count);
2608*5113495bSYour Name 
2609*5113495bSYour Name 			/* Extract received packet byte count from buffer */
2610*5113495bSYour Name 			tag_buf = tlv_buf_temp +
2611*5113495bSYour Name 					HTT_VDEV_STATS_GET_INDEX(RX_BYTE_CNT);
2612*5113495bSYour Name 			byte_count = HTT_VDEV_GET_STATS_U64(tag_buf);
2613*5113495bSYour Name 			DP_STATS_UPD(vdev, rx_i.reo_rcvd_pkt.bytes, byte_count);
2614*5113495bSYour Name 
2615*5113495bSYour Name 			/* Extract tx success packet count from buffer */
2616*5113495bSYour Name 			tag_buf = tlv_buf_temp +
2617*5113495bSYour Name 				HTT_VDEV_STATS_GET_INDEX(TX_SUCCESS_PKT_CNT);
2618*5113495bSYour Name 			pkt_count = HTT_VDEV_GET_STATS_U64(tag_buf);
2619*5113495bSYour Name 			tx_comp.num = pkt_count;
2620*5113495bSYour Name 
2621*5113495bSYour Name 			/* Extract tx success packet byte count from buffer */
2622*5113495bSYour Name 			tag_buf = tlv_buf_temp +
2623*5113495bSYour Name 				HTT_VDEV_STATS_GET_INDEX(TX_SUCCESS_BYTE_CNT);
2624*5113495bSYour Name 			byte_count = HTT_VDEV_GET_STATS_U64(tag_buf);
2625*5113495bSYour Name 			tx_comp.bytes = byte_count;
2626*5113495bSYour Name 
2627*5113495bSYour Name 			/* Extract tx retry packet count from buffer */
2628*5113495bSYour Name 			tag_buf = tlv_buf_temp +
2629*5113495bSYour Name 				HTT_VDEV_STATS_GET_INDEX(TX_RETRY_PKT_CNT);
2630*5113495bSYour Name 			pkt_count = HTT_VDEV_GET_STATS_U64(tag_buf);
2631*5113495bSYour Name 			tx_comp.num += pkt_count;
2632*5113495bSYour Name 			tx_failed.num = pkt_count;
2633*5113495bSYour Name 
2634*5113495bSYour Name 			/* Extract tx retry packet byte count from buffer */
2635*5113495bSYour Name 			tag_buf = tlv_buf_temp +
2636*5113495bSYour Name 				HTT_VDEV_STATS_GET_INDEX(TX_RETRY_BYTE_CNT);
2637*5113495bSYour Name 			byte_count = HTT_VDEV_GET_STATS_U64(tag_buf);
2638*5113495bSYour Name 			tx_comp.bytes += byte_count;
2639*5113495bSYour Name 			tx_failed.bytes = byte_count;
2640*5113495bSYour Name 
2641*5113495bSYour Name 			/* Extract tx drop packet count from buffer */
2642*5113495bSYour Name 			tag_buf = tlv_buf_temp +
2643*5113495bSYour Name 				HTT_VDEV_STATS_GET_INDEX(TX_DROP_PKT_CNT);
2644*5113495bSYour Name 			pkt_count = HTT_VDEV_GET_STATS_U64(tag_buf);
2645*5113495bSYour Name 			tx_comp.num += pkt_count;
2646*5113495bSYour Name 			tx_failed.num += pkt_count;
2647*5113495bSYour Name 
2648*5113495bSYour Name 			/* Extract tx drop packet byte count from buffer */
2649*5113495bSYour Name 			tag_buf = tlv_buf_temp +
2650*5113495bSYour Name 				HTT_VDEV_STATS_GET_INDEX(TX_DROP_BYTE_CNT);
2651*5113495bSYour Name 			byte_count = HTT_VDEV_GET_STATS_U64(tag_buf);
2652*5113495bSYour Name 			tx_comp.bytes += byte_count;
2653*5113495bSYour Name 			tx_failed.bytes += byte_count;
2654*5113495bSYour Name 
2655*5113495bSYour Name 			/* Extract tx age-out packet count from buffer */
2656*5113495bSYour Name 			tag_buf = tlv_buf_temp +
2657*5113495bSYour Name 				HTT_VDEV_STATS_GET_INDEX(TX_AGE_OUT_PKT_CNT);
2658*5113495bSYour Name 			pkt_count = HTT_VDEV_GET_STATS_U64(tag_buf);
2659*5113495bSYour Name 			tx_comp.num += pkt_count;
2660*5113495bSYour Name 			tx_failed.num += pkt_count;
2661*5113495bSYour Name 
2662*5113495bSYour Name 			/* Extract tx age-out packet byte count from buffer */
2663*5113495bSYour Name 			tag_buf = tlv_buf_temp +
2664*5113495bSYour Name 				HTT_VDEV_STATS_GET_INDEX(TX_AGE_OUT_BYTE_CNT);
2665*5113495bSYour Name 			byte_count = HTT_VDEV_GET_STATS_U64(tag_buf);
2666*5113495bSYour Name 			tx_comp.bytes += byte_count;
2667*5113495bSYour Name 			tx_failed.bytes += byte_count;
2668*5113495bSYour Name 
2669*5113495bSYour Name 			/* Extract tqm bypass packet count from buffer */
2670*5113495bSYour Name 			tag_buf = tlv_buf_temp +
2671*5113495bSYour Name 				HTT_VDEV_STATS_GET_INDEX(TX_TQM_BYPASS_PKT_CNT);
2672*5113495bSYour Name 			pkt_count = HTT_VDEV_GET_STATS_U64(tag_buf);
2673*5113495bSYour Name 			tx_comp.num += pkt_count;
2674*5113495bSYour Name 
2675*5113495bSYour Name 			/* Extract tx bypass packet byte count from buffer */
2676*5113495bSYour Name 			tag_buf = tlv_buf_temp +
2677*5113495bSYour Name 				HTT_VDEV_STATS_GET_INDEX(TX_TQM_BYPASS_BYTE_CNT);
2678*5113495bSYour Name 			byte_count = HTT_VDEV_GET_STATS_U64(tag_buf);
2679*5113495bSYour Name 			tx_comp.bytes += byte_count;
2680*5113495bSYour Name 
2681*5113495bSYour Name 			DP_STATS_UPD(vdev, tx.comp_pkt.num, tx_comp.num);
2682*5113495bSYour Name 			DP_STATS_UPD(vdev, tx.comp_pkt.bytes, tx_comp.bytes);
2683*5113495bSYour Name 
2684*5113495bSYour Name 			DP_STATS_UPD(vdev, tx.tx_failed, tx_failed.num);
2685*5113495bSYour Name 
2686*5113495bSYour Name 			dp_vdev_unref_delete(dpsoc, vdev, DP_MOD_ID_HTT);
2687*5113495bSYour Name 			break;
2688*5113495bSYour Name 		}
2689*5113495bSYour Name 		default:
2690*5113495bSYour Name 			dp_htt_err("Invalid tlv_type value:%d\n", tlv_type);
2691*5113495bSYour Name 		}
2692*5113495bSYour Name invalid_vdev:
2693*5113495bSYour Name 		msg_word = (uint32_t *)((uint8_t *)tlv_buf + tlv_length);
2694*5113495bSYour Name 		payload_size -= tlv_length;
2695*5113495bSYour Name 	}
2696*5113495bSYour Name }
2697*5113495bSYour Name #else
2698*5113495bSYour Name static void dp_vdev_txrx_hw_stats_handler(struct htt_soc *soc,
2699*5113495bSYour Name 					  uint32_t *msg_word)
2700*5113495bSYour Name {}
2701*5113495bSYour Name #endif
2702*5113495bSYour Name 
2703*5113495bSYour Name #ifdef CONFIG_SAWF_DEF_QUEUES
2704*5113495bSYour Name static void dp_sawf_def_queues_update_map_report_conf(struct htt_soc *soc,
2705*5113495bSYour Name 						      uint32_t *msg_word,
2706*5113495bSYour Name 						      qdf_nbuf_t htt_t2h_msg)
2707*5113495bSYour Name {
2708*5113495bSYour Name 	dp_htt_sawf_def_queues_map_report_conf(soc, msg_word, htt_t2h_msg);
2709*5113495bSYour Name }
2710*5113495bSYour Name #else
2711*5113495bSYour Name static void dp_sawf_def_queues_update_map_report_conf(struct htt_soc *soc,
2712*5113495bSYour Name 						      uint32_t *msg_word,
2713*5113495bSYour Name 						      qdf_nbuf_t htt_t2h_msg)
2714*5113495bSYour Name {}
2715*5113495bSYour Name #endif
2716*5113495bSYour Name 
2717*5113495bSYour Name #ifdef CONFIG_SAWF
2718*5113495bSYour Name /**
2719*5113495bSYour Name  * dp_sawf_msduq_map() - Msdu queue creation information received
2720*5113495bSYour Name  * from target
2721*5113495bSYour Name  * @soc: soc handle.
2722*5113495bSYour Name  * @msg_word: Pointer to htt msg word.
2723*5113495bSYour Name  * @htt_t2h_msg: HTT message nbuf
2724*5113495bSYour Name  *
2725*5113495bSYour Name  * Return: void
2726*5113495bSYour Name  */
2727*5113495bSYour Name static void dp_sawf_msduq_map(struct htt_soc *soc, uint32_t *msg_word,
2728*5113495bSYour Name 			      qdf_nbuf_t htt_t2h_msg)
2729*5113495bSYour Name {
2730*5113495bSYour Name 	dp_htt_sawf_msduq_map(soc, msg_word, htt_t2h_msg);
2731*5113495bSYour Name }
2732*5113495bSYour Name 
2733*5113495bSYour Name /**
2734*5113495bSYour Name  * dp_sawf_dynamic_ast_update() - Dynamic AST index update for SAWF peer
2735*5113495bSYour Name  * from target
2736*5113495bSYour Name  * @soc: soc handle.
2737*5113495bSYour Name  * @msg_word: Pointer to htt msg word.
2738*5113495bSYour Name  * @htt_t2h_msg: HTT message nbuf
2739*5113495bSYour Name  *
2740*5113495bSYour Name  * Return: void
2741*5113495bSYour Name  */
2742*5113495bSYour Name static void dp_sawf_dynamic_ast_update(struct htt_soc *soc, uint32_t *msg_word,
2743*5113495bSYour Name 				       qdf_nbuf_t htt_t2h_msg)
2744*5113495bSYour Name {
2745*5113495bSYour Name 	dp_htt_sawf_dynamic_ast_update(soc, msg_word, htt_t2h_msg);
2746*5113495bSYour Name }
2747*5113495bSYour Name 
2748*5113495bSYour Name /**
2749*5113495bSYour Name  * dp_sawf_mpdu_stats_handler() - HTT message handler for MPDU stats
2750*5113495bSYour Name  * @soc: soc handle.
2751*5113495bSYour Name  * @htt_t2h_msg: HTT message nbuf
2752*5113495bSYour Name  *
2753*5113495bSYour Name  * Return: void
2754*5113495bSYour Name  */
2755*5113495bSYour Name static void dp_sawf_mpdu_stats_handler(struct htt_soc *soc,
2756*5113495bSYour Name 				       qdf_nbuf_t htt_t2h_msg)
2757*5113495bSYour Name {
2758*5113495bSYour Name 	dp_sawf_htt_mpdu_stats_handler(soc, htt_t2h_msg);
2759*5113495bSYour Name }
2760*5113495bSYour Name #else
2761*5113495bSYour Name static void dp_sawf_msduq_map(struct htt_soc *soc, uint32_t *msg_word,
2762*5113495bSYour Name 			      qdf_nbuf_t htt_t2h_msg)
2763*5113495bSYour Name {}
2764*5113495bSYour Name 
2765*5113495bSYour Name static void dp_sawf_mpdu_stats_handler(struct htt_soc *soc,
2766*5113495bSYour Name 				       qdf_nbuf_t htt_t2h_msg)
2767*5113495bSYour Name {}
2768*5113495bSYour Name static void dp_sawf_dynamic_ast_update(struct htt_soc *soc, uint32_t *msg_word,
2769*5113495bSYour Name 				       qdf_nbuf_t htt_t2h_msg)
2770*5113495bSYour Name {}
2771*5113495bSYour Name #endif
2772*5113495bSYour Name 
2773*5113495bSYour Name /**
2774*5113495bSYour Name  * time_allow_print() - time allow print
2775*5113495bSYour Name  * @htt_bp_handler:	backpressure handler
2776*5113495bSYour Name  * @ring_id:		ring_id (index)
2777*5113495bSYour Name  * @th_time:		threshold time
2778*5113495bSYour Name  *
2779*5113495bSYour Name  * Return: 1 for successfully saving timestamp in array
2780*5113495bSYour Name  *	and 0 for timestamp falling within 2 seconds after last one
2781*5113495bSYour Name  */
2782*5113495bSYour Name static bool time_allow_print(struct bp_handler *htt_bp_handler,
2783*5113495bSYour Name 			     u_int8_t ring_id, u_int32_t th_time)
2784*5113495bSYour Name {
2785*5113495bSYour Name 	unsigned long tstamp;
2786*5113495bSYour Name 	struct bp_handler *path = &htt_bp_handler[ring_id];
2787*5113495bSYour Name 
2788*5113495bSYour Name 	tstamp = qdf_get_system_timestamp();
2789*5113495bSYour Name 
2790*5113495bSYour Name 	if (!path)
2791*5113495bSYour Name 		return 0; //unable to print backpressure messages
2792*5113495bSYour Name 
2793*5113495bSYour Name 	if (path->bp_start_tt == -1) {
2794*5113495bSYour Name 		path->bp_start_tt = tstamp;
2795*5113495bSYour Name 		path->bp_duration = 0;
2796*5113495bSYour Name 		path->bp_last_tt = tstamp;
2797*5113495bSYour Name 		path->bp_counter = 1;
2798*5113495bSYour Name 		return 1;
2799*5113495bSYour Name 	}
2800*5113495bSYour Name 
2801*5113495bSYour Name 	path->bp_duration = tstamp - path->bp_start_tt;
2802*5113495bSYour Name 	path->bp_last_tt = tstamp;
2803*5113495bSYour Name 	path->bp_counter++;
2804*5113495bSYour Name 
2805*5113495bSYour Name 	if (path->bp_duration >= th_time) {
2806*5113495bSYour Name 		path->bp_start_tt = -1;
2807*5113495bSYour Name 		return 1;
2808*5113495bSYour Name 	}
2809*5113495bSYour Name 
2810*5113495bSYour Name 	return 0;
2811*5113495bSYour Name }
2812*5113495bSYour Name 
2813*5113495bSYour Name static void dp_htt_alert_print(enum htt_t2h_msg_type msg_type,
2814*5113495bSYour Name 			       struct dp_pdev *pdev, u_int8_t ring_id,
2815*5113495bSYour Name 			       u_int16_t hp_idx, u_int16_t tp_idx,
2816*5113495bSYour Name 			       u_int32_t bkp_time,
2817*5113495bSYour Name 			       struct bp_handler *htt_bp_handler,
2818*5113495bSYour Name 			       char *ring_stype)
2819*5113495bSYour Name {
2820*5113495bSYour Name 	dp_alert("seq_num %u msg_type: %d pdev_id: %d ring_type: %s ",
2821*5113495bSYour Name 		 pdev->bkp_stats.seq_num, msg_type, pdev->pdev_id, ring_stype);
2822*5113495bSYour Name 	dp_alert("ring_id: %d hp_idx: %d tp_idx: %d bkpressure_time_ms: %d ",
2823*5113495bSYour Name 		 ring_id, hp_idx, tp_idx, bkp_time);
2824*5113495bSYour Name 	dp_alert("last_bp_event: %ld, total_bp_duration: %ld, bp_counter: %ld",
2825*5113495bSYour Name 		 htt_bp_handler[ring_id].bp_last_tt,
2826*5113495bSYour Name 		 htt_bp_handler[ring_id].bp_duration,
2827*5113495bSYour Name 		 htt_bp_handler[ring_id].bp_counter);
2828*5113495bSYour Name }
2829*5113495bSYour Name 
2830*5113495bSYour Name /**
2831*5113495bSYour Name  * dp_get_srng_ring_state_from_hal(): Get hal level ring stats
2832*5113495bSYour Name  * @soc: DP_SOC handle
2833*5113495bSYour Name  * @pdev: DP pdev handle
2834*5113495bSYour Name  * @srng: DP_SRNG handle
2835*5113495bSYour Name  * @ring_type: srng src/dst ring
2836*5113495bSYour Name  * @state: ring state
2837*5113495bSYour Name  * @pdev: pdev
2838*5113495bSYour Name  * @srng: DP_SRNG handle
2839*5113495bSYour Name  * @ring_type: srng src/dst ring
2840*5113495bSYour Name  * @state: ring_state
2841*5113495bSYour Name  *
2842*5113495bSYour Name  * Return: void
2843*5113495bSYour Name  */
2844*5113495bSYour Name static QDF_STATUS
2845*5113495bSYour Name dp_get_srng_ring_state_from_hal(struct dp_soc *soc,
2846*5113495bSYour Name 				struct dp_pdev *pdev,
2847*5113495bSYour Name 				struct dp_srng *srng,
2848*5113495bSYour Name 				enum hal_ring_type ring_type,
2849*5113495bSYour Name 				struct dp_srng_ring_state *state)
2850*5113495bSYour Name {
2851*5113495bSYour Name 	struct hal_soc *hal_soc;
2852*5113495bSYour Name 
2853*5113495bSYour Name 	if (!soc || !srng || !srng->hal_srng || !state)
2854*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
2855*5113495bSYour Name 
2856*5113495bSYour Name 	hal_soc = (struct hal_soc *)soc->hal_soc;
2857*5113495bSYour Name 
2858*5113495bSYour Name 	hal_get_sw_hptp(soc->hal_soc, srng->hal_srng, &state->sw_tail,
2859*5113495bSYour Name 			&state->sw_head);
2860*5113495bSYour Name 
2861*5113495bSYour Name 	hal_get_hw_hptp(soc->hal_soc, srng->hal_srng, &state->hw_head,
2862*5113495bSYour Name 			&state->hw_tail, ring_type);
2863*5113495bSYour Name 
2864*5113495bSYour Name 	state->ring_type = ring_type;
2865*5113495bSYour Name 
2866*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
2867*5113495bSYour Name }
2868*5113495bSYour Name 
2869*5113495bSYour Name #ifdef QCA_MONITOR_PKT_SUPPORT
2870*5113495bSYour Name static void
2871*5113495bSYour Name dp_queue_mon_ring_stats(struct dp_pdev *pdev,
2872*5113495bSYour Name 			int lmac_id, uint32_t *num_srng,
2873*5113495bSYour Name 			struct dp_soc_srngs_state *soc_srngs_state)
2874*5113495bSYour Name {
2875*5113495bSYour Name 	QDF_STATUS status;
2876*5113495bSYour Name 
2877*5113495bSYour Name 	if (pdev->soc->wlan_cfg_ctx->rxdma1_enable) {
2878*5113495bSYour Name 		status = dp_get_srng_ring_state_from_hal
2879*5113495bSYour Name 			(pdev->soc, pdev,
2880*5113495bSYour Name 			 &pdev->soc->rxdma_mon_buf_ring[lmac_id],
2881*5113495bSYour Name 			 RXDMA_MONITOR_BUF,
2882*5113495bSYour Name 			 &soc_srngs_state->ring_state[*num_srng]);
2883*5113495bSYour Name 
2884*5113495bSYour Name 		if (status == QDF_STATUS_SUCCESS) {
2885*5113495bSYour Name 			++(*num_srng);
2886*5113495bSYour Name 			qdf_assert_always(*num_srng < DP_MAX_SRNGS);
2887*5113495bSYour Name 		}
2888*5113495bSYour Name 
2889*5113495bSYour Name 		status = dp_get_srng_ring_state_from_hal
2890*5113495bSYour Name 			(pdev->soc, pdev,
2891*5113495bSYour Name 			 &pdev->soc->rxdma_mon_dst_ring[lmac_id],
2892*5113495bSYour Name 			 RXDMA_MONITOR_DST,
2893*5113495bSYour Name 			 &soc_srngs_state->ring_state[*num_srng]);
2894*5113495bSYour Name 
2895*5113495bSYour Name 		if (status == QDF_STATUS_SUCCESS) {
2896*5113495bSYour Name 			++(*num_srng);
2897*5113495bSYour Name 			qdf_assert_always(*num_srng < DP_MAX_SRNGS);
2898*5113495bSYour Name 		}
2899*5113495bSYour Name 
2900*5113495bSYour Name 		status = dp_get_srng_ring_state_from_hal
2901*5113495bSYour Name 			(pdev->soc, pdev,
2902*5113495bSYour Name 			 &pdev->soc->rxdma_mon_desc_ring[lmac_id],
2903*5113495bSYour Name 			 RXDMA_MONITOR_DESC,
2904*5113495bSYour Name 			 &soc_srngs_state->ring_state[*num_srng]);
2905*5113495bSYour Name 
2906*5113495bSYour Name 		if (status == QDF_STATUS_SUCCESS) {
2907*5113495bSYour Name 			++(*num_srng);
2908*5113495bSYour Name 			qdf_assert_always(*num_srng < DP_MAX_SRNGS);
2909*5113495bSYour Name 		}
2910*5113495bSYour Name 	}
2911*5113495bSYour Name }
2912*5113495bSYour Name #else
2913*5113495bSYour Name static void
2914*5113495bSYour Name dp_queue_mon_ring_stats(struct dp_pdev *pdev,
2915*5113495bSYour Name 			int lmac_id, uint32_t *num_srng,
2916*5113495bSYour Name 			struct dp_soc_srngs_state *soc_srngs_state)
2917*5113495bSYour Name {
2918*5113495bSYour Name }
2919*5113495bSYour Name #endif
2920*5113495bSYour Name 
2921*5113495bSYour Name #ifndef WLAN_DP_DISABLE_TCL_CMD_CRED_SRNG
2922*5113495bSYour Name static inline QDF_STATUS
2923*5113495bSYour Name dp_get_tcl_cmd_cred_ring_state_from_hal(struct dp_pdev *pdev,
2924*5113495bSYour Name 					struct dp_srng_ring_state *ring_state)
2925*5113495bSYour Name {
2926*5113495bSYour Name 	return dp_get_srng_ring_state_from_hal(pdev->soc, pdev,
2927*5113495bSYour Name 					       &pdev->soc->tcl_cmd_credit_ring,
2928*5113495bSYour Name 					       TCL_CMD_CREDIT, ring_state);
2929*5113495bSYour Name }
2930*5113495bSYour Name #else
2931*5113495bSYour Name static inline QDF_STATUS
2932*5113495bSYour Name dp_get_tcl_cmd_cred_ring_state_from_hal(struct dp_pdev *pdev,
2933*5113495bSYour Name 					struct dp_srng_ring_state *ring_state)
2934*5113495bSYour Name {
2935*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
2936*5113495bSYour Name }
2937*5113495bSYour Name #endif
2938*5113495bSYour Name 
2939*5113495bSYour Name #ifndef WLAN_DP_DISABLE_TCL_STATUS_SRNG
2940*5113495bSYour Name static inline QDF_STATUS
2941*5113495bSYour Name dp_get_tcl_status_ring_state_from_hal(struct dp_pdev *pdev,
2942*5113495bSYour Name 				      struct dp_srng_ring_state *ring_state)
2943*5113495bSYour Name {
2944*5113495bSYour Name 	return dp_get_srng_ring_state_from_hal(pdev->soc, pdev,
2945*5113495bSYour Name 					       &pdev->soc->tcl_status_ring,
2946*5113495bSYour Name 					       TCL_STATUS, ring_state);
2947*5113495bSYour Name }
2948*5113495bSYour Name #else
2949*5113495bSYour Name static inline QDF_STATUS
2950*5113495bSYour Name dp_get_tcl_status_ring_state_from_hal(struct dp_pdev *pdev,
2951*5113495bSYour Name 				      struct dp_srng_ring_state *ring_state)
2952*5113495bSYour Name {
2953*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
2954*5113495bSYour Name }
2955*5113495bSYour Name #endif
2956*5113495bSYour Name 
2957*5113495bSYour Name /**
2958*5113495bSYour Name  * dp_queue_ring_stats() - Print pdev hal level ring stats
2959*5113495bSYour Name  * dp_queue_ring_stats(): Print pdev hal level ring stats
2960*5113495bSYour Name  * @pdev: DP_pdev handle
2961*5113495bSYour Name  *
2962*5113495bSYour Name  * Return: void
2963*5113495bSYour Name  */
2964*5113495bSYour Name static void dp_queue_ring_stats(struct dp_pdev *pdev)
2965*5113495bSYour Name {
2966*5113495bSYour Name 	uint32_t i;
2967*5113495bSYour Name 	int mac_id;
2968*5113495bSYour Name 	int lmac_id;
2969*5113495bSYour Name 	uint32_t j = 0;
2970*5113495bSYour Name 	struct dp_soc *soc = pdev->soc;
2971*5113495bSYour Name 	struct dp_soc_srngs_state * soc_srngs_state = NULL;
2972*5113495bSYour Name 	struct dp_soc_srngs_state *drop_srngs_state = NULL;
2973*5113495bSYour Name 	QDF_STATUS status;
2974*5113495bSYour Name 
2975*5113495bSYour Name 	soc_srngs_state = qdf_mem_malloc(sizeof(struct dp_soc_srngs_state));
2976*5113495bSYour Name 	if (!soc_srngs_state) {
2977*5113495bSYour Name 		dp_htt_alert("Memory alloc failed for back pressure event");
2978*5113495bSYour Name 		return;
2979*5113495bSYour Name 	}
2980*5113495bSYour Name 
2981*5113495bSYour Name 	status = dp_get_srng_ring_state_from_hal
2982*5113495bSYour Name 				(pdev->soc, pdev,
2983*5113495bSYour Name 				 &pdev->soc->reo_exception_ring,
2984*5113495bSYour Name 				 REO_EXCEPTION,
2985*5113495bSYour Name 				 &soc_srngs_state->ring_state[j]);
2986*5113495bSYour Name 
2987*5113495bSYour Name 	if (status == QDF_STATUS_SUCCESS) {
2988*5113495bSYour Name 		j++;
2989*5113495bSYour Name 		qdf_assert_always(j < DP_MAX_SRNGS);
2990*5113495bSYour Name 	}
2991*5113495bSYour Name 
2992*5113495bSYour Name 	status = dp_get_srng_ring_state_from_hal
2993*5113495bSYour Name 				(pdev->soc, pdev,
2994*5113495bSYour Name 				 &pdev->soc->reo_reinject_ring,
2995*5113495bSYour Name 				 REO_REINJECT,
2996*5113495bSYour Name 				 &soc_srngs_state->ring_state[j]);
2997*5113495bSYour Name 
2998*5113495bSYour Name 	if (status == QDF_STATUS_SUCCESS) {
2999*5113495bSYour Name 		j++;
3000*5113495bSYour Name 		qdf_assert_always(j < DP_MAX_SRNGS);
3001*5113495bSYour Name 	}
3002*5113495bSYour Name 
3003*5113495bSYour Name 	status = dp_get_srng_ring_state_from_hal
3004*5113495bSYour Name 				(pdev->soc, pdev,
3005*5113495bSYour Name 				 &pdev->soc->reo_cmd_ring,
3006*5113495bSYour Name 				 REO_CMD,
3007*5113495bSYour Name 				 &soc_srngs_state->ring_state[j]);
3008*5113495bSYour Name 
3009*5113495bSYour Name 	if (status == QDF_STATUS_SUCCESS) {
3010*5113495bSYour Name 		j++;
3011*5113495bSYour Name 		qdf_assert_always(j < DP_MAX_SRNGS);
3012*5113495bSYour Name 	}
3013*5113495bSYour Name 
3014*5113495bSYour Name 	status = dp_get_srng_ring_state_from_hal
3015*5113495bSYour Name 				(pdev->soc, pdev,
3016*5113495bSYour Name 				 &pdev->soc->reo_status_ring,
3017*5113495bSYour Name 				 REO_STATUS,
3018*5113495bSYour Name 				 &soc_srngs_state->ring_state[j]);
3019*5113495bSYour Name 
3020*5113495bSYour Name 	if (status == QDF_STATUS_SUCCESS) {
3021*5113495bSYour Name 		j++;
3022*5113495bSYour Name 		qdf_assert_always(j < DP_MAX_SRNGS);
3023*5113495bSYour Name 	}
3024*5113495bSYour Name 
3025*5113495bSYour Name 	status = dp_get_srng_ring_state_from_hal
3026*5113495bSYour Name 				(pdev->soc, pdev,
3027*5113495bSYour Name 				 &pdev->soc->rx_rel_ring,
3028*5113495bSYour Name 				 WBM2SW_RELEASE,
3029*5113495bSYour Name 				 &soc_srngs_state->ring_state[j]);
3030*5113495bSYour Name 
3031*5113495bSYour Name 	if (status == QDF_STATUS_SUCCESS) {
3032*5113495bSYour Name 		j++;
3033*5113495bSYour Name 		qdf_assert_always(j < DP_MAX_SRNGS);
3034*5113495bSYour Name 	}
3035*5113495bSYour Name 
3036*5113495bSYour Name 	status = dp_get_tcl_cmd_cred_ring_state_from_hal
3037*5113495bSYour Name 				(pdev, &soc_srngs_state->ring_state[j]);
3038*5113495bSYour Name 	if (status == QDF_STATUS_SUCCESS) {
3039*5113495bSYour Name 		j++;
3040*5113495bSYour Name 		qdf_assert_always(j < DP_MAX_SRNGS);
3041*5113495bSYour Name 	}
3042*5113495bSYour Name 
3043*5113495bSYour Name 	status = dp_get_tcl_status_ring_state_from_hal
3044*5113495bSYour Name 				(pdev, &soc_srngs_state->ring_state[j]);
3045*5113495bSYour Name 	if (status == QDF_STATUS_SUCCESS) {
3046*5113495bSYour Name 		j++;
3047*5113495bSYour Name 		qdf_assert_always(j < DP_MAX_SRNGS);
3048*5113495bSYour Name 	}
3049*5113495bSYour Name 
3050*5113495bSYour Name 	status = dp_get_srng_ring_state_from_hal
3051*5113495bSYour Name 				(pdev->soc, pdev,
3052*5113495bSYour Name 				 &pdev->soc->wbm_desc_rel_ring,
3053*5113495bSYour Name 				 SW2WBM_RELEASE,
3054*5113495bSYour Name 				 &soc_srngs_state->ring_state[j]);
3055*5113495bSYour Name 
3056*5113495bSYour Name 	if (status == QDF_STATUS_SUCCESS) {
3057*5113495bSYour Name 		j++;
3058*5113495bSYour Name 		qdf_assert_always(j < DP_MAX_SRNGS);
3059*5113495bSYour Name 	}
3060*5113495bSYour Name 
3061*5113495bSYour Name 	for (i = 0; i < MAX_REO_DEST_RINGS; i++) {
3062*5113495bSYour Name 		status = dp_get_srng_ring_state_from_hal
3063*5113495bSYour Name 				(pdev->soc, pdev,
3064*5113495bSYour Name 				 &pdev->soc->reo_dest_ring[i],
3065*5113495bSYour Name 				 REO_DST,
3066*5113495bSYour Name 				 &soc_srngs_state->ring_state[j]);
3067*5113495bSYour Name 
3068*5113495bSYour Name 		if (status == QDF_STATUS_SUCCESS) {
3069*5113495bSYour Name 			j++;
3070*5113495bSYour Name 			qdf_assert_always(j < DP_MAX_SRNGS);
3071*5113495bSYour Name 		}
3072*5113495bSYour Name 	}
3073*5113495bSYour Name 
3074*5113495bSYour Name 	for (i = 0; i < pdev->soc->num_tcl_data_rings; i++) {
3075*5113495bSYour Name 		status = dp_get_srng_ring_state_from_hal
3076*5113495bSYour Name 				(pdev->soc, pdev,
3077*5113495bSYour Name 				 &pdev->soc->tcl_data_ring[i],
3078*5113495bSYour Name 				 TCL_DATA,
3079*5113495bSYour Name 				 &soc_srngs_state->ring_state[j]);
3080*5113495bSYour Name 
3081*5113495bSYour Name 		if (status == QDF_STATUS_SUCCESS) {
3082*5113495bSYour Name 			j++;
3083*5113495bSYour Name 			qdf_assert_always(j < DP_MAX_SRNGS);
3084*5113495bSYour Name 		}
3085*5113495bSYour Name 	}
3086*5113495bSYour Name 
3087*5113495bSYour Name 	for (i = 0; i < MAX_TCL_DATA_RINGS; i++) {
3088*5113495bSYour Name 		status = dp_get_srng_ring_state_from_hal
3089*5113495bSYour Name 				(pdev->soc, pdev,
3090*5113495bSYour Name 				 &pdev->soc->tx_comp_ring[i],
3091*5113495bSYour Name 				 WBM2SW_RELEASE,
3092*5113495bSYour Name 				 &soc_srngs_state->ring_state[j]);
3093*5113495bSYour Name 
3094*5113495bSYour Name 		if (status == QDF_STATUS_SUCCESS) {
3095*5113495bSYour Name 			j++;
3096*5113495bSYour Name 			qdf_assert_always(j < DP_MAX_SRNGS);
3097*5113495bSYour Name 		}
3098*5113495bSYour Name 	}
3099*5113495bSYour Name 
3100*5113495bSYour Name 	lmac_id = dp_get_lmac_id_for_pdev_id(pdev->soc, 0, pdev->pdev_id);
3101*5113495bSYour Name 	status = dp_get_srng_ring_state_from_hal
3102*5113495bSYour Name 				(pdev->soc, pdev,
3103*5113495bSYour Name 				 &pdev->soc->rx_refill_buf_ring
3104*5113495bSYour Name 				 [lmac_id],
3105*5113495bSYour Name 				 RXDMA_BUF,
3106*5113495bSYour Name 				 &soc_srngs_state->ring_state[j]);
3107*5113495bSYour Name 
3108*5113495bSYour Name 	if (status == QDF_STATUS_SUCCESS) {
3109*5113495bSYour Name 		j++;
3110*5113495bSYour Name 		qdf_assert_always(j < DP_MAX_SRNGS);
3111*5113495bSYour Name 	}
3112*5113495bSYour Name 
3113*5113495bSYour Name 	status = dp_get_srng_ring_state_from_hal
3114*5113495bSYour Name 				(pdev->soc, pdev,
3115*5113495bSYour Name 				 &pdev->rx_refill_buf_ring2,
3116*5113495bSYour Name 				 RXDMA_BUF,
3117*5113495bSYour Name 				 &soc_srngs_state->ring_state[j]);
3118*5113495bSYour Name 
3119*5113495bSYour Name 	if (status == QDF_STATUS_SUCCESS) {
3120*5113495bSYour Name 		j++;
3121*5113495bSYour Name 		qdf_assert_always(j < DP_MAX_SRNGS);
3122*5113495bSYour Name 	}
3123*5113495bSYour Name 
3124*5113495bSYour Name 
3125*5113495bSYour Name 	for (i = 0; i < MAX_RX_MAC_RINGS; i++) {
3126*5113495bSYour Name 		status = dp_get_srng_ring_state_from_hal
3127*5113495bSYour Name 				(pdev->soc, pdev,
3128*5113495bSYour Name 				 &pdev->rx_mac_buf_ring[i],
3129*5113495bSYour Name 				 RXDMA_BUF,
3130*5113495bSYour Name 				 &soc_srngs_state->ring_state[j]);
3131*5113495bSYour Name 
3132*5113495bSYour Name 		if (status == QDF_STATUS_SUCCESS) {
3133*5113495bSYour Name 			j++;
3134*5113495bSYour Name 			qdf_assert_always(j < DP_MAX_SRNGS);
3135*5113495bSYour Name 		}
3136*5113495bSYour Name 	}
3137*5113495bSYour Name 
3138*5113495bSYour Name 	for (mac_id = 0;
3139*5113495bSYour Name 	     mac_id  < soc->wlan_cfg_ctx->num_rxdma_status_rings_per_pdev;
3140*5113495bSYour Name 	     mac_id++) {
3141*5113495bSYour Name 		lmac_id = dp_get_lmac_id_for_pdev_id(pdev->soc,
3142*5113495bSYour Name 						     mac_id, pdev->pdev_id);
3143*5113495bSYour Name 
3144*5113495bSYour Name 		dp_queue_mon_ring_stats(pdev, lmac_id, &j,
3145*5113495bSYour Name 					soc_srngs_state);
3146*5113495bSYour Name 
3147*5113495bSYour Name 		status = dp_get_srng_ring_state_from_hal
3148*5113495bSYour Name 			(pdev->soc, pdev,
3149*5113495bSYour Name 			 &pdev->soc->rxdma_mon_status_ring[lmac_id],
3150*5113495bSYour Name 			 RXDMA_MONITOR_STATUS,
3151*5113495bSYour Name 			 &soc_srngs_state->ring_state[j]);
3152*5113495bSYour Name 
3153*5113495bSYour Name 		if (status == QDF_STATUS_SUCCESS) {
3154*5113495bSYour Name 			j++;
3155*5113495bSYour Name 			qdf_assert_always(j < DP_MAX_SRNGS);
3156*5113495bSYour Name 		}
3157*5113495bSYour Name 	}
3158*5113495bSYour Name 
3159*5113495bSYour Name 	for (i = 0; i < soc->wlan_cfg_ctx->num_rxdma_dst_rings_per_pdev; i++) {
3160*5113495bSYour Name 		lmac_id = dp_get_lmac_id_for_pdev_id(pdev->soc,
3161*5113495bSYour Name 						     i, pdev->pdev_id);
3162*5113495bSYour Name 
3163*5113495bSYour Name 		status = dp_get_srng_ring_state_from_hal
3164*5113495bSYour Name 				(pdev->soc, pdev,
3165*5113495bSYour Name 				 &pdev->soc->rxdma_err_dst_ring
3166*5113495bSYour Name 				 [lmac_id],
3167*5113495bSYour Name 				 RXDMA_DST,
3168*5113495bSYour Name 				 &soc_srngs_state->ring_state[j]);
3169*5113495bSYour Name 
3170*5113495bSYour Name 		if (status == QDF_STATUS_SUCCESS) {
3171*5113495bSYour Name 			j++;
3172*5113495bSYour Name 			qdf_assert_always(j < DP_MAX_SRNGS);
3173*5113495bSYour Name 		}
3174*5113495bSYour Name 	}
3175*5113495bSYour Name 	soc_srngs_state->max_ring_id = j;
3176*5113495bSYour Name 
3177*5113495bSYour Name 	qdf_spin_lock_bh(&pdev->bkp_stats.list_lock);
3178*5113495bSYour Name 
3179*5113495bSYour Name 	soc_srngs_state->seq_num = pdev->bkp_stats.seq_num;
3180*5113495bSYour Name 
3181*5113495bSYour Name 	if (pdev->bkp_stats.queue_depth >= HTT_BKP_STATS_MAX_QUEUE_DEPTH) {
3182*5113495bSYour Name 		drop_srngs_state = TAILQ_FIRST(&pdev->bkp_stats.list);
3183*5113495bSYour Name 		qdf_assert_always(drop_srngs_state);
3184*5113495bSYour Name 		TAILQ_REMOVE(&pdev->bkp_stats.list, drop_srngs_state,
3185*5113495bSYour Name 			     list_elem);
3186*5113495bSYour Name 		qdf_mem_free(drop_srngs_state);
3187*5113495bSYour Name 		pdev->bkp_stats.queue_depth--;
3188*5113495bSYour Name 	}
3189*5113495bSYour Name 
3190*5113495bSYour Name 	pdev->bkp_stats.queue_depth++;
3191*5113495bSYour Name 	TAILQ_INSERT_TAIL(&pdev->bkp_stats.list, soc_srngs_state,
3192*5113495bSYour Name 			  list_elem);
3193*5113495bSYour Name 	pdev->bkp_stats.seq_num++;
3194*5113495bSYour Name 	qdf_spin_unlock_bh(&pdev->bkp_stats.list_lock);
3195*5113495bSYour Name 
3196*5113495bSYour Name 	qdf_queue_work(0, pdev->bkp_stats.work_queue,
3197*5113495bSYour Name 		       &pdev->bkp_stats.work);
3198*5113495bSYour Name }
3199*5113495bSYour Name 
3200*5113495bSYour Name #ifdef WIFI_MONITOR_SUPPORT
3201*5113495bSYour Name static void
3202*5113495bSYour Name dp_check_backpressure_in_monitor(uint8_t ring_id, struct dp_pdev *pdev)
3203*5113495bSYour Name {
3204*5113495bSYour Name 	if (ring_id >= HTT_SW_RING_IDX_MONITOR_STATUS_RING &&
3205*5113495bSYour Name 	    ring_id <= HTT_SW_LMAC_RING_IDX_MAX)
3206*5113495bSYour Name 		pdev->monitor_pdev->is_bkpressure = true;
3207*5113495bSYour Name }
3208*5113495bSYour Name #else
3209*5113495bSYour Name static void
3210*5113495bSYour Name dp_check_backpressure_in_monitor(uint8_t ring_id, struct dp_pdev *pdev)
3211*5113495bSYour Name {
3212*5113495bSYour Name }
3213*5113495bSYour Name #endif
3214*5113495bSYour Name 
3215*5113495bSYour Name /**
3216*5113495bSYour Name  * dp_htt_bkp_event_alert() - htt backpressure event alert
3217*5113495bSYour Name  * @msg_word:	htt packet context
3218*5113495bSYour Name  * @soc:	HTT SOC handle
3219*5113495bSYour Name  *
3220*5113495bSYour Name  * Return: after attempting to print stats
3221*5113495bSYour Name  */
3222*5113495bSYour Name static void dp_htt_bkp_event_alert(u_int32_t *msg_word, struct htt_soc *soc)
3223*5113495bSYour Name {
3224*5113495bSYour Name 	u_int8_t ring_type;
3225*5113495bSYour Name 	u_int8_t pdev_id;
3226*5113495bSYour Name 	uint8_t target_pdev_id;
3227*5113495bSYour Name 	u_int8_t ring_id;
3228*5113495bSYour Name 	u_int16_t hp_idx;
3229*5113495bSYour Name 	u_int16_t tp_idx;
3230*5113495bSYour Name 	u_int32_t bkp_time;
3231*5113495bSYour Name 	u_int32_t th_time;
3232*5113495bSYour Name 	enum htt_t2h_msg_type msg_type;
3233*5113495bSYour Name 	struct dp_soc *dpsoc;
3234*5113495bSYour Name 	struct dp_pdev *pdev;
3235*5113495bSYour Name 	struct dp_htt_timestamp *radio_tt;
3236*5113495bSYour Name 	struct wlan_cfg_dp_soc_ctxt *soc_cfg_ctx;
3237*5113495bSYour Name 
3238*5113495bSYour Name 
3239*5113495bSYour Name 	if (!soc)
3240*5113495bSYour Name 		return;
3241*5113495bSYour Name 
3242*5113495bSYour Name 	dpsoc = (struct dp_soc *)soc->dp_soc;
3243*5113495bSYour Name 	soc_cfg_ctx = dpsoc->wlan_cfg_ctx;
3244*5113495bSYour Name 	msg_type = HTT_T2H_MSG_TYPE_GET(*msg_word);
3245*5113495bSYour Name 	ring_type = HTT_T2H_RX_BKPRESSURE_RING_TYPE_GET(*msg_word);
3246*5113495bSYour Name 	target_pdev_id = HTT_T2H_RX_BKPRESSURE_PDEV_ID_GET(*msg_word);
3247*5113495bSYour Name 	pdev_id = dp_get_host_pdev_id_for_target_pdev_id(soc->dp_soc,
3248*5113495bSYour Name 							 target_pdev_id);
3249*5113495bSYour Name 	if (pdev_id >= MAX_PDEV_CNT) {
3250*5113495bSYour Name 		dp_htt_debug("%pK: pdev id %d is invalid", soc, pdev_id);
3251*5113495bSYour Name 		return;
3252*5113495bSYour Name 	}
3253*5113495bSYour Name 
3254*5113495bSYour Name 	th_time = wlan_cfg_time_control_bp(soc_cfg_ctx);
3255*5113495bSYour Name 	pdev = (struct dp_pdev *)dpsoc->pdev_list[pdev_id];
3256*5113495bSYour Name 	ring_id = HTT_T2H_RX_BKPRESSURE_RINGID_GET(*msg_word);
3257*5113495bSYour Name 	hp_idx = HTT_T2H_RX_BKPRESSURE_HEAD_IDX_GET(*(msg_word + 1));
3258*5113495bSYour Name 	tp_idx = HTT_T2H_RX_BKPRESSURE_TAIL_IDX_GET(*(msg_word + 1));
3259*5113495bSYour Name 	bkp_time = HTT_T2H_RX_BKPRESSURE_TIME_MS_GET(*(msg_word + 2));
3260*5113495bSYour Name 	radio_tt = &soc->pdevid_tt[pdev_id];
3261*5113495bSYour Name 
3262*5113495bSYour Name 	switch (ring_type) {
3263*5113495bSYour Name 	case HTT_SW_RING_TYPE_UMAC:
3264*5113495bSYour Name 		if (!time_allow_print(radio_tt->umac_path, ring_id, th_time))
3265*5113495bSYour Name 			return;
3266*5113495bSYour Name 		dp_htt_alert_print(msg_type, pdev, ring_id, hp_idx, tp_idx,
3267*5113495bSYour Name 				   bkp_time, radio_tt->umac_path,
3268*5113495bSYour Name 				   "HTT_SW_RING_TYPE_UMAC");
3269*5113495bSYour Name 	break;
3270*5113495bSYour Name 	case HTT_SW_RING_TYPE_LMAC:
3271*5113495bSYour Name 		if (!time_allow_print(radio_tt->lmac_path, ring_id, th_time))
3272*5113495bSYour Name 			return;
3273*5113495bSYour Name 		dp_check_backpressure_in_monitor(ring_id, pdev);
3274*5113495bSYour Name 		dp_htt_alert_print(msg_type, pdev, ring_id, hp_idx, tp_idx,
3275*5113495bSYour Name 				   bkp_time, radio_tt->lmac_path,
3276*5113495bSYour Name 				   "HTT_SW_RING_TYPE_LMAC");
3277*5113495bSYour Name 	break;
3278*5113495bSYour Name 	default:
3279*5113495bSYour Name 		dp_alert("Invalid ring type: %d", ring_type);
3280*5113495bSYour Name 	break;
3281*5113495bSYour Name 	}
3282*5113495bSYour Name 
3283*5113495bSYour Name 	dp_queue_ring_stats(pdev);
3284*5113495bSYour Name }
3285*5113495bSYour Name 
3286*5113495bSYour Name #ifdef WLAN_FEATURE_PKT_CAPTURE_V2
3287*5113495bSYour Name /**
3288*5113495bSYour Name  * dp_offload_ind_handler() - offload msg handler
3289*5113495bSYour Name  * @soc: HTT SOC handle
3290*5113495bSYour Name  * @msg_word: Pointer to payload
3291*5113495bSYour Name  *
3292*5113495bSYour Name  * Return: None
3293*5113495bSYour Name  */
3294*5113495bSYour Name static void
3295*5113495bSYour Name dp_offload_ind_handler(struct htt_soc *soc, uint32_t *msg_word)
3296*5113495bSYour Name {
3297*5113495bSYour Name 	u_int8_t pdev_id;
3298*5113495bSYour Name 	u_int8_t target_pdev_id;
3299*5113495bSYour Name 
3300*5113495bSYour Name 	target_pdev_id = HTT_T2H_PPDU_STATS_PDEV_ID_GET(*msg_word);
3301*5113495bSYour Name 	pdev_id = dp_get_host_pdev_id_for_target_pdev_id(soc->dp_soc,
3302*5113495bSYour Name 							 target_pdev_id);
3303*5113495bSYour Name 	dp_wdi_event_handler(WDI_EVENT_PKT_CAPTURE_OFFLOAD_TX_DATA, soc->dp_soc,
3304*5113495bSYour Name 			     msg_word, HTT_INVALID_VDEV, WDI_NO_VAL,
3305*5113495bSYour Name 			     pdev_id);
3306*5113495bSYour Name }
3307*5113495bSYour Name #else
3308*5113495bSYour Name static void
3309*5113495bSYour Name dp_offload_ind_handler(struct htt_soc *soc, uint32_t *msg_word)
3310*5113495bSYour Name {
3311*5113495bSYour Name }
3312*5113495bSYour Name #endif
3313*5113495bSYour Name 
3314*5113495bSYour Name #ifdef WLAN_FEATURE_11BE_MLO
3315*5113495bSYour Name #ifdef WLAN_MLO_MULTI_CHIP
3316*5113495bSYour Name static inline void dp_update_mlo_ts_offset(struct dp_soc *soc,
3317*5113495bSYour Name 					   uint32_t ts_lo, uint32_t ts_hi)
3318*5113495bSYour Name {
3319*5113495bSYour Name 	uint64_t mlo_offset;
3320*5113495bSYour Name 
3321*5113495bSYour Name 	mlo_offset = ((uint64_t)(ts_hi) << 32 | ts_lo);
3322*5113495bSYour Name 	soc->cdp_soc.ops->mlo_ops->mlo_update_mlo_ts_offset
3323*5113495bSYour Name 		((struct cdp_soc_t *)soc, mlo_offset);
3324*5113495bSYour Name }
3325*5113495bSYour Name 
3326*5113495bSYour Name static inline
3327*5113495bSYour Name void dp_update_mlo_delta_tsf2(struct dp_soc *soc, struct dp_pdev *pdev)
3328*5113495bSYour Name {
3329*5113495bSYour Name 	uint64_t delta_tsf2 = 0;
3330*5113495bSYour Name 
3331*5113495bSYour Name 	hal_get_tsf2_offset(soc->hal_soc, pdev->lmac_id, &delta_tsf2);
3332*5113495bSYour Name 	soc->cdp_soc.ops->mlo_ops->mlo_update_delta_tsf2
3333*5113495bSYour Name 		((struct cdp_soc_t *)soc, pdev->pdev_id, delta_tsf2);
3334*5113495bSYour Name }
3335*5113495bSYour Name #else
3336*5113495bSYour Name static inline void dp_update_mlo_ts_offset(struct dp_soc *soc,
3337*5113495bSYour Name 					   uint32_t ts_lo, uint32_t ts_hi)
3338*5113495bSYour Name {}
3339*5113495bSYour Name static inline
3340*5113495bSYour Name void dp_update_mlo_delta_tsf2(struct dp_soc *soc, struct dp_pdev *pdev)
3341*5113495bSYour Name {}
3342*5113495bSYour Name #endif
3343*5113495bSYour Name static void dp_htt_mlo_peer_map_handler(struct htt_soc *soc,
3344*5113495bSYour Name 					uint32_t *msg_word)
3345*5113495bSYour Name {
3346*5113495bSYour Name 	uint8_t mac_addr_deswizzle_buf[QDF_MAC_ADDR_SIZE];
3347*5113495bSYour Name 	uint8_t *mlo_peer_mac_addr;
3348*5113495bSYour Name 	uint16_t mlo_peer_id;
3349*5113495bSYour Name 	uint8_t num_links;
3350*5113495bSYour Name 	struct dp_mlo_flow_override_info mlo_flow_info[DP_MLO_FLOW_INFO_MAX];
3351*5113495bSYour Name 	struct dp_mlo_link_info mlo_link_info[DP_MAX_MLO_LINKS];
3352*5113495bSYour Name 	MLO_PEER_MAP_TLV_TAG_ID tlv_type = 0xff;
3353*5113495bSYour Name 	uint16_t tlv_len = 0;
3354*5113495bSYour Name 	int i = 0;
3355*5113495bSYour Name 
3356*5113495bSYour Name 	mlo_peer_id = HTT_RX_MLO_PEER_MAP_MLO_PEER_ID_GET(*msg_word);
3357*5113495bSYour Name 	num_links =
3358*5113495bSYour Name 		HTT_RX_MLO_PEER_MAP_NUM_LOGICAL_LINKS_GET(*msg_word);
3359*5113495bSYour Name 	mlo_peer_mac_addr =
3360*5113495bSYour Name 	htt_t2h_mac_addr_deswizzle((u_int8_t *)(msg_word + 1),
3361*5113495bSYour Name 				   &mac_addr_deswizzle_buf[0]);
3362*5113495bSYour Name 
3363*5113495bSYour Name 	mlo_flow_info[0].ast_idx =
3364*5113495bSYour Name 		HTT_RX_MLO_PEER_MAP_PRIMARY_AST_INDEX_GET(*(msg_word + 3));
3365*5113495bSYour Name 	mlo_flow_info[0].ast_idx_valid =
3366*5113495bSYour Name 		HTT_RX_MLO_PEER_MAP_AST_INDEX_VALID_FLAG_GET(*(msg_word + 3));
3367*5113495bSYour Name 	mlo_flow_info[0].chip_id =
3368*5113495bSYour Name 		HTT_RX_MLO_PEER_MAP_CHIP_ID_AST_INDEX_GET(*(msg_word + 3));
3369*5113495bSYour Name 	mlo_flow_info[0].tidmask =
3370*5113495bSYour Name 		HTT_RX_MLO_PEER_MAP_TIDMASK_AST_INDEX_GET(*(msg_word + 3));
3371*5113495bSYour Name 	mlo_flow_info[0].cache_set_num =
3372*5113495bSYour Name 	HTT_RX_MLO_PEER_MAP_CACHE_SET_NUM_AST_INDEX_GET(*(msg_word + 3));
3373*5113495bSYour Name 
3374*5113495bSYour Name 	mlo_flow_info[1].ast_idx =
3375*5113495bSYour Name 		HTT_RX_MLO_PEER_MAP_PRIMARY_AST_INDEX_GET(*(msg_word + 3));
3376*5113495bSYour Name 	mlo_flow_info[1].ast_idx_valid =
3377*5113495bSYour Name 		HTT_RX_MLO_PEER_MAP_AST_INDEX_VALID_FLAG_GET(*(msg_word + 3));
3378*5113495bSYour Name 	mlo_flow_info[1].chip_id =
3379*5113495bSYour Name 		HTT_RX_MLO_PEER_MAP_CHIP_ID_AST_INDEX_GET(*(msg_word + 3));
3380*5113495bSYour Name 	mlo_flow_info[1].tidmask =
3381*5113495bSYour Name 		HTT_RX_MLO_PEER_MAP_TIDMASK_AST_INDEX_GET(*(msg_word + 3));
3382*5113495bSYour Name 	mlo_flow_info[1].cache_set_num =
3383*5113495bSYour Name 	HTT_RX_MLO_PEER_MAP_CACHE_SET_NUM_AST_INDEX_GET(*(msg_word + 3));
3384*5113495bSYour Name 
3385*5113495bSYour Name 	mlo_flow_info[2].ast_idx =
3386*5113495bSYour Name 		HTT_RX_MLO_PEER_MAP_PRIMARY_AST_INDEX_GET(*(msg_word + 3));
3387*5113495bSYour Name 	mlo_flow_info[2].ast_idx_valid =
3388*5113495bSYour Name 		HTT_RX_MLO_PEER_MAP_AST_INDEX_VALID_FLAG_GET(*(msg_word + 3));
3389*5113495bSYour Name 	mlo_flow_info[2].chip_id =
3390*5113495bSYour Name 		HTT_RX_MLO_PEER_MAP_CHIP_ID_AST_INDEX_GET(*(msg_word + 3));
3391*5113495bSYour Name 	mlo_flow_info[2].tidmask =
3392*5113495bSYour Name 		HTT_RX_MLO_PEER_MAP_TIDMASK_AST_INDEX_GET(*(msg_word + 3));
3393*5113495bSYour Name 	mlo_flow_info[2].cache_set_num =
3394*5113495bSYour Name 	HTT_RX_MLO_PEER_MAP_CACHE_SET_NUM_AST_INDEX_GET(*(msg_word + 3));
3395*5113495bSYour Name 
3396*5113495bSYour Name 	msg_word = msg_word + 8;
3397*5113495bSYour Name 	while (msg_word && (i < DP_MAX_MLO_LINKS)) {
3398*5113495bSYour Name 		mlo_link_info[i].peer_chip_id = 0xFF;
3399*5113495bSYour Name 		mlo_link_info[i].vdev_id = 0xFF;
3400*5113495bSYour Name 
3401*5113495bSYour Name 		tlv_type = HTT_RX_MLO_PEER_MAP_TLV_TAG_GET(*msg_word);
3402*5113495bSYour Name 		tlv_len = HTT_RX_MLO_PEER_MAP_TLV_LENGTH_GET(*msg_word);
3403*5113495bSYour Name 
3404*5113495bSYour Name 		if (tlv_len == 0) {
3405*5113495bSYour Name 			dp_err("TLV Length is 0");
3406*5113495bSYour Name 			break;
3407*5113495bSYour Name 		}
3408*5113495bSYour Name 
3409*5113495bSYour Name 		if (tlv_type == MLO_PEER_MAP_TLV_STRUCT_SOC_VDEV_PEER_IDS) {
3410*5113495bSYour Name 			mlo_link_info[i].peer_chip_id =
3411*5113495bSYour Name 				HTT_RX_MLO_PEER_MAP_CHIP_ID_GET(
3412*5113495bSYour Name 							*(msg_word + 1));
3413*5113495bSYour Name 			mlo_link_info[i].vdev_id =
3414*5113495bSYour Name 				HTT_RX_MLO_PEER_MAP_VDEV_ID_GET(
3415*5113495bSYour Name 							*(msg_word + 1));
3416*5113495bSYour Name 		}
3417*5113495bSYour Name 		/* Add header size to tlv length */
3418*5113495bSYour Name 		tlv_len = tlv_len + HTT_TLV_HDR_LEN;
3419*5113495bSYour Name 		msg_word = (uint32_t *)(((uint8_t *)msg_word) + tlv_len);
3420*5113495bSYour Name 		i++;
3421*5113495bSYour Name 	}
3422*5113495bSYour Name 
3423*5113495bSYour Name 	dp_rx_mlo_peer_map_handler(soc->dp_soc, mlo_peer_id,
3424*5113495bSYour Name 				   mlo_peer_mac_addr,
3425*5113495bSYour Name 				   mlo_flow_info, mlo_link_info);
3426*5113495bSYour Name }
3427*5113495bSYour Name 
3428*5113495bSYour Name #ifdef QCA_SUPPORT_PRIMARY_LINK_MIGRATE
3429*5113495bSYour Name static void dp_htt_t2h_primary_link_migration(struct htt_soc *soc,
3430*5113495bSYour Name 					      uint32_t *msg_word)
3431*5113495bSYour Name {
3432*5113495bSYour Name 	u_int16_t peer_id;
3433*5113495bSYour Name 	u_int16_t ml_peer_id;
3434*5113495bSYour Name 	u_int16_t vdev_id;
3435*5113495bSYour Name 	u_int8_t pdev_id;
3436*5113495bSYour Name 	u_int8_t chip_id;
3437*5113495bSYour Name 
3438*5113495bSYour Name 	vdev_id = HTT_T2H_PRIMARY_LINK_PEER_MIGRATE_VDEV_ID_GET(
3439*5113495bSYour Name 			*msg_word);
3440*5113495bSYour Name 	pdev_id = HTT_T2H_PRIMARY_LINK_PEER_MIGRATE_PDEV_ID_GET(
3441*5113495bSYour Name 			*msg_word);
3442*5113495bSYour Name 	chip_id = HTT_T2H_PRIMARY_LINK_PEER_MIGRATE_CHIP_ID_GET(
3443*5113495bSYour Name 			*msg_word);
3444*5113495bSYour Name 	ml_peer_id = HTT_T2H_PRIMARY_LINK_PEER_MIGRATE_ML_PEER_ID_GET(
3445*5113495bSYour Name 			*(msg_word + 1));
3446*5113495bSYour Name 	peer_id = HTT_T2H_PRIMARY_LINK_PEER_MIGRATE_SW_LINK_PEER_ID_GET(
3447*5113495bSYour Name 			*(msg_word + 1));
3448*5113495bSYour Name 
3449*5113495bSYour Name 	dp_htt_info("HTT_T2H_MSG_TYPE_PRIMARY_PEER_MIGRATE_IND msg"
3450*5113495bSYour Name 		    "for peer id %d vdev id %d", peer_id, vdev_id);
3451*5113495bSYour Name 
3452*5113495bSYour Name 	dp_htt_reo_migration(soc->dp_soc, peer_id, ml_peer_id,
3453*5113495bSYour Name 			vdev_id, pdev_id, chip_id);
3454*5113495bSYour Name }
3455*5113495bSYour Name #else
3456*5113495bSYour Name static void dp_htt_t2h_primary_link_migration(struct htt_soc *soc,
3457*5113495bSYour Name 					      uint32_t *msg_word)
3458*5113495bSYour Name {
3459*5113495bSYour Name }
3460*5113495bSYour Name #endif
3461*5113495bSYour Name 
3462*5113495bSYour Name static void dp_htt_mlo_peer_unmap_handler(struct htt_soc *soc,
3463*5113495bSYour Name 					  uint32_t *msg_word)
3464*5113495bSYour Name {
3465*5113495bSYour Name 	uint16_t mlo_peer_id;
3466*5113495bSYour Name 
3467*5113495bSYour Name 	mlo_peer_id = HTT_RX_MLO_PEER_UNMAP_MLO_PEER_ID_GET(*msg_word);
3468*5113495bSYour Name 	dp_rx_mlo_peer_unmap_handler(soc->dp_soc, mlo_peer_id);
3469*5113495bSYour Name }
3470*5113495bSYour Name 
3471*5113495bSYour Name static void
3472*5113495bSYour Name dp_rx_mlo_timestamp_ind_handler(struct dp_soc *soc,
3473*5113495bSYour Name 				uint32_t *msg_word)
3474*5113495bSYour Name {
3475*5113495bSYour Name 	uint8_t pdev_id;
3476*5113495bSYour Name 	uint8_t target_pdev_id;
3477*5113495bSYour Name 	struct dp_pdev *pdev;
3478*5113495bSYour Name 
3479*5113495bSYour Name 	if (!soc)
3480*5113495bSYour Name 		return;
3481*5113495bSYour Name 
3482*5113495bSYour Name 	target_pdev_id = HTT_T2H_MLO_TIMESTAMP_OFFSET_PDEV_ID_GET(*msg_word);
3483*5113495bSYour Name 	pdev_id = dp_get_host_pdev_id_for_target_pdev_id(soc,
3484*5113495bSYour Name 							 target_pdev_id);
3485*5113495bSYour Name 
3486*5113495bSYour Name 	if (pdev_id >= MAX_PDEV_CNT) {
3487*5113495bSYour Name 		dp_htt_debug("%pK: pdev id %d is invalid", soc, pdev_id);
3488*5113495bSYour Name 		return;
3489*5113495bSYour Name 	}
3490*5113495bSYour Name 
3491*5113495bSYour Name 	pdev = (struct dp_pdev *)soc->pdev_list[pdev_id];
3492*5113495bSYour Name 
3493*5113495bSYour Name 	if (!pdev) {
3494*5113495bSYour Name 		dp_err("Invalid pdev");
3495*5113495bSYour Name 		return;
3496*5113495bSYour Name 	}
3497*5113495bSYour Name 	dp_wdi_event_handler(WDI_EVENT_MLO_TSTMP, soc,
3498*5113495bSYour Name 			     msg_word, HTT_INVALID_PEER, WDI_NO_VAL,
3499*5113495bSYour Name 			     pdev_id);
3500*5113495bSYour Name 
3501*5113495bSYour Name 	qdf_spin_lock_bh(&soc->htt_stats.lock);
3502*5113495bSYour Name 	pdev->timestamp.msg_type =
3503*5113495bSYour Name 		HTT_T2H_MLO_TIMESTAMP_OFFSET_MSG_TYPE_GET(*msg_word);
3504*5113495bSYour Name 	pdev->timestamp.pdev_id = pdev_id;
3505*5113495bSYour Name 	pdev->timestamp.chip_id =
3506*5113495bSYour Name 		HTT_T2H_MLO_TIMESTAMP_OFFSET_CHIP_ID_GET(*msg_word);
3507*5113495bSYour Name 	pdev->timestamp.mac_clk_freq =
3508*5113495bSYour Name 		HTT_T2H_MLO_TIMESTAMP_OFFSET_MAC_CLK_FREQ_MHZ_GET(*msg_word);
3509*5113495bSYour Name 	pdev->timestamp.sync_tstmp_lo_us = *(msg_word + 1);
3510*5113495bSYour Name 	pdev->timestamp.sync_tstmp_hi_us = *(msg_word + 2);
3511*5113495bSYour Name 	pdev->timestamp.mlo_offset_lo_us = *(msg_word + 3);
3512*5113495bSYour Name 	pdev->timestamp.mlo_offset_hi_us = *(msg_word + 4);
3513*5113495bSYour Name 	pdev->timestamp.mlo_offset_clks  = *(msg_word + 5);
3514*5113495bSYour Name 	pdev->timestamp.mlo_comp_us =
3515*5113495bSYour Name 	HTT_T2H_MLO_TIMESTAMP_OFFSET_MLO_TIMESTAMP_COMP_US_GET(
3516*5113495bSYour Name 							*(msg_word + 6));
3517*5113495bSYour Name 	pdev->timestamp.mlo_comp_clks =
3518*5113495bSYour Name 	HTT_T2H_MLO_TIMESTAMP_OFFSET_MLO_TIMESTAMP_COMP_CLKS_GET(
3519*5113495bSYour Name 							*(msg_word + 6));
3520*5113495bSYour Name 	pdev->timestamp.mlo_comp_timer =
3521*5113495bSYour Name 	HTT_T2H_MLO_TIMESTAMP_OFFSET_MLO_TIMESTAMP_COMP_PERIOD_US_GET(
3522*5113495bSYour Name 							*(msg_word + 7));
3523*5113495bSYour Name 
3524*5113495bSYour Name 	dp_htt_debug("tsf_lo=%d tsf_hi=%d, mlo_ofst_lo=%d, mlo_ofst_hi=%d",
3525*5113495bSYour Name 		     pdev->timestamp.sync_tstmp_lo_us,
3526*5113495bSYour Name 		     pdev->timestamp.sync_tstmp_hi_us,
3527*5113495bSYour Name 		     pdev->timestamp.mlo_offset_lo_us,
3528*5113495bSYour Name 		     pdev->timestamp.mlo_offset_hi_us);
3529*5113495bSYour Name 
3530*5113495bSYour Name 	qdf_spin_unlock_bh(&soc->htt_stats.lock);
3531*5113495bSYour Name 
3532*5113495bSYour Name 	dp_update_mlo_ts_offset(soc,
3533*5113495bSYour Name 				pdev->timestamp.mlo_offset_lo_us,
3534*5113495bSYour Name 				pdev->timestamp.mlo_offset_hi_us);
3535*5113495bSYour Name 
3536*5113495bSYour Name 	dp_update_mlo_delta_tsf2(soc, pdev);
3537*5113495bSYour Name }
3538*5113495bSYour Name #else
3539*5113495bSYour Name static void dp_htt_mlo_peer_map_handler(struct htt_soc *soc,
3540*5113495bSYour Name 					uint32_t *msg_word)
3541*5113495bSYour Name {
3542*5113495bSYour Name 	dp_alert("Unexpected event");
3543*5113495bSYour Name }
3544*5113495bSYour Name 
3545*5113495bSYour Name static void dp_htt_mlo_peer_unmap_handler(struct htt_soc *soc,
3546*5113495bSYour Name 					 uint32_t *msg_word)
3547*5113495bSYour Name {
3548*5113495bSYour Name 	dp_alert("Unexpected event");
3549*5113495bSYour Name }
3550*5113495bSYour Name 
3551*5113495bSYour Name static void
3552*5113495bSYour Name dp_rx_mlo_timestamp_ind_handler(void *soc_handle,
3553*5113495bSYour Name 				uint32_t *msg_word)
3554*5113495bSYour Name {
3555*5113495bSYour Name 	dp_alert("Unexpected event");
3556*5113495bSYour Name }
3557*5113495bSYour Name 
3558*5113495bSYour Name static void dp_htt_t2h_primary_link_migration(struct htt_soc *soc,
3559*5113495bSYour Name 					      uint32_t *msg_word)
3560*5113495bSYour Name {
3561*5113495bSYour Name }
3562*5113495bSYour Name #endif
3563*5113495bSYour Name 
3564*5113495bSYour Name /**
3565*5113495bSYour Name  * dp_htt_rx_addba_handler() - RX Addba HTT msg handler
3566*5113495bSYour Name  * @soc: DP Soc handler
3567*5113495bSYour Name  * @peer_id: ID of peer
3568*5113495bSYour Name  * @tid: TID number
3569*5113495bSYour Name  * @win_sz: BA window size
3570*5113495bSYour Name  *
3571*5113495bSYour Name  * Return: None
3572*5113495bSYour Name  */
3573*5113495bSYour Name static void
3574*5113495bSYour Name dp_htt_rx_addba_handler(struct dp_soc *soc, uint16_t peer_id,
3575*5113495bSYour Name 			uint8_t tid, uint16_t win_sz)
3576*5113495bSYour Name {
3577*5113495bSYour Name 	uint16_t status;
3578*5113495bSYour Name 	struct dp_peer *peer;
3579*5113495bSYour Name 
3580*5113495bSYour Name 	peer = dp_peer_get_ref_by_id(soc, peer_id, DP_MOD_ID_HTT);
3581*5113495bSYour Name 
3582*5113495bSYour Name 	if (!peer) {
3583*5113495bSYour Name 		dp_err("Peer not found peer id %d", peer_id);
3584*5113495bSYour Name 		return;
3585*5113495bSYour Name 	}
3586*5113495bSYour Name 
3587*5113495bSYour Name 	status = dp_addba_requestprocess_wifi3((struct cdp_soc_t *)soc,
3588*5113495bSYour Name 					       peer->mac_addr.raw,
3589*5113495bSYour Name 					       peer->vdev->vdev_id, 0,
3590*5113495bSYour Name 					       tid, 0, win_sz, 0xffff);
3591*5113495bSYour Name 
3592*5113495bSYour Name 	dp_addba_resp_tx_completion_wifi3(
3593*5113495bSYour Name 		(struct cdp_soc_t *)soc,
3594*5113495bSYour Name 		peer->mac_addr.raw, peer->vdev->vdev_id,
3595*5113495bSYour Name 		tid,
3596*5113495bSYour Name 		status);
3597*5113495bSYour Name 
3598*5113495bSYour Name 	dp_peer_unref_delete(peer, DP_MOD_ID_HTT);
3599*5113495bSYour Name 
3600*5113495bSYour Name 	dp_info("PeerID %d BAW %d TID %d stat %d",
3601*5113495bSYour Name 		peer_id, win_sz, tid, status);
3602*5113495bSYour Name }
3603*5113495bSYour Name 
3604*5113495bSYour Name /**
3605*5113495bSYour Name  * dp_htt_ppdu_id_fmt_handler() - PPDU ID Format handler
3606*5113495bSYour Name  * @soc: HTT SOC handle
3607*5113495bSYour Name  * @msg_word: Pointer to payload
3608*5113495bSYour Name  *
3609*5113495bSYour Name  * Return: None
3610*5113495bSYour Name  */
3611*5113495bSYour Name static void
3612*5113495bSYour Name dp_htt_ppdu_id_fmt_handler(struct dp_soc *soc, uint32_t *msg_word)
3613*5113495bSYour Name {
3614*5113495bSYour Name 	uint8_t msg_type, valid, bits, offset;
3615*5113495bSYour Name 
3616*5113495bSYour Name 	msg_type = HTT_T2H_MSG_TYPE_GET(*msg_word);
3617*5113495bSYour Name 
3618*5113495bSYour Name 	msg_word += HTT_PPDU_ID_FMT_IND_LINK_ID_OFFSET;
3619*5113495bSYour Name 	valid = HTT_PPDU_ID_FMT_IND_VALID_GET_BITS31_16(*msg_word);
3620*5113495bSYour Name 	bits = HTT_PPDU_ID_FMT_IND_BITS_GET_BITS31_16(*msg_word);
3621*5113495bSYour Name 	offset = HTT_PPDU_ID_FMT_IND_OFFSET_GET_BITS31_16(*msg_word);
3622*5113495bSYour Name 
3623*5113495bSYour Name 	dp_info("link_id: valid %u bits %u offset %u", valid, bits, offset);
3624*5113495bSYour Name 
3625*5113495bSYour Name 	if (valid) {
3626*5113495bSYour Name 		soc->link_id_offset = offset;
3627*5113495bSYour Name 		soc->link_id_bits = bits;
3628*5113495bSYour Name 	}
3629*5113495bSYour Name }
3630*5113495bSYour Name 
3631*5113495bSYour Name #ifdef IPA_OPT_WIFI_DP
3632*5113495bSYour Name static void dp_ipa_rx_cce_super_rule_setup_done_handler(struct htt_soc *soc,
3633*5113495bSYour Name 							uint32_t *msg_word)
3634*5113495bSYour Name {
3635*5113495bSYour Name 	uint8_t pdev_id = 0;
3636*5113495bSYour Name 	uint8_t resp_type = 0;
3637*5113495bSYour Name 	uint8_t is_rules_enough = 0;
3638*5113495bSYour Name 	uint8_t num_rules_avail = 0;
3639*5113495bSYour Name 	int filter0_result = 0, filter1_result = 0;
3640*5113495bSYour Name 	bool is_success = false;
3641*5113495bSYour Name 
3642*5113495bSYour Name 	pdev_id = HTT_RX_CCE_SUPER_RULE_SETUP_DONE_PDEV_ID_GET(*msg_word);
3643*5113495bSYour Name 	resp_type = HTT_RX_CCE_SUPER_RULE_SETUP_DONE_RESPONSE_TYPE_GET(
3644*5113495bSYour Name 								*msg_word);
3645*5113495bSYour Name 	dp_info("opt_dp:: cce_super_rule_rsp pdev_id: %d resp_type: %d",
3646*5113495bSYour Name 		pdev_id, resp_type);
3647*5113495bSYour Name 
3648*5113495bSYour Name 	switch (resp_type) {
3649*5113495bSYour Name 	case HTT_RX_CCE_SUPER_RULE_SETUP_REQ_RESPONSE:
3650*5113495bSYour Name 	{
3651*5113495bSYour Name 		is_rules_enough =
3652*5113495bSYour Name 			HTT_RX_CCE_SUPER_RULE_SETUP_DONE_IS_RULE_ENOUGH_GET(
3653*5113495bSYour Name 								*msg_word);
3654*5113495bSYour Name 		num_rules_avail =
3655*5113495bSYour Name 			HTT_RX_CCE_SUPER_RULE_SETUP_DONE_AVAIL_RULE_NUM_GET(
3656*5113495bSYour Name 								*msg_word);
3657*5113495bSYour Name 		if (is_rules_enough == 1) {
3658*5113495bSYour Name 			is_success = true;
3659*5113495bSYour Name 			soc->stats.reserve_fail_cnt = 0;
3660*5113495bSYour Name 		} else {
3661*5113495bSYour Name 			is_success = false;
3662*5113495bSYour Name 			soc->stats.reserve_fail_cnt++;
3663*5113495bSYour Name 			if (soc->stats.reserve_fail_cnt >
3664*5113495bSYour Name 					MAX_RESERVE_FAIL_ATTEMPT) {
3665*5113495bSYour Name 				/*
3666*5113495bSYour Name 				 * IPA will retry only after an hour by default
3667*5113495bSYour Name 				 * after MAX_RESERVE_FAIL_ATTEMPT
3668*5113495bSYour Name 				 */
3669*5113495bSYour Name 				soc->stats.abort_count++;
3670*5113495bSYour Name 				soc->stats.reserve_fail_cnt = 0;
3671*5113495bSYour Name 				dp_info(
3672*5113495bSYour Name 				  "opt_dp: Filter reserve failed max attempts");
3673*5113495bSYour Name 			}
3674*5113495bSYour Name 			dp_info("opt_dp:: Filter reserve failed. Rules avail %d",
3675*5113495bSYour Name 				num_rules_avail);
3676*5113495bSYour Name 		}
3677*5113495bSYour Name 		dp_ipa_wdi_opt_dpath_notify_flt_rsvd(is_success);
3678*5113495bSYour Name 		break;
3679*5113495bSYour Name 	}
3680*5113495bSYour Name 	case HTT_RX_CCE_SUPER_RULE_INSTALL_RESPONSE:
3681*5113495bSYour Name 	{
3682*5113495bSYour Name 		filter0_result =
3683*5113495bSYour Name 			HTT_RX_CCE_SUPER_RULE_SETUP_DONE_CFG_RESULT_0_GET(
3684*5113495bSYour Name 								     *msg_word);
3685*5113495bSYour Name 		filter1_result =
3686*5113495bSYour Name 			HTT_RX_CCE_SUPER_RULE_SETUP_DONE_CFG_RESULT_1_GET(
3687*5113495bSYour Name 								     *msg_word);
3688*5113495bSYour Name 
3689*5113495bSYour Name 		dp_ipa_wdi_opt_dpath_notify_flt_add_rem_cb(filter0_result,
3690*5113495bSYour Name 							   filter1_result);
3691*5113495bSYour Name 		break;
3692*5113495bSYour Name 	}
3693*5113495bSYour Name 	case HTT_RX_CCE_SUPER_RULE_RELEASE_RESPONSE:
3694*5113495bSYour Name 	{
3695*5113495bSYour Name 		filter0_result =
3696*5113495bSYour Name 			HTT_RX_CCE_SUPER_RULE_SETUP_DONE_CFG_RESULT_0_GET(
3697*5113495bSYour Name 								     *msg_word);
3698*5113495bSYour Name 		filter1_result =
3699*5113495bSYour Name 			HTT_RX_CCE_SUPER_RULE_SETUP_DONE_CFG_RESULT_1_GET(
3700*5113495bSYour Name 								     *msg_word);
3701*5113495bSYour Name 
3702*5113495bSYour Name 		dp_ipa_wdi_opt_dpath_notify_flt_rlsd(filter0_result,
3703*5113495bSYour Name 						     filter1_result);
3704*5113495bSYour Name 		break;
3705*5113495bSYour Name 	}
3706*5113495bSYour Name 	default:
3707*5113495bSYour Name 		dp_info("opt_dp:: Wrong Super rule setup response");
3708*5113495bSYour Name 	};
3709*5113495bSYour Name 
3710*5113495bSYour Name 	dp_info("opt_dp:: cce super rule resp type: %d, is_rules_enough: %d",
3711*5113495bSYour Name 		resp_type, is_rules_enough);
3712*5113495bSYour Name 	dp_info("num_rules_avail: %d, rslt0: %d, rslt1: %d",
3713*5113495bSYour Name 		num_rules_avail, filter0_result, filter1_result);
3714*5113495bSYour Name }
3715*5113495bSYour Name #else
3716*5113495bSYour Name static void dp_ipa_rx_cce_super_rule_setup_done_handler(struct htt_soc *soc,
3717*5113495bSYour Name 							uint32_t *msg_word)
3718*5113495bSYour Name {
3719*5113495bSYour Name }
3720*5113495bSYour Name #endif
3721*5113495bSYour Name #if defined(WLAN_FEATURE_11BE_MLO) && defined(DP_MLO_LINK_STATS_SUPPORT)
3722*5113495bSYour Name static inline void
3723*5113495bSYour Name dp_htt_peer_ext_evt(struct htt_soc *soc, uint32_t *msg_word)
3724*5113495bSYour Name {
3725*5113495bSYour Name 	struct dp_peer_ext_evt_info info;
3726*5113495bSYour Name 	uint8_t mac_addr_deswizzle_buf[QDF_MAC_ADDR_SIZE];
3727*5113495bSYour Name 
3728*5113495bSYour Name 	info.peer_id = HTT_RX_PEER_EXTENDED_PEER_ID_GET(*msg_word);
3729*5113495bSYour Name 	info.vdev_id = HTT_RX_PEER_EXTENDED_VDEV_ID_GET(*msg_word);
3730*5113495bSYour Name 	info.link_id =
3731*5113495bSYour Name 		HTT_RX_PEER_EXTENDED_LOGICAL_LINK_ID_GET(*(msg_word + 2));
3732*5113495bSYour Name 	info.link_id_valid =
3733*5113495bSYour Name 		HTT_RX_PEER_EXTENDED_LOGICAL_LINK_ID_VALID_GET(*(msg_word + 2));
3734*5113495bSYour Name 
3735*5113495bSYour Name 	info.peer_mac_addr =
3736*5113495bSYour Name 	htt_t2h_mac_addr_deswizzle((u_int8_t *)(msg_word + 1),
3737*5113495bSYour Name 				   &mac_addr_deswizzle_buf[0]);
3738*5113495bSYour Name 
3739*5113495bSYour Name 	dp_htt_info("peer id %u, vdev id %u, link id %u, valid %u,peer_mac " QDF_MAC_ADDR_FMT,
3740*5113495bSYour Name 		    info.peer_id, info.vdev_id, info.link_id,
3741*5113495bSYour Name 		    info.link_id_valid, QDF_MAC_ADDR_REF(info.peer_mac_addr));
3742*5113495bSYour Name 
3743*5113495bSYour Name 	dp_rx_peer_ext_evt(soc->dp_soc, &info);
3744*5113495bSYour Name }
3745*5113495bSYour Name #else
3746*5113495bSYour Name static inline void
3747*5113495bSYour Name dp_htt_peer_ext_evt(struct htt_soc *soc, uint32_t *msg_word)
3748*5113495bSYour Name {
3749*5113495bSYour Name }
3750*5113495bSYour Name #endif
3751*5113495bSYour Name 
3752*5113495bSYour Name #ifdef WLAN_FEATURE_CE_RX_BUFFER_REUSE
3753*5113495bSYour Name static void dp_htt_rx_nbuf_free(qdf_nbuf_t nbuf)
3754*5113495bSYour Name {
3755*5113495bSYour Name 	nbuf = wbuff_buff_put(nbuf);
3756*5113495bSYour Name 	if (nbuf)
3757*5113495bSYour Name 		qdf_nbuf_free(nbuf);
3758*5113495bSYour Name }
3759*5113495bSYour Name #else
3760*5113495bSYour Name static inline void dp_htt_rx_nbuf_free(qdf_nbuf_t nbuf)
3761*5113495bSYour Name {
3762*5113495bSYour Name 	return qdf_nbuf_free(nbuf);
3763*5113495bSYour Name }
3764*5113495bSYour Name #endif
3765*5113495bSYour Name 
3766*5113495bSYour Name #ifdef WLAN_FEATURE_TX_LATENCY_STATS
3767*5113495bSYour Name #define TX_LATENCY_STATS_PERIOD_MAX_MS \
3768*5113495bSYour Name 	(HTT_H2T_TX_LATENCY_STATS_CFG_PERIODIC_INTERVAL_M >> \
3769*5113495bSYour Name 	 HTT_H2T_TX_LATENCY_STATS_CFG_PERIODIC_INTERVAL_S)
3770*5113495bSYour Name 
3771*5113495bSYour Name #define TX_LATENCY_STATS_GRANULARITY_MAX_MS \
3772*5113495bSYour Name 	(HTT_H2T_TX_LATENCY_STATS_CFG_GRANULARITY_M >> \
3773*5113495bSYour Name 	 HTT_H2T_TX_LATENCY_STATS_CFG_GRANULARITY_S)
3774*5113495bSYour Name 
3775*5113495bSYour Name /**
3776*5113495bSYour Name  * dp_h2t_tx_latency_stats_cfg_msg_send(): send HTT message for tx latency
3777*5113495bSYour Name  * stats config to FW
3778*5113495bSYour Name  * @dp_soc: DP SOC handle
3779*5113495bSYour Name  * @vdev_id: vdev id
3780*5113495bSYour Name  * @enable: indicates enablement of the feature
3781*5113495bSYour Name  * @period: statistical period for transmit latency in terms of ms
3782*5113495bSYour Name  * @granularity: granularity for tx latency distribution in terms of ms
3783*5113495bSYour Name  *
3784*5113495bSYour Name  * return: QDF STATUS
3785*5113495bSYour Name  */
3786*5113495bSYour Name QDF_STATUS
3787*5113495bSYour Name dp_h2t_tx_latency_stats_cfg_msg_send(struct dp_soc *dp_soc, uint16_t vdev_id,
3788*5113495bSYour Name 				     bool enable, uint32_t period,
3789*5113495bSYour Name 				     uint32_t granularity)
3790*5113495bSYour Name {
3791*5113495bSYour Name 	struct htt_soc *soc = dp_soc->htt_handle;
3792*5113495bSYour Name 	struct dp_htt_htc_pkt *pkt;
3793*5113495bSYour Name 	uint8_t *htt_logger_bufp;
3794*5113495bSYour Name 	qdf_nbuf_t msg;
3795*5113495bSYour Name 	uint32_t *msg_word;
3796*5113495bSYour Name 	QDF_STATUS status;
3797*5113495bSYour Name 	qdf_size_t size;
3798*5113495bSYour Name 
3799*5113495bSYour Name 	if (period > TX_LATENCY_STATS_PERIOD_MAX_MS ||
3800*5113495bSYour Name 	    granularity > TX_LATENCY_STATS_GRANULARITY_MAX_MS)
3801*5113495bSYour Name 		return QDF_STATUS_E_INVAL;
3802*5113495bSYour Name 
3803*5113495bSYour Name 	size = sizeof(struct htt_h2t_tx_latency_stats_cfg);
3804*5113495bSYour Name 	msg = qdf_nbuf_alloc(soc->osdev, HTT_MSG_BUF_SIZE(size),
3805*5113495bSYour Name 			     HTC_HEADER_LEN + HTC_HDR_ALIGNMENT_PADDING,
3806*5113495bSYour Name 			     4, TRUE);
3807*5113495bSYour Name 	if (!msg)
3808*5113495bSYour Name 		return QDF_STATUS_E_NOMEM;
3809*5113495bSYour Name 
3810*5113495bSYour Name 	/*
3811*5113495bSYour Name 	 * Set the length of the message.
3812*5113495bSYour Name 	 * The contribution from the HTC_HDR_ALIGNMENT_PADDING is added
3813*5113495bSYour Name 	 * separately during the below call to qdf_nbuf_push_head.
3814*5113495bSYour Name 	 * The contribution from the HTC header is added separately inside HTC.
3815*5113495bSYour Name 	 */
3816*5113495bSYour Name 	if (!qdf_nbuf_put_tail(msg, size)) {
3817*5113495bSYour Name 		dp_htt_err("Failed to expand head");
3818*5113495bSYour Name 		qdf_nbuf_free(msg);
3819*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
3820*5113495bSYour Name 	}
3821*5113495bSYour Name 
3822*5113495bSYour Name 	msg_word = (uint32_t *)qdf_nbuf_data(msg);
3823*5113495bSYour Name 	memset(msg_word, 0, size);
3824*5113495bSYour Name 
3825*5113495bSYour Name 	qdf_nbuf_push_head(msg, HTC_HDR_ALIGNMENT_PADDING);
3826*5113495bSYour Name 	htt_logger_bufp = (uint8_t *)msg_word;
3827*5113495bSYour Name 	HTT_H2T_MSG_TYPE_SET(*msg_word,
3828*5113495bSYour Name 			     HTT_H2T_MSG_TYPE_TX_LATENCY_STATS_CFG);
3829*5113495bSYour Name 	HTT_H2T_TX_LATENCY_STATS_CFG_VDEV_ID_SET(*msg_word, vdev_id);
3830*5113495bSYour Name 	HTT_H2T_TX_LATENCY_STATS_CFG_ENABLE_SET(*msg_word, enable);
3831*5113495bSYour Name 	HTT_H2T_TX_LATENCY_STATS_CFG_PERIODIC_INTERVAL_SET(*msg_word, period);
3832*5113495bSYour Name 	HTT_H2T_TX_LATENCY_STATS_CFG_GRANULARITY_SET(*msg_word, granularity);
3833*5113495bSYour Name 
3834*5113495bSYour Name 	pkt = htt_htc_pkt_alloc(soc);
3835*5113495bSYour Name 	if (!pkt) {
3836*5113495bSYour Name 		dp_htt_err("Fail to allocate dp_htt_htc_pkt buffer");
3837*5113495bSYour Name 		qdf_nbuf_free(msg);
3838*5113495bSYour Name 		return QDF_STATUS_E_NOMEM;
3839*5113495bSYour Name 	}
3840*5113495bSYour Name 
3841*5113495bSYour Name 	pkt->soc_ctxt = NULL;
3842*5113495bSYour Name 
3843*5113495bSYour Name 	/* macro to set packet parameters for TX */
3844*5113495bSYour Name 	SET_HTC_PACKET_INFO_TX(
3845*5113495bSYour Name 			&pkt->htc_pkt,
3846*5113495bSYour Name 			dp_htt_h2t_send_complete_free_netbuf,
3847*5113495bSYour Name 			qdf_nbuf_data(msg),
3848*5113495bSYour Name 			qdf_nbuf_len(msg),
3849*5113495bSYour Name 			soc->htc_endpoint,
3850*5113495bSYour Name 			HTC_TX_PACKET_TAG_RUNTIME_PUT);
3851*5113495bSYour Name 
3852*5113495bSYour Name 	SET_HTC_PACKET_NET_BUF_CONTEXT(&pkt->htc_pkt, msg);
3853*5113495bSYour Name 
3854*5113495bSYour Name 	status = DP_HTT_SEND_HTC_PKT(
3855*5113495bSYour Name 			soc, pkt,
3856*5113495bSYour Name 			HTT_H2T_MSG_TYPE_TX_LATENCY_STATS_CFG,
3857*5113495bSYour Name 			htt_logger_bufp);
3858*5113495bSYour Name 
3859*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(status)) {
3860*5113495bSYour Name 		qdf_nbuf_free(msg);
3861*5113495bSYour Name 		htt_htc_pkt_free(soc, pkt);
3862*5113495bSYour Name 	}
3863*5113495bSYour Name 
3864*5113495bSYour Name 	dp_htt_debug("vdev id %u enable %u period %u granularity %u status %d",
3865*5113495bSYour Name 		     vdev_id, enable, period, granularity, status);
3866*5113495bSYour Name 	return status;
3867*5113495bSYour Name }
3868*5113495bSYour Name 
3869*5113495bSYour Name /**
3870*5113495bSYour Name  * dp_htt_tx_latency_get_stats_elem(): get tx latency stats from HTT message
3871*5113495bSYour Name  * @msg_buf: pointer to stats in HTT message
3872*5113495bSYour Name  * @elem_size_msg: size of per peer stats which is reported in HTT message
3873*5113495bSYour Name  * @local_buf: additional buffer to hold the stats
3874*5113495bSYour Name  * @elem_size_local: size of per peer stats according to current host side
3875*5113495bSYour Name  * htt definition
3876*5113495bSYour Name  *
3877*5113495bSYour Name  * This function is to handle htt version mismatch(between host and target)
3878*5113495bSYour Name  * case. It compares elem_size_msg with elem_size_local, when elem_size_msg
3879*5113495bSYour Name  * is greater than or equal to elem_size_local, return the pointer to stats
3880*5113495bSYour Name  * in HTT message; otherwise, copy the stas(with size elem_size_msg) from
3881*5113495bSYour Name  * HTT message to local buffer and leave the left as zero, then return pointer
3882*5113495bSYour Name  * to this local buffer.
3883*5113495bSYour Name  *
3884*5113495bSYour Name  * return: pointer to tx latency stats
3885*5113495bSYour Name  */
3886*5113495bSYour Name static inline htt_t2h_peer_tx_latency_stats *
3887*5113495bSYour Name dp_htt_tx_latency_get_stats_elem(uint8_t *msg_buf, uint32_t elem_size_msg,
3888*5113495bSYour Name 				 htt_t2h_peer_tx_latency_stats *local_buf,
3889*5113495bSYour Name 				 uint32_t elem_size_local) {
3890*5113495bSYour Name 	if (elem_size_msg >= elem_size_local)
3891*5113495bSYour Name 		return (htt_t2h_peer_tx_latency_stats *)msg_buf;
3892*5113495bSYour Name 
3893*5113495bSYour Name 	qdf_mem_zero(local_buf, sizeof(*local_buf));
3894*5113495bSYour Name 	qdf_mem_copy(local_buf, msg_buf, elem_size_msg);
3895*5113495bSYour Name 	return local_buf;
3896*5113495bSYour Name }
3897*5113495bSYour Name 
3898*5113495bSYour Name #define TX_LATENCY_STATS_GET_PAYLOAD_ELEM_SIZE \
3899*5113495bSYour Name 	HTT_T2H_TX_LATENCY_STATS_PERIODIC_IND_PAYLOAD_ELEM_SIZE_GET
3900*5113495bSYour Name #define TX_LATENCY_STATS_GET_GRANULARITY \
3901*5113495bSYour Name 	HTT_T2H_TX_LATENCY_STATS_PERIODIC_IND_GRANULARITY_GET
3902*5113495bSYour Name 
3903*5113495bSYour Name /**
3904*5113495bSYour Name  * dp_htt_tx_latency_stats_handler - Handle tx latency stats received from FW
3905*5113495bSYour Name  * @soc: htt soc handle
3906*5113495bSYour Name  * @htt_t2h_msg: HTT message nbuf
3907*5113495bSYour Name  *
3908*5113495bSYour Name  * Return: void
3909*5113495bSYour Name  */
3910*5113495bSYour Name static void
3911*5113495bSYour Name dp_htt_tx_latency_stats_handler(struct htt_soc *soc,
3912*5113495bSYour Name 				qdf_nbuf_t htt_t2h_msg)
3913*5113495bSYour Name {
3914*5113495bSYour Name 	struct dp_soc *dpsoc = (struct dp_soc *)soc->dp_soc;
3915*5113495bSYour Name 	uint8_t pdev_id;
3916*5113495bSYour Name 	uint8_t target_pdev_id;
3917*5113495bSYour Name 	struct dp_pdev *pdev;
3918*5113495bSYour Name 	htt_t2h_peer_tx_latency_stats stats, *pstats;
3919*5113495bSYour Name 	uint32_t elem_size_msg, elem_size_local, granularity;
3920*5113495bSYour Name 	uint32_t *msg_word;
3921*5113495bSYour Name 	int32_t buf_len;
3922*5113495bSYour Name 	uint8_t *pbuf;
3923*5113495bSYour Name 
3924*5113495bSYour Name 	buf_len = qdf_nbuf_len(htt_t2h_msg);
3925*5113495bSYour Name 	if (buf_len <= HTT_T2H_TX_LATENCY_STATS_PERIODIC_IND_HDR_SIZE)
3926*5113495bSYour Name 		return;
3927*5113495bSYour Name 
3928*5113495bSYour Name 	pbuf = qdf_nbuf_data(htt_t2h_msg);
3929*5113495bSYour Name 	msg_word = (uint32_t *)pbuf;
3930*5113495bSYour Name 	target_pdev_id =
3931*5113495bSYour Name 		HTT_T2H_TX_LATENCY_STATS_PERIODIC_IND_PDEV_ID_GET(*msg_word);
3932*5113495bSYour Name 	pdev_id = dp_get_host_pdev_id_for_target_pdev_id(dpsoc,
3933*5113495bSYour Name 							 target_pdev_id);
3934*5113495bSYour Name 	if (pdev_id >= MAX_PDEV_CNT)
3935*5113495bSYour Name 		return;
3936*5113495bSYour Name 
3937*5113495bSYour Name 	pdev = dpsoc->pdev_list[pdev_id];
3938*5113495bSYour Name 	if (!pdev) {
3939*5113495bSYour Name 		dp_err("PDEV is NULL for pdev_id:%d", pdev_id);
3940*5113495bSYour Name 		return;
3941*5113495bSYour Name 	}
3942*5113495bSYour Name 
3943*5113495bSYour Name 	qdf_trace_hex_dump(QDF_MODULE_ID_DP_HTT, QDF_TRACE_LEVEL_INFO,
3944*5113495bSYour Name 			   (void *)pbuf, buf_len);
3945*5113495bSYour Name 
3946*5113495bSYour Name 	elem_size_msg = TX_LATENCY_STATS_GET_PAYLOAD_ELEM_SIZE(*msg_word);
3947*5113495bSYour Name 	elem_size_local = sizeof(stats);
3948*5113495bSYour Name 	granularity = TX_LATENCY_STATS_GET_GRANULARITY(*msg_word);
3949*5113495bSYour Name 
3950*5113495bSYour Name 	/* Adjust pbuf to point to the first stat in buffer */
3951*5113495bSYour Name 	pbuf += HTT_T2H_TX_LATENCY_STATS_PERIODIC_IND_HDR_SIZE;
3952*5113495bSYour Name 	buf_len -= HTT_T2H_TX_LATENCY_STATS_PERIODIC_IND_HDR_SIZE;
3953*5113495bSYour Name 
3954*5113495bSYour Name 	/* Parse the received buffer till payload size reaches 0 */
3955*5113495bSYour Name 	while (buf_len > 0) {
3956*5113495bSYour Name 		if (buf_len < elem_size_msg) {
3957*5113495bSYour Name 			dp_err_rl("invalid payload size left %d - %d",
3958*5113495bSYour Name 				  buf_len, elem_size_msg);
3959*5113495bSYour Name 			break;
3960*5113495bSYour Name 		}
3961*5113495bSYour Name 
3962*5113495bSYour Name 		pstats = dp_htt_tx_latency_get_stats_elem(pbuf, elem_size_msg,
3963*5113495bSYour Name 							  &stats,
3964*5113495bSYour Name 							  elem_size_local);
3965*5113495bSYour Name 		dp_tx_latency_stats_update_cca(dpsoc, pstats->peer_id,
3966*5113495bSYour Name 					       granularity,
3967*5113495bSYour Name 					       pstats->peer_tx_latency,
3968*5113495bSYour Name 					       pstats->avg_latency);
3969*5113495bSYour Name 		pbuf += elem_size_msg;
3970*5113495bSYour Name 		buf_len -= elem_size_msg;
3971*5113495bSYour Name 	}
3972*5113495bSYour Name 
3973*5113495bSYour Name 	dp_tx_latency_stats_report(dpsoc, pdev);
3974*5113495bSYour Name }
3975*5113495bSYour Name #else
3976*5113495bSYour Name static inline void
3977*5113495bSYour Name dp_htt_tx_latency_stats_handler(struct htt_soc *soc,
3978*5113495bSYour Name 				qdf_nbuf_t htt_t2h_msg)
3979*5113495bSYour Name {
3980*5113495bSYour Name }
3981*5113495bSYour Name #endif
3982*5113495bSYour Name 
3983*5113495bSYour Name void dp_htt_t2h_msg_handler(void *context, HTC_PACKET *pkt)
3984*5113495bSYour Name {
3985*5113495bSYour Name 	struct htt_soc *soc = (struct htt_soc *) context;
3986*5113495bSYour Name 	qdf_nbuf_t htt_t2h_msg = (qdf_nbuf_t) pkt->pPktContext;
3987*5113495bSYour Name 	u_int32_t *msg_word;
3988*5113495bSYour Name 	enum htt_t2h_msg_type msg_type;
3989*5113495bSYour Name 	bool free_buf = true;
3990*5113495bSYour Name 
3991*5113495bSYour Name 	/* check for successful message reception */
3992*5113495bSYour Name 	if (pkt->Status != QDF_STATUS_SUCCESS) {
3993*5113495bSYour Name 		if (pkt->Status != QDF_STATUS_E_CANCELED)
3994*5113495bSYour Name 			soc->stats.htc_err_cnt++;
3995*5113495bSYour Name 
3996*5113495bSYour Name 		dp_htt_rx_nbuf_free(htt_t2h_msg);
3997*5113495bSYour Name 		return;
3998*5113495bSYour Name 	}
3999*5113495bSYour Name 
4000*5113495bSYour Name 	/* TODO: Check if we should pop the HTC/HTT header alignment padding */
4001*5113495bSYour Name 
4002*5113495bSYour Name 	msg_word = (u_int32_t *) qdf_nbuf_data(htt_t2h_msg);
4003*5113495bSYour Name 	msg_type = HTT_T2H_MSG_TYPE_GET(*msg_word);
4004*5113495bSYour Name 	htt_event_record(soc->htt_logger_handle,
4005*5113495bSYour Name 			 msg_type, (uint8_t *)msg_word);
4006*5113495bSYour Name 	switch (msg_type) {
4007*5113495bSYour Name 	case HTT_T2H_MSG_TYPE_BKPRESSURE_EVENT_IND:
4008*5113495bSYour Name 	{
4009*5113495bSYour Name 		dp_htt_bkp_event_alert(msg_word, soc);
4010*5113495bSYour Name 		break;
4011*5113495bSYour Name 	}
4012*5113495bSYour Name 	case HTT_T2H_MSG_TYPE_PEER_MAP:
4013*5113495bSYour Name 		{
4014*5113495bSYour Name 			u_int8_t mac_addr_deswizzle_buf[QDF_MAC_ADDR_SIZE];
4015*5113495bSYour Name 			u_int8_t *peer_mac_addr;
4016*5113495bSYour Name 			u_int16_t peer_id;
4017*5113495bSYour Name 			u_int16_t hw_peer_id;
4018*5113495bSYour Name 			u_int8_t vdev_id;
4019*5113495bSYour Name 			u_int8_t is_wds;
4020*5113495bSYour Name 			struct dp_soc *dpsoc = (struct dp_soc *)soc->dp_soc;
4021*5113495bSYour Name 
4022*5113495bSYour Name 			peer_id = HTT_RX_PEER_MAP_PEER_ID_GET(*msg_word);
4023*5113495bSYour Name 			hw_peer_id =
4024*5113495bSYour Name 				HTT_RX_PEER_MAP_HW_PEER_ID_GET(*(msg_word+2));
4025*5113495bSYour Name 			vdev_id = HTT_RX_PEER_MAP_VDEV_ID_GET(*msg_word);
4026*5113495bSYour Name 			peer_mac_addr = htt_t2h_mac_addr_deswizzle(
4027*5113495bSYour Name 				(u_int8_t *) (msg_word+1),
4028*5113495bSYour Name 				&mac_addr_deswizzle_buf[0]);
4029*5113495bSYour Name 			QDF_TRACE(QDF_MODULE_ID_TXRX,
4030*5113495bSYour Name 				QDF_TRACE_LEVEL_DEBUG,
4031*5113495bSYour Name 				"HTT_T2H_MSG_TYPE_PEER_MAP msg for peer id %d vdev id %d n",
4032*5113495bSYour Name 				peer_id, vdev_id);
4033*5113495bSYour Name 
4034*5113495bSYour Name 			/*
4035*5113495bSYour Name 			 * check if peer already exists for this peer_id, if so
4036*5113495bSYour Name 			 * this peer map event is in response for a wds peer add
4037*5113495bSYour Name 			 * wmi command sent during wds source port learning.
4038*5113495bSYour Name 			 * in this case just add the ast entry to the existing
4039*5113495bSYour Name 			 * peer ast_list.
4040*5113495bSYour Name 			 */
4041*5113495bSYour Name 			is_wds = !!(dpsoc->peer_id_to_obj_map[peer_id]);
4042*5113495bSYour Name 			dp_rx_peer_map_handler(soc->dp_soc, peer_id, hw_peer_id,
4043*5113495bSYour Name 					       vdev_id, peer_mac_addr, 0,
4044*5113495bSYour Name 					       is_wds);
4045*5113495bSYour Name 			break;
4046*5113495bSYour Name 		}
4047*5113495bSYour Name 	case HTT_T2H_MSG_TYPE_PEER_UNMAP:
4048*5113495bSYour Name 		{
4049*5113495bSYour Name 			u_int16_t peer_id;
4050*5113495bSYour Name 			u_int8_t vdev_id;
4051*5113495bSYour Name 			u_int8_t mac_addr[QDF_MAC_ADDR_SIZE] = {0};
4052*5113495bSYour Name 			peer_id = HTT_RX_PEER_UNMAP_PEER_ID_GET(*msg_word);
4053*5113495bSYour Name 			vdev_id = HTT_RX_PEER_UNMAP_VDEV_ID_GET(*msg_word);
4054*5113495bSYour Name 
4055*5113495bSYour Name 			dp_rx_peer_unmap_handler(soc->dp_soc, peer_id,
4056*5113495bSYour Name 						 vdev_id, mac_addr, 0,
4057*5113495bSYour Name 						 DP_PEER_WDS_COUNT_INVALID);
4058*5113495bSYour Name 			break;
4059*5113495bSYour Name 		}
4060*5113495bSYour Name 	case HTT_T2H_MSG_TYPE_SEC_IND:
4061*5113495bSYour Name 		{
4062*5113495bSYour Name 			u_int16_t peer_id;
4063*5113495bSYour Name 			enum cdp_sec_type sec_type;
4064*5113495bSYour Name 			int is_unicast;
4065*5113495bSYour Name 
4066*5113495bSYour Name 			peer_id = HTT_SEC_IND_PEER_ID_GET(*msg_word);
4067*5113495bSYour Name 			sec_type = HTT_SEC_IND_SEC_TYPE_GET(*msg_word);
4068*5113495bSYour Name 			is_unicast = HTT_SEC_IND_UNICAST_GET(*msg_word);
4069*5113495bSYour Name 			/* point to the first part of the Michael key */
4070*5113495bSYour Name 			msg_word++;
4071*5113495bSYour Name 			dp_rx_sec_ind_handler(
4072*5113495bSYour Name 				soc->dp_soc, peer_id, sec_type, is_unicast,
4073*5113495bSYour Name 				msg_word, msg_word + 2);
4074*5113495bSYour Name 			break;
4075*5113495bSYour Name 		}
4076*5113495bSYour Name 
4077*5113495bSYour Name 	case HTT_T2H_MSG_TYPE_PPDU_STATS_IND:
4078*5113495bSYour Name 		{
4079*5113495bSYour Name 			free_buf =
4080*5113495bSYour Name 				dp_monitor_ppdu_stats_ind_handler(soc,
4081*5113495bSYour Name 								  msg_word,
4082*5113495bSYour Name 								  htt_t2h_msg);
4083*5113495bSYour Name 			break;
4084*5113495bSYour Name 		}
4085*5113495bSYour Name 
4086*5113495bSYour Name 	case HTT_T2H_MSG_TYPE_PKTLOG:
4087*5113495bSYour Name 		{
4088*5113495bSYour Name 			dp_pktlog_msg_handler(soc, msg_word);
4089*5113495bSYour Name 			break;
4090*5113495bSYour Name 		}
4091*5113495bSYour Name 
4092*5113495bSYour Name 	case HTT_T2H_MSG_TYPE_VERSION_CONF:
4093*5113495bSYour Name 		{
4094*5113495bSYour Name 			/*
4095*5113495bSYour Name 			 * HTC maintains runtime pm count for H2T messages that
4096*5113495bSYour Name 			 * have a response msg from FW. This count ensures that
4097*5113495bSYour Name 			 * in the case FW does not sent out the response or host
4098*5113495bSYour Name 			 * did not process this indication runtime_put happens
4099*5113495bSYour Name 			 * properly in the cleanup path.
4100*5113495bSYour Name 			 */
4101*5113495bSYour Name 			if (htc_dec_return_htt_runtime_cnt(soc->htc_soc) >= 0)
4102*5113495bSYour Name 				htc_pm_runtime_put(soc->htc_soc);
4103*5113495bSYour Name 			else
4104*5113495bSYour Name 				soc->stats.htt_ver_req_put_skip++;
4105*5113495bSYour Name 			soc->tgt_ver.major = HTT_VER_CONF_MAJOR_GET(*msg_word);
4106*5113495bSYour Name 			soc->tgt_ver.minor = HTT_VER_CONF_MINOR_GET(*msg_word);
4107*5113495bSYour Name 			QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_INFO_LOW,
4108*5113495bSYour Name 				"target uses HTT version %d.%d; host uses %d.%d",
4109*5113495bSYour Name 				soc->tgt_ver.major, soc->tgt_ver.minor,
4110*5113495bSYour Name 				HTT_CURRENT_VERSION_MAJOR,
4111*5113495bSYour Name 				HTT_CURRENT_VERSION_MINOR);
4112*5113495bSYour Name 			if (soc->tgt_ver.major != HTT_CURRENT_VERSION_MAJOR) {
4113*5113495bSYour Name 				QDF_TRACE(QDF_MODULE_ID_TXRX,
4114*5113495bSYour Name 					QDF_TRACE_LEVEL_WARN,
4115*5113495bSYour Name 					"*** Incompatible host/target HTT versions!");
4116*5113495bSYour Name 			}
4117*5113495bSYour Name 			/* abort if the target is incompatible with the host */
4118*5113495bSYour Name 			qdf_assert(soc->tgt_ver.major ==
4119*5113495bSYour Name 				HTT_CURRENT_VERSION_MAJOR);
4120*5113495bSYour Name 			if (soc->tgt_ver.minor != HTT_CURRENT_VERSION_MINOR) {
4121*5113495bSYour Name 				QDF_TRACE(QDF_MODULE_ID_TXRX,
4122*5113495bSYour Name 					QDF_TRACE_LEVEL_INFO_LOW,
4123*5113495bSYour Name 					"*** Warning: host/target HTT versions"
4124*5113495bSYour Name 					" are different, though compatible!");
4125*5113495bSYour Name 			}
4126*5113495bSYour Name 			break;
4127*5113495bSYour Name 		}
4128*5113495bSYour Name 	case HTT_T2H_MSG_TYPE_RX_ADDBA:
4129*5113495bSYour Name 		{
4130*5113495bSYour Name 			uint16_t peer_id;
4131*5113495bSYour Name 			uint8_t tid;
4132*5113495bSYour Name 			uint16_t win_sz;
4133*5113495bSYour Name 
4134*5113495bSYour Name 			/*
4135*5113495bSYour Name 			 * Update REO Queue Desc with new values
4136*5113495bSYour Name 			 */
4137*5113495bSYour Name 			peer_id = HTT_RX_ADDBA_PEER_ID_GET(*msg_word);
4138*5113495bSYour Name 			tid = HTT_RX_ADDBA_TID_GET(*msg_word);
4139*5113495bSYour Name 			win_sz = HTT_RX_ADDBA_WIN_SIZE_GET(*msg_word);
4140*5113495bSYour Name 
4141*5113495bSYour Name 			/*
4142*5113495bSYour Name 			 * Window size needs to be incremented by 1
4143*5113495bSYour Name 			 * since fw needs to represent a value of 256
4144*5113495bSYour Name 			 * using just 8 bits
4145*5113495bSYour Name 			 */
4146*5113495bSYour Name 			dp_htt_rx_addba_handler(soc->dp_soc, peer_id,
4147*5113495bSYour Name 						tid, win_sz + 1);
4148*5113495bSYour Name 			break;
4149*5113495bSYour Name 		}
4150*5113495bSYour Name 	case HTT_T2H_MSG_TYPE_RX_ADDBA_EXTN:
4151*5113495bSYour Name 		{
4152*5113495bSYour Name 			uint16_t peer_id;
4153*5113495bSYour Name 			uint8_t tid;
4154*5113495bSYour Name 			uint16_t win_sz;
4155*5113495bSYour Name 
4156*5113495bSYour Name 			peer_id = HTT_RX_ADDBA_EXTN_PEER_ID_GET(*msg_word);
4157*5113495bSYour Name 			tid = HTT_RX_ADDBA_EXTN_TID_GET(*msg_word);
4158*5113495bSYour Name 
4159*5113495bSYour Name 			msg_word++;
4160*5113495bSYour Name 			win_sz = HTT_RX_ADDBA_EXTN_WIN_SIZE_GET(*msg_word);
4161*5113495bSYour Name 
4162*5113495bSYour Name 			dp_htt_rx_addba_handler(soc->dp_soc, peer_id,
4163*5113495bSYour Name 						tid, win_sz);
4164*5113495bSYour Name 			break;
4165*5113495bSYour Name 		}
4166*5113495bSYour Name 	case HTT_T2H_PPDU_ID_FMT_IND:
4167*5113495bSYour Name 		{
4168*5113495bSYour Name 			dp_htt_ppdu_id_fmt_handler(soc->dp_soc, msg_word);
4169*5113495bSYour Name 			break;
4170*5113495bSYour Name 		}
4171*5113495bSYour Name 	case HTT_T2H_MSG_TYPE_EXT_STATS_CONF:
4172*5113495bSYour Name 		{
4173*5113495bSYour Name 			dp_txrx_fw_stats_handler(soc->dp_soc, htt_t2h_msg);
4174*5113495bSYour Name 			break;
4175*5113495bSYour Name 		}
4176*5113495bSYour Name 	case HTT_T2H_MSG_TYPE_PEER_MAP_V2:
4177*5113495bSYour Name 		{
4178*5113495bSYour Name 			u_int8_t mac_addr_deswizzle_buf[QDF_MAC_ADDR_SIZE];
4179*5113495bSYour Name 			u_int8_t *peer_mac_addr;
4180*5113495bSYour Name 			u_int16_t peer_id;
4181*5113495bSYour Name 			u_int16_t hw_peer_id;
4182*5113495bSYour Name 			u_int8_t vdev_id;
4183*5113495bSYour Name 			bool is_wds;
4184*5113495bSYour Name 			u_int16_t ast_hash;
4185*5113495bSYour Name 			struct dp_ast_flow_override_info ast_flow_info = {0};
4186*5113495bSYour Name 
4187*5113495bSYour Name 			peer_id = HTT_RX_PEER_MAP_V2_SW_PEER_ID_GET(*msg_word);
4188*5113495bSYour Name 			hw_peer_id =
4189*5113495bSYour Name 			HTT_RX_PEER_MAP_V2_HW_PEER_ID_GET(*(msg_word + 2));
4190*5113495bSYour Name 			vdev_id = HTT_RX_PEER_MAP_V2_VDEV_ID_GET(*msg_word);
4191*5113495bSYour Name 			peer_mac_addr =
4192*5113495bSYour Name 			htt_t2h_mac_addr_deswizzle((u_int8_t *)(msg_word + 1),
4193*5113495bSYour Name 						   &mac_addr_deswizzle_buf[0]);
4194*5113495bSYour Name 			is_wds =
4195*5113495bSYour Name 			HTT_RX_PEER_MAP_V2_NEXT_HOP_GET(*(msg_word + 3));
4196*5113495bSYour Name 			ast_hash =
4197*5113495bSYour Name 			HTT_RX_PEER_MAP_V2_AST_HASH_VALUE_GET(*(msg_word + 3));
4198*5113495bSYour Name 			/*
4199*5113495bSYour Name 			 * Update 4 ast_index per peer, ast valid mask
4200*5113495bSYour Name 			 * and TID flow valid mask.
4201*5113495bSYour Name 			 * AST valid mask is 3 bit field corresponds to
4202*5113495bSYour Name 			 * ast_index[3:1]. ast_index 0 is always valid.
4203*5113495bSYour Name 			 */
4204*5113495bSYour Name 			ast_flow_info.ast_valid_mask =
4205*5113495bSYour Name 			HTT_RX_PEER_MAP_V2_AST_VALID_MASK_GET(*(msg_word + 3));
4206*5113495bSYour Name 			ast_flow_info.ast_idx[0] = hw_peer_id;
4207*5113495bSYour Name 			ast_flow_info.ast_flow_mask[0] =
4208*5113495bSYour Name 			HTT_RX_PEER_MAP_V2_AST_0_FLOW_MASK_GET(*(msg_word + 4));
4209*5113495bSYour Name 			ast_flow_info.ast_idx[1] =
4210*5113495bSYour Name 			HTT_RX_PEER_MAP_V2_AST_INDEX_1_GET(*(msg_word + 4));
4211*5113495bSYour Name 			ast_flow_info.ast_flow_mask[1] =
4212*5113495bSYour Name 			HTT_RX_PEER_MAP_V2_AST_1_FLOW_MASK_GET(*(msg_word + 4));
4213*5113495bSYour Name 			ast_flow_info.ast_idx[2] =
4214*5113495bSYour Name 			HTT_RX_PEER_MAP_V2_AST_INDEX_2_GET(*(msg_word + 5));
4215*5113495bSYour Name 			ast_flow_info.ast_flow_mask[2] =
4216*5113495bSYour Name 			HTT_RX_PEER_MAP_V2_AST_2_FLOW_MASK_GET(*(msg_word + 4));
4217*5113495bSYour Name 			ast_flow_info.ast_idx[3] =
4218*5113495bSYour Name 			HTT_RX_PEER_MAP_V2_AST_INDEX_3_GET(*(msg_word + 6));
4219*5113495bSYour Name 			ast_flow_info.ast_flow_mask[3] =
4220*5113495bSYour Name 			HTT_RX_PEER_MAP_V2_AST_3_FLOW_MASK_GET(*(msg_word + 4));
4221*5113495bSYour Name 			/*
4222*5113495bSYour Name 			 * TID valid mask is applicable only
4223*5113495bSYour Name 			 * for HI and LOW priority flows.
4224*5113495bSYour Name 			 * tid_valid_mas is 8 bit field corresponds
4225*5113495bSYour Name 			 * to TID[7:0]
4226*5113495bSYour Name 			 */
4227*5113495bSYour Name 			ast_flow_info.tid_valid_low_pri_mask =
4228*5113495bSYour Name 			HTT_RX_PEER_MAP_V2_TID_VALID_LOW_PRI_GET(*(msg_word + 5));
4229*5113495bSYour Name 			ast_flow_info.tid_valid_hi_pri_mask =
4230*5113495bSYour Name 			HTT_RX_PEER_MAP_V2_TID_VALID_HI_PRI_GET(*(msg_word + 5));
4231*5113495bSYour Name 
4232*5113495bSYour Name 			QDF_TRACE(QDF_MODULE_ID_TXRX,
4233*5113495bSYour Name 				  QDF_TRACE_LEVEL_DEBUG,
4234*5113495bSYour Name 				  "HTT_T2H_MSG_TYPE_PEER_MAP msg for peer id %d vdev id %d n",
4235*5113495bSYour Name 				  peer_id, vdev_id);
4236*5113495bSYour Name 
4237*5113495bSYour Name 			QDF_TRACE(QDF_MODULE_ID_TXRX,
4238*5113495bSYour Name 				  QDF_TRACE_LEVEL_INFO,
4239*5113495bSYour Name 				  "ast_idx[0] %d ast_idx[1] %d ast_idx[2] %d ast_idx[3] %d n",
4240*5113495bSYour Name 				  ast_flow_info.ast_idx[0],
4241*5113495bSYour Name 				  ast_flow_info.ast_idx[1],
4242*5113495bSYour Name 				  ast_flow_info.ast_idx[2],
4243*5113495bSYour Name 				  ast_flow_info.ast_idx[3]);
4244*5113495bSYour Name 
4245*5113495bSYour Name 			dp_rx_peer_map_handler(soc->dp_soc, peer_id,
4246*5113495bSYour Name 					       hw_peer_id, vdev_id,
4247*5113495bSYour Name 					       peer_mac_addr, ast_hash,
4248*5113495bSYour Name 					       is_wds);
4249*5113495bSYour Name 
4250*5113495bSYour Name 			/*
4251*5113495bSYour Name 			 * Update ast indexes for flow override support
4252*5113495bSYour Name 			 * Applicable only for non wds peers
4253*5113495bSYour Name 			 */
4254*5113495bSYour Name 			if (!soc->dp_soc->ast_offload_support)
4255*5113495bSYour Name 				dp_peer_ast_index_flow_queue_map_create(
4256*5113495bSYour Name 						soc->dp_soc, is_wds,
4257*5113495bSYour Name 						peer_id, peer_mac_addr,
4258*5113495bSYour Name 						&ast_flow_info);
4259*5113495bSYour Name 
4260*5113495bSYour Name 			break;
4261*5113495bSYour Name 		}
4262*5113495bSYour Name 	case HTT_T2H_MSG_TYPE_PEER_UNMAP_V2:
4263*5113495bSYour Name 		{
4264*5113495bSYour Name 			u_int8_t mac_addr_deswizzle_buf[QDF_MAC_ADDR_SIZE];
4265*5113495bSYour Name 			u_int8_t *mac_addr;
4266*5113495bSYour Name 			u_int16_t peer_id;
4267*5113495bSYour Name 			u_int8_t vdev_id;
4268*5113495bSYour Name 			u_int8_t is_wds;
4269*5113495bSYour Name 			u_int32_t free_wds_count;
4270*5113495bSYour Name 
4271*5113495bSYour Name 			peer_id =
4272*5113495bSYour Name 			HTT_RX_PEER_UNMAP_V2_SW_PEER_ID_GET(*msg_word);
4273*5113495bSYour Name 			vdev_id = HTT_RX_PEER_UNMAP_V2_VDEV_ID_GET(*msg_word);
4274*5113495bSYour Name 			mac_addr =
4275*5113495bSYour Name 			htt_t2h_mac_addr_deswizzle((u_int8_t *)(msg_word + 1),
4276*5113495bSYour Name 						   &mac_addr_deswizzle_buf[0]);
4277*5113495bSYour Name 			is_wds =
4278*5113495bSYour Name 			HTT_RX_PEER_UNMAP_V2_NEXT_HOP_GET(*(msg_word + 2));
4279*5113495bSYour Name 			free_wds_count =
4280*5113495bSYour Name 			HTT_RX_PEER_UNMAP_V2_PEER_WDS_FREE_COUNT_GET(*(msg_word + 4));
4281*5113495bSYour Name 
4282*5113495bSYour Name 			QDF_TRACE(QDF_MODULE_ID_TXRX,
4283*5113495bSYour Name 				  QDF_TRACE_LEVEL_INFO,
4284*5113495bSYour Name 				  "HTT_T2H_MSG_TYPE_PEER_UNMAP msg for peer id %d vdev id %d n",
4285*5113495bSYour Name 				  peer_id, vdev_id);
4286*5113495bSYour Name 
4287*5113495bSYour Name 			dp_rx_peer_unmap_handler(soc->dp_soc, peer_id,
4288*5113495bSYour Name 						 vdev_id, mac_addr,
4289*5113495bSYour Name 						 is_wds, free_wds_count);
4290*5113495bSYour Name 			break;
4291*5113495bSYour Name 		}
4292*5113495bSYour Name 	case HTT_T2H_MSG_TYPE_RX_DELBA:
4293*5113495bSYour Name 		{
4294*5113495bSYour Name 			uint16_t peer_id;
4295*5113495bSYour Name 			uint8_t tid;
4296*5113495bSYour Name 			uint8_t win_sz;
4297*5113495bSYour Name 			QDF_STATUS status;
4298*5113495bSYour Name 
4299*5113495bSYour Name 			peer_id = HTT_RX_DELBA_PEER_ID_GET(*msg_word);
4300*5113495bSYour Name 			tid = HTT_RX_DELBA_TID_GET(*msg_word);
4301*5113495bSYour Name 			win_sz = HTT_RX_DELBA_WIN_SIZE_GET(*msg_word);
4302*5113495bSYour Name 
4303*5113495bSYour Name 			status = dp_rx_delba_ind_handler(
4304*5113495bSYour Name 				soc->dp_soc,
4305*5113495bSYour Name 				peer_id, tid, win_sz);
4306*5113495bSYour Name 
4307*5113495bSYour Name 			QDF_TRACE(QDF_MODULE_ID_TXRX,
4308*5113495bSYour Name 				  QDF_TRACE_LEVEL_INFO,
4309*5113495bSYour Name 				  FL("DELBA PeerID %d BAW %d TID %d stat %d"),
4310*5113495bSYour Name 				  peer_id, win_sz, tid, status);
4311*5113495bSYour Name 			break;
4312*5113495bSYour Name 		}
4313*5113495bSYour Name 	case HTT_T2H_MSG_TYPE_RX_DELBA_EXTN:
4314*5113495bSYour Name 		{
4315*5113495bSYour Name 			uint16_t peer_id;
4316*5113495bSYour Name 			uint8_t tid;
4317*5113495bSYour Name 			uint16_t win_sz;
4318*5113495bSYour Name 			QDF_STATUS status;
4319*5113495bSYour Name 
4320*5113495bSYour Name 			peer_id = HTT_RX_DELBA_EXTN_PEER_ID_GET(*msg_word);
4321*5113495bSYour Name 			tid = HTT_RX_DELBA_EXTN_TID_GET(*msg_word);
4322*5113495bSYour Name 
4323*5113495bSYour Name 			msg_word++;
4324*5113495bSYour Name 			win_sz = HTT_RX_DELBA_EXTN_WIN_SIZE_GET(*msg_word);
4325*5113495bSYour Name 
4326*5113495bSYour Name 			status = dp_rx_delba_ind_handler(soc->dp_soc,
4327*5113495bSYour Name 							 peer_id, tid,
4328*5113495bSYour Name 							 win_sz);
4329*5113495bSYour Name 
4330*5113495bSYour Name 			dp_info("DELBA PeerID %d BAW %d TID %d stat %d",
4331*5113495bSYour Name 				peer_id, win_sz, tid, status);
4332*5113495bSYour Name 			break;
4333*5113495bSYour Name 		}
4334*5113495bSYour Name 	case HTT_T2H_MSG_TYPE_FSE_CMEM_BASE_SEND:
4335*5113495bSYour Name 		{
4336*5113495bSYour Name 			uint16_t num_entries;
4337*5113495bSYour Name 			uint32_t cmem_ba_lo;
4338*5113495bSYour Name 			uint32_t cmem_ba_hi;
4339*5113495bSYour Name 
4340*5113495bSYour Name 			num_entries = HTT_CMEM_BASE_SEND_NUM_ENTRIES_GET(*msg_word);
4341*5113495bSYour Name 			cmem_ba_lo = *(msg_word + 1);
4342*5113495bSYour Name 			cmem_ba_hi = *(msg_word + 2);
4343*5113495bSYour Name 
4344*5113495bSYour Name 			QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_INFO,
4345*5113495bSYour Name 				  FL("CMEM FSE num_entries %u CMEM BA LO %x HI %x"),
4346*5113495bSYour Name 				  num_entries, cmem_ba_lo, cmem_ba_hi);
4347*5113495bSYour Name 
4348*5113495bSYour Name 			dp_rx_fst_update_cmem_params(soc->dp_soc, num_entries,
4349*5113495bSYour Name 						     cmem_ba_lo, cmem_ba_hi);
4350*5113495bSYour Name 			break;
4351*5113495bSYour Name 		}
4352*5113495bSYour Name 	case HTT_T2H_MSG_TYPE_TX_OFFLOAD_DELIVER_IND:
4353*5113495bSYour Name 		{
4354*5113495bSYour Name 			dp_offload_ind_handler(soc, msg_word);
4355*5113495bSYour Name 			break;
4356*5113495bSYour Name 		}
4357*5113495bSYour Name 	case HTT_T2H_MSG_TYPE_PEER_MAP_V3:
4358*5113495bSYour Name 	{
4359*5113495bSYour Name 		u_int8_t mac_addr_deswizzle_buf[QDF_MAC_ADDR_SIZE];
4360*5113495bSYour Name 		u_int8_t *peer_mac_addr;
4361*5113495bSYour Name 		u_int16_t peer_id;
4362*5113495bSYour Name 		u_int16_t hw_peer_id;
4363*5113495bSYour Name 		u_int8_t vdev_id;
4364*5113495bSYour Name 		uint8_t is_wds;
4365*5113495bSYour Name 		u_int16_t ast_hash = 0;
4366*5113495bSYour Name 
4367*5113495bSYour Name 		peer_id = HTT_RX_PEER_MAP_V3_SW_PEER_ID_GET(*msg_word);
4368*5113495bSYour Name 		vdev_id = HTT_RX_PEER_MAP_V3_VDEV_ID_GET(*msg_word);
4369*5113495bSYour Name 		peer_mac_addr =
4370*5113495bSYour Name 		htt_t2h_mac_addr_deswizzle((u_int8_t *)(msg_word + 1),
4371*5113495bSYour Name 					   &mac_addr_deswizzle_buf[0]);
4372*5113495bSYour Name 		hw_peer_id = HTT_RX_PEER_MAP_V3_HW_PEER_ID_GET(*(msg_word + 3));
4373*5113495bSYour Name 		ast_hash = HTT_RX_PEER_MAP_V3_CACHE_SET_NUM_GET(*(msg_word + 3));
4374*5113495bSYour Name 		is_wds = HTT_RX_PEER_MAP_V3_NEXT_HOP_GET(*(msg_word + 4));
4375*5113495bSYour Name 
4376*5113495bSYour Name 		dp_htt_info("HTT_T2H_MSG_TYPE_PEER_MAP_V3 msg for peer id %d vdev id %d n",
4377*5113495bSYour Name 			    peer_id, vdev_id);
4378*5113495bSYour Name 
4379*5113495bSYour Name 		dp_rx_peer_map_handler(soc->dp_soc, peer_id,
4380*5113495bSYour Name 				       hw_peer_id, vdev_id,
4381*5113495bSYour Name 				       peer_mac_addr, ast_hash,
4382*5113495bSYour Name 				       is_wds);
4383*5113495bSYour Name 
4384*5113495bSYour Name 		break;
4385*5113495bSYour Name 	}
4386*5113495bSYour Name 	case HTT_T2H_MSG_TYPE_PRIMARY_LINK_PEER_MIGRATE_IND:
4387*5113495bSYour Name 	{
4388*5113495bSYour Name 		dp_htt_t2h_primary_link_migration(soc, msg_word);
4389*5113495bSYour Name 		break;
4390*5113495bSYour Name 	}
4391*5113495bSYour Name 	case HTT_T2H_MSG_TYPE_MLO_RX_PEER_MAP:
4392*5113495bSYour Name 	{
4393*5113495bSYour Name 		dp_htt_mlo_peer_map_handler(soc, msg_word);
4394*5113495bSYour Name 		break;
4395*5113495bSYour Name 	}
4396*5113495bSYour Name 	case HTT_T2H_MSG_TYPE_MLO_RX_PEER_UNMAP:
4397*5113495bSYour Name 	{
4398*5113495bSYour Name 		dp_htt_mlo_peer_unmap_handler(soc, msg_word);
4399*5113495bSYour Name 		break;
4400*5113495bSYour Name 	}
4401*5113495bSYour Name 	case HTT_T2H_MSG_TYPE_MLO_TIMESTAMP_OFFSET_IND:
4402*5113495bSYour Name 	{
4403*5113495bSYour Name 		dp_rx_mlo_timestamp_ind_handler(soc->dp_soc, msg_word);
4404*5113495bSYour Name 		break;
4405*5113495bSYour Name 	}
4406*5113495bSYour Name 	case HTT_T2H_MSG_TYPE_VDEVS_TXRX_STATS_PERIODIC_IND:
4407*5113495bSYour Name 	{
4408*5113495bSYour Name 		dp_vdev_txrx_hw_stats_handler(soc, msg_word);
4409*5113495bSYour Name 		break;
4410*5113495bSYour Name 	}
4411*5113495bSYour Name 	case HTT_T2H_SAWF_DEF_QUEUES_MAP_REPORT_CONF:
4412*5113495bSYour Name 	{
4413*5113495bSYour Name 		dp_sawf_def_queues_update_map_report_conf(soc, msg_word,
4414*5113495bSYour Name 							  htt_t2h_msg);
4415*5113495bSYour Name 		break;
4416*5113495bSYour Name 	}
4417*5113495bSYour Name 	case HTT_T2H_SAWF_MSDUQ_INFO_IND:
4418*5113495bSYour Name 	{
4419*5113495bSYour Name 		dp_sawf_msduq_map(soc, msg_word, htt_t2h_msg);
4420*5113495bSYour Name 		break;
4421*5113495bSYour Name 	}
4422*5113495bSYour Name 	case HTT_T2H_MSG_TYPE_PEER_AST_OVERRIDE_INDEX_IND:
4423*5113495bSYour Name 	{
4424*5113495bSYour Name 		dp_sawf_dynamic_ast_update(soc, msg_word, htt_t2h_msg);
4425*5113495bSYour Name 		break;
4426*5113495bSYour Name 	}
4427*5113495bSYour Name 	case HTT_T2H_MSG_TYPE_STREAMING_STATS_IND:
4428*5113495bSYour Name 	{
4429*5113495bSYour Name 		dp_sawf_mpdu_stats_handler(soc, htt_t2h_msg);
4430*5113495bSYour Name 		break;
4431*5113495bSYour Name 	}
4432*5113495bSYour Name 	case HTT_T2H_MSG_TYPE_RX_CCE_SUPER_RULE_SETUP_DONE:
4433*5113495bSYour Name 	{
4434*5113495bSYour Name 		dp_ipa_rx_cce_super_rule_setup_done_handler(soc, msg_word);
4435*5113495bSYour Name 		break;
4436*5113495bSYour Name 	}
4437*5113495bSYour Name 	case HTT_T2H_MSG_TYPE_PEER_EXTENDED_EVENT:
4438*5113495bSYour Name 	{
4439*5113495bSYour Name 		dp_htt_peer_ext_evt(soc, msg_word);
4440*5113495bSYour Name 		break;
4441*5113495bSYour Name 	}
4442*5113495bSYour Name 	case HTT_T2H_MSG_TYPE_TX_LATENCY_STATS_PERIODIC_IND:
4443*5113495bSYour Name 	{
4444*5113495bSYour Name 		dp_htt_tx_latency_stats_handler(soc, htt_t2h_msg);
4445*5113495bSYour Name 		break;
4446*5113495bSYour Name 	}
4447*5113495bSYour Name 	default:
4448*5113495bSYour Name 		break;
4449*5113495bSYour Name 	};
4450*5113495bSYour Name 
4451*5113495bSYour Name 	/* Free the indication buffer */
4452*5113495bSYour Name 	if (free_buf)
4453*5113495bSYour Name 		dp_htt_rx_nbuf_free(htt_t2h_msg);
4454*5113495bSYour Name }
4455*5113495bSYour Name 
4456*5113495bSYour Name enum htc_send_full_action
4457*5113495bSYour Name dp_htt_h2t_full(void *context, HTC_PACKET *pkt)
4458*5113495bSYour Name {
4459*5113495bSYour Name 	return HTC_SEND_FULL_KEEP;
4460*5113495bSYour Name }
4461*5113495bSYour Name 
4462*5113495bSYour Name QDF_STATUS
4463*5113495bSYour Name dp_htt_hif_t2h_hp_callback (void *context, qdf_nbuf_t nbuf, uint8_t pipe_id)
4464*5113495bSYour Name {
4465*5113495bSYour Name 	QDF_STATUS rc = QDF_STATUS_SUCCESS;
4466*5113495bSYour Name 	HTC_PACKET htc_pkt;
4467*5113495bSYour Name 
4468*5113495bSYour Name 	qdf_assert_always(pipe_id == DP_HTT_T2H_HP_PIPE);
4469*5113495bSYour Name 	qdf_mem_zero(&htc_pkt, sizeof(htc_pkt));
4470*5113495bSYour Name 	htc_pkt.Status = QDF_STATUS_SUCCESS;
4471*5113495bSYour Name 	htc_pkt.pPktContext = (void *)nbuf;
4472*5113495bSYour Name 	dp_htt_t2h_msg_handler(context, &htc_pkt);
4473*5113495bSYour Name 
4474*5113495bSYour Name 	return rc;
4475*5113495bSYour Name }
4476*5113495bSYour Name 
4477*5113495bSYour Name /**
4478*5113495bSYour Name  * htt_htc_soc_attach() - Register SOC level HTT instance with HTC
4479*5113495bSYour Name  * @soc:	HTT SOC handle
4480*5113495bSYour Name  *
4481*5113495bSYour Name  * Return: QDF_STATUS
4482*5113495bSYour Name  */
4483*5113495bSYour Name static QDF_STATUS
4484*5113495bSYour Name htt_htc_soc_attach(struct htt_soc *soc)
4485*5113495bSYour Name {
4486*5113495bSYour Name 	struct htc_service_connect_req connect;
4487*5113495bSYour Name 	struct htc_service_connect_resp response;
4488*5113495bSYour Name 	QDF_STATUS status;
4489*5113495bSYour Name 	struct dp_soc *dpsoc = soc->dp_soc;
4490*5113495bSYour Name 
4491*5113495bSYour Name 	qdf_mem_zero(&connect, sizeof(connect));
4492*5113495bSYour Name 	qdf_mem_zero(&response, sizeof(response));
4493*5113495bSYour Name 
4494*5113495bSYour Name 	connect.pMetaData = NULL;
4495*5113495bSYour Name 	connect.MetaDataLength = 0;
4496*5113495bSYour Name 	connect.EpCallbacks.pContext = soc;
4497*5113495bSYour Name 	connect.EpCallbacks.EpTxComplete = dp_htt_h2t_send_complete;
4498*5113495bSYour Name 	connect.EpCallbacks.EpTxCompleteMultiple = NULL;
4499*5113495bSYour Name 	connect.EpCallbacks.EpRecv = dp_htt_t2h_msg_handler;
4500*5113495bSYour Name 
4501*5113495bSYour Name 	/* rx buffers currently are provided by HIF, not by EpRecvRefill */
4502*5113495bSYour Name 	connect.EpCallbacks.EpRecvRefill = NULL;
4503*5113495bSYour Name 
4504*5113495bSYour Name 	/* N/A, fill is done by HIF */
4505*5113495bSYour Name 	connect.EpCallbacks.RecvRefillWaterMark = 1;
4506*5113495bSYour Name 
4507*5113495bSYour Name 	connect.EpCallbacks.EpSendFull = dp_htt_h2t_full;
4508*5113495bSYour Name 	/*
4509*5113495bSYour Name 	 * Specify how deep to let a queue get before htc_send_pkt will
4510*5113495bSYour Name 	 * call the EpSendFull function due to excessive send queue depth.
4511*5113495bSYour Name 	 */
4512*5113495bSYour Name 	connect.MaxSendQueueDepth = DP_HTT_MAX_SEND_QUEUE_DEPTH;
4513*5113495bSYour Name 
4514*5113495bSYour Name 	/* disable flow control for HTT data message service */
4515*5113495bSYour Name 	connect.ConnectionFlags |= HTC_CONNECT_FLAGS_DISABLE_CREDIT_FLOW_CTRL;
4516*5113495bSYour Name 
4517*5113495bSYour Name 	/* connect to control service */
4518*5113495bSYour Name 	connect.service_id = HTT_DATA_MSG_SVC;
4519*5113495bSYour Name 
4520*5113495bSYour Name 	status = htc_connect_service(soc->htc_soc, &connect, &response);
4521*5113495bSYour Name 
4522*5113495bSYour Name 	if (status != QDF_STATUS_SUCCESS)
4523*5113495bSYour Name 		return status;
4524*5113495bSYour Name 
4525*5113495bSYour Name 	soc->htc_endpoint = response.Endpoint;
4526*5113495bSYour Name 
4527*5113495bSYour Name 	hif_save_htc_htt_config_endpoint(dpsoc->hif_handle, soc->htc_endpoint);
4528*5113495bSYour Name 
4529*5113495bSYour Name 	htt_interface_logging_init(&soc->htt_logger_handle, soc->ctrl_psoc);
4530*5113495bSYour Name 	dp_hif_update_pipe_callback(soc->dp_soc, (void *)soc,
4531*5113495bSYour Name 		dp_htt_hif_t2h_hp_callback, DP_HTT_T2H_HP_PIPE);
4532*5113495bSYour Name 
4533*5113495bSYour Name 	return QDF_STATUS_SUCCESS; /* success */
4534*5113495bSYour Name }
4535*5113495bSYour Name 
4536*5113495bSYour Name void *
4537*5113495bSYour Name htt_soc_initialize(struct htt_soc *htt_soc,
4538*5113495bSYour Name 		   struct cdp_ctrl_objmgr_psoc *ctrl_psoc,
4539*5113495bSYour Name 		   HTC_HANDLE htc_soc,
4540*5113495bSYour Name 		   hal_soc_handle_t hal_soc_hdl, qdf_device_t osdev)
4541*5113495bSYour Name {
4542*5113495bSYour Name 	struct htt_soc *soc = (struct htt_soc *)htt_soc;
4543*5113495bSYour Name 
4544*5113495bSYour Name 	soc->osdev = osdev;
4545*5113495bSYour Name 	soc->ctrl_psoc = ctrl_psoc;
4546*5113495bSYour Name 	soc->htc_soc = htc_soc;
4547*5113495bSYour Name 	soc->hal_soc = hal_soc_hdl;
4548*5113495bSYour Name 
4549*5113495bSYour Name 	if (htt_htc_soc_attach(soc))
4550*5113495bSYour Name 		goto fail2;
4551*5113495bSYour Name 
4552*5113495bSYour Name 	return soc;
4553*5113495bSYour Name 
4554*5113495bSYour Name fail2:
4555*5113495bSYour Name 	return NULL;
4556*5113495bSYour Name }
4557*5113495bSYour Name 
4558*5113495bSYour Name void htt_soc_htc_dealloc(struct htt_soc *htt_handle)
4559*5113495bSYour Name {
4560*5113495bSYour Name 	htt_interface_logging_deinit(htt_handle->htt_logger_handle);
4561*5113495bSYour Name 	htt_htc_misc_pkt_pool_free(htt_handle);
4562*5113495bSYour Name 	htt_htc_pkt_pool_free(htt_handle);
4563*5113495bSYour Name }
4564*5113495bSYour Name 
4565*5113495bSYour Name QDF_STATUS htt_soc_htc_prealloc(struct htt_soc *soc)
4566*5113495bSYour Name {
4567*5113495bSYour Name 	int i;
4568*5113495bSYour Name 
4569*5113495bSYour Name 	soc->htt_htc_pkt_freelist = NULL;
4570*5113495bSYour Name 	/* pre-allocate some HTC_PACKET objects */
4571*5113495bSYour Name 	for (i = 0; i < HTT_HTC_PKT_POOL_INIT_SIZE; i++) {
4572*5113495bSYour Name 		struct dp_htt_htc_pkt_union *pkt;
4573*5113495bSYour Name 		pkt = qdf_mem_malloc(sizeof(*pkt));
4574*5113495bSYour Name 		if (!pkt)
4575*5113495bSYour Name 			return QDF_STATUS_E_NOMEM;
4576*5113495bSYour Name 
4577*5113495bSYour Name 		htt_htc_pkt_free(soc, &pkt->u.pkt);
4578*5113495bSYour Name 	}
4579*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
4580*5113495bSYour Name }
4581*5113495bSYour Name 
4582*5113495bSYour Name void htt_soc_detach(struct htt_soc *htt_hdl)
4583*5113495bSYour Name {
4584*5113495bSYour Name 	int i;
4585*5113495bSYour Name 	struct htt_soc *htt_handle = (struct htt_soc *)htt_hdl;
4586*5113495bSYour Name 
4587*5113495bSYour Name 	for (i = 0; i < MAX_PDEV_CNT; i++) {
4588*5113495bSYour Name 		qdf_mem_free(htt_handle->pdevid_tt[i].umac_path);
4589*5113495bSYour Name 		qdf_mem_free(htt_handle->pdevid_tt[i].lmac_path);
4590*5113495bSYour Name 	}
4591*5113495bSYour Name 
4592*5113495bSYour Name 	HTT_TX_MUTEX_DESTROY(&htt_handle->htt_tx_mutex);
4593*5113495bSYour Name 	qdf_mem_free(htt_handle);
4594*5113495bSYour Name 
4595*5113495bSYour Name }
4596*5113495bSYour Name 
4597*5113495bSYour Name /**
4598*5113495bSYour Name  * dp_h2t_ext_stats_msg_send(): function to construct HTT message to pass to FW
4599*5113495bSYour Name  * @pdev: DP PDEV handle
4600*5113495bSYour Name  * @stats_type_upload_mask: stats type requested by user
4601*5113495bSYour Name  * @config_param_0: extra configuration parameters
4602*5113495bSYour Name  * @config_param_1: extra configuration parameters
4603*5113495bSYour Name  * @config_param_2: extra configuration parameters
4604*5113495bSYour Name  * @config_param_3: extra configuration parameters
4605*5113495bSYour Name  * @cookie_val: cookie value
4606*5113495bSYour Name  * @cookie_msb: msb of debug status cookie
4607*5113495bSYour Name  * @mac_id: mac number
4608*5113495bSYour Name  *
4609*5113495bSYour Name  * return: QDF STATUS
4610*5113495bSYour Name  */
4611*5113495bSYour Name QDF_STATUS dp_h2t_ext_stats_msg_send(struct dp_pdev *pdev,
4612*5113495bSYour Name 		uint32_t stats_type_upload_mask, uint32_t config_param_0,
4613*5113495bSYour Name 		uint32_t config_param_1, uint32_t config_param_2,
4614*5113495bSYour Name 		uint32_t config_param_3, int cookie_val, int cookie_msb,
4615*5113495bSYour Name 		uint8_t mac_id)
4616*5113495bSYour Name {
4617*5113495bSYour Name 	struct htt_soc *soc = pdev->soc->htt_handle;
4618*5113495bSYour Name 	struct dp_htt_htc_pkt *pkt;
4619*5113495bSYour Name 	qdf_nbuf_t msg;
4620*5113495bSYour Name 	uint32_t *msg_word;
4621*5113495bSYour Name 	uint8_t pdev_mask = 0;
4622*5113495bSYour Name 	uint8_t *htt_logger_bufp;
4623*5113495bSYour Name 	int mac_for_pdev;
4624*5113495bSYour Name 	int target_pdev_id;
4625*5113495bSYour Name 	QDF_STATUS status;
4626*5113495bSYour Name 
4627*5113495bSYour Name 	msg = qdf_nbuf_alloc(
4628*5113495bSYour Name 			soc->osdev,
4629*5113495bSYour Name 			HTT_MSG_BUF_SIZE(HTT_H2T_EXT_STATS_REQ_MSG_SZ),
4630*5113495bSYour Name 			HTC_HEADER_LEN + HTC_HDR_ALIGNMENT_PADDING, 4, TRUE);
4631*5113495bSYour Name 
4632*5113495bSYour Name 	if (!msg)
4633*5113495bSYour Name 		return QDF_STATUS_E_NOMEM;
4634*5113495bSYour Name 
4635*5113495bSYour Name 	/*TODO:Add support for SOC stats
4636*5113495bSYour Name 	 * Bit 0: SOC Stats
4637*5113495bSYour Name 	 * Bit 1: Pdev stats for pdev id 0
4638*5113495bSYour Name 	 * Bit 2: Pdev stats for pdev id 1
4639*5113495bSYour Name 	 * Bit 3: Pdev stats for pdev id 2
4640*5113495bSYour Name 	 */
4641*5113495bSYour Name 	mac_for_pdev = dp_get_mac_id_for_pdev(mac_id, pdev->pdev_id);
4642*5113495bSYour Name 	target_pdev_id =
4643*5113495bSYour Name 	dp_get_target_pdev_id_for_host_pdev_id(pdev->soc, mac_for_pdev);
4644*5113495bSYour Name 
4645*5113495bSYour Name 	pdev_mask = 1 << target_pdev_id;
4646*5113495bSYour Name 
4647*5113495bSYour Name 	/*
4648*5113495bSYour Name 	 * Set the length of the message.
4649*5113495bSYour Name 	 * The contribution from the HTC_HDR_ALIGNMENT_PADDING is added
4650*5113495bSYour Name 	 * separately during the below call to qdf_nbuf_push_head.
4651*5113495bSYour Name 	 * The contribution from the HTC header is added separately inside HTC.
4652*5113495bSYour Name 	 */
4653*5113495bSYour Name 	if (qdf_nbuf_put_tail(msg, HTT_H2T_EXT_STATS_REQ_MSG_SZ) == NULL) {
4654*5113495bSYour Name 		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
4655*5113495bSYour Name 				"Failed to expand head for HTT_EXT_STATS");
4656*5113495bSYour Name 		qdf_nbuf_free(msg);
4657*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
4658*5113495bSYour Name 	}
4659*5113495bSYour Name 
4660*5113495bSYour Name 	msg_word = (uint32_t *) qdf_nbuf_data(msg);
4661*5113495bSYour Name 
4662*5113495bSYour Name 	qdf_nbuf_push_head(msg, HTC_HDR_ALIGNMENT_PADDING);
4663*5113495bSYour Name 	htt_logger_bufp = (uint8_t *)msg_word;
4664*5113495bSYour Name 	*msg_word = 0;
4665*5113495bSYour Name 	HTT_H2T_MSG_TYPE_SET(*msg_word, HTT_H2T_MSG_TYPE_EXT_STATS_REQ);
4666*5113495bSYour Name 	HTT_H2T_EXT_STATS_REQ_PDEV_MASK_SET(*msg_word, pdev_mask);
4667*5113495bSYour Name 	HTT_H2T_EXT_STATS_REQ_STATS_TYPE_SET(*msg_word, stats_type_upload_mask);
4668*5113495bSYour Name 
4669*5113495bSYour Name 	/* word 1 */
4670*5113495bSYour Name 	msg_word++;
4671*5113495bSYour Name 	*msg_word = 0;
4672*5113495bSYour Name 	HTT_H2T_EXT_STATS_REQ_CONFIG_PARAM_SET(*msg_word, config_param_0);
4673*5113495bSYour Name 
4674*5113495bSYour Name 	/* word 2 */
4675*5113495bSYour Name 	msg_word++;
4676*5113495bSYour Name 	*msg_word = 0;
4677*5113495bSYour Name 	HTT_H2T_EXT_STATS_REQ_CONFIG_PARAM_SET(*msg_word, config_param_1);
4678*5113495bSYour Name 
4679*5113495bSYour Name 	/* word 3 */
4680*5113495bSYour Name 	msg_word++;
4681*5113495bSYour Name 	*msg_word = 0;
4682*5113495bSYour Name 	HTT_H2T_EXT_STATS_REQ_CONFIG_PARAM_SET(*msg_word, config_param_2);
4683*5113495bSYour Name 
4684*5113495bSYour Name 	/* word 4 */
4685*5113495bSYour Name 	msg_word++;
4686*5113495bSYour Name 	*msg_word = 0;
4687*5113495bSYour Name 	HTT_H2T_EXT_STATS_REQ_CONFIG_PARAM_SET(*msg_word, config_param_3);
4688*5113495bSYour Name 
4689*5113495bSYour Name 	HTT_H2T_EXT_STATS_REQ_CONFIG_PARAM_SET(*msg_word, 0);
4690*5113495bSYour Name 
4691*5113495bSYour Name 	/* word 5 */
4692*5113495bSYour Name 	msg_word++;
4693*5113495bSYour Name 
4694*5113495bSYour Name 	/* word 6 */
4695*5113495bSYour Name 	msg_word++;
4696*5113495bSYour Name 	*msg_word = 0;
4697*5113495bSYour Name 	HTT_H2T_EXT_STATS_REQ_CONFIG_PARAM_SET(*msg_word, cookie_val);
4698*5113495bSYour Name 
4699*5113495bSYour Name 	/* word 7 */
4700*5113495bSYour Name 	msg_word++;
4701*5113495bSYour Name 	*msg_word = 0;
4702*5113495bSYour Name 	/* Currently Using last 2 bits for pdev_id
4703*5113495bSYour Name 	 * For future reference, reserving 3 bits in cookie_msb for pdev_id
4704*5113495bSYour Name 	 */
4705*5113495bSYour Name 	cookie_msb = (cookie_msb | pdev->pdev_id);
4706*5113495bSYour Name 	HTT_H2T_EXT_STATS_REQ_CONFIG_PARAM_SET(*msg_word, cookie_msb);
4707*5113495bSYour Name 
4708*5113495bSYour Name 	pkt = htt_htc_pkt_alloc(soc);
4709*5113495bSYour Name 	if (!pkt) {
4710*5113495bSYour Name 		qdf_nbuf_free(msg);
4711*5113495bSYour Name 		return QDF_STATUS_E_NOMEM;
4712*5113495bSYour Name 	}
4713*5113495bSYour Name 
4714*5113495bSYour Name 	pkt->soc_ctxt = NULL; /* not used during send-done callback */
4715*5113495bSYour Name 
4716*5113495bSYour Name 	SET_HTC_PACKET_INFO_TX(&pkt->htc_pkt,
4717*5113495bSYour Name 			dp_htt_h2t_send_complete_free_netbuf,
4718*5113495bSYour Name 			qdf_nbuf_data(msg), qdf_nbuf_len(msg),
4719*5113495bSYour Name 			soc->htc_endpoint,
4720*5113495bSYour Name 			/* tag for FW response msg not guaranteed */
4721*5113495bSYour Name 			HTC_TX_PACKET_TAG_RUNTIME_PUT);
4722*5113495bSYour Name 
4723*5113495bSYour Name 	SET_HTC_PACKET_NET_BUF_CONTEXT(&pkt->htc_pkt, msg);
4724*5113495bSYour Name 	status = DP_HTT_SEND_HTC_PKT(soc, pkt, HTT_H2T_MSG_TYPE_EXT_STATS_REQ,
4725*5113495bSYour Name 				     htt_logger_bufp);
4726*5113495bSYour Name 
4727*5113495bSYour Name 	if (status != QDF_STATUS_SUCCESS) {
4728*5113495bSYour Name 		qdf_nbuf_free(msg);
4729*5113495bSYour Name 		htt_htc_pkt_free(soc, pkt);
4730*5113495bSYour Name 	}
4731*5113495bSYour Name 
4732*5113495bSYour Name 	return status;
4733*5113495bSYour Name }
4734*5113495bSYour Name 
4735*5113495bSYour Name #ifdef QCA_VDEV_STATS_HW_OFFLOAD_SUPPORT
4736*5113495bSYour Name #define HTT_VDEV_TXRX_STATS_RESET_BITMASK_L32_MASK 0xFFFFFFFF
4737*5113495bSYour Name #define HTT_VDEV_TXRX_STATS_RESET_BITMASK_U32_MASK 0xFFFFFFFF00000000
4738*5113495bSYour Name #define HTT_VDEV_TXRX_STATS_RESET_BITMASK_U32_SHIFT 32
4739*5113495bSYour Name 
4740*5113495bSYour Name QDF_STATUS dp_h2t_hw_vdev_stats_config_send(struct dp_soc *dpsoc,
4741*5113495bSYour Name 					    uint8_t pdev_id, bool enable,
4742*5113495bSYour Name 					    bool reset, uint64_t reset_bitmask)
4743*5113495bSYour Name {
4744*5113495bSYour Name 	struct htt_soc *soc = dpsoc->htt_handle;
4745*5113495bSYour Name 	struct dp_htt_htc_pkt *pkt;
4746*5113495bSYour Name 	qdf_nbuf_t msg;
4747*5113495bSYour Name 	uint32_t *msg_word;
4748*5113495bSYour Name 	uint8_t *htt_logger_bufp;
4749*5113495bSYour Name 	QDF_STATUS status;
4750*5113495bSYour Name 	int duration;
4751*5113495bSYour Name 	uint32_t bitmask;
4752*5113495bSYour Name 	int target_pdev_id;
4753*5113495bSYour Name 
4754*5113495bSYour Name 	msg = qdf_nbuf_alloc(
4755*5113495bSYour Name 			soc->osdev,
4756*5113495bSYour Name 			HTT_MSG_BUF_SIZE(sizeof(struct htt_h2t_vdevs_txrx_stats_cfg)),
4757*5113495bSYour Name 			HTC_HEADER_LEN + HTC_HDR_ALIGNMENT_PADDING, 4, true);
4758*5113495bSYour Name 
4759*5113495bSYour Name 	if (!msg) {
4760*5113495bSYour Name 		dp_htt_err("%pK: Fail to allocate "
4761*5113495bSYour Name 		"HTT_H2T_HW_VDEV_TXRX_STATS_CFG_MSG_SZ msg buffer", dpsoc);
4762*5113495bSYour Name 		return QDF_STATUS_E_NOMEM;
4763*5113495bSYour Name 	}
4764*5113495bSYour Name 
4765*5113495bSYour Name 	if (pdev_id != INVALID_PDEV_ID)
4766*5113495bSYour Name 		target_pdev_id = DP_SW2HW_MACID(pdev_id);
4767*5113495bSYour Name 	else
4768*5113495bSYour Name 		target_pdev_id = 0;
4769*5113495bSYour Name 
4770*5113495bSYour Name 	duration =
4771*5113495bSYour Name 	wlan_cfg_get_vdev_stats_hw_offload_timer(dpsoc->wlan_cfg_ctx);
4772*5113495bSYour Name 
4773*5113495bSYour Name 	/*
4774*5113495bSYour Name 	 * Set the length of the message.
4775*5113495bSYour Name 	 * The contribution from the HTC_HDR_ALIGNMENT_PADDING is added
4776*5113495bSYour Name 	 * separately during the below call to qdf_nbuf_push_head.
4777*5113495bSYour Name 	 * The contribution from the HTC header is added separately inside HTC.
4778*5113495bSYour Name 	 */
4779*5113495bSYour Name 	if (!qdf_nbuf_put_tail(msg,
4780*5113495bSYour Name 			       sizeof(struct htt_h2t_vdevs_txrx_stats_cfg))) {
4781*5113495bSYour Name 		dp_htt_err("%pK: Failed to expand head for HTT_HW_VDEV_STATS"
4782*5113495bSYour Name 			   , dpsoc);
4783*5113495bSYour Name 		qdf_nbuf_free(msg);
4784*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
4785*5113495bSYour Name 	}
4786*5113495bSYour Name 
4787*5113495bSYour Name 	msg_word = (uint32_t *)qdf_nbuf_data(msg);
4788*5113495bSYour Name 
4789*5113495bSYour Name 	qdf_nbuf_push_head(msg, HTC_HDR_ALIGNMENT_PADDING);
4790*5113495bSYour Name 	htt_logger_bufp = (uint8_t *)msg_word;
4791*5113495bSYour Name 	*msg_word = 0;
4792*5113495bSYour Name 
4793*5113495bSYour Name 	HTT_H2T_MSG_TYPE_SET(*msg_word, HTT_H2T_MSG_TYPE_VDEVS_TXRX_STATS_CFG);
4794*5113495bSYour Name 	HTT_RX_VDEVS_TXRX_STATS_PDEV_ID_SET(*msg_word, target_pdev_id);
4795*5113495bSYour Name 
4796*5113495bSYour Name 	HTT_RX_VDEVS_TXRX_STATS_ENABLE_SET(*msg_word, enable);
4797*5113495bSYour Name 
4798*5113495bSYour Name 	HTT_RX_VDEVS_TXRX_STATS_PERIODIC_INTERVAL_SET(*msg_word,
4799*5113495bSYour Name 						      (duration >> 3));
4800*5113495bSYour Name 
4801*5113495bSYour Name 	HTT_RX_VDEVS_TXRX_STATS_RESET_STATS_BITS_SET(*msg_word, reset);
4802*5113495bSYour Name 
4803*5113495bSYour Name 	msg_word++;
4804*5113495bSYour Name 	*msg_word = 0;
4805*5113495bSYour Name 	bitmask = (reset_bitmask & HTT_VDEV_TXRX_STATS_RESET_BITMASK_L32_MASK);
4806*5113495bSYour Name 	*msg_word = bitmask;
4807*5113495bSYour Name 
4808*5113495bSYour Name 	msg_word++;
4809*5113495bSYour Name 	*msg_word = 0;
4810*5113495bSYour Name 	bitmask =
4811*5113495bSYour Name 		((reset_bitmask & HTT_VDEV_TXRX_STATS_RESET_BITMASK_U32_MASK) >>
4812*5113495bSYour Name 		 HTT_VDEV_TXRX_STATS_RESET_BITMASK_U32_SHIFT);
4813*5113495bSYour Name 	*msg_word = bitmask;
4814*5113495bSYour Name 
4815*5113495bSYour Name 	pkt = htt_htc_pkt_alloc(soc);
4816*5113495bSYour Name 	if (!pkt) {
4817*5113495bSYour Name 		dp_htt_err("%pK: Fail to allocate dp_htt_htc_pkt buffer",
4818*5113495bSYour Name 			   dpsoc);
4819*5113495bSYour Name 		qdf_assert(0);
4820*5113495bSYour Name 		qdf_nbuf_free(msg);
4821*5113495bSYour Name 		return QDF_STATUS_E_NOMEM;
4822*5113495bSYour Name 	}
4823*5113495bSYour Name 
4824*5113495bSYour Name 	pkt->soc_ctxt = NULL; /* not used during send-done callback */
4825*5113495bSYour Name 
4826*5113495bSYour Name 	SET_HTC_PACKET_INFO_TX(&pkt->htc_pkt,
4827*5113495bSYour Name 			       dp_htt_h2t_send_complete_free_netbuf,
4828*5113495bSYour Name 			       qdf_nbuf_data(msg), qdf_nbuf_len(msg),
4829*5113495bSYour Name 			       soc->htc_endpoint,
4830*5113495bSYour Name 			       /* tag for no FW response msg */
4831*5113495bSYour Name 			       HTC_TX_PACKET_TAG_RUNTIME_PUT);
4832*5113495bSYour Name 
4833*5113495bSYour Name 	SET_HTC_PACKET_NET_BUF_CONTEXT(&pkt->htc_pkt, msg);
4834*5113495bSYour Name 	status = DP_HTT_SEND_HTC_PKT(soc, pkt,
4835*5113495bSYour Name 				     HTT_H2T_MSG_TYPE_VDEVS_TXRX_STATS_CFG,
4836*5113495bSYour Name 				     htt_logger_bufp);
4837*5113495bSYour Name 
4838*5113495bSYour Name 	if (status != QDF_STATUS_SUCCESS) {
4839*5113495bSYour Name 		qdf_nbuf_free(msg);
4840*5113495bSYour Name 		htt_htc_pkt_free(soc, pkt);
4841*5113495bSYour Name 	}
4842*5113495bSYour Name 
4843*5113495bSYour Name 	return status;
4844*5113495bSYour Name }
4845*5113495bSYour Name #else
4846*5113495bSYour Name QDF_STATUS dp_h2t_hw_vdev_stats_config_send(struct dp_soc *dpsoc,
4847*5113495bSYour Name 					    uint8_t pdev_id, bool enable,
4848*5113495bSYour Name 					    bool reset, uint64_t reset_bitmask)
4849*5113495bSYour Name {
4850*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
4851*5113495bSYour Name }
4852*5113495bSYour Name #endif
4853*5113495bSYour Name 
4854*5113495bSYour Name /**
4855*5113495bSYour Name  * dp_h2t_3tuple_config_send(): function to construct 3 tuple configuration
4856*5113495bSYour Name  * HTT message to pass to FW
4857*5113495bSYour Name  * @pdev: DP PDEV handle
4858*5113495bSYour Name  * @tuple_mask: tuple configuration to report 3 tuple hash value in either
4859*5113495bSYour Name  * toeplitz_2_or_4 or flow_id_toeplitz in MSDU START TLV.
4860*5113495bSYour Name  * @mac_id: mac id
4861*5113495bSYour Name  *
4862*5113495bSYour Name  * tuple_mask[1:0]:
4863*5113495bSYour Name  *   00 - Do not report 3 tuple hash value
4864*5113495bSYour Name  *   10 - Report 3 tuple hash value in toeplitz_2_or_4
4865*5113495bSYour Name  *   01 - Report 3 tuple hash value in flow_id_toeplitz
4866*5113495bSYour Name  *   11 - Report 3 tuple hash value in both toeplitz_2_or_4 & flow_id_toeplitz
4867*5113495bSYour Name  *
4868*5113495bSYour Name  * return: QDF STATUS
4869*5113495bSYour Name  */
4870*5113495bSYour Name QDF_STATUS dp_h2t_3tuple_config_send(struct dp_pdev *pdev,
4871*5113495bSYour Name 				     uint32_t tuple_mask, uint8_t mac_id)
4872*5113495bSYour Name {
4873*5113495bSYour Name 	struct htt_soc *soc = pdev->soc->htt_handle;
4874*5113495bSYour Name 	struct dp_htt_htc_pkt *pkt;
4875*5113495bSYour Name 	qdf_nbuf_t msg;
4876*5113495bSYour Name 	uint32_t *msg_word;
4877*5113495bSYour Name 	uint8_t *htt_logger_bufp;
4878*5113495bSYour Name 	int mac_for_pdev;
4879*5113495bSYour Name 	int target_pdev_id;
4880*5113495bSYour Name 
4881*5113495bSYour Name 	msg = qdf_nbuf_alloc(
4882*5113495bSYour Name 			soc->osdev,
4883*5113495bSYour Name 			HTT_MSG_BUF_SIZE(HTT_3_TUPLE_HASH_CFG_REQ_BYTES),
4884*5113495bSYour Name 			HTC_HEADER_LEN + HTC_HDR_ALIGNMENT_PADDING, 4, TRUE);
4885*5113495bSYour Name 
4886*5113495bSYour Name 	if (!msg)
4887*5113495bSYour Name 		return QDF_STATUS_E_NOMEM;
4888*5113495bSYour Name 
4889*5113495bSYour Name 	mac_for_pdev = dp_get_mac_id_for_pdev(mac_id, pdev->pdev_id);
4890*5113495bSYour Name 	target_pdev_id =
4891*5113495bSYour Name 	dp_get_target_pdev_id_for_host_pdev_id(pdev->soc, mac_for_pdev);
4892*5113495bSYour Name 
4893*5113495bSYour Name 	/*
4894*5113495bSYour Name 	 * Set the length of the message.
4895*5113495bSYour Name 	 * The contribution from the HTC_HDR_ALIGNMENT_PADDING is added
4896*5113495bSYour Name 	 * separately during the below call to qdf_nbuf_push_head.
4897*5113495bSYour Name 	 * The contribution from the HTC header is added separately inside HTC.
4898*5113495bSYour Name 	 */
4899*5113495bSYour Name 	if (!qdf_nbuf_put_tail(msg, HTT_3_TUPLE_HASH_CFG_REQ_BYTES)) {
4900*5113495bSYour Name 		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
4901*5113495bSYour Name 			  "Failed to expand head for HTT_3TUPLE_CONFIG");
4902*5113495bSYour Name 		qdf_nbuf_free(msg);
4903*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
4904*5113495bSYour Name 	}
4905*5113495bSYour Name 
4906*5113495bSYour Name 	dp_htt_info("%pK: config_param_sent 0x%x for target_pdev %d\n -------------",
4907*5113495bSYour Name 		    pdev->soc, tuple_mask, target_pdev_id);
4908*5113495bSYour Name 
4909*5113495bSYour Name 	msg_word = (uint32_t *)qdf_nbuf_data(msg);
4910*5113495bSYour Name 	qdf_nbuf_push_head(msg, HTC_HDR_ALIGNMENT_PADDING);
4911*5113495bSYour Name 	htt_logger_bufp = (uint8_t *)msg_word;
4912*5113495bSYour Name 
4913*5113495bSYour Name 	*msg_word = 0;
4914*5113495bSYour Name 	HTT_H2T_MSG_TYPE_SET(*msg_word, HTT_H2T_MSG_TYPE_3_TUPLE_HASH_CFG);
4915*5113495bSYour Name 	HTT_RX_3_TUPLE_HASH_PDEV_ID_SET(*msg_word, target_pdev_id);
4916*5113495bSYour Name 
4917*5113495bSYour Name 	msg_word++;
4918*5113495bSYour Name 	*msg_word = 0;
4919*5113495bSYour Name 	HTT_H2T_FLOW_ID_TOEPLITZ_FIELD_CONFIG_SET(*msg_word, tuple_mask);
4920*5113495bSYour Name 	HTT_H2T_TOEPLITZ_2_OR_4_FIELD_CONFIG_SET(*msg_word, tuple_mask);
4921*5113495bSYour Name 
4922*5113495bSYour Name 	pkt = htt_htc_pkt_alloc(soc);
4923*5113495bSYour Name 	if (!pkt) {
4924*5113495bSYour Name 		qdf_nbuf_free(msg);
4925*5113495bSYour Name 		return QDF_STATUS_E_NOMEM;
4926*5113495bSYour Name 	}
4927*5113495bSYour Name 
4928*5113495bSYour Name 	pkt->soc_ctxt = NULL; /* not used during send-done callback */
4929*5113495bSYour Name 
4930*5113495bSYour Name 	SET_HTC_PACKET_INFO_TX(
4931*5113495bSYour Name 			&pkt->htc_pkt,
4932*5113495bSYour Name 			dp_htt_h2t_send_complete_free_netbuf,
4933*5113495bSYour Name 			qdf_nbuf_data(msg),
4934*5113495bSYour Name 			qdf_nbuf_len(msg),
4935*5113495bSYour Name 			soc->htc_endpoint,
4936*5113495bSYour Name 			/* tag for no FW response msg */
4937*5113495bSYour Name 			HTC_TX_PACKET_TAG_RUNTIME_PUT);
4938*5113495bSYour Name 
4939*5113495bSYour Name 	SET_HTC_PACKET_NET_BUF_CONTEXT(&pkt->htc_pkt, msg);
4940*5113495bSYour Name 	DP_HTT_SEND_HTC_PKT(soc, pkt, HTT_H2T_MSG_TYPE_3_TUPLE_HASH_CFG,
4941*5113495bSYour Name 			    htt_logger_bufp);
4942*5113495bSYour Name 
4943*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
4944*5113495bSYour Name }
4945*5113495bSYour Name 
4946*5113495bSYour Name /* This macro will revert once proper HTT header will define for
4947*5113495bSYour Name  * HTT_H2T_MSG_TYPE_PPDU_STATS_CFG in htt.h file
4948*5113495bSYour Name  * */
4949*5113495bSYour Name #if defined(WDI_EVENT_ENABLE)
4950*5113495bSYour Name QDF_STATUS dp_h2t_cfg_stats_msg_send(struct dp_pdev *pdev,
4951*5113495bSYour Name 		uint32_t stats_type_upload_mask, uint8_t mac_id)
4952*5113495bSYour Name {
4953*5113495bSYour Name 	struct htt_soc *soc = pdev->soc->htt_handle;
4954*5113495bSYour Name 	struct dp_htt_htc_pkt *pkt;
4955*5113495bSYour Name 	qdf_nbuf_t msg;
4956*5113495bSYour Name 	uint32_t *msg_word;
4957*5113495bSYour Name 	uint8_t pdev_mask;
4958*5113495bSYour Name 	QDF_STATUS status;
4959*5113495bSYour Name 
4960*5113495bSYour Name 	msg = qdf_nbuf_alloc(
4961*5113495bSYour Name 			soc->osdev,
4962*5113495bSYour Name 			HTT_MSG_BUF_SIZE(HTT_H2T_PPDU_STATS_CFG_MSG_SZ),
4963*5113495bSYour Name 			HTC_HEADER_LEN + HTC_HDR_ALIGNMENT_PADDING, 4, true);
4964*5113495bSYour Name 
4965*5113495bSYour Name 	if (!msg) {
4966*5113495bSYour Name 		dp_htt_err("%pK: Fail to allocate HTT_H2T_PPDU_STATS_CFG_MSG_SZ msg buffer"
4967*5113495bSYour Name 			   , pdev->soc);
4968*5113495bSYour Name 		qdf_assert(0);
4969*5113495bSYour Name 		return QDF_STATUS_E_NOMEM;
4970*5113495bSYour Name 	}
4971*5113495bSYour Name 
4972*5113495bSYour Name 	/*TODO:Add support for SOC stats
4973*5113495bSYour Name 	 * Bit 0: SOC Stats
4974*5113495bSYour Name 	 * Bit 1: Pdev stats for pdev id 0
4975*5113495bSYour Name 	 * Bit 2: Pdev stats for pdev id 1
4976*5113495bSYour Name 	 * Bit 3: Pdev stats for pdev id 2
4977*5113495bSYour Name 	 */
4978*5113495bSYour Name 	pdev_mask = 1 << dp_get_target_pdev_id_for_host_pdev_id(pdev->soc,
4979*5113495bSYour Name 								mac_id);
4980*5113495bSYour Name 
4981*5113495bSYour Name 	/*
4982*5113495bSYour Name 	 * Set the length of the message.
4983*5113495bSYour Name 	 * The contribution from the HTC_HDR_ALIGNMENT_PADDING is added
4984*5113495bSYour Name 	 * separately during the below call to qdf_nbuf_push_head.
4985*5113495bSYour Name 	 * The contribution from the HTC header is added separately inside HTC.
4986*5113495bSYour Name 	 */
4987*5113495bSYour Name 	if (qdf_nbuf_put_tail(msg, HTT_H2T_PPDU_STATS_CFG_MSG_SZ) == NULL) {
4988*5113495bSYour Name 		dp_htt_err("%pK: Failed to expand head for HTT_CFG_STATS"
4989*5113495bSYour Name 			   , pdev->soc);
4990*5113495bSYour Name 		qdf_nbuf_free(msg);
4991*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
4992*5113495bSYour Name 	}
4993*5113495bSYour Name 
4994*5113495bSYour Name 	msg_word = (uint32_t *) qdf_nbuf_data(msg);
4995*5113495bSYour Name 
4996*5113495bSYour Name 	qdf_nbuf_push_head(msg, HTC_HDR_ALIGNMENT_PADDING);
4997*5113495bSYour Name 	*msg_word = 0;
4998*5113495bSYour Name 	HTT_H2T_MSG_TYPE_SET(*msg_word, HTT_H2T_MSG_TYPE_PPDU_STATS_CFG);
4999*5113495bSYour Name 	HTT_H2T_PPDU_STATS_CFG_PDEV_MASK_SET(*msg_word, pdev_mask);
5000*5113495bSYour Name 	HTT_H2T_PPDU_STATS_CFG_TLV_BITMASK_SET(*msg_word,
5001*5113495bSYour Name 			stats_type_upload_mask);
5002*5113495bSYour Name 
5003*5113495bSYour Name 	pkt = htt_htc_pkt_alloc(soc);
5004*5113495bSYour Name 	if (!pkt) {
5005*5113495bSYour Name 		dp_htt_err("%pK: Fail to allocate dp_htt_htc_pkt buffer", pdev->soc);
5006*5113495bSYour Name 		qdf_assert(0);
5007*5113495bSYour Name 		qdf_nbuf_free(msg);
5008*5113495bSYour Name 		return QDF_STATUS_E_NOMEM;
5009*5113495bSYour Name 	}
5010*5113495bSYour Name 
5011*5113495bSYour Name 	pkt->soc_ctxt = NULL; /* not used during send-done callback */
5012*5113495bSYour Name 
5013*5113495bSYour Name 	SET_HTC_PACKET_INFO_TX(&pkt->htc_pkt,
5014*5113495bSYour Name 			dp_htt_h2t_send_complete_free_netbuf,
5015*5113495bSYour Name 			qdf_nbuf_data(msg), qdf_nbuf_len(msg),
5016*5113495bSYour Name 			soc->htc_endpoint,
5017*5113495bSYour Name 			/* tag for no FW response msg */
5018*5113495bSYour Name 			HTC_TX_PACKET_TAG_RUNTIME_PUT);
5019*5113495bSYour Name 
5020*5113495bSYour Name 	SET_HTC_PACKET_NET_BUF_CONTEXT(&pkt->htc_pkt, msg);
5021*5113495bSYour Name 	status = DP_HTT_SEND_HTC_PKT(soc, pkt, HTT_H2T_MSG_TYPE_PPDU_STATS_CFG,
5022*5113495bSYour Name 				     (uint8_t *)msg_word);
5023*5113495bSYour Name 
5024*5113495bSYour Name 	if (status != QDF_STATUS_SUCCESS) {
5025*5113495bSYour Name 		qdf_nbuf_free(msg);
5026*5113495bSYour Name 		htt_htc_pkt_free(soc, pkt);
5027*5113495bSYour Name 	}
5028*5113495bSYour Name 
5029*5113495bSYour Name 	return status;
5030*5113495bSYour Name }
5031*5113495bSYour Name 
5032*5113495bSYour Name qdf_export_symbol(dp_h2t_cfg_stats_msg_send);
5033*5113495bSYour Name #endif
5034*5113495bSYour Name 
5035*5113495bSYour Name void
5036*5113495bSYour Name dp_peer_update_inactive_time(struct dp_pdev *pdev, uint32_t tag_type,
5037*5113495bSYour Name 			     uint32_t *tag_buf)
5038*5113495bSYour Name {
5039*5113495bSYour Name 	struct dp_peer *peer = NULL;
5040*5113495bSYour Name 	switch (tag_type) {
5041*5113495bSYour Name 	case HTT_STATS_PEER_DETAILS_TAG:
5042*5113495bSYour Name 	{
5043*5113495bSYour Name 		htt_peer_details_tlv *dp_stats_buf =
5044*5113495bSYour Name 			(htt_peer_details_tlv *)tag_buf;
5045*5113495bSYour Name 
5046*5113495bSYour Name 		pdev->fw_stats_peer_id = dp_stats_buf->sw_peer_id;
5047*5113495bSYour Name 	}
5048*5113495bSYour Name 	break;
5049*5113495bSYour Name 	case HTT_STATS_PEER_STATS_CMN_TAG:
5050*5113495bSYour Name 	{
5051*5113495bSYour Name 		htt_peer_stats_cmn_tlv *dp_stats_buf =
5052*5113495bSYour Name 			(htt_peer_stats_cmn_tlv *)tag_buf;
5053*5113495bSYour Name 
5054*5113495bSYour Name 		peer = dp_peer_get_ref_by_id(pdev->soc, pdev->fw_stats_peer_id,
5055*5113495bSYour Name 					     DP_MOD_ID_HTT);
5056*5113495bSYour Name 
5057*5113495bSYour Name 		if (peer && !peer->bss_peer) {
5058*5113495bSYour Name 			peer->stats.tx.inactive_time =
5059*5113495bSYour Name 				dp_stats_buf->inactive_time;
5060*5113495bSYour Name 			qdf_event_set(&pdev->fw_peer_stats_event);
5061*5113495bSYour Name 		}
5062*5113495bSYour Name 		if (peer)
5063*5113495bSYour Name 			dp_peer_unref_delete(peer, DP_MOD_ID_HTT);
5064*5113495bSYour Name 	}
5065*5113495bSYour Name 	break;
5066*5113495bSYour Name 	default:
5067*5113495bSYour Name 		qdf_err("Invalid tag_type: %u", tag_type);
5068*5113495bSYour Name 	}
5069*5113495bSYour Name }
5070*5113495bSYour Name 
5071*5113495bSYour Name QDF_STATUS
5072*5113495bSYour Name dp_htt_rx_flow_fst_setup(struct dp_pdev *pdev,
5073*5113495bSYour Name 			 struct dp_htt_rx_flow_fst_setup *fse_setup_info)
5074*5113495bSYour Name {
5075*5113495bSYour Name 	struct htt_soc *soc = pdev->soc->htt_handle;
5076*5113495bSYour Name 	struct dp_htt_htc_pkt *pkt;
5077*5113495bSYour Name 	qdf_nbuf_t msg;
5078*5113495bSYour Name 	u_int32_t *msg_word;
5079*5113495bSYour Name 	struct htt_h2t_msg_rx_fse_setup_t *fse_setup;
5080*5113495bSYour Name 	uint8_t *htt_logger_bufp;
5081*5113495bSYour Name 	u_int32_t *key;
5082*5113495bSYour Name 	QDF_STATUS status;
5083*5113495bSYour Name 
5084*5113495bSYour Name 	msg = qdf_nbuf_alloc(
5085*5113495bSYour Name 		soc->osdev,
5086*5113495bSYour Name 		HTT_MSG_BUF_SIZE(sizeof(struct htt_h2t_msg_rx_fse_setup_t)),
5087*5113495bSYour Name 		/* reserve room for the HTC header */
5088*5113495bSYour Name 		HTC_HEADER_LEN + HTC_HDR_ALIGNMENT_PADDING, 4, TRUE);
5089*5113495bSYour Name 
5090*5113495bSYour Name 	if (!msg)
5091*5113495bSYour Name 		return QDF_STATUS_E_NOMEM;
5092*5113495bSYour Name 
5093*5113495bSYour Name 	/*
5094*5113495bSYour Name 	 * Set the length of the message.
5095*5113495bSYour Name 	 * The contribution from the HTC_HDR_ALIGNMENT_PADDING is added
5096*5113495bSYour Name 	 * separately during the below call to qdf_nbuf_push_head.
5097*5113495bSYour Name 	 * The contribution from the HTC header is added separately inside HTC.
5098*5113495bSYour Name 	 */
5099*5113495bSYour Name 	if (!qdf_nbuf_put_tail(msg,
5100*5113495bSYour Name 			       sizeof(struct htt_h2t_msg_rx_fse_setup_t))) {
5101*5113495bSYour Name 		qdf_err("Failed to expand head for HTT RX_FSE_SETUP msg");
5102*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
5103*5113495bSYour Name 	}
5104*5113495bSYour Name 
5105*5113495bSYour Name 	/* fill in the message contents */
5106*5113495bSYour Name 	msg_word = (u_int32_t *)qdf_nbuf_data(msg);
5107*5113495bSYour Name 
5108*5113495bSYour Name 	memset(msg_word, 0, sizeof(struct htt_h2t_msg_rx_fse_setup_t));
5109*5113495bSYour Name 	/* rewind beyond alignment pad to get to the HTC header reserved area */
5110*5113495bSYour Name 	qdf_nbuf_push_head(msg, HTC_HDR_ALIGNMENT_PADDING);
5111*5113495bSYour Name 	htt_logger_bufp = (uint8_t *)msg_word;
5112*5113495bSYour Name 
5113*5113495bSYour Name 	*msg_word = 0;
5114*5113495bSYour Name 	HTT_H2T_MSG_TYPE_SET(*msg_word, HTT_H2T_MSG_TYPE_RX_FSE_SETUP_CFG);
5115*5113495bSYour Name 
5116*5113495bSYour Name 	fse_setup = (struct htt_h2t_msg_rx_fse_setup_t *)msg_word;
5117*5113495bSYour Name 
5118*5113495bSYour Name 	HTT_RX_FSE_SETUP_PDEV_ID_SET(*msg_word, fse_setup_info->pdev_id);
5119*5113495bSYour Name 
5120*5113495bSYour Name 	msg_word++;
5121*5113495bSYour Name 	HTT_RX_FSE_SETUP_NUM_REC_SET(*msg_word, fse_setup_info->max_entries);
5122*5113495bSYour Name 	HTT_RX_FSE_SETUP_MAX_SEARCH_SET(*msg_word, fse_setup_info->max_search);
5123*5113495bSYour Name 	HTT_RX_FSE_SETUP_IP_DA_SA_PREFIX_SET(*msg_word,
5124*5113495bSYour Name 					     fse_setup_info->ip_da_sa_prefix);
5125*5113495bSYour Name 
5126*5113495bSYour Name 	msg_word++;
5127*5113495bSYour Name 	HTT_RX_FSE_SETUP_BASE_ADDR_LO_SET(*msg_word,
5128*5113495bSYour Name 					  fse_setup_info->base_addr_lo);
5129*5113495bSYour Name 	msg_word++;
5130*5113495bSYour Name 	HTT_RX_FSE_SETUP_BASE_ADDR_HI_SET(*msg_word,
5131*5113495bSYour Name 					  fse_setup_info->base_addr_hi);
5132*5113495bSYour Name 
5133*5113495bSYour Name 	key = (u_int32_t *)fse_setup_info->hash_key;
5134*5113495bSYour Name 	fse_setup->toeplitz31_0 = *key++;
5135*5113495bSYour Name 	fse_setup->toeplitz63_32 = *key++;
5136*5113495bSYour Name 	fse_setup->toeplitz95_64 = *key++;
5137*5113495bSYour Name 	fse_setup->toeplitz127_96 = *key++;
5138*5113495bSYour Name 	fse_setup->toeplitz159_128 = *key++;
5139*5113495bSYour Name 	fse_setup->toeplitz191_160 = *key++;
5140*5113495bSYour Name 	fse_setup->toeplitz223_192 = *key++;
5141*5113495bSYour Name 	fse_setup->toeplitz255_224 = *key++;
5142*5113495bSYour Name 	fse_setup->toeplitz287_256 = *key++;
5143*5113495bSYour Name 	fse_setup->toeplitz314_288 = *key;
5144*5113495bSYour Name 
5145*5113495bSYour Name 	msg_word++;
5146*5113495bSYour Name 	HTT_RX_FSE_SETUP_HASH_VALUE_SET(*msg_word, fse_setup->toeplitz31_0);
5147*5113495bSYour Name 	msg_word++;
5148*5113495bSYour Name 	HTT_RX_FSE_SETUP_HASH_VALUE_SET(*msg_word, fse_setup->toeplitz63_32);
5149*5113495bSYour Name 	msg_word++;
5150*5113495bSYour Name 	HTT_RX_FSE_SETUP_HASH_VALUE_SET(*msg_word, fse_setup->toeplitz95_64);
5151*5113495bSYour Name 	msg_word++;
5152*5113495bSYour Name 	HTT_RX_FSE_SETUP_HASH_VALUE_SET(*msg_word, fse_setup->toeplitz127_96);
5153*5113495bSYour Name 	msg_word++;
5154*5113495bSYour Name 	HTT_RX_FSE_SETUP_HASH_VALUE_SET(*msg_word, fse_setup->toeplitz159_128);
5155*5113495bSYour Name 	msg_word++;
5156*5113495bSYour Name 	HTT_RX_FSE_SETUP_HASH_VALUE_SET(*msg_word, fse_setup->toeplitz191_160);
5157*5113495bSYour Name 	msg_word++;
5158*5113495bSYour Name 	HTT_RX_FSE_SETUP_HASH_VALUE_SET(*msg_word, fse_setup->toeplitz223_192);
5159*5113495bSYour Name 	msg_word++;
5160*5113495bSYour Name 	HTT_RX_FSE_SETUP_HASH_VALUE_SET(*msg_word, fse_setup->toeplitz255_224);
5161*5113495bSYour Name 	msg_word++;
5162*5113495bSYour Name 	HTT_RX_FSE_SETUP_HASH_VALUE_SET(*msg_word, fse_setup->toeplitz287_256);
5163*5113495bSYour Name 	msg_word++;
5164*5113495bSYour Name 	HTT_RX_FSE_SETUP_HASH_314_288_SET(*msg_word,
5165*5113495bSYour Name 					  fse_setup->toeplitz314_288);
5166*5113495bSYour Name 
5167*5113495bSYour Name 	pkt = htt_htc_pkt_alloc(soc);
5168*5113495bSYour Name 	if (!pkt) {
5169*5113495bSYour Name 		qdf_err("Fail to allocate dp_htt_htc_pkt buffer");
5170*5113495bSYour Name 		qdf_assert(0);
5171*5113495bSYour Name 		qdf_nbuf_free(msg);
5172*5113495bSYour Name 		return QDF_STATUS_E_RESOURCES; /* failure */
5173*5113495bSYour Name 	}
5174*5113495bSYour Name 
5175*5113495bSYour Name 	pkt->soc_ctxt = NULL; /* not used during send-done callback */
5176*5113495bSYour Name 
5177*5113495bSYour Name 	SET_HTC_PACKET_INFO_TX(
5178*5113495bSYour Name 		&pkt->htc_pkt,
5179*5113495bSYour Name 		dp_htt_h2t_send_complete_free_netbuf,
5180*5113495bSYour Name 		qdf_nbuf_data(msg),
5181*5113495bSYour Name 		qdf_nbuf_len(msg),
5182*5113495bSYour Name 		soc->htc_endpoint,
5183*5113495bSYour Name 		/* tag for no FW response msg */
5184*5113495bSYour Name 		HTC_TX_PACKET_TAG_RUNTIME_PUT);
5185*5113495bSYour Name 
5186*5113495bSYour Name 	SET_HTC_PACKET_NET_BUF_CONTEXT(&pkt->htc_pkt, msg);
5187*5113495bSYour Name 
5188*5113495bSYour Name 	status = DP_HTT_SEND_HTC_PKT(soc, pkt,
5189*5113495bSYour Name 				     HTT_H2T_MSG_TYPE_RX_FSE_SETUP_CFG,
5190*5113495bSYour Name 				     htt_logger_bufp);
5191*5113495bSYour Name 
5192*5113495bSYour Name 	if (status == QDF_STATUS_SUCCESS) {
5193*5113495bSYour Name 		dp_info("HTT_H2T RX_FSE_SETUP sent to FW for pdev = %u",
5194*5113495bSYour Name 			fse_setup_info->pdev_id);
5195*5113495bSYour Name 		QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_ANY, QDF_TRACE_LEVEL_DEBUG,
5196*5113495bSYour Name 				   (void *)fse_setup_info->hash_key,
5197*5113495bSYour Name 				   fse_setup_info->hash_key_len);
5198*5113495bSYour Name 	} else {
5199*5113495bSYour Name 		qdf_nbuf_free(msg);
5200*5113495bSYour Name 		htt_htc_pkt_free(soc, pkt);
5201*5113495bSYour Name 	}
5202*5113495bSYour Name 
5203*5113495bSYour Name 	return status;
5204*5113495bSYour Name }
5205*5113495bSYour Name 
5206*5113495bSYour Name QDF_STATUS
5207*5113495bSYour Name dp_htt_rx_flow_fse_operation(struct dp_pdev *pdev,
5208*5113495bSYour Name 			     struct dp_htt_rx_flow_fst_operation *fse_op_info)
5209*5113495bSYour Name {
5210*5113495bSYour Name 	struct htt_soc *soc = pdev->soc->htt_handle;
5211*5113495bSYour Name 	struct dp_htt_htc_pkt *pkt;
5212*5113495bSYour Name 	qdf_nbuf_t msg;
5213*5113495bSYour Name 	u_int32_t *msg_word;
5214*5113495bSYour Name 	struct htt_h2t_msg_rx_fse_operation_t *fse_operation;
5215*5113495bSYour Name 	uint8_t *htt_logger_bufp;
5216*5113495bSYour Name 	QDF_STATUS status;
5217*5113495bSYour Name 
5218*5113495bSYour Name 	msg = qdf_nbuf_alloc(
5219*5113495bSYour Name 		soc->osdev,
5220*5113495bSYour Name 		HTT_MSG_BUF_SIZE(sizeof(struct htt_h2t_msg_rx_fse_operation_t)),
5221*5113495bSYour Name 		/* reserve room for the HTC header */
5222*5113495bSYour Name 		HTC_HEADER_LEN + HTC_HDR_ALIGNMENT_PADDING, 4, TRUE);
5223*5113495bSYour Name 	if (!msg)
5224*5113495bSYour Name 		return QDF_STATUS_E_NOMEM;
5225*5113495bSYour Name 
5226*5113495bSYour Name 	/*
5227*5113495bSYour Name 	 * Set the length of the message.
5228*5113495bSYour Name 	 * The contribution from the HTC_HDR_ALIGNMENT_PADDING is added
5229*5113495bSYour Name 	 * separately during the below call to qdf_nbuf_push_head.
5230*5113495bSYour Name 	 * The contribution from the HTC header is added separately inside HTC.
5231*5113495bSYour Name 	 */
5232*5113495bSYour Name 	if (!qdf_nbuf_put_tail(msg,
5233*5113495bSYour Name 			       sizeof(struct htt_h2t_msg_rx_fse_operation_t))) {
5234*5113495bSYour Name 		qdf_err("Failed to expand head for HTT_RX_FSE_OPERATION msg");
5235*5113495bSYour Name 		qdf_nbuf_free(msg);
5236*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
5237*5113495bSYour Name 	}
5238*5113495bSYour Name 
5239*5113495bSYour Name 	/* fill in the message contents */
5240*5113495bSYour Name 	msg_word = (u_int32_t *)qdf_nbuf_data(msg);
5241*5113495bSYour Name 
5242*5113495bSYour Name 	memset(msg_word, 0, sizeof(struct htt_h2t_msg_rx_fse_operation_t));
5243*5113495bSYour Name 	/* rewind beyond alignment pad to get to the HTC header reserved area */
5244*5113495bSYour Name 	qdf_nbuf_push_head(msg, HTC_HDR_ALIGNMENT_PADDING);
5245*5113495bSYour Name 	htt_logger_bufp = (uint8_t *)msg_word;
5246*5113495bSYour Name 
5247*5113495bSYour Name 	*msg_word = 0;
5248*5113495bSYour Name 	HTT_H2T_MSG_TYPE_SET(*msg_word, HTT_H2T_MSG_TYPE_RX_FSE_OPERATION_CFG);
5249*5113495bSYour Name 
5250*5113495bSYour Name 	fse_operation = (struct htt_h2t_msg_rx_fse_operation_t *)msg_word;
5251*5113495bSYour Name 
5252*5113495bSYour Name 	HTT_RX_FSE_OPERATION_PDEV_ID_SET(*msg_word, fse_op_info->pdev_id);
5253*5113495bSYour Name 	msg_word++;
5254*5113495bSYour Name 	HTT_RX_FSE_IPSEC_VALID_SET(*msg_word, false);
5255*5113495bSYour Name 	if (fse_op_info->op_code == DP_HTT_FST_CACHE_INVALIDATE_ENTRY) {
5256*5113495bSYour Name 		HTT_RX_FSE_OPERATION_SET(*msg_word,
5257*5113495bSYour Name 					 HTT_RX_FSE_CACHE_INVALIDATE_ENTRY);
5258*5113495bSYour Name 		msg_word++;
5259*5113495bSYour Name 		HTT_RX_FSE_OPERATION_IP_ADDR_SET(
5260*5113495bSYour Name 		*msg_word,
5261*5113495bSYour Name 		qdf_htonl(fse_op_info->rx_flow->flow_tuple_info.src_ip_31_0));
5262*5113495bSYour Name 		msg_word++;
5263*5113495bSYour Name 		HTT_RX_FSE_OPERATION_IP_ADDR_SET(
5264*5113495bSYour Name 		*msg_word,
5265*5113495bSYour Name 		qdf_htonl(fse_op_info->rx_flow->flow_tuple_info.src_ip_63_32));
5266*5113495bSYour Name 		msg_word++;
5267*5113495bSYour Name 		HTT_RX_FSE_OPERATION_IP_ADDR_SET(
5268*5113495bSYour Name 		*msg_word,
5269*5113495bSYour Name 		qdf_htonl(fse_op_info->rx_flow->flow_tuple_info.src_ip_95_64));
5270*5113495bSYour Name 		msg_word++;
5271*5113495bSYour Name 		HTT_RX_FSE_OPERATION_IP_ADDR_SET(
5272*5113495bSYour Name 		*msg_word,
5273*5113495bSYour Name 		qdf_htonl(fse_op_info->rx_flow->flow_tuple_info.src_ip_127_96));
5274*5113495bSYour Name 		msg_word++;
5275*5113495bSYour Name 		HTT_RX_FSE_OPERATION_IP_ADDR_SET(
5276*5113495bSYour Name 		*msg_word,
5277*5113495bSYour Name 		qdf_htonl(fse_op_info->rx_flow->flow_tuple_info.dest_ip_31_0));
5278*5113495bSYour Name 		msg_word++;
5279*5113495bSYour Name 		HTT_RX_FSE_OPERATION_IP_ADDR_SET(
5280*5113495bSYour Name 		*msg_word,
5281*5113495bSYour Name 		qdf_htonl(fse_op_info->rx_flow->flow_tuple_info.dest_ip_63_32));
5282*5113495bSYour Name 		msg_word++;
5283*5113495bSYour Name 		HTT_RX_FSE_OPERATION_IP_ADDR_SET(
5284*5113495bSYour Name 		*msg_word,
5285*5113495bSYour Name 		qdf_htonl(fse_op_info->rx_flow->flow_tuple_info.dest_ip_95_64));
5286*5113495bSYour Name 		msg_word++;
5287*5113495bSYour Name 		HTT_RX_FSE_OPERATION_IP_ADDR_SET(
5288*5113495bSYour Name 		*msg_word,
5289*5113495bSYour Name 		qdf_htonl(
5290*5113495bSYour Name 		fse_op_info->rx_flow->flow_tuple_info.dest_ip_127_96));
5291*5113495bSYour Name 		msg_word++;
5292*5113495bSYour Name 		HTT_RX_FSE_SOURCEPORT_SET(
5293*5113495bSYour Name 			*msg_word,
5294*5113495bSYour Name 			fse_op_info->rx_flow->flow_tuple_info.src_port);
5295*5113495bSYour Name 		HTT_RX_FSE_DESTPORT_SET(
5296*5113495bSYour Name 			*msg_word,
5297*5113495bSYour Name 			fse_op_info->rx_flow->flow_tuple_info.dest_port);
5298*5113495bSYour Name 		msg_word++;
5299*5113495bSYour Name 		HTT_RX_FSE_L4_PROTO_SET(
5300*5113495bSYour Name 			*msg_word,
5301*5113495bSYour Name 			fse_op_info->rx_flow->flow_tuple_info.l4_protocol);
5302*5113495bSYour Name 	} else if (fse_op_info->op_code == DP_HTT_FST_CACHE_INVALIDATE_FULL) {
5303*5113495bSYour Name 		HTT_RX_FSE_OPERATION_SET(*msg_word,
5304*5113495bSYour Name 					 HTT_RX_FSE_CACHE_INVALIDATE_FULL);
5305*5113495bSYour Name 	} else if (fse_op_info->op_code == DP_HTT_FST_DISABLE) {
5306*5113495bSYour Name 		HTT_RX_FSE_OPERATION_SET(*msg_word, HTT_RX_FSE_DISABLE);
5307*5113495bSYour Name 	} else if (fse_op_info->op_code == DP_HTT_FST_ENABLE) {
5308*5113495bSYour Name 		HTT_RX_FSE_OPERATION_SET(*msg_word, HTT_RX_FSE_ENABLE);
5309*5113495bSYour Name 	}
5310*5113495bSYour Name 
5311*5113495bSYour Name 	pkt = htt_htc_pkt_alloc(soc);
5312*5113495bSYour Name 	if (!pkt) {
5313*5113495bSYour Name 		qdf_err("Fail to allocate dp_htt_htc_pkt buffer");
5314*5113495bSYour Name 		qdf_assert(0);
5315*5113495bSYour Name 		qdf_nbuf_free(msg);
5316*5113495bSYour Name 		return QDF_STATUS_E_RESOURCES; /* failure */
5317*5113495bSYour Name 	}
5318*5113495bSYour Name 
5319*5113495bSYour Name 	pkt->soc_ctxt = NULL; /* not used during send-done callback */
5320*5113495bSYour Name 
5321*5113495bSYour Name 	SET_HTC_PACKET_INFO_TX(
5322*5113495bSYour Name 		&pkt->htc_pkt,
5323*5113495bSYour Name 		dp_htt_h2t_send_complete_free_netbuf,
5324*5113495bSYour Name 		qdf_nbuf_data(msg),
5325*5113495bSYour Name 		qdf_nbuf_len(msg),
5326*5113495bSYour Name 		soc->htc_endpoint,
5327*5113495bSYour Name 		/* tag for no FW response msg */
5328*5113495bSYour Name 		HTC_TX_PACKET_TAG_RUNTIME_PUT);
5329*5113495bSYour Name 
5330*5113495bSYour Name 	SET_HTC_PACKET_NET_BUF_CONTEXT(&pkt->htc_pkt, msg);
5331*5113495bSYour Name 
5332*5113495bSYour Name 	status = DP_HTT_SEND_HTC_PKT(soc, pkt,
5333*5113495bSYour Name 				     HTT_H2T_MSG_TYPE_RX_FSE_OPERATION_CFG,
5334*5113495bSYour Name 				     htt_logger_bufp);
5335*5113495bSYour Name 
5336*5113495bSYour Name 	if (status == QDF_STATUS_SUCCESS) {
5337*5113495bSYour Name 		dp_info("HTT_H2T RX_FSE_OPERATION_CFG sent to FW for pdev = %u",
5338*5113495bSYour Name 			fse_op_info->pdev_id);
5339*5113495bSYour Name 	} else {
5340*5113495bSYour Name 		qdf_nbuf_free(msg);
5341*5113495bSYour Name 		htt_htc_pkt_free(soc, pkt);
5342*5113495bSYour Name 	}
5343*5113495bSYour Name 
5344*5113495bSYour Name 	return status;
5345*5113495bSYour Name }
5346*5113495bSYour Name 
5347*5113495bSYour Name /**
5348*5113495bSYour Name  * dp_htt_rx_fisa_config(): Send HTT msg to configure FISA
5349*5113495bSYour Name  * @pdev: DP pdev handle
5350*5113495bSYour Name  * @fisa_config: Fisa config struct
5351*5113495bSYour Name  *
5352*5113495bSYour Name  * Return: Success when HTT message is sent, error on failure
5353*5113495bSYour Name  */
5354*5113495bSYour Name QDF_STATUS
5355*5113495bSYour Name dp_htt_rx_fisa_config(struct dp_pdev *pdev,
5356*5113495bSYour Name 		      struct dp_htt_rx_fisa_cfg *fisa_config)
5357*5113495bSYour Name {
5358*5113495bSYour Name 	struct htt_soc *soc = pdev->soc->htt_handle;
5359*5113495bSYour Name 	struct dp_htt_htc_pkt *pkt;
5360*5113495bSYour Name 	qdf_nbuf_t msg;
5361*5113495bSYour Name 	u_int32_t *msg_word;
5362*5113495bSYour Name 	struct htt_h2t_msg_type_fisa_config_t *htt_fisa_config;
5363*5113495bSYour Name 	uint8_t *htt_logger_bufp;
5364*5113495bSYour Name 	uint32_t len;
5365*5113495bSYour Name 	QDF_STATUS status;
5366*5113495bSYour Name 
5367*5113495bSYour Name 	len = HTT_MSG_BUF_SIZE(sizeof(struct htt_h2t_msg_type_fisa_config_t));
5368*5113495bSYour Name 
5369*5113495bSYour Name 	msg = qdf_nbuf_alloc(soc->osdev,
5370*5113495bSYour Name 			     len,
5371*5113495bSYour Name 			     /* reserve room for the HTC header */
5372*5113495bSYour Name 			     HTC_HEADER_LEN + HTC_HDR_ALIGNMENT_PADDING,
5373*5113495bSYour Name 			     4,
5374*5113495bSYour Name 			     TRUE);
5375*5113495bSYour Name 	if (!msg)
5376*5113495bSYour Name 		return QDF_STATUS_E_NOMEM;
5377*5113495bSYour Name 
5378*5113495bSYour Name 	/*
5379*5113495bSYour Name 	 * Set the length of the message.
5380*5113495bSYour Name 	 * The contribution from the HTC_HDR_ALIGNMENT_PADDING is added
5381*5113495bSYour Name 	 * separately during the below call to qdf_nbuf_push_head.
5382*5113495bSYour Name 	 * The contribution from the HTC header is added separately inside HTC.
5383*5113495bSYour Name 	 */
5384*5113495bSYour Name 	if (!qdf_nbuf_put_tail(msg,
5385*5113495bSYour Name 			       sizeof(struct htt_h2t_msg_type_fisa_config_t))) {
5386*5113495bSYour Name 		qdf_err("Failed to expand head for HTT_RX_FSE_OPERATION msg");
5387*5113495bSYour Name 		qdf_nbuf_free(msg);
5388*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
5389*5113495bSYour Name 	}
5390*5113495bSYour Name 
5391*5113495bSYour Name 	/* fill in the message contents */
5392*5113495bSYour Name 	msg_word = (u_int32_t *)qdf_nbuf_data(msg);
5393*5113495bSYour Name 
5394*5113495bSYour Name 	memset(msg_word, 0, sizeof(struct htt_h2t_msg_type_fisa_config_t));
5395*5113495bSYour Name 	/* rewind beyond alignment pad to get to the HTC header reserved area */
5396*5113495bSYour Name 	qdf_nbuf_push_head(msg, HTC_HDR_ALIGNMENT_PADDING);
5397*5113495bSYour Name 	htt_logger_bufp = (uint8_t *)msg_word;
5398*5113495bSYour Name 
5399*5113495bSYour Name 	*msg_word = 0;
5400*5113495bSYour Name 	HTT_H2T_MSG_TYPE_SET(*msg_word, HTT_H2T_MSG_TYPE_RX_FISA_CFG);
5401*5113495bSYour Name 
5402*5113495bSYour Name 	htt_fisa_config = (struct htt_h2t_msg_type_fisa_config_t *)msg_word;
5403*5113495bSYour Name 
5404*5113495bSYour Name 	HTT_RX_FSE_OPERATION_PDEV_ID_SET(*msg_word, htt_fisa_config->pdev_id);
5405*5113495bSYour Name 
5406*5113495bSYour Name 	msg_word++;
5407*5113495bSYour Name 	HTT_RX_FISA_CONFIG_FISA_V2_ENABLE_SET(*msg_word, 1);
5408*5113495bSYour Name 	HTT_RX_FISA_CONFIG_FISA_V2_AGGR_LIMIT_SET(*msg_word,
5409*5113495bSYour Name 	(fisa_config->max_aggr_supported ? fisa_config->max_aggr_supported : 0xf));
5410*5113495bSYour Name 
5411*5113495bSYour Name 	msg_word++;
5412*5113495bSYour Name 	htt_fisa_config->fisa_timeout_threshold = fisa_config->fisa_timeout;
5413*5113495bSYour Name 
5414*5113495bSYour Name 	pkt = htt_htc_pkt_alloc(soc);
5415*5113495bSYour Name 	if (!pkt) {
5416*5113495bSYour Name 		qdf_err("Fail to allocate dp_htt_htc_pkt buffer");
5417*5113495bSYour Name 		qdf_assert(0);
5418*5113495bSYour Name 		qdf_nbuf_free(msg);
5419*5113495bSYour Name 		return QDF_STATUS_E_RESOURCES; /* failure */
5420*5113495bSYour Name 	}
5421*5113495bSYour Name 
5422*5113495bSYour Name 	pkt->soc_ctxt = NULL; /* not used during send-done callback */
5423*5113495bSYour Name 
5424*5113495bSYour Name 	SET_HTC_PACKET_INFO_TX(&pkt->htc_pkt,
5425*5113495bSYour Name 			       dp_htt_h2t_send_complete_free_netbuf,
5426*5113495bSYour Name 			       qdf_nbuf_data(msg),
5427*5113495bSYour Name 			       qdf_nbuf_len(msg),
5428*5113495bSYour Name 			       soc->htc_endpoint,
5429*5113495bSYour Name 			       /* tag for no FW response msg */
5430*5113495bSYour Name 			       HTC_TX_PACKET_TAG_RUNTIME_PUT);
5431*5113495bSYour Name 
5432*5113495bSYour Name 	SET_HTC_PACKET_NET_BUF_CONTEXT(&pkt->htc_pkt, msg);
5433*5113495bSYour Name 
5434*5113495bSYour Name 	status = DP_HTT_SEND_HTC_PKT(soc, pkt, HTT_H2T_MSG_TYPE_RX_FISA_CFG,
5435*5113495bSYour Name 				     htt_logger_bufp);
5436*5113495bSYour Name 
5437*5113495bSYour Name 	if (status == QDF_STATUS_SUCCESS) {
5438*5113495bSYour Name 		dp_info("HTT_H2T_MSG_TYPE_RX_FISA_CFG sent to FW for pdev = %u",
5439*5113495bSYour Name 			fisa_config->pdev_id);
5440*5113495bSYour Name 	} else {
5441*5113495bSYour Name 		qdf_nbuf_free(msg);
5442*5113495bSYour Name 		htt_htc_pkt_free(soc, pkt);
5443*5113495bSYour Name 	}
5444*5113495bSYour Name 
5445*5113495bSYour Name 	return status;
5446*5113495bSYour Name }
5447*5113495bSYour Name 
5448*5113495bSYour Name #ifdef WLAN_SUPPORT_PPEDS
5449*5113495bSYour Name /**
5450*5113495bSYour Name  * dp_htt_rxdma_rxole_ppe_cfg_set() - Send RxOLE and RxDMA PPE config
5451*5113495bSYour Name  * @soc: Data path SoC handle
5452*5113495bSYour Name  * @cfg: RxDMA and RxOLE PPE config
5453*5113495bSYour Name  *
5454*5113495bSYour Name  * Return: Success when HTT message is sent, error on failure
5455*5113495bSYour Name  */
5456*5113495bSYour Name QDF_STATUS
5457*5113495bSYour Name dp_htt_rxdma_rxole_ppe_cfg_set(struct dp_soc *soc,
5458*5113495bSYour Name 			       struct dp_htt_rxdma_rxole_ppe_config *cfg)
5459*5113495bSYour Name {
5460*5113495bSYour Name 	struct htt_soc *htt_handle = soc->htt_handle;
5461*5113495bSYour Name 	uint32_t len;
5462*5113495bSYour Name 	qdf_nbuf_t msg;
5463*5113495bSYour Name 	u_int32_t *msg_word;
5464*5113495bSYour Name 	QDF_STATUS status;
5465*5113495bSYour Name 	uint8_t *htt_logger_bufp;
5466*5113495bSYour Name 	struct dp_htt_htc_pkt *pkt;
5467*5113495bSYour Name 
5468*5113495bSYour Name 	len = HTT_MSG_BUF_SIZE(
5469*5113495bSYour Name 	      sizeof(struct htt_h2t_msg_type_rxdma_rxole_ppe_cfg_t));
5470*5113495bSYour Name 
5471*5113495bSYour Name 	msg = qdf_nbuf_alloc(soc->osdev,
5472*5113495bSYour Name 			     len,
5473*5113495bSYour Name 			     /* reserve room for the HTC header */
5474*5113495bSYour Name 			     HTC_HEADER_LEN + HTC_HDR_ALIGNMENT_PADDING,
5475*5113495bSYour Name 			     4,
5476*5113495bSYour Name 			     TRUE);
5477*5113495bSYour Name 	if (!msg)
5478*5113495bSYour Name 		return QDF_STATUS_E_NOMEM;
5479*5113495bSYour Name 
5480*5113495bSYour Name 	/*
5481*5113495bSYour Name 	 * Set the length of the message.
5482*5113495bSYour Name 	 * The contribution from the HTC_HDR_ALIGNMENT_PADDING is added
5483*5113495bSYour Name 	 * separately during the below call to qdf_nbuf_push_head.
5484*5113495bSYour Name 	 * The contribution from the HTC header is added separately inside HTC.
5485*5113495bSYour Name 	 */
5486*5113495bSYour Name 	if (!qdf_nbuf_put_tail(
5487*5113495bSYour Name 		msg, sizeof(struct htt_h2t_msg_type_rxdma_rxole_ppe_cfg_t))) {
5488*5113495bSYour Name 		qdf_err("Failed to expand head for HTT_H2T_MSG_TYPE_RXDMA_RXOLE_PPE_CFG msg");
5489*5113495bSYour Name 		qdf_nbuf_free(msg);
5490*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
5491*5113495bSYour Name 	}
5492*5113495bSYour Name 
5493*5113495bSYour Name 	/* fill in the message contents */
5494*5113495bSYour Name 	msg_word = (u_int32_t *)qdf_nbuf_data(msg);
5495*5113495bSYour Name 
5496*5113495bSYour Name 	memset(msg_word, 0,
5497*5113495bSYour Name 	       sizeof(struct htt_h2t_msg_type_rxdma_rxole_ppe_cfg_t));
5498*5113495bSYour Name 
5499*5113495bSYour Name 	/* Rewind beyond alignment pad to get to the HTC header reserved area */
5500*5113495bSYour Name 	qdf_nbuf_push_head(msg, HTC_HDR_ALIGNMENT_PADDING);
5501*5113495bSYour Name 	htt_logger_bufp = (uint8_t *)msg_word;
5502*5113495bSYour Name 
5503*5113495bSYour Name 	*msg_word = 0;
5504*5113495bSYour Name 	HTT_H2T_MSG_TYPE_SET(*msg_word, HTT_H2T_MSG_TYPE_RXDMA_RXOLE_PPE_CFG);
5505*5113495bSYour Name 	HTT_PPE_CFG_OVERRIDE_SET(*msg_word, cfg->override);
5506*5113495bSYour Name 	HTT_PPE_CFG_REO_DEST_IND_SET(
5507*5113495bSYour Name 			*msg_word, cfg->reo_destination_indication);
5508*5113495bSYour Name 	HTT_PPE_CFG_MULTI_BUF_MSDU_OVERRIDE_EN_SET(
5509*5113495bSYour Name 			*msg_word, cfg->multi_buffer_msdu_override_en);
5510*5113495bSYour Name 	HTT_PPE_CFG_INTRA_BSS_OVERRIDE_EN_SET(
5511*5113495bSYour Name 			*msg_word, cfg->intra_bss_override);
5512*5113495bSYour Name 	HTT_PPE_CFG_DECAP_RAW_OVERRIDE_EN_SET(
5513*5113495bSYour Name 			*msg_word, cfg->decap_raw_override);
5514*5113495bSYour Name 	HTT_PPE_CFG_DECAP_NWIFI_OVERRIDE_EN_SET(
5515*5113495bSYour Name 			*msg_word, cfg->decap_nwifi_override);
5516*5113495bSYour Name 	HTT_PPE_CFG_IP_FRAG_OVERRIDE_EN_SET(
5517*5113495bSYour Name 			*msg_word, cfg->ip_frag_override);
5518*5113495bSYour Name 
5519*5113495bSYour Name 	pkt = htt_htc_pkt_alloc(htt_handle);
5520*5113495bSYour Name 	if (!pkt) {
5521*5113495bSYour Name 		qdf_err("Fail to allocate dp_htt_htc_pkt buffer");
5522*5113495bSYour Name 		qdf_assert(0);
5523*5113495bSYour Name 		qdf_nbuf_free(msg);
5524*5113495bSYour Name 		return QDF_STATUS_E_RESOURCES; /* failure */
5525*5113495bSYour Name 	}
5526*5113495bSYour Name 
5527*5113495bSYour Name 	pkt->soc_ctxt = NULL; /* not used during send-done callback */
5528*5113495bSYour Name 
5529*5113495bSYour Name 	SET_HTC_PACKET_INFO_TX(&pkt->htc_pkt,
5530*5113495bSYour Name 			       dp_htt_h2t_send_complete_free_netbuf,
5531*5113495bSYour Name 			       qdf_nbuf_data(msg),
5532*5113495bSYour Name 			       qdf_nbuf_len(msg),
5533*5113495bSYour Name 			       htt_handle->htc_endpoint,
5534*5113495bSYour Name 			       /* tag for no FW response msg */
5535*5113495bSYour Name 			       HTC_TX_PACKET_TAG_RUNTIME_PUT);
5536*5113495bSYour Name 
5537*5113495bSYour Name 	SET_HTC_PACKET_NET_BUF_CONTEXT(&pkt->htc_pkt, msg);
5538*5113495bSYour Name 
5539*5113495bSYour Name 	status = DP_HTT_SEND_HTC_PKT(htt_handle, pkt,
5540*5113495bSYour Name 				     HTT_H2T_MSG_TYPE_RXDMA_RXOLE_PPE_CFG,
5541*5113495bSYour Name 				     htt_logger_bufp);
5542*5113495bSYour Name 
5543*5113495bSYour Name 	if (status != QDF_STATUS_SUCCESS) {
5544*5113495bSYour Name 		qdf_nbuf_free(msg);
5545*5113495bSYour Name 		htt_htc_pkt_free(htt_handle, pkt);
5546*5113495bSYour Name 		return status;
5547*5113495bSYour Name 	}
5548*5113495bSYour Name 
5549*5113495bSYour Name 	dp_info("HTT_H2T_MSG_TYPE_RXDMA_RXOLE_PPE_CFG sent");
5550*5113495bSYour Name 	return status;
5551*5113495bSYour Name }
5552*5113495bSYour Name #endif /* WLAN_SUPPORT_PPEDS */
5553*5113495bSYour Name 
5554*5113495bSYour Name /**
5555*5113495bSYour Name  * dp_bk_pressure_stats_handler(): worker function to print back pressure
5556*5113495bSYour Name  *				   stats
5557*5113495bSYour Name  *
5558*5113495bSYour Name  * @context : argument to work function
5559*5113495bSYour Name  */
5560*5113495bSYour Name static void dp_bk_pressure_stats_handler(void *context)
5561*5113495bSYour Name {
5562*5113495bSYour Name 	struct dp_pdev *pdev = (struct dp_pdev *)context;
5563*5113495bSYour Name 	struct dp_soc_srngs_state *soc_srngs_state = NULL;
5564*5113495bSYour Name 	const char *ring_name;
5565*5113495bSYour Name 	int i;
5566*5113495bSYour Name 	struct dp_srng_ring_state *ring_state;
5567*5113495bSYour Name 	bool empty_flag;
5568*5113495bSYour Name 
5569*5113495bSYour Name 	qdf_spin_lock_bh(&pdev->bkp_stats.list_lock);
5570*5113495bSYour Name 
5571*5113495bSYour Name 	/* Extract only first entry for printing in one work event */
5572*5113495bSYour Name 	if (pdev->bkp_stats.queue_depth &&
5573*5113495bSYour Name 	    !TAILQ_EMPTY(&pdev->bkp_stats.list)) {
5574*5113495bSYour Name 		soc_srngs_state = TAILQ_FIRST(&pdev->bkp_stats.list);
5575*5113495bSYour Name 		TAILQ_REMOVE(&pdev->bkp_stats.list, soc_srngs_state,
5576*5113495bSYour Name 			     list_elem);
5577*5113495bSYour Name 		pdev->bkp_stats.queue_depth--;
5578*5113495bSYour Name 	}
5579*5113495bSYour Name 
5580*5113495bSYour Name 	empty_flag = TAILQ_EMPTY(&pdev->bkp_stats.list);
5581*5113495bSYour Name 	qdf_spin_unlock_bh(&pdev->bkp_stats.list_lock);
5582*5113495bSYour Name 
5583*5113495bSYour Name 	if (soc_srngs_state) {
5584*5113495bSYour Name 		DP_PRINT_STATS("### BKP stats for seq_num %u START ###",
5585*5113495bSYour Name 			       soc_srngs_state->seq_num);
5586*5113495bSYour Name 		for (i = 0; i < soc_srngs_state->max_ring_id; i++) {
5587*5113495bSYour Name 			ring_state = &soc_srngs_state->ring_state[i];
5588*5113495bSYour Name 			ring_name = dp_srng_get_str_from_hal_ring_type
5589*5113495bSYour Name 						(ring_state->ring_type);
5590*5113495bSYour Name 			DP_PRINT_STATS("%s: SW:Head pointer = %d Tail Pointer = %d\n",
5591*5113495bSYour Name 				       ring_name,
5592*5113495bSYour Name 				       ring_state->sw_head,
5593*5113495bSYour Name 				       ring_state->sw_tail);
5594*5113495bSYour Name 
5595*5113495bSYour Name 			DP_PRINT_STATS("%s: HW:Head pointer = %d Tail Pointer = %d\n",
5596*5113495bSYour Name 				       ring_name,
5597*5113495bSYour Name 				       ring_state->hw_head,
5598*5113495bSYour Name 				       ring_state->hw_tail);
5599*5113495bSYour Name 		}
5600*5113495bSYour Name 
5601*5113495bSYour Name 		DP_PRINT_STATS("### BKP stats for seq_num %u COMPLETE ###",
5602*5113495bSYour Name 			       soc_srngs_state->seq_num);
5603*5113495bSYour Name 		qdf_mem_free(soc_srngs_state);
5604*5113495bSYour Name 	}
5605*5113495bSYour Name 	dp_print_napi_stats(pdev->soc);
5606*5113495bSYour Name 
5607*5113495bSYour Name 	/* Schedule work again if queue is not empty */
5608*5113495bSYour Name 	if (!empty_flag)
5609*5113495bSYour Name 		qdf_queue_work(0, pdev->bkp_stats.work_queue,
5610*5113495bSYour Name 			       &pdev->bkp_stats.work);
5611*5113495bSYour Name }
5612*5113495bSYour Name 
5613*5113495bSYour Name void dp_pdev_bkp_stats_detach(struct dp_pdev *pdev)
5614*5113495bSYour Name {
5615*5113495bSYour Name 	struct dp_soc_srngs_state *ring_state, *ring_state_next;
5616*5113495bSYour Name 
5617*5113495bSYour Name 	if (!pdev->bkp_stats.work_queue)
5618*5113495bSYour Name 		return;
5619*5113495bSYour Name 
5620*5113495bSYour Name 	qdf_flush_workqueue(0, pdev->bkp_stats.work_queue);
5621*5113495bSYour Name 	qdf_destroy_workqueue(0, pdev->bkp_stats.work_queue);
5622*5113495bSYour Name 	qdf_flush_work(&pdev->bkp_stats.work);
5623*5113495bSYour Name 	qdf_disable_work(&pdev->bkp_stats.work);
5624*5113495bSYour Name 	qdf_spin_lock_bh(&pdev->bkp_stats.list_lock);
5625*5113495bSYour Name 	TAILQ_FOREACH_SAFE(ring_state, &pdev->bkp_stats.list,
5626*5113495bSYour Name 			   list_elem, ring_state_next) {
5627*5113495bSYour Name 		TAILQ_REMOVE(&pdev->bkp_stats.list, ring_state,
5628*5113495bSYour Name 			     list_elem);
5629*5113495bSYour Name 		qdf_mem_free(ring_state);
5630*5113495bSYour Name 	}
5631*5113495bSYour Name 	qdf_spin_unlock_bh(&pdev->bkp_stats.list_lock);
5632*5113495bSYour Name 	qdf_spinlock_destroy(&pdev->bkp_stats.list_lock);
5633*5113495bSYour Name }
5634*5113495bSYour Name 
5635*5113495bSYour Name QDF_STATUS dp_pdev_bkp_stats_attach(struct dp_pdev *pdev)
5636*5113495bSYour Name {
5637*5113495bSYour Name 	TAILQ_INIT(&pdev->bkp_stats.list);
5638*5113495bSYour Name 	pdev->bkp_stats.seq_num = 0;
5639*5113495bSYour Name 	pdev->bkp_stats.queue_depth = 0;
5640*5113495bSYour Name 
5641*5113495bSYour Name 	qdf_create_work(0, &pdev->bkp_stats.work,
5642*5113495bSYour Name 			dp_bk_pressure_stats_handler, pdev);
5643*5113495bSYour Name 
5644*5113495bSYour Name 	pdev->bkp_stats.work_queue =
5645*5113495bSYour Name 		qdf_alloc_unbound_workqueue("dp_bkp_work_queue");
5646*5113495bSYour Name 	if (!pdev->bkp_stats.work_queue)
5647*5113495bSYour Name 		goto fail;
5648*5113495bSYour Name 
5649*5113495bSYour Name 	qdf_spinlock_create(&pdev->bkp_stats.list_lock);
5650*5113495bSYour Name 	return QDF_STATUS_SUCCESS;
5651*5113495bSYour Name 
5652*5113495bSYour Name fail:
5653*5113495bSYour Name 	dp_htt_alert("BKP stats attach failed");
5654*5113495bSYour Name 	qdf_flush_work(&pdev->bkp_stats.work);
5655*5113495bSYour Name 	qdf_disable_work(&pdev->bkp_stats.work);
5656*5113495bSYour Name 	return QDF_STATUS_E_FAILURE;
5657*5113495bSYour Name }
5658*5113495bSYour Name 
5659*5113495bSYour Name #ifdef DP_UMAC_HW_RESET_SUPPORT
5660*5113495bSYour Name QDF_STATUS dp_htt_umac_reset_send_setup_cmd(
5661*5113495bSYour Name 		struct dp_soc *soc,
5662*5113495bSYour Name 		const struct dp_htt_umac_reset_setup_cmd_params *setup_params)
5663*5113495bSYour Name {
5664*5113495bSYour Name 	struct htt_soc *htt_handle = soc->htt_handle;
5665*5113495bSYour Name 	uint32_t len;
5666*5113495bSYour Name 	qdf_nbuf_t msg;
5667*5113495bSYour Name 	u_int32_t *msg_word;
5668*5113495bSYour Name 	QDF_STATUS status;
5669*5113495bSYour Name 	uint8_t *htt_logger_bufp;
5670*5113495bSYour Name 	struct dp_htt_htc_pkt *pkt;
5671*5113495bSYour Name 
5672*5113495bSYour Name 	len = HTT_MSG_BUF_SIZE(
5673*5113495bSYour Name 		HTT_H2T_UMAC_HANG_RECOVERY_PREREQUISITE_SETUP_BYTES);
5674*5113495bSYour Name 
5675*5113495bSYour Name 	msg = qdf_nbuf_alloc(soc->osdev,
5676*5113495bSYour Name 			     len,
5677*5113495bSYour Name 			     /* reserve room for the HTC header */
5678*5113495bSYour Name 			     HTC_HEADER_LEN + HTC_HDR_ALIGNMENT_PADDING,
5679*5113495bSYour Name 			     4,
5680*5113495bSYour Name 			     TRUE);
5681*5113495bSYour Name 	if (!msg)
5682*5113495bSYour Name 		return QDF_STATUS_E_NOMEM;
5683*5113495bSYour Name 
5684*5113495bSYour Name 	/*
5685*5113495bSYour Name 	 * Set the length of the message.
5686*5113495bSYour Name 	 * The contribution from the HTC_HDR_ALIGNMENT_PADDING is added
5687*5113495bSYour Name 	 * separately during the below call to qdf_nbuf_push_head.
5688*5113495bSYour Name 	 * The contribution from the HTC header is added separately inside HTC.
5689*5113495bSYour Name 	 */
5690*5113495bSYour Name 	if (!qdf_nbuf_put_tail(
5691*5113495bSYour Name 		msg, HTT_H2T_UMAC_HANG_RECOVERY_PREREQUISITE_SETUP_BYTES)) {
5692*5113495bSYour Name 		dp_htt_err("Failed to expand head");
5693*5113495bSYour Name 		qdf_nbuf_free(msg);
5694*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
5695*5113495bSYour Name 	}
5696*5113495bSYour Name 
5697*5113495bSYour Name 	/* fill in the message contents */
5698*5113495bSYour Name 	msg_word = (uint32_t *)qdf_nbuf_data(msg);
5699*5113495bSYour Name 
5700*5113495bSYour Name 	/* Rewind beyond alignment pad to get to the HTC header reserved area */
5701*5113495bSYour Name 	qdf_nbuf_push_head(msg, HTC_HDR_ALIGNMENT_PADDING);
5702*5113495bSYour Name 	htt_logger_bufp = (uint8_t *)msg_word;
5703*5113495bSYour Name 
5704*5113495bSYour Name 	qdf_mem_zero(msg_word,
5705*5113495bSYour Name 		     HTT_H2T_UMAC_HANG_RECOVERY_PREREQUISITE_SETUP_BYTES);
5706*5113495bSYour Name 
5707*5113495bSYour Name 	HTT_H2T_MSG_TYPE_SET(
5708*5113495bSYour Name 		*msg_word,
5709*5113495bSYour Name 		HTT_H2T_MSG_TYPE_UMAC_HANG_RECOVERY_PREREQUISITE_SETUP);
5710*5113495bSYour Name 	HTT_H2T_UMAC_HANG_RECOVERY_PREREQUISITE_SETUP_T2H_MSG_METHOD_SET(
5711*5113495bSYour Name 		*msg_word, htt_umac_hang_recovery_msg_t2h_msi_and_h2t_polling);
5712*5113495bSYour Name 	HTT_H2T_UMAC_HANG_RECOVERY_PREREQUISITE_SETUP_H2T_MSG_METHOD_SET(
5713*5113495bSYour Name 		*msg_word, htt_umac_hang_recovery_msg_t2h_msi_and_h2t_polling);
5714*5113495bSYour Name 
5715*5113495bSYour Name 	msg_word++;
5716*5113495bSYour Name 	*msg_word = setup_params->msi_data;
5717*5113495bSYour Name 
5718*5113495bSYour Name 	msg_word++;
5719*5113495bSYour Name 	*msg_word = sizeof(htt_umac_hang_recovery_msg_shmem_t);
5720*5113495bSYour Name 
5721*5113495bSYour Name 	msg_word++;
5722*5113495bSYour Name 	*msg_word = setup_params->shmem_addr_low;
5723*5113495bSYour Name 
5724*5113495bSYour Name 	msg_word++;
5725*5113495bSYour Name 	*msg_word = setup_params->shmem_addr_high;
5726*5113495bSYour Name 
5727*5113495bSYour Name 	pkt = htt_htc_pkt_alloc(htt_handle);
5728*5113495bSYour Name 	if (!pkt) {
5729*5113495bSYour Name 		qdf_err("Fail to allocate dp_htt_htc_pkt buffer");
5730*5113495bSYour Name 		qdf_assert(0);
5731*5113495bSYour Name 		qdf_nbuf_free(msg);
5732*5113495bSYour Name 		return QDF_STATUS_E_NOMEM;
5733*5113495bSYour Name 	}
5734*5113495bSYour Name 
5735*5113495bSYour Name 	pkt->soc_ctxt = NULL; /* not used during send-done callback */
5736*5113495bSYour Name 
5737*5113495bSYour Name 	SET_HTC_PACKET_INFO_TX(&pkt->htc_pkt,
5738*5113495bSYour Name 			       dp_htt_h2t_send_complete_free_netbuf,
5739*5113495bSYour Name 			       qdf_nbuf_data(msg),
5740*5113495bSYour Name 			       qdf_nbuf_len(msg),
5741*5113495bSYour Name 			       htt_handle->htc_endpoint,
5742*5113495bSYour Name 			       /* tag for no FW response msg */
5743*5113495bSYour Name 			       HTC_TX_PACKET_TAG_RUNTIME_PUT);
5744*5113495bSYour Name 
5745*5113495bSYour Name 	SET_HTC_PACKET_NET_BUF_CONTEXT(&pkt->htc_pkt, msg);
5746*5113495bSYour Name 
5747*5113495bSYour Name 	status = DP_HTT_SEND_HTC_PKT(
5748*5113495bSYour Name 			htt_handle, pkt,
5749*5113495bSYour Name 			HTT_H2T_MSG_TYPE_UMAC_HANG_RECOVERY_PREREQUISITE_SETUP,
5750*5113495bSYour Name 			htt_logger_bufp);
5751*5113495bSYour Name 
5752*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(status)) {
5753*5113495bSYour Name 		qdf_nbuf_free(msg);
5754*5113495bSYour Name 		htt_htc_pkt_free(htt_handle, pkt);
5755*5113495bSYour Name 		return status;
5756*5113495bSYour Name 	}
5757*5113495bSYour Name 
5758*5113495bSYour Name 	dp_info("HTT_H2T_MSG_TYPE_UMAC_HANG_RECOVERY_PREREQUISITE_SETUP sent");
5759*5113495bSYour Name 	return status;
5760*5113495bSYour Name }
5761*5113495bSYour Name 
5762*5113495bSYour Name QDF_STATUS dp_htt_umac_reset_send_start_pre_reset_cmd(
5763*5113495bSYour Name 		struct dp_soc *soc, bool is_initiator, bool is_umac_hang)
5764*5113495bSYour Name {
5765*5113495bSYour Name 	struct htt_soc *htt_handle = soc->htt_handle;
5766*5113495bSYour Name 	uint32_t len;
5767*5113495bSYour Name 	qdf_nbuf_t msg;
5768*5113495bSYour Name 	u_int32_t *msg_word;
5769*5113495bSYour Name 	QDF_STATUS status;
5770*5113495bSYour Name 	uint8_t *htt_logger_bufp;
5771*5113495bSYour Name 	struct dp_htt_htc_pkt *pkt;
5772*5113495bSYour Name 
5773*5113495bSYour Name 	len = HTT_MSG_BUF_SIZE(
5774*5113495bSYour Name 		HTT_H2T_UMAC_HANG_RECOVERY_START_PRE_RESET_BYTES);
5775*5113495bSYour Name 
5776*5113495bSYour Name 	msg = qdf_nbuf_alloc(soc->osdev,
5777*5113495bSYour Name 			     len,
5778*5113495bSYour Name 			     /* reserve room for the HTC header */
5779*5113495bSYour Name 			     HTC_HEADER_LEN + HTC_HDR_ALIGNMENT_PADDING,
5780*5113495bSYour Name 			     4,
5781*5113495bSYour Name 			     TRUE);
5782*5113495bSYour Name 	if (!msg)
5783*5113495bSYour Name 		return QDF_STATUS_E_NOMEM;
5784*5113495bSYour Name 
5785*5113495bSYour Name 	/*
5786*5113495bSYour Name 	 * Set the length of the message.
5787*5113495bSYour Name 	 * The contribution from the HTC_HDR_ALIGNMENT_PADDING is added
5788*5113495bSYour Name 	 * separately during the below call to qdf_nbuf_push_head.
5789*5113495bSYour Name 	 * The contribution from the HTC header is added separately inside HTC.
5790*5113495bSYour Name 	 */
5791*5113495bSYour Name 	if (!qdf_nbuf_put_tail(
5792*5113495bSYour Name 		msg, HTT_H2T_UMAC_HANG_RECOVERY_START_PRE_RESET_BYTES)) {
5793*5113495bSYour Name 		dp_htt_err("Failed to expand head");
5794*5113495bSYour Name 		qdf_nbuf_free(msg);
5795*5113495bSYour Name 		return QDF_STATUS_E_FAILURE;
5796*5113495bSYour Name 	}
5797*5113495bSYour Name 
5798*5113495bSYour Name 	/* fill in the message contents */
5799*5113495bSYour Name 	msg_word = (uint32_t *)qdf_nbuf_data(msg);
5800*5113495bSYour Name 
5801*5113495bSYour Name 	/* Rewind beyond alignment pad to get to the HTC header reserved area */
5802*5113495bSYour Name 	qdf_nbuf_push_head(msg, HTC_HDR_ALIGNMENT_PADDING);
5803*5113495bSYour Name 	htt_logger_bufp = (uint8_t *)msg_word;
5804*5113495bSYour Name 
5805*5113495bSYour Name 	qdf_mem_zero(msg_word,
5806*5113495bSYour Name 		     HTT_H2T_UMAC_HANG_RECOVERY_START_PRE_RESET_BYTES);
5807*5113495bSYour Name 
5808*5113495bSYour Name 	HTT_H2T_MSG_TYPE_SET(
5809*5113495bSYour Name 		*msg_word,
5810*5113495bSYour Name 		HTT_H2T_MSG_TYPE_UMAC_HANG_RECOVERY_SOC_START_PRE_RESET);
5811*5113495bSYour Name 
5812*5113495bSYour Name 	HTT_H2T_UMAC_HANG_RECOVERY_START_PRE_RESET_IS_INITIATOR_SET(
5813*5113495bSYour Name 		*msg_word, is_initiator);
5814*5113495bSYour Name 
5815*5113495bSYour Name 	HTT_H2T_UMAC_HANG_RECOVERY_START_PRE_RESET_IS_UMAC_HANG_SET(
5816*5113495bSYour Name 		*msg_word, is_umac_hang);
5817*5113495bSYour Name 
5818*5113495bSYour Name 	pkt = htt_htc_pkt_alloc(htt_handle);
5819*5113495bSYour Name 	if (!pkt) {
5820*5113495bSYour Name 		qdf_err("Fail to allocate dp_htt_htc_pkt buffer");
5821*5113495bSYour Name 		qdf_assert(0);
5822*5113495bSYour Name 		qdf_nbuf_free(msg);
5823*5113495bSYour Name 		return QDF_STATUS_E_NOMEM;
5824*5113495bSYour Name 	}
5825*5113495bSYour Name 
5826*5113495bSYour Name 	pkt->soc_ctxt = NULL; /* not used during send-done callback */
5827*5113495bSYour Name 
5828*5113495bSYour Name 	SET_HTC_PACKET_INFO_TX(&pkt->htc_pkt,
5829*5113495bSYour Name 			       dp_htt_h2t_send_complete_free_netbuf,
5830*5113495bSYour Name 			       qdf_nbuf_data(msg),
5831*5113495bSYour Name 			       qdf_nbuf_len(msg),
5832*5113495bSYour Name 			       htt_handle->htc_endpoint,
5833*5113495bSYour Name 			       /* tag for no FW response msg */
5834*5113495bSYour Name 			       HTC_TX_PACKET_TAG_RUNTIME_PUT);
5835*5113495bSYour Name 
5836*5113495bSYour Name 	SET_HTC_PACKET_NET_BUF_CONTEXT(&pkt->htc_pkt, msg);
5837*5113495bSYour Name 
5838*5113495bSYour Name 	status = DP_HTT_SEND_HTC_PKT(
5839*5113495bSYour Name 			htt_handle, pkt,
5840*5113495bSYour Name 			HTT_H2T_MSG_TYPE_UMAC_HANG_RECOVERY_SOC_START_PRE_RESET,
5841*5113495bSYour Name 			htt_logger_bufp);
5842*5113495bSYour Name 
5843*5113495bSYour Name 	if (QDF_IS_STATUS_ERROR(status)) {
5844*5113495bSYour Name 		qdf_nbuf_free(msg);
5845*5113495bSYour Name 		htt_htc_pkt_free(htt_handle, pkt);
5846*5113495bSYour Name 		return status;
5847*5113495bSYour Name 	}
5848*5113495bSYour Name 
5849*5113495bSYour Name 	dp_info("HTT_H2T_MSG_TYPE_UMAC_HANG_RECOVERY_SOC_START_PRE_RESET sent");
5850*5113495bSYour Name 	return status;
5851*5113495bSYour Name }
5852*5113495bSYour Name #endif
5853