xref: /wlan-driver/qcacld-3.0/core/dp/htt/htt_t2h.c (revision 5113495b16420b49004c444715d2daae2066e7dc)
1*5113495bSYour Name /*
2*5113495bSYour Name  * Copyright (c) 2011-2020 The Linux Foundation. All rights reserved.
3*5113495bSYour Name  * Copyright (c) 2022-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 /**
21*5113495bSYour Name  *  DOC: htt_t2h.c
22*5113495bSYour Name  *
23*5113495bSYour Name  *  brief Provide functions to process target->host HTT messages.
24*5113495bSYour Name  *  details
25*5113495bSYour Name  *  This file contains functions related to target->host HTT messages.
26*5113495bSYour Name  *  There are two categories of functions:
27*5113495bSYour Name  *  1.  A function that receives a HTT message from HTC, and dispatches it
28*5113495bSYour Name  *      based on the HTT message type.
29*5113495bSYour Name  *  2.  functions that provide the info elements from specific HTT messages.
30*5113495bSYour Name  */
31*5113495bSYour Name #include <wma.h>
32*5113495bSYour Name #include <htc_api.h>            /* HTC_PACKET */
33*5113495bSYour Name #include <htt.h>                /* HTT_T2H_MSG_TYPE, etc. */
34*5113495bSYour Name #include <qdf_nbuf.h>           /* qdf_nbuf_t */
35*5113495bSYour Name 
36*5113495bSYour Name #include <ol_rx.h>
37*5113495bSYour Name #include <ol_htt_rx_api.h>
38*5113495bSYour Name #include <ol_htt_tx_api.h>
39*5113495bSYour Name #include <ol_txrx_htt_api.h>    /* htt_tx_status */
40*5113495bSYour Name 
41*5113495bSYour Name #include <htt_internal.h>       /* HTT_TX_SCHED, etc. */
42*5113495bSYour Name #include <pktlog_ac_fmt.h>
43*5113495bSYour Name #include <wdi_event.h>
44*5113495bSYour Name #include <ol_htt_tx_api.h>
45*5113495bSYour Name #include <ol_txrx_peer_find.h>
46*5113495bSYour Name #include <cdp_txrx_ipa.h>
47*5113495bSYour Name #include "pktlog_ac.h"
48*5113495bSYour Name #include <cdp_txrx_handle.h>
49*5113495bSYour Name #include <wlan_pkt_capture_ucfg_api.h>
50*5113495bSYour Name #include <ol_txrx.h>
51*5113495bSYour Name /*--- target->host HTT message dispatch function ----------------------------*/
52*5113495bSYour Name 
53*5113495bSYour Name #ifndef DEBUG_CREDIT
54*5113495bSYour Name #define DEBUG_CREDIT 0
55*5113495bSYour Name #endif
56*5113495bSYour Name 
57*5113495bSYour Name #if defined(CONFIG_HL_SUPPORT)
58*5113495bSYour Name 
59*5113495bSYour Name 
60*5113495bSYour Name 
61*5113495bSYour Name /**
62*5113495bSYour Name  * htt_rx_frag_set_last_msdu() - set last msdu bit in rx descriptor
63*5113495bSYour Name  *				 for received frames
64*5113495bSYour Name  * @pdev: Handle (pointer) to HTT pdev.
65*5113495bSYour Name  * @msg: htt received msg
66*5113495bSYour Name  *
67*5113495bSYour Name  * Return: None
68*5113495bSYour Name  */
69*5113495bSYour Name static inline
htt_rx_frag_set_last_msdu(struct htt_pdev_t * pdev,qdf_nbuf_t msg)70*5113495bSYour Name void htt_rx_frag_set_last_msdu(struct htt_pdev_t *pdev, qdf_nbuf_t msg)
71*5113495bSYour Name {
72*5113495bSYour Name }
73*5113495bSYour Name #else
74*5113495bSYour Name 
htt_rx_frag_set_last_msdu(struct htt_pdev_t * pdev,qdf_nbuf_t msg)75*5113495bSYour Name static void htt_rx_frag_set_last_msdu(struct htt_pdev_t *pdev, qdf_nbuf_t msg)
76*5113495bSYour Name {
77*5113495bSYour Name 	uint32_t *msg_word;
78*5113495bSYour Name 	unsigned int num_msdu_bytes;
79*5113495bSYour Name 	qdf_nbuf_t msdu;
80*5113495bSYour Name 	struct htt_host_rx_desc_base *rx_desc;
81*5113495bSYour Name 	int start_idx;
82*5113495bSYour Name 	uint8_t *p_fw_msdu_rx_desc = 0;
83*5113495bSYour Name 
84*5113495bSYour Name 	msg_word = (uint32_t *) qdf_nbuf_data(msg);
85*5113495bSYour Name 	num_msdu_bytes = HTT_RX_FRAG_IND_FW_RX_DESC_BYTES_GET(
86*5113495bSYour Name 		*(msg_word + HTT_RX_FRAG_IND_HDR_PREFIX_SIZE32));
87*5113495bSYour Name 	/*
88*5113495bSYour Name 	 * 1 word for the message header,
89*5113495bSYour Name 	 * 1 word to specify the number of MSDU bytes,
90*5113495bSYour Name 	 * 1 word for every 4 MSDU bytes (round up),
91*5113495bSYour Name 	 * 1 word for the MPDU range header
92*5113495bSYour Name 	 */
93*5113495bSYour Name 	pdev->rx_mpdu_range_offset_words = 3 + ((num_msdu_bytes + 3) >> 2);
94*5113495bSYour Name 	pdev->rx_ind_msdu_byte_idx = 0;
95*5113495bSYour Name 
96*5113495bSYour Name 	p_fw_msdu_rx_desc = ((uint8_t *) (msg_word) +
97*5113495bSYour Name 			     HTT_ENDIAN_BYTE_IDX_SWAP
98*5113495bSYour Name 				     (HTT_RX_FRAG_IND_FW_DESC_BYTE_OFFSET));
99*5113495bSYour Name 
100*5113495bSYour Name 	/*
101*5113495bSYour Name 	 * Fix for EV126710, in which BSOD occurs due to last_msdu bit
102*5113495bSYour Name 	 * not set while the next pointer is deliberately set to NULL
103*5113495bSYour Name 	 * before calling ol_rx_pn_check_base()
104*5113495bSYour Name 	 *
105*5113495bSYour Name 	 * For fragment frames, the HW may not have set the last_msdu bit
106*5113495bSYour Name 	 * in the rx descriptor, but the SW expects this flag to be set,
107*5113495bSYour Name 	 * since each fragment is in a separate MPDU. Thus, set the flag here,
108*5113495bSYour Name 	 * just in case the HW didn't.
109*5113495bSYour Name 	 */
110*5113495bSYour Name 	start_idx = pdev->rx_ring.sw_rd_idx.msdu_payld;
111*5113495bSYour Name 	msdu = pdev->rx_ring.buf.netbufs_ring[start_idx];
112*5113495bSYour Name 	qdf_nbuf_set_pktlen(msdu, HTT_RX_BUF_SIZE);
113*5113495bSYour Name 	qdf_nbuf_unmap(pdev->osdev, msdu, QDF_DMA_FROM_DEVICE);
114*5113495bSYour Name 	rx_desc = htt_rx_desc(msdu);
115*5113495bSYour Name 	*((uint8_t *) &rx_desc->fw_desc.u.val) = *p_fw_msdu_rx_desc;
116*5113495bSYour Name 	rx_desc->msdu_end.last_msdu = 1;
117*5113495bSYour Name 	qdf_nbuf_map(pdev->osdev, msdu, QDF_DMA_FROM_DEVICE);
118*5113495bSYour Name }
119*5113495bSYour Name #endif
120*5113495bSYour Name 
htt_t2h_mac_addr_deswizzle(uint8_t * tgt_mac_addr,uint8_t * buffer)121*5113495bSYour Name static uint8_t *htt_t2h_mac_addr_deswizzle(uint8_t *tgt_mac_addr,
122*5113495bSYour Name 					   uint8_t *buffer)
123*5113495bSYour Name {
124*5113495bSYour Name #ifdef BIG_ENDIAN_HOST
125*5113495bSYour Name 	/*
126*5113495bSYour Name 	 * The host endianness is opposite of the target endianness.
127*5113495bSYour Name 	 * To make uint32_t elements come out correctly, the target->host
128*5113495bSYour Name 	 * upload has swizzled the bytes in each uint32_t element of the
129*5113495bSYour Name 	 * message.
130*5113495bSYour Name 	 * For byte-array message fields like the MAC address, this
131*5113495bSYour Name 	 * upload swizzling puts the bytes in the wrong order, and needs
132*5113495bSYour Name 	 * to be undone.
133*5113495bSYour Name 	 */
134*5113495bSYour Name 	buffer[0] = tgt_mac_addr[3];
135*5113495bSYour Name 	buffer[1] = tgt_mac_addr[2];
136*5113495bSYour Name 	buffer[2] = tgt_mac_addr[1];
137*5113495bSYour Name 	buffer[3] = tgt_mac_addr[0];
138*5113495bSYour Name 	buffer[4] = tgt_mac_addr[7];
139*5113495bSYour Name 	buffer[5] = tgt_mac_addr[6];
140*5113495bSYour Name 	return buffer;
141*5113495bSYour Name #else
142*5113495bSYour Name 	/*
143*5113495bSYour Name 	 * The host endianness matches the target endianness -
144*5113495bSYour Name 	 * we can use the mac addr directly from the message buffer.
145*5113495bSYour Name 	 */
146*5113495bSYour Name 	return tgt_mac_addr;
147*5113495bSYour Name #endif
148*5113495bSYour Name }
149*5113495bSYour Name 
150*5113495bSYour Name /**
151*5113495bSYour Name  * htt_ipa_op_response() - invoke an event handler from FW
152*5113495bSYour Name  * @pdev: Handle (pointer) to HTT pdev.
153*5113495bSYour Name  * @msg_word: htt msg
154*5113495bSYour Name  *
155*5113495bSYour Name  * Return: None
156*5113495bSYour Name  */
157*5113495bSYour Name #ifdef IPA_OFFLOAD
htt_ipa_op_response(struct htt_pdev_t * pdev,uint32_t * msg_word)158*5113495bSYour Name static void htt_ipa_op_response(struct htt_pdev_t *pdev, uint32_t *msg_word)
159*5113495bSYour Name {
160*5113495bSYour Name 	uint8_t op_code;
161*5113495bSYour Name 	uint16_t len;
162*5113495bSYour Name 	uint8_t *op_msg_buffer;
163*5113495bSYour Name 	uint8_t *msg_start_ptr;
164*5113495bSYour Name 
165*5113495bSYour Name 	htc_pm_runtime_put(pdev->htc_pdev);
166*5113495bSYour Name 	msg_start_ptr = (uint8_t *) msg_word;
167*5113495bSYour Name 	op_code =
168*5113495bSYour Name 		HTT_WDI_IPA_OP_RESPONSE_OP_CODE_GET(*msg_word);
169*5113495bSYour Name 	msg_word++;
170*5113495bSYour Name 	len = HTT_WDI_IPA_OP_RESPONSE_RSP_LEN_GET(*msg_word);
171*5113495bSYour Name 
172*5113495bSYour Name 	op_msg_buffer =
173*5113495bSYour Name 		qdf_mem_malloc(sizeof
174*5113495bSYour Name 				(struct htt_wdi_ipa_op_response_t) +
175*5113495bSYour Name 				len);
176*5113495bSYour Name 	if (!op_msg_buffer)
177*5113495bSYour Name 		return;
178*5113495bSYour Name 
179*5113495bSYour Name 	qdf_mem_copy(op_msg_buffer,
180*5113495bSYour Name 			msg_start_ptr,
181*5113495bSYour Name 			sizeof(struct htt_wdi_ipa_op_response_t) +
182*5113495bSYour Name 			len);
183*5113495bSYour Name 	cdp_ipa_op_response(cds_get_context(QDF_MODULE_ID_SOC),
184*5113495bSYour Name 			    OL_TXRX_PDEV_ID, op_msg_buffer);
185*5113495bSYour Name }
186*5113495bSYour Name #else
htt_ipa_op_response(struct htt_pdev_t * pdev,uint32_t * msg_word)187*5113495bSYour Name static void htt_ipa_op_response(struct htt_pdev_t *pdev, uint32_t *msg_word)
188*5113495bSYour Name {
189*5113495bSYour Name }
190*5113495bSYour Name #endif
191*5113495bSYour Name 
192*5113495bSYour Name #ifndef QCN7605_SUPPORT
htt_t2h_adjust_bus_target_delta(struct htt_pdev_t * pdev,int32_t htt_credit_delta)193*5113495bSYour Name static int htt_t2h_adjust_bus_target_delta(struct htt_pdev_t *pdev,
194*5113495bSYour Name 					   int32_t htt_credit_delta)
195*5113495bSYour Name {
196*5113495bSYour Name 	if (pdev->cfg.is_high_latency && !pdev->cfg.default_tx_comp_req) {
197*5113495bSYour Name 		HTT_TX_MUTEX_ACQUIRE(&pdev->credit_mutex);
198*5113495bSYour Name 		qdf_atomic_add(htt_credit_delta,
199*5113495bSYour Name 			       &pdev->htt_tx_credit.target_delta);
200*5113495bSYour Name 		htt_credit_delta = htt_tx_credit_update(pdev);
201*5113495bSYour Name 		HTT_TX_MUTEX_RELEASE(&pdev->credit_mutex);
202*5113495bSYour Name 	}
203*5113495bSYour Name 	return htt_credit_delta;
204*5113495bSYour Name }
205*5113495bSYour Name #else
htt_t2h_adjust_bus_target_delta(struct htt_pdev_t * pdev,int32_t htt_credit_delta)206*5113495bSYour Name static int htt_t2h_adjust_bus_target_delta(struct htt_pdev_t *pdev,
207*5113495bSYour Name 					   int32_t htt_credit_delta)
208*5113495bSYour Name {
209*5113495bSYour Name 	return htt_credit_delta;
210*5113495bSYour Name }
211*5113495bSYour Name #endif
212*5113495bSYour Name 
213*5113495bSYour Name #define MAX_TARGET_TX_CREDIT    204800
214*5113495bSYour Name #define HTT_CFR_DUMP_COMPL_HEAD_SZ	4
215*5113495bSYour Name 
216*5113495bSYour Name /* Target to host Msg/event  handler  for low priority messages*/
htt_t2h_lp_msg_handler(void * context,qdf_nbuf_t htt_t2h_msg,bool free_msg_buf)217*5113495bSYour Name static void htt_t2h_lp_msg_handler(void *context, qdf_nbuf_t htt_t2h_msg,
218*5113495bSYour Name 				   bool free_msg_buf)
219*5113495bSYour Name {
220*5113495bSYour Name 	struct htt_pdev_t *pdev = (struct htt_pdev_t *)context;
221*5113495bSYour Name 	uint32_t *msg_word;
222*5113495bSYour Name 	enum htt_t2h_msg_type msg_type;
223*5113495bSYour Name 
224*5113495bSYour Name 	msg_word = (uint32_t *) qdf_nbuf_data(htt_t2h_msg);
225*5113495bSYour Name 	msg_type = HTT_T2H_MSG_TYPE_GET(*msg_word);
226*5113495bSYour Name 	switch (msg_type) {
227*5113495bSYour Name 	case HTT_T2H_MSG_TYPE_VERSION_CONF:
228*5113495bSYour Name 	{
229*5113495bSYour Name 		if (htc_dec_return_htt_runtime_cnt(pdev->htc_pdev) >= 0)
230*5113495bSYour Name 			htc_pm_runtime_put(pdev->htc_pdev);
231*5113495bSYour Name 
232*5113495bSYour Name 		pdev->tgt_ver.major = HTT_VER_CONF_MAJOR_GET(*msg_word);
233*5113495bSYour Name 		pdev->tgt_ver.minor = HTT_VER_CONF_MINOR_GET(*msg_word);
234*5113495bSYour Name 		QDF_TRACE(QDF_MODULE_ID_HTT, QDF_TRACE_LEVEL_INFO_LOW,
235*5113495bSYour Name 			  "target uses HTT version %d.%d; host uses %d.%d",
236*5113495bSYour Name 			  pdev->tgt_ver.major, pdev->tgt_ver.minor,
237*5113495bSYour Name 			  HTT_CURRENT_VERSION_MAJOR,
238*5113495bSYour Name 			  HTT_CURRENT_VERSION_MINOR);
239*5113495bSYour Name 		if (pdev->tgt_ver.major != HTT_CURRENT_VERSION_MAJOR)
240*5113495bSYour Name 			QDF_TRACE(QDF_MODULE_ID_HTT, QDF_TRACE_LEVEL_WARN,
241*5113495bSYour Name 				  "*** Incompatible host/target HTT versions!");
242*5113495bSYour Name 		/* abort if the target is incompatible with the host */
243*5113495bSYour Name 		qdf_assert(pdev->tgt_ver.major ==
244*5113495bSYour Name 			   HTT_CURRENT_VERSION_MAJOR);
245*5113495bSYour Name 		if (pdev->tgt_ver.minor != HTT_CURRENT_VERSION_MINOR) {
246*5113495bSYour Name 			QDF_TRACE(QDF_MODULE_ID_HTT, QDF_TRACE_LEVEL_INFO_LOW,
247*5113495bSYour Name 				  "*** Warning: host/target HTT versions are ");
248*5113495bSYour Name 			QDF_TRACE(QDF_MODULE_ID_HTT, QDF_TRACE_LEVEL_INFO_LOW,
249*5113495bSYour Name 				  "different, though compatible!");
250*5113495bSYour Name 		}
251*5113495bSYour Name 		break;
252*5113495bSYour Name 	}
253*5113495bSYour Name 	case HTT_T2H_MSG_TYPE_RX_FLUSH:
254*5113495bSYour Name 	{
255*5113495bSYour Name 		uint16_t peer_id;
256*5113495bSYour Name 		uint8_t tid;
257*5113495bSYour Name 		uint16_t seq_num_start, seq_num_end;
258*5113495bSYour Name 		enum htt_rx_flush_action action;
259*5113495bSYour Name 
260*5113495bSYour Name 		if (qdf_nbuf_len(htt_t2h_msg) < HTT_RX_FLUSH_BYTES) {
261*5113495bSYour Name 			qdf_print("invalid nbuff len");
262*5113495bSYour Name 			WARN_ON(1);
263*5113495bSYour Name 			break;
264*5113495bSYour Name 		}
265*5113495bSYour Name 
266*5113495bSYour Name 		peer_id = HTT_RX_FLUSH_PEER_ID_GET(*msg_word);
267*5113495bSYour Name 		tid = HTT_RX_FLUSH_TID_GET(*msg_word);
268*5113495bSYour Name 		seq_num_start =
269*5113495bSYour Name 			HTT_RX_FLUSH_SEQ_NUM_START_GET(*(msg_word + 1));
270*5113495bSYour Name 		seq_num_end =
271*5113495bSYour Name 			HTT_RX_FLUSH_SEQ_NUM_END_GET(*(msg_word + 1));
272*5113495bSYour Name 		action =
273*5113495bSYour Name 			HTT_RX_FLUSH_MPDU_STATUS_GET(*(msg_word + 1)) ==
274*5113495bSYour Name 			1 ? htt_rx_flush_release : htt_rx_flush_discard;
275*5113495bSYour Name 		ol_rx_flush_handler(pdev->txrx_pdev, peer_id, tid,
276*5113495bSYour Name 				    seq_num_start, seq_num_end, action);
277*5113495bSYour Name 		break;
278*5113495bSYour Name 	}
279*5113495bSYour Name 	case HTT_T2H_MSG_TYPE_RX_OFFLOAD_DELIVER_IND:
280*5113495bSYour Name 	{
281*5113495bSYour Name 		uint16_t msdu_cnt;
282*5113495bSYour Name 
283*5113495bSYour Name 		if (!pdev->cfg.is_high_latency &&
284*5113495bSYour Name 		    pdev->cfg.is_full_reorder_offload) {
285*5113495bSYour Name 			qdf_print("HTT_T2H_MSG_TYPE_RX_OFFLOAD_DELIVER_IND not ");
286*5113495bSYour Name 			qdf_print("supported when full reorder offload is ");
287*5113495bSYour Name 			qdf_print("enabled in the configuration.\n");
288*5113495bSYour Name 			break;
289*5113495bSYour Name 		}
290*5113495bSYour Name 		msdu_cnt =
291*5113495bSYour Name 			HTT_RX_OFFLOAD_DELIVER_IND_MSDU_CNT_GET(*msg_word);
292*5113495bSYour Name 		ol_rx_offload_deliver_ind_handler(pdev->txrx_pdev,
293*5113495bSYour Name 						  htt_t2h_msg,
294*5113495bSYour Name 						  msdu_cnt);
295*5113495bSYour Name 		if (pdev->cfg.is_high_latency) {
296*5113495bSYour Name 			/*
297*5113495bSYour Name 			 * return here for HL to avoid double free on
298*5113495bSYour Name 			 * htt_t2h_msg
299*5113495bSYour Name 			 */
300*5113495bSYour Name 			return;
301*5113495bSYour Name 		}
302*5113495bSYour Name 		break;
303*5113495bSYour Name 	}
304*5113495bSYour Name 	case HTT_T2H_MSG_TYPE_RX_FRAG_IND:
305*5113495bSYour Name 	{
306*5113495bSYour Name 		uint16_t peer_id;
307*5113495bSYour Name 		uint8_t tid;
308*5113495bSYour Name 		int msg_len = qdf_nbuf_len(htt_t2h_msg);
309*5113495bSYour Name 
310*5113495bSYour Name 		if (msg_len < HTT_RX_FRAG_IND_BYTES) {
311*5113495bSYour Name 			qdf_print("invalid nbuff len");
312*5113495bSYour Name 			WARN_ON(1);
313*5113495bSYour Name 			break;
314*5113495bSYour Name 		}
315*5113495bSYour Name 		peer_id = HTT_RX_FRAG_IND_PEER_ID_GET(*msg_word);
316*5113495bSYour Name 		tid = HTT_RX_FRAG_IND_EXT_TID_GET(*msg_word);
317*5113495bSYour Name 		htt_rx_frag_set_last_msdu(pdev, htt_t2h_msg);
318*5113495bSYour Name 
319*5113495bSYour Name 		/* If packet len is invalid, will discard this frame. */
320*5113495bSYour Name 		if (pdev->cfg.is_high_latency) {
321*5113495bSYour Name 			u_int32_t rx_pkt_len = 0;
322*5113495bSYour Name 
323*5113495bSYour Name 			rx_pkt_len = qdf_nbuf_len(htt_t2h_msg);
324*5113495bSYour Name 
325*5113495bSYour Name 			if (rx_pkt_len < (HTT_RX_FRAG_IND_BYTES +
326*5113495bSYour Name 				sizeof(struct hl_htt_rx_ind_base)+
327*5113495bSYour Name 				sizeof(struct ieee80211_frame))) {
328*5113495bSYour Name 
329*5113495bSYour Name 				qdf_print("invalid packet len, %u", rx_pkt_len);
330*5113495bSYour Name 				/*
331*5113495bSYour Name 				 * This buf will be freed before
332*5113495bSYour Name 				 * exiting this function.
333*5113495bSYour Name 				 */
334*5113495bSYour Name 				break;
335*5113495bSYour Name 			}
336*5113495bSYour Name 		}
337*5113495bSYour Name 
338*5113495bSYour Name 		ol_rx_frag_indication_handler(pdev->txrx_pdev,
339*5113495bSYour Name 					      htt_t2h_msg,
340*5113495bSYour Name 					      peer_id, tid);
341*5113495bSYour Name 
342*5113495bSYour Name 		if (pdev->cfg.is_high_latency) {
343*5113495bSYour Name 			/*
344*5113495bSYour Name 			* For high latency solution,
345*5113495bSYour Name 			* HTT_T2H_MSG_TYPE_RX_FRAG_IND message and RX packet
346*5113495bSYour Name 			* share the same buffer. All buffer will be freed by
347*5113495bSYour Name 			* ol_rx_frag_indication_handler or upper layer to
348*5113495bSYour Name 			* avoid double free issue.
349*5113495bSYour Name 			*
350*5113495bSYour Name 			*/
351*5113495bSYour Name 			return;
352*5113495bSYour Name 		}
353*5113495bSYour Name 
354*5113495bSYour Name 		break;
355*5113495bSYour Name 	}
356*5113495bSYour Name 	case HTT_T2H_MSG_TYPE_RX_ADDBA:
357*5113495bSYour Name 	{
358*5113495bSYour Name 		uint16_t peer_id;
359*5113495bSYour Name 		uint8_t tid;
360*5113495bSYour Name 		uint8_t win_sz;
361*5113495bSYour Name 		uint16_t start_seq_num;
362*5113495bSYour Name 
363*5113495bSYour Name 		/*
364*5113495bSYour Name 		 * FOR NOW, the host doesn't need to know the initial
365*5113495bSYour Name 		 * sequence number for rx aggregation.
366*5113495bSYour Name 		 * Thus, any value will do - specify 0.
367*5113495bSYour Name 		 */
368*5113495bSYour Name 		start_seq_num = 0;
369*5113495bSYour Name 		peer_id = HTT_RX_ADDBA_PEER_ID_GET(*msg_word);
370*5113495bSYour Name 		tid = HTT_RX_ADDBA_TID_GET(*msg_word);
371*5113495bSYour Name 		win_sz = HTT_RX_ADDBA_WIN_SIZE_GET(*msg_word);
372*5113495bSYour Name 		ol_rx_addba_handler(pdev->txrx_pdev, peer_id, tid,
373*5113495bSYour Name 				    win_sz, start_seq_num,
374*5113495bSYour Name 				    0 /* success */);
375*5113495bSYour Name 		break;
376*5113495bSYour Name 	}
377*5113495bSYour Name 	case HTT_T2H_MSG_TYPE_RX_DELBA:
378*5113495bSYour Name 	{
379*5113495bSYour Name 		uint16_t peer_id;
380*5113495bSYour Name 		uint8_t tid;
381*5113495bSYour Name 
382*5113495bSYour Name 		peer_id = HTT_RX_DELBA_PEER_ID_GET(*msg_word);
383*5113495bSYour Name 		tid = HTT_RX_DELBA_TID_GET(*msg_word);
384*5113495bSYour Name 		ol_rx_delba_handler(pdev->txrx_pdev, peer_id, tid);
385*5113495bSYour Name 		break;
386*5113495bSYour Name 	}
387*5113495bSYour Name 	case HTT_T2H_MSG_TYPE_PEER_MAP:
388*5113495bSYour Name 	{
389*5113495bSYour Name 		uint8_t mac_addr_deswizzle_buf[QDF_MAC_ADDR_SIZE];
390*5113495bSYour Name 		uint8_t *peer_mac_addr;
391*5113495bSYour Name 		uint16_t peer_id;
392*5113495bSYour Name 		uint8_t vdev_id;
393*5113495bSYour Name 
394*5113495bSYour Name 		if (qdf_nbuf_len(htt_t2h_msg) < HTT_RX_PEER_MAP_BYTES) {
395*5113495bSYour Name 			qdf_print("invalid nbuff len");
396*5113495bSYour Name 			WARN_ON(1);
397*5113495bSYour Name 			break;
398*5113495bSYour Name 		}
399*5113495bSYour Name 
400*5113495bSYour Name 		peer_id = HTT_RX_PEER_MAP_PEER_ID_GET(*msg_word);
401*5113495bSYour Name 		vdev_id = HTT_RX_PEER_MAP_VDEV_ID_GET(*msg_word);
402*5113495bSYour Name 		peer_mac_addr = htt_t2h_mac_addr_deswizzle(
403*5113495bSYour Name 			(uint8_t *) (msg_word + 1),
404*5113495bSYour Name 			&mac_addr_deswizzle_buf[0]);
405*5113495bSYour Name 
406*5113495bSYour Name 		if (peer_id > ol_cfg_max_peer_id(pdev->ctrl_pdev)) {
407*5113495bSYour Name 			qdf_print("%s: HTT_T2H_MSG_TYPE_PEER_MAP,"
408*5113495bSYour Name 				"invalid peer_id, %u\n",
409*5113495bSYour Name 				__FUNCTION__,
410*5113495bSYour Name 				peer_id);
411*5113495bSYour Name 			break;
412*5113495bSYour Name 		}
413*5113495bSYour Name 
414*5113495bSYour Name 		ol_rx_peer_map_handler(pdev->txrx_pdev, peer_id,
415*5113495bSYour Name 				       vdev_id, peer_mac_addr,
416*5113495bSYour Name 				       1 /*can tx */);
417*5113495bSYour Name 		break;
418*5113495bSYour Name 	}
419*5113495bSYour Name 	case HTT_T2H_MSG_TYPE_PEER_UNMAP:
420*5113495bSYour Name 	{
421*5113495bSYour Name 		uint16_t peer_id;
422*5113495bSYour Name 
423*5113495bSYour Name 		if (qdf_nbuf_len(htt_t2h_msg) < HTT_RX_PEER_UNMAP_BYTES) {
424*5113495bSYour Name 			qdf_print("invalid nbuff len");
425*5113495bSYour Name 			WARN_ON(1);
426*5113495bSYour Name 			break;
427*5113495bSYour Name 		}
428*5113495bSYour Name 
429*5113495bSYour Name 		peer_id = HTT_RX_PEER_UNMAP_PEER_ID_GET(*msg_word);
430*5113495bSYour Name 		if (peer_id > ol_cfg_max_peer_id(pdev->ctrl_pdev)) {
431*5113495bSYour Name 			qdf_print("%s: HTT_T2H_MSG_TYPE_PEER_UNMAP,"
432*5113495bSYour Name 				"invalid peer_id, %u\n",
433*5113495bSYour Name 				__FUNCTION__,
434*5113495bSYour Name 				peer_id);
435*5113495bSYour Name 			break;
436*5113495bSYour Name 		}
437*5113495bSYour Name 
438*5113495bSYour Name 		ol_rx_peer_unmap_handler(pdev->txrx_pdev, peer_id);
439*5113495bSYour Name 		break;
440*5113495bSYour Name 	}
441*5113495bSYour Name 	case HTT_T2H_MSG_TYPE_SEC_IND:
442*5113495bSYour Name 	{
443*5113495bSYour Name 		uint16_t peer_id;
444*5113495bSYour Name 		enum htt_sec_type sec_type;
445*5113495bSYour Name 		int is_unicast;
446*5113495bSYour Name 
447*5113495bSYour Name 		if (qdf_nbuf_len(htt_t2h_msg) < HTT_SEC_IND_BYTES) {
448*5113495bSYour Name 			qdf_print("invalid nbuff len");
449*5113495bSYour Name 			WARN_ON(1);
450*5113495bSYour Name 			break;
451*5113495bSYour Name 		}
452*5113495bSYour Name 
453*5113495bSYour Name 		peer_id = HTT_SEC_IND_PEER_ID_GET(*msg_word);
454*5113495bSYour Name 		sec_type = HTT_SEC_IND_SEC_TYPE_GET(*msg_word);
455*5113495bSYour Name 		is_unicast = HTT_SEC_IND_UNICAST_GET(*msg_word);
456*5113495bSYour Name 		msg_word++;   /* point to the first part of the Michael key */
457*5113495bSYour Name 		ol_rx_sec_ind_handler(pdev->txrx_pdev, peer_id,
458*5113495bSYour Name 				      sec_type, is_unicast, msg_word,
459*5113495bSYour Name 				      msg_word + 2);
460*5113495bSYour Name 		break;
461*5113495bSYour Name 	}
462*5113495bSYour Name 	case HTT_T2H_MSG_TYPE_MGMT_TX_COMPL_IND:
463*5113495bSYour Name 	{
464*5113495bSYour Name 		struct htt_mgmt_tx_compl_ind *compl_msg;
465*5113495bSYour Name 		int32_t credit_delta = 1;
466*5113495bSYour Name 		int msg_len = qdf_nbuf_len(htt_t2h_msg);
467*5113495bSYour Name 		if (msg_len < (sizeof(struct htt_mgmt_tx_compl_ind) + sizeof(*msg_word))) {
468*5113495bSYour Name 			QDF_TRACE(QDF_MODULE_ID_HTT, QDF_TRACE_LEVEL_ERROR,
469*5113495bSYour Name 				  "Invalid msg_word length in HTT_T2H_MSG_TYPE_MGMT_TX_COMPL_IND");
470*5113495bSYour Name 			WARN_ON(1);
471*5113495bSYour Name 			break;
472*5113495bSYour Name 		}
473*5113495bSYour Name 
474*5113495bSYour Name 		compl_msg =
475*5113495bSYour Name 			(struct htt_mgmt_tx_compl_ind *)(msg_word + 1);
476*5113495bSYour Name 
477*5113495bSYour Name 		if (pdev->cfg.is_high_latency) {
478*5113495bSYour Name 			if (!pdev->cfg.default_tx_comp_req) {
479*5113495bSYour Name 				HTT_TX_MUTEX_ACQUIRE(&pdev->credit_mutex);
480*5113495bSYour Name 				qdf_atomic_add(credit_delta,
481*5113495bSYour Name 					       &pdev->htt_tx_credit.
482*5113495bSYour Name 								target_delta);
483*5113495bSYour Name 				credit_delta = htt_tx_credit_update(pdev);
484*5113495bSYour Name 				HTT_TX_MUTEX_RELEASE(&pdev->credit_mutex);
485*5113495bSYour Name 			}
486*5113495bSYour Name 			if (credit_delta)
487*5113495bSYour Name 				ol_tx_target_credit_update(
488*5113495bSYour Name 						pdev->txrx_pdev, credit_delta);
489*5113495bSYour Name 		}
490*5113495bSYour Name 		ol_tx_desc_update_group_credit(
491*5113495bSYour Name 			pdev->txrx_pdev, compl_msg->desc_id, 1,
492*5113495bSYour Name 			0, compl_msg->status);
493*5113495bSYour Name 
494*5113495bSYour Name 		DPTRACE(qdf_dp_trace_credit_record(QDF_TX_COMP, QDF_CREDIT_INC,
495*5113495bSYour Name 			1, qdf_atomic_read(&pdev->txrx_pdev->target_tx_credit),
496*5113495bSYour Name 			qdf_atomic_read(&pdev->txrx_pdev->txq_grps[0].credit),
497*5113495bSYour Name 			qdf_atomic_read(&pdev->txrx_pdev->txq_grps[1].credit)));
498*5113495bSYour Name 
499*5113495bSYour Name 		if (!ol_tx_get_is_mgmt_over_wmi_enabled()) {
500*5113495bSYour Name 			ol_tx_single_completion_handler(pdev->txrx_pdev,
501*5113495bSYour Name 							compl_msg->status,
502*5113495bSYour Name 							compl_msg->desc_id);
503*5113495bSYour Name 			htc_pm_runtime_put(pdev->htc_pdev);
504*5113495bSYour Name 			HTT_TX_SCHED(pdev);
505*5113495bSYour Name 		} else {
506*5113495bSYour Name 			QDF_TRACE(QDF_MODULE_ID_HTT, QDF_TRACE_LEVEL_INFO,
507*5113495bSYour Name 				  "Ignoring HTT_T2H_MSG_TYPE_MGMT_TX_COMPL_IND indication");
508*5113495bSYour Name 		}
509*5113495bSYour Name 		break;
510*5113495bSYour Name 	}
511*5113495bSYour Name 	case HTT_T2H_MSG_TYPE_STATS_CONF:
512*5113495bSYour Name 	{
513*5113495bSYour Name 		uint8_t cookie;
514*5113495bSYour Name 		uint8_t *stats_info_list;
515*5113495bSYour Name 
516*5113495bSYour Name 		cookie = *(msg_word + 1);
517*5113495bSYour Name 
518*5113495bSYour Name 		stats_info_list = (uint8_t *) (msg_word + 3);
519*5113495bSYour Name 		htc_pm_runtime_put(pdev->htc_pdev);
520*5113495bSYour Name 		ol_txrx_fw_stats_handler(pdev->txrx_pdev, cookie,
521*5113495bSYour Name 					 stats_info_list);
522*5113495bSYour Name 		break;
523*5113495bSYour Name 	}
524*5113495bSYour Name #ifndef REMOVE_PKT_LOG
525*5113495bSYour Name 	case HTT_T2H_MSG_TYPE_PKTLOG:
526*5113495bSYour Name 	{
527*5113495bSYour Name 		uint32_t len = qdf_nbuf_len(htt_t2h_msg);
528*5113495bSYour Name 
529*5113495bSYour Name 		if (len < sizeof(*msg_word) + sizeof(uint32_t)) {
530*5113495bSYour Name 			qdf_print("invalid nbuff len");
531*5113495bSYour Name 			WARN_ON(1);
532*5113495bSYour Name 			break;
533*5113495bSYour Name 		}
534*5113495bSYour Name 
535*5113495bSYour Name 		/*len is reduced by sizeof(*msg_word)*/
536*5113495bSYour Name 		pktlog_process_fw_msg(OL_TXRX_PDEV_ID, msg_word + 1,
537*5113495bSYour Name 				      len - sizeof(*msg_word));
538*5113495bSYour Name 		break;
539*5113495bSYour Name 	}
540*5113495bSYour Name #endif
541*5113495bSYour Name 	case HTT_T2H_MSG_TYPE_TX_CREDIT_UPDATE_IND:
542*5113495bSYour Name 	{
543*5113495bSYour Name 		uint32_t htt_credit_delta_abs;
544*5113495bSYour Name 		int32_t htt_credit_delta;
545*5113495bSYour Name 		int sign, old_credit;
546*5113495bSYour Name 		int msg_len = qdf_nbuf_len(htt_t2h_msg);
547*5113495bSYour Name 
548*5113495bSYour Name 		if (msg_len < HTT_TX_CREDIT_MSG_BYTES) {
549*5113495bSYour Name 			qdf_print("invalid nbuff len");
550*5113495bSYour Name 			WARN_ON(1);
551*5113495bSYour Name 			break;
552*5113495bSYour Name 		}
553*5113495bSYour Name 
554*5113495bSYour Name 		htt_credit_delta_abs =
555*5113495bSYour Name 			HTT_TX_CREDIT_DELTA_ABS_GET(*msg_word);
556*5113495bSYour Name 		sign = HTT_TX_CREDIT_SIGN_BIT_GET(*msg_word) ? -1 : 1;
557*5113495bSYour Name 		htt_credit_delta = sign * htt_credit_delta_abs;
558*5113495bSYour Name 
559*5113495bSYour Name 		old_credit = qdf_atomic_read(&pdev->htt_tx_credit.target_delta);
560*5113495bSYour Name 		if (((old_credit + htt_credit_delta) > MAX_TARGET_TX_CREDIT) ||
561*5113495bSYour Name 			((old_credit + htt_credit_delta) < -MAX_TARGET_TX_CREDIT)) {
562*5113495bSYour Name 			qdf_err("invalid update,old_credit=%d, htt_credit_delta=%d",
563*5113495bSYour Name 				old_credit, htt_credit_delta);
564*5113495bSYour Name 			break;
565*5113495bSYour Name 		}
566*5113495bSYour Name 		htt_credit_delta =
567*5113495bSYour Name 		htt_t2h_adjust_bus_target_delta(pdev, htt_credit_delta);
568*5113495bSYour Name 		htt_tx_group_credit_process(pdev, msg_word);
569*5113495bSYour Name 		DPTRACE(qdf_dp_trace_credit_record(QDF_TX_CREDIT_UPDATE,
570*5113495bSYour Name 			QDF_CREDIT_INC,	htt_credit_delta,
571*5113495bSYour Name 			qdf_atomic_read(&pdev->txrx_pdev->target_tx_credit) +
572*5113495bSYour Name 			htt_credit_delta,
573*5113495bSYour Name 			qdf_atomic_read(&pdev->txrx_pdev->txq_grps[0].credit),
574*5113495bSYour Name 			qdf_atomic_read(&pdev->txrx_pdev->txq_grps[1].credit)));
575*5113495bSYour Name 
576*5113495bSYour Name 		ol_tx_credit_completion_handler(pdev->txrx_pdev,
577*5113495bSYour Name 						htt_credit_delta);
578*5113495bSYour Name 		break;
579*5113495bSYour Name 	}
580*5113495bSYour Name 
581*5113495bSYour Name 	case HTT_T2H_MSG_TYPE_WDI_IPA_OP_RESPONSE:
582*5113495bSYour Name 	{
583*5113495bSYour Name 		uint16_t len;
584*5113495bSYour Name 		int msg_len = qdf_nbuf_len(htt_t2h_msg);
585*5113495bSYour Name 		len = HTT_WDI_IPA_OP_RESPONSE_RSP_LEN_GET(*(msg_word + 1));
586*5113495bSYour Name 
587*5113495bSYour Name 		if (sizeof(struct htt_wdi_ipa_op_response_t) + len > msg_len) {
588*5113495bSYour Name 			qdf_print("Invalid buf len size %zu len %d, msg_len %d",
589*5113495bSYour Name 				  sizeof(struct htt_wdi_ipa_op_response_t),
590*5113495bSYour Name 				  len, msg_len);
591*5113495bSYour Name 			WARN_ON(1);
592*5113495bSYour Name 			break;
593*5113495bSYour Name 		}
594*5113495bSYour Name 		htt_ipa_op_response(pdev, msg_word);
595*5113495bSYour Name 		break;
596*5113495bSYour Name 	}
597*5113495bSYour Name 
598*5113495bSYour Name 	case HTT_T2H_MSG_TYPE_FLOW_POOL_MAP:
599*5113495bSYour Name 	{
600*5113495bSYour Name 		uint8_t num_flows;
601*5113495bSYour Name 		struct htt_flow_pool_map_payload_t *pool_map_payoad;
602*5113495bSYour Name 		int msg_len = qdf_nbuf_len(htt_t2h_msg);
603*5113495bSYour Name 
604*5113495bSYour Name 		num_flows = HTT_FLOW_POOL_MAP_NUM_FLOWS_GET(*msg_word);
605*5113495bSYour Name 
606*5113495bSYour Name 		if (((HTT_FLOW_POOL_MAP_PAYLOAD_SZ /
607*5113495bSYour Name 			HTT_FLOW_POOL_MAP_HEADER_SZ) * num_flows + 1) * sizeof(*msg_word) > msg_len) {
608*5113495bSYour Name 			qdf_print("Invalid num_flows");
609*5113495bSYour Name 			WARN_ON(1);
610*5113495bSYour Name 			break;
611*5113495bSYour Name 		}
612*5113495bSYour Name 
613*5113495bSYour Name 		msg_word++;
614*5113495bSYour Name 		while (num_flows) {
615*5113495bSYour Name 			pool_map_payoad = (struct htt_flow_pool_map_payload_t *)
616*5113495bSYour Name 								msg_word;
617*5113495bSYour Name 			ol_tx_flow_pool_map_handler(pool_map_payoad->flow_id,
618*5113495bSYour Name 					pool_map_payoad->flow_type,
619*5113495bSYour Name 					pool_map_payoad->flow_pool_id,
620*5113495bSYour Name 					pool_map_payoad->flow_pool_size);
621*5113495bSYour Name 
622*5113495bSYour Name 			msg_word += (HTT_FLOW_POOL_MAP_PAYLOAD_SZ /
623*5113495bSYour Name 						 HTT_FLOW_POOL_MAP_HEADER_SZ);
624*5113495bSYour Name 			num_flows--;
625*5113495bSYour Name 		}
626*5113495bSYour Name 		break;
627*5113495bSYour Name 	}
628*5113495bSYour Name 
629*5113495bSYour Name 	case HTT_T2H_MSG_TYPE_FLOW_POOL_UNMAP:
630*5113495bSYour Name 	{
631*5113495bSYour Name 		struct htt_flow_pool_unmap_t *pool_numap_payload;
632*5113495bSYour Name 		int msg_len = qdf_nbuf_len(htt_t2h_msg);
633*5113495bSYour Name 
634*5113495bSYour Name 		if (msg_len < sizeof(struct htt_flow_pool_unmap_t)) {
635*5113495bSYour Name 			QDF_TRACE(QDF_MODULE_ID_HTT, QDF_TRACE_LEVEL_ERROR,
636*5113495bSYour Name 				  "Invalid msg_word length in HTT_T2H_MSG_TYPE_FLOW_POOL_UNMAP");
637*5113495bSYour Name 			WARN_ON(1);
638*5113495bSYour Name 			break;
639*5113495bSYour Name 		}
640*5113495bSYour Name 
641*5113495bSYour Name 		pool_numap_payload = (struct htt_flow_pool_unmap_t *)msg_word;
642*5113495bSYour Name 		ol_tx_flow_pool_unmap_handler(pool_numap_payload->flow_id,
643*5113495bSYour Name 					pool_numap_payload->flow_type,
644*5113495bSYour Name 					pool_numap_payload->flow_pool_id);
645*5113495bSYour Name 		break;
646*5113495bSYour Name 	}
647*5113495bSYour Name 
648*5113495bSYour Name 	case HTT_T2H_MSG_TYPE_FLOW_POOL_RESIZE:
649*5113495bSYour Name 	{
650*5113495bSYour Name 		struct htt_flow_pool_resize_t *msg;
651*5113495bSYour Name 		int msg_len = qdf_nbuf_len(htt_t2h_msg);
652*5113495bSYour Name 
653*5113495bSYour Name 		if (msg_len < sizeof(struct htt_flow_pool_resize_t)) {
654*5113495bSYour Name 			QDF_TRACE(QDF_MODULE_ID_HTT, QDF_TRACE_LEVEL_ERROR,
655*5113495bSYour Name 				  "Invalid msg_word length in HTT_T2H_MSG_TYPE_FLOW_POOL_RESIZE");
656*5113495bSYour Name 			WARN_ON(1);
657*5113495bSYour Name 			break;
658*5113495bSYour Name 		}
659*5113495bSYour Name 
660*5113495bSYour Name 		msg = (struct htt_flow_pool_resize_t *)msg_word;
661*5113495bSYour Name 		ol_tx_flow_pool_resize_handler(msg->flow_pool_id,
662*5113495bSYour Name 					       msg->flow_pool_new_size);
663*5113495bSYour Name 
664*5113495bSYour Name 		break;
665*5113495bSYour Name 	}
666*5113495bSYour Name 
667*5113495bSYour Name 	case HTT_T2H_MSG_TYPE_RX_OFLD_PKT_ERR:
668*5113495bSYour Name 	{
669*5113495bSYour Name 		switch (HTT_RX_OFLD_PKT_ERR_MSG_SUB_TYPE_GET(*msg_word)) {
670*5113495bSYour Name 		case HTT_RX_OFLD_PKT_ERR_TYPE_MIC_ERR:
671*5113495bSYour Name 		{
672*5113495bSYour Name 			struct ol_txrx_vdev_t *vdev;
673*5113495bSYour Name 			struct ol_txrx_peer_t *peer;
674*5113495bSYour Name 			uint64_t pn;
675*5113495bSYour Name 			uint32_t key_id;
676*5113495bSYour Name 			uint16_t peer_id;
677*5113495bSYour Name 			int msg_len = qdf_nbuf_len(htt_t2h_msg);
678*5113495bSYour Name 
679*5113495bSYour Name 			if (msg_len < HTT_RX_OFLD_PKT_ERR_MIC_ERR_BYTES) {
680*5113495bSYour Name 				qdf_print("invalid nbuff len");
681*5113495bSYour Name 				WARN_ON(1);
682*5113495bSYour Name 				break;
683*5113495bSYour Name 			}
684*5113495bSYour Name 
685*5113495bSYour Name 			peer_id = HTT_RX_OFLD_PKT_ERR_MIC_ERR_PEER_ID_GET
686*5113495bSYour Name 				(*(msg_word + 1));
687*5113495bSYour Name 
688*5113495bSYour Name 			peer = ol_txrx_peer_find_by_id(pdev->txrx_pdev,
689*5113495bSYour Name 						       peer_id);
690*5113495bSYour Name 			if (!peer) {
691*5113495bSYour Name 				qdf_print("invalid peer id %d", peer_id);
692*5113495bSYour Name 					  qdf_assert(0);
693*5113495bSYour Name 				break;
694*5113495bSYour Name 			}
695*5113495bSYour Name 			vdev = peer->vdev;
696*5113495bSYour Name 			key_id = HTT_RX_OFLD_PKT_ERR_MIC_ERR_KEYID_GET
697*5113495bSYour Name 				(*(msg_word + 1));
698*5113495bSYour Name 			qdf_mem_copy(&pn, (uint8_t *)(msg_word + 6), 6);
699*5113495bSYour Name 
700*5113495bSYour Name 			ol_rx_send_mic_err_ind(vdev->pdev, vdev->vdev_id,
701*5113495bSYour Name 					       peer->mac_addr.raw, 0, 0,
702*5113495bSYour Name 					       OL_RX_ERR_TKIP_MIC, htt_t2h_msg,
703*5113495bSYour Name 					       &pn, key_id);
704*5113495bSYour Name 			break;
705*5113495bSYour Name 		}
706*5113495bSYour Name 		default:
707*5113495bSYour Name 		{
708*5113495bSYour Name 			qdf_print("unhandled error type %d",
709*5113495bSYour Name 			  HTT_RX_OFLD_PKT_ERR_MSG_SUB_TYPE_GET(*msg_word));
710*5113495bSYour Name 			break;
711*5113495bSYour Name 		}
712*5113495bSYour Name 		}
713*5113495bSYour Name 		break;
714*5113495bSYour Name 	}
715*5113495bSYour Name #ifdef WLAN_CFR_ENABLE
716*5113495bSYour Name 	case HTT_T2H_MSG_TYPE_CFR_DUMP_COMPL_IND:
717*5113495bSYour Name 	{
718*5113495bSYour Name 		int expected_len;
719*5113495bSYour Name 		int msg_len = qdf_nbuf_len(htt_t2h_msg);
720*5113495bSYour Name 
721*5113495bSYour Name 		expected_len = HTT_CFR_DUMP_COMPL_HEAD_SZ +
722*5113495bSYour Name 				sizeof(struct htt_cfr_dump_compl_ind);
723*5113495bSYour Name 		if (msg_len < expected_len) {
724*5113495bSYour Name 			qdf_print("Invalid length of CFR capture event");
725*5113495bSYour Name 			break;
726*5113495bSYour Name 		}
727*5113495bSYour Name 
728*5113495bSYour Name 		ol_rx_cfr_capture_msg_handler(htt_t2h_msg);
729*5113495bSYour Name 		break;
730*5113495bSYour Name 	}
731*5113495bSYour Name #endif
732*5113495bSYour Name 	default:
733*5113495bSYour Name 		break;
734*5113495bSYour Name 	};
735*5113495bSYour Name 	/* Free the indication buffer */
736*5113495bSYour Name 	if (free_msg_buf)
737*5113495bSYour Name 		qdf_nbuf_free(htt_t2h_msg);
738*5113495bSYour Name }
739*5113495bSYour Name 
740*5113495bSYour Name #define HTT_TX_COMPL_HEAD_SZ			4
741*5113495bSYour Name #define HTT_TX_COMPL_BYTES_PER_MSDU_ID		2
742*5113495bSYour Name 
743*5113495bSYour Name /*
744*5113495bSYour Name  * Generic Target to host Msg/event  handler  for low priority messages
745*5113495bSYour Name  * Low priority message are handler in a different handler called from
746*5113495bSYour Name  * this function . So that the most likely success path like Rx and
747*5113495bSYour Name  * Tx comp   has little code   foot print
748*5113495bSYour Name  */
htt_t2h_msg_handler(void * context,HTC_PACKET * pkt)749*5113495bSYour Name void htt_t2h_msg_handler(void *context, HTC_PACKET *pkt)
750*5113495bSYour Name {
751*5113495bSYour Name 	struct htt_pdev_t *pdev = (struct htt_pdev_t *)context;
752*5113495bSYour Name 	qdf_nbuf_t htt_t2h_msg = (qdf_nbuf_t) pkt->pPktContext;
753*5113495bSYour Name 	uint32_t *msg_word;
754*5113495bSYour Name 	enum htt_t2h_msg_type msg_type;
755*5113495bSYour Name 
756*5113495bSYour Name 	/* check for successful message reception */
757*5113495bSYour Name 	if (pkt->Status != QDF_STATUS_SUCCESS) {
758*5113495bSYour Name 		if (pkt->Status != QDF_STATUS_E_CANCELED)
759*5113495bSYour Name 			pdev->stats.htc_err_cnt++;
760*5113495bSYour Name 		qdf_nbuf_free(htt_t2h_msg);
761*5113495bSYour Name 		return;
762*5113495bSYour Name 	}
763*5113495bSYour Name #ifdef HTT_RX_RESTORE
764*5113495bSYour Name 	if (qdf_unlikely(pdev->rx_ring.rx_reset)) {
765*5113495bSYour Name 		qdf_print("rx restore ..\n");
766*5113495bSYour Name 		qdf_nbuf_free(htt_t2h_msg);
767*5113495bSYour Name 		return;
768*5113495bSYour Name 	}
769*5113495bSYour Name #endif
770*5113495bSYour Name 
771*5113495bSYour Name 	/* confirm alignment */
772*5113495bSYour Name 	HTT_ASSERT3((((unsigned long)qdf_nbuf_data(htt_t2h_msg)) & 0x3) == 0);
773*5113495bSYour Name 
774*5113495bSYour Name 	msg_word = (uint32_t *) qdf_nbuf_data(htt_t2h_msg);
775*5113495bSYour Name 	msg_type = HTT_T2H_MSG_TYPE_GET(*msg_word);
776*5113495bSYour Name 
777*5113495bSYour Name #if defined(HELIUMPLUS_DEBUG)
778*5113495bSYour Name 	QDF_TRACE(QDF_MODULE_ID_HTT, QDF_TRACE_LEVEL_INFO,
779*5113495bSYour Name 		  "%s %d: msg_word 0x%x msg_type %d", __func__, __LINE__,
780*5113495bSYour Name 		  *msg_word, msg_type);
781*5113495bSYour Name #endif
782*5113495bSYour Name 
783*5113495bSYour Name 	switch (msg_type) {
784*5113495bSYour Name 	case HTT_T2H_MSG_TYPE_RX_IND:
785*5113495bSYour Name 	{
786*5113495bSYour Name 		unsigned int num_mpdu_ranges;
787*5113495bSYour Name 		unsigned int num_msdu_bytes;
788*5113495bSYour Name 		unsigned int calculated_msg_len;
789*5113495bSYour Name 		unsigned int rx_mpdu_range_offset_bytes;
790*5113495bSYour Name 		uint16_t peer_id;
791*5113495bSYour Name 		uint8_t tid;
792*5113495bSYour Name 		int msg_len = qdf_nbuf_len(htt_t2h_msg);
793*5113495bSYour Name 
794*5113495bSYour Name 		if (qdf_unlikely(pdev->cfg.is_full_reorder_offload)) {
795*5113495bSYour Name 			qdf_print("HTT_T2H_MSG_TYPE_RX_IND not supported ");
796*5113495bSYour Name 			qdf_print("with full reorder offload\n");
797*5113495bSYour Name 			break;
798*5113495bSYour Name 		}
799*5113495bSYour Name 		peer_id = HTT_RX_IND_PEER_ID_GET(*msg_word);
800*5113495bSYour Name 		tid = HTT_RX_IND_EXT_TID_GET(*msg_word);
801*5113495bSYour Name 
802*5113495bSYour Name 		if (tid >= OL_TXRX_NUM_EXT_TIDS) {
803*5113495bSYour Name 			qdf_print("HTT_T2H_MSG_TYPE_RX_IND, invalid tid %d\n",
804*5113495bSYour Name 				tid);
805*5113495bSYour Name 			break;
806*5113495bSYour Name 		}
807*5113495bSYour Name 		if (msg_len < (2 + HTT_RX_PPDU_DESC_SIZE32 + 1) * sizeof(uint32_t)) {
808*5113495bSYour Name 			qdf_print("HTT_T2H_MSG_TYPE_RX_IND, invalid msg_len\n");
809*5113495bSYour Name 			break;
810*5113495bSYour Name 		}
811*5113495bSYour Name 		num_msdu_bytes =
812*5113495bSYour Name 			HTT_RX_IND_FW_RX_DESC_BYTES_GET(
813*5113495bSYour Name 				*(msg_word + 2 + HTT_RX_PPDU_DESC_SIZE32));
814*5113495bSYour Name 		/*
815*5113495bSYour Name 		 * 1 word for the message header,
816*5113495bSYour Name 		 * HTT_RX_PPDU_DESC_SIZE32 words for the FW rx PPDU desc
817*5113495bSYour Name 		 * 1 word to specify the number of MSDU bytes,
818*5113495bSYour Name 		 * 1 word for every 4 MSDU bytes (round up),
819*5113495bSYour Name 		 * 1 word for the MPDU range header
820*5113495bSYour Name 		 */
821*5113495bSYour Name 		rx_mpdu_range_offset_bytes =
822*5113495bSYour Name 			(HTT_RX_IND_HDR_BYTES + num_msdu_bytes + 3);
823*5113495bSYour Name 		if (qdf_unlikely(num_msdu_bytes >
824*5113495bSYour Name 				 rx_mpdu_range_offset_bytes)) {
825*5113495bSYour Name 			qdf_print("HTT_T2H_MSG_TYPE_RX_IND, invalid %s %u\n",
826*5113495bSYour Name 				  "num_msdu_bytes",
827*5113495bSYour Name 				  num_msdu_bytes);
828*5113495bSYour Name 			WARN_ON(1);
829*5113495bSYour Name 			break;
830*5113495bSYour Name 		}
831*5113495bSYour Name 		pdev->rx_mpdu_range_offset_words =
832*5113495bSYour Name 			rx_mpdu_range_offset_bytes >> 2;
833*5113495bSYour Name 		num_mpdu_ranges =
834*5113495bSYour Name 			HTT_RX_IND_NUM_MPDU_RANGES_GET(*(msg_word + 1));
835*5113495bSYour Name 		pdev->rx_ind_msdu_byte_idx = 0;
836*5113495bSYour Name 		if (qdf_unlikely(rx_mpdu_range_offset_bytes >
837*5113495bSYour Name 		    msg_len)) {
838*5113495bSYour Name 			qdf_print("HTT_T2H_MSG_TYPE_RX_IND, invalid %s %d\n",
839*5113495bSYour Name 				  "rx_mpdu_range_offset_words",
840*5113495bSYour Name 				  pdev->rx_mpdu_range_offset_words);
841*5113495bSYour Name 			WARN_ON(1);
842*5113495bSYour Name 			break;
843*5113495bSYour Name 		}
844*5113495bSYour Name 		calculated_msg_len = rx_mpdu_range_offset_bytes +
845*5113495bSYour Name 			(num_mpdu_ranges * (int)sizeof(uint32_t));
846*5113495bSYour Name 		/*
847*5113495bSYour Name 		 * Check that the addition and multiplication
848*5113495bSYour Name 		 * do not cause integer overflow
849*5113495bSYour Name 		 */
850*5113495bSYour Name 		if (qdf_unlikely(calculated_msg_len <
851*5113495bSYour Name 		    rx_mpdu_range_offset_bytes)) {
852*5113495bSYour Name 			qdf_print("HTT_T2H_MSG_TYPE_RX_IND, invalid %s %u\n",
853*5113495bSYour Name 				  "num_mpdu_ranges",
854*5113495bSYour Name 				  (num_mpdu_ranges * (int)sizeof(uint32_t)));
855*5113495bSYour Name 			WARN_ON(1);
856*5113495bSYour Name 			break;
857*5113495bSYour Name 		}
858*5113495bSYour Name 		if (qdf_unlikely(calculated_msg_len > msg_len)) {
859*5113495bSYour Name 			qdf_print("HTT_T2H_MSG_TYPE_RX_IND, invalid %s %u\n",
860*5113495bSYour Name 				  "offset_words + mpdu_ranges",
861*5113495bSYour Name 				  calculated_msg_len);
862*5113495bSYour Name 			WARN_ON(1);
863*5113495bSYour Name 			break;
864*5113495bSYour Name 		}
865*5113495bSYour Name 		ol_rx_indication_handler(pdev->txrx_pdev,
866*5113495bSYour Name 					 htt_t2h_msg, peer_id,
867*5113495bSYour Name 					 tid, num_mpdu_ranges);
868*5113495bSYour Name 
869*5113495bSYour Name 		if (pdev->cfg.is_high_latency)
870*5113495bSYour Name 			return;
871*5113495bSYour Name 
872*5113495bSYour Name 		break;
873*5113495bSYour Name 	}
874*5113495bSYour Name 	case HTT_T2H_MSG_TYPE_TX_COMPL_IND:
875*5113495bSYour Name 	{
876*5113495bSYour Name 		int old_credit;
877*5113495bSYour Name 		int num_msdus;
878*5113495bSYour Name 		enum htt_tx_status status;
879*5113495bSYour Name 		int msg_len = qdf_nbuf_len(htt_t2h_msg);
880*5113495bSYour Name 
881*5113495bSYour Name 		/* status - no enum translation needed */
882*5113495bSYour Name 		status = HTT_TX_COMPL_IND_STATUS_GET(*msg_word);
883*5113495bSYour Name 		num_msdus = HTT_TX_COMPL_IND_NUM_GET(*msg_word);
884*5113495bSYour Name 
885*5113495bSYour Name 		/*
886*5113495bSYour Name 		 * each desc id will occupy 2 bytes.
887*5113495bSYour Name 		 * the 4 is for htt msg header
888*5113495bSYour Name 		 */
889*5113495bSYour Name 		if ((num_msdus * HTT_TX_COMPL_BYTES_PER_MSDU_ID +
890*5113495bSYour Name 			HTT_TX_COMPL_HEAD_SZ) > msg_len) {
891*5113495bSYour Name 			qdf_print("%s: num_msdus(%d) is invalid,"
892*5113495bSYour Name 				"adf_nbuf_len = %d\n",
893*5113495bSYour Name 				__FUNCTION__,
894*5113495bSYour Name 				num_msdus,
895*5113495bSYour Name 				msg_len);
896*5113495bSYour Name 			break;
897*5113495bSYour Name 		}
898*5113495bSYour Name 
899*5113495bSYour Name 		if (num_msdus & 0x1) {
900*5113495bSYour Name 			struct htt_tx_compl_ind_base *compl =
901*5113495bSYour Name 				(void *)msg_word;
902*5113495bSYour Name 
903*5113495bSYour Name 			/*
904*5113495bSYour Name 			 * Host CPU endianness can be different from FW CPU.
905*5113495bSYour Name 			 * This can result in even and odd MSDU IDs being
906*5113495bSYour Name 			 * switched. If this happens, copy the switched final
907*5113495bSYour Name 			 * odd MSDU ID from location payload[size], to
908*5113495bSYour Name 			 * location payload[size-1], where the message
909*5113495bSYour Name 			 * handler function expects to find it
910*5113495bSYour Name 			 */
911*5113495bSYour Name 			if (compl->payload[num_msdus] !=
912*5113495bSYour Name 			    HTT_TX_COMPL_INV_MSDU_ID) {
913*5113495bSYour Name 				compl->payload[num_msdus - 1] =
914*5113495bSYour Name 					compl->payload[num_msdus];
915*5113495bSYour Name 			}
916*5113495bSYour Name 		}
917*5113495bSYour Name 
918*5113495bSYour Name 		if (pdev->cfg.is_high_latency &&
919*5113495bSYour Name 		    !pdev->cfg.credit_update_enabled) {
920*5113495bSYour Name 			old_credit = qdf_atomic_read(
921*5113495bSYour Name 						&pdev->htt_tx_credit.target_delta);
922*5113495bSYour Name 			if (((old_credit + num_msdus) > MAX_TARGET_TX_CREDIT) ||
923*5113495bSYour Name 				((old_credit + num_msdus) < -MAX_TARGET_TX_CREDIT)) {
924*5113495bSYour Name 				qdf_err("invalid update,old_credit=%d, num_msdus=%d",
925*5113495bSYour Name 					old_credit, num_msdus);
926*5113495bSYour Name 			} else {
927*5113495bSYour Name 				if (!pdev->cfg.default_tx_comp_req) {
928*5113495bSYour Name 					int credit_delta;
929*5113495bSYour Name 
930*5113495bSYour Name 					HTT_TX_MUTEX_ACQUIRE(&pdev->credit_mutex);
931*5113495bSYour Name 					qdf_atomic_add(num_msdus,
932*5113495bSYour Name 						       &pdev->htt_tx_credit.
933*5113495bSYour Name 							target_delta);
934*5113495bSYour Name 					credit_delta = htt_tx_credit_update(pdev);
935*5113495bSYour Name 					HTT_TX_MUTEX_RELEASE(&pdev->credit_mutex);
936*5113495bSYour Name 
937*5113495bSYour Name 					if (credit_delta) {
938*5113495bSYour Name 						ol_tx_target_credit_update(
939*5113495bSYour Name 								pdev->txrx_pdev,
940*5113495bSYour Name 								credit_delta);
941*5113495bSYour Name 					}
942*5113495bSYour Name 				} else {
943*5113495bSYour Name 					ol_tx_target_credit_update(pdev->txrx_pdev,
944*5113495bSYour Name 								   num_msdus);
945*5113495bSYour Name 				}
946*5113495bSYour Name 			}
947*5113495bSYour Name 		}
948*5113495bSYour Name 
949*5113495bSYour Name 		ol_tx_completion_handler(pdev->txrx_pdev, num_msdus,
950*5113495bSYour Name 					 status, msg_word);
951*5113495bSYour Name 		HTT_TX_SCHED(pdev);
952*5113495bSYour Name 		break;
953*5113495bSYour Name 	}
954*5113495bSYour Name 	case HTT_T2H_MSG_TYPE_RX_PN_IND:
955*5113495bSYour Name 	{
956*5113495bSYour Name 		uint16_t peer_id;
957*5113495bSYour Name 		uint8_t tid, pn_ie_cnt, *pn_ie = NULL;
958*5113495bSYour Name 		uint16_t seq_num_start, seq_num_end;
959*5113495bSYour Name 		int msg_len = qdf_nbuf_len(htt_t2h_msg);
960*5113495bSYour Name 
961*5113495bSYour Name 		if (msg_len < HTT_RX_PN_IND_BYTES) {
962*5113495bSYour Name 			qdf_print("invalid nbuff len");
963*5113495bSYour Name 			WARN_ON(1);
964*5113495bSYour Name 			break;
965*5113495bSYour Name 		}
966*5113495bSYour Name 
967*5113495bSYour Name 		/*First dword */
968*5113495bSYour Name 		peer_id = HTT_RX_PN_IND_PEER_ID_GET(*msg_word);
969*5113495bSYour Name 		tid = HTT_RX_PN_IND_EXT_TID_GET(*msg_word);
970*5113495bSYour Name 
971*5113495bSYour Name 		msg_word++;
972*5113495bSYour Name 		/*Second dword */
973*5113495bSYour Name 		seq_num_start =
974*5113495bSYour Name 			HTT_RX_PN_IND_SEQ_NUM_START_GET(*msg_word);
975*5113495bSYour Name 		seq_num_end = HTT_RX_PN_IND_SEQ_NUM_END_GET(*msg_word);
976*5113495bSYour Name 		pn_ie_cnt = HTT_RX_PN_IND_PN_IE_CNT_GET(*msg_word);
977*5113495bSYour Name 
978*5113495bSYour Name 		if (msg_len - HTT_RX_PN_IND_BYTES <
979*5113495bSYour Name 		    pn_ie_cnt * sizeof(uint8_t)) {
980*5113495bSYour Name 			qdf_print("invalid pn_ie count");
981*5113495bSYour Name 			WARN_ON(1);
982*5113495bSYour Name 			break;
983*5113495bSYour Name 		}
984*5113495bSYour Name 
985*5113495bSYour Name 		msg_word++;
986*5113495bSYour Name 		/*Third dword */
987*5113495bSYour Name 		if (pn_ie_cnt)
988*5113495bSYour Name 			pn_ie = (uint8_t *) msg_word;
989*5113495bSYour Name 
990*5113495bSYour Name 		ol_rx_pn_ind_handler(pdev->txrx_pdev, peer_id, tid,
991*5113495bSYour Name 				     seq_num_start, seq_num_end,
992*5113495bSYour Name 				     pn_ie_cnt, pn_ie);
993*5113495bSYour Name 
994*5113495bSYour Name 		break;
995*5113495bSYour Name 	}
996*5113495bSYour Name 	case HTT_T2H_MSG_TYPE_TX_INSPECT_IND:
997*5113495bSYour Name 	{
998*5113495bSYour Name 		int num_msdus;
999*5113495bSYour Name 		int msg_len = qdf_nbuf_len(htt_t2h_msg);
1000*5113495bSYour Name 
1001*5113495bSYour Name 		num_msdus = HTT_TX_COMPL_IND_NUM_GET(*msg_word);
1002*5113495bSYour Name 		/*
1003*5113495bSYour Name 		 * each desc id will occupy 2 bytes.
1004*5113495bSYour Name 		 * the 4 is for htt msg header
1005*5113495bSYour Name 		 */
1006*5113495bSYour Name 		if ((num_msdus * HTT_TX_COMPL_BYTES_PER_MSDU_ID +
1007*5113495bSYour Name 			HTT_TX_COMPL_HEAD_SZ) > msg_len) {
1008*5113495bSYour Name 			qdf_print("%s: num_msdus(%d) is invalid,"
1009*5113495bSYour Name 				"adf_nbuf_len = %d\n",
1010*5113495bSYour Name 				__FUNCTION__,
1011*5113495bSYour Name 				num_msdus,
1012*5113495bSYour Name 				msg_len);
1013*5113495bSYour Name 			break;
1014*5113495bSYour Name 		}
1015*5113495bSYour Name 
1016*5113495bSYour Name 		if (num_msdus & 0x1) {
1017*5113495bSYour Name 			struct htt_tx_compl_ind_base *compl =
1018*5113495bSYour Name 				(void *)msg_word;
1019*5113495bSYour Name 
1020*5113495bSYour Name 			/*
1021*5113495bSYour Name 			 * Host CPU endianness can be different from FW CPU.
1022*5113495bSYour Name 			 * This can result in even and odd MSDU IDs being
1023*5113495bSYour Name 			 * switched. If this happens, copy the switched final
1024*5113495bSYour Name 			 * odd MSDU ID from location payload[size], to
1025*5113495bSYour Name 			 * location payload[size-1], where the message handler
1026*5113495bSYour Name 			 * function expects to find it
1027*5113495bSYour Name 			 */
1028*5113495bSYour Name 			if (compl->payload[num_msdus] !=
1029*5113495bSYour Name 			    HTT_TX_COMPL_INV_MSDU_ID) {
1030*5113495bSYour Name 				compl->payload[num_msdus - 1] =
1031*5113495bSYour Name 					compl->payload[num_msdus];
1032*5113495bSYour Name 			}
1033*5113495bSYour Name 		}
1034*5113495bSYour Name 		ol_tx_inspect_handler(pdev->txrx_pdev, num_msdus,
1035*5113495bSYour Name 				      msg_word + 1);
1036*5113495bSYour Name 		HTT_TX_SCHED(pdev);
1037*5113495bSYour Name 		break;
1038*5113495bSYour Name 	}
1039*5113495bSYour Name 	case HTT_T2H_MSG_TYPE_RX_IN_ORD_PADDR_IND:
1040*5113495bSYour Name 	{
1041*5113495bSYour Name 		uint16_t peer_id;
1042*5113495bSYour Name 		uint8_t tid;
1043*5113495bSYour Name 		uint8_t offload_ind, frag_ind;
1044*5113495bSYour Name 
1045*5113495bSYour Name 		if (qdf_unlikely(!pdev->cfg.is_full_reorder_offload)) {
1046*5113495bSYour Name 			qdf_print("full reorder offload is disable");
1047*5113495bSYour Name 			break;
1048*5113495bSYour Name 		}
1049*5113495bSYour Name 
1050*5113495bSYour Name 		if (qdf_unlikely(pdev->cfg.is_high_latency)) {
1051*5113495bSYour Name 			qdf_print("full reorder offload not support in HL");
1052*5113495bSYour Name 			break;
1053*5113495bSYour Name 		}
1054*5113495bSYour Name 
1055*5113495bSYour Name 		peer_id = HTT_RX_IN_ORD_PADDR_IND_PEER_ID_GET(*msg_word);
1056*5113495bSYour Name 		tid = HTT_RX_IN_ORD_PADDR_IND_EXT_TID_GET(*msg_word);
1057*5113495bSYour Name 		offload_ind = HTT_RX_IN_ORD_PADDR_IND_OFFLOAD_GET(*msg_word);
1058*5113495bSYour Name 		frag_ind = HTT_RX_IN_ORD_PADDR_IND_FRAG_GET(*msg_word);
1059*5113495bSYour Name 
1060*5113495bSYour Name #if defined(HELIUMPLUS_DEBUG)
1061*5113495bSYour Name 		qdf_print("peerid %d tid %d offloadind %d fragind %d",
1062*5113495bSYour Name 			  peer_id, tid, offload_ind,
1063*5113495bSYour Name 			  frag_ind);
1064*5113495bSYour Name #endif
1065*5113495bSYour Name 		if (qdf_unlikely(frag_ind)) {
1066*5113495bSYour Name 			ol_rx_frag_indication_handler(pdev->txrx_pdev,
1067*5113495bSYour Name 						      htt_t2h_msg,
1068*5113495bSYour Name 						      peer_id, tid);
1069*5113495bSYour Name 			break;
1070*5113495bSYour Name 		}
1071*5113495bSYour Name 
1072*5113495bSYour Name 		ol_rx_in_order_indication_handler(pdev->txrx_pdev,
1073*5113495bSYour Name 						  htt_t2h_msg, peer_id,
1074*5113495bSYour Name 						  tid, offload_ind);
1075*5113495bSYour Name 		break;
1076*5113495bSYour Name 	}
1077*5113495bSYour Name 
1078*5113495bSYour Name 	default:
1079*5113495bSYour Name 		htt_t2h_lp_msg_handler(context, htt_t2h_msg, true);
1080*5113495bSYour Name 		return;
1081*5113495bSYour Name 
1082*5113495bSYour Name 	};
1083*5113495bSYour Name 
1084*5113495bSYour Name 	/* Free the indication buffer */
1085*5113495bSYour Name 	qdf_nbuf_free(htt_t2h_msg);
1086*5113495bSYour Name }
1087*5113495bSYour Name 
1088*5113495bSYour Name #ifdef WLAN_FEATURE_FASTPATH
1089*5113495bSYour Name #define HTT_T2H_MSG_BUF_REINIT(_buf, dev)				\
1090*5113495bSYour Name 	do {								\
1091*5113495bSYour Name 		qdf_nbuf_push_head(_buf, (HTC_HEADER_LEN) +		\
1092*5113495bSYour Name 				   HTC_HDR_ALIGNMENT_PADDING);		\
1093*5113495bSYour Name 		qdf_nbuf_init_fast((_buf));				\
1094*5113495bSYour Name 		qdf_mem_dma_sync_single_for_device(dev,			\
1095*5113495bSYour Name 					(QDF_NBUF_CB_PADDR(_buf)),	\
1096*5113495bSYour Name 					(skb_end_pointer(_buf) -	\
1097*5113495bSYour Name 					(_buf)->data),			\
1098*5113495bSYour Name 					DMA_FROM_DEVICE);		\
1099*5113495bSYour Name 	} while (0)
1100*5113495bSYour Name 
1101*5113495bSYour Name /**
1102*5113495bSYour Name  * htt_t2h_msg_handler_fast() -  Fastpath specific message handler
1103*5113495bSYour Name  * @context: HTT context
1104*5113495bSYour Name  * @cmpl_msdus: netbuf completions
1105*5113495bSYour Name  * @num_cmpls: number of completions to be handled
1106*5113495bSYour Name  *
1107*5113495bSYour Name  * Return: None
1108*5113495bSYour Name  */
htt_t2h_msg_handler_fast(void * context,qdf_nbuf_t * cmpl_msdus,uint32_t num_cmpls)1109*5113495bSYour Name void htt_t2h_msg_handler_fast(void *context, qdf_nbuf_t *cmpl_msdus,
1110*5113495bSYour Name 			      uint32_t num_cmpls)
1111*5113495bSYour Name {
1112*5113495bSYour Name 	struct htt_pdev_t *pdev = (struct htt_pdev_t *)context;
1113*5113495bSYour Name 	qdf_nbuf_t htt_t2h_msg;
1114*5113495bSYour Name 	uint32_t *msg_word;
1115*5113495bSYour Name 	uint32_t i;
1116*5113495bSYour Name 	enum htt_t2h_msg_type msg_type;
1117*5113495bSYour Name 	uint32_t msg_len;
1118*5113495bSYour Name 	struct ol_txrx_soc_t *soc = cds_get_context(QDF_MODULE_ID_SOC);
1119*5113495bSYour Name 
1120*5113495bSYour Name 	for (i = 0; i < num_cmpls; i++) {
1121*5113495bSYour Name 		htt_t2h_msg = cmpl_msdus[i];
1122*5113495bSYour Name 		msg_len = qdf_nbuf_len(htt_t2h_msg);
1123*5113495bSYour Name 
1124*5113495bSYour Name 		/*
1125*5113495bSYour Name 		 * Move the data pointer to point to HTT header
1126*5113495bSYour Name 		 * past the HTC header + HTC header alignment padding
1127*5113495bSYour Name 		 */
1128*5113495bSYour Name 		qdf_nbuf_pull_head(htt_t2h_msg, HTC_HEADER_LEN +
1129*5113495bSYour Name 				   HTC_HDR_ALIGNMENT_PADDING);
1130*5113495bSYour Name 
1131*5113495bSYour Name 		/* confirm alignment */
1132*5113495bSYour Name 		HTT_ASSERT3((((unsigned long) qdf_nbuf_data(htt_t2h_msg)) & 0x3)
1133*5113495bSYour Name 			    == 0);
1134*5113495bSYour Name 
1135*5113495bSYour Name 		msg_word = (u_int32_t *) qdf_nbuf_data(htt_t2h_msg);
1136*5113495bSYour Name 		msg_type = HTT_T2H_MSG_TYPE_GET(*msg_word);
1137*5113495bSYour Name 
1138*5113495bSYour Name 		switch (msg_type) {
1139*5113495bSYour Name 		case HTT_T2H_MSG_TYPE_RX_IND:
1140*5113495bSYour Name 		{
1141*5113495bSYour Name 			unsigned int num_mpdu_ranges;
1142*5113495bSYour Name 			unsigned int num_msdu_bytes;
1143*5113495bSYour Name 			unsigned int calculated_msg_len;
1144*5113495bSYour Name 			unsigned int rx_mpdu_range_offset_bytes;
1145*5113495bSYour Name 			u_int16_t peer_id;
1146*5113495bSYour Name 			u_int8_t tid;
1147*5113495bSYour Name 			msg_len = qdf_nbuf_len(htt_t2h_msg);
1148*5113495bSYour Name 
1149*5113495bSYour Name 			peer_id = HTT_RX_IND_PEER_ID_GET(*msg_word);
1150*5113495bSYour Name 			tid = HTT_RX_IND_EXT_TID_GET(*msg_word);
1151*5113495bSYour Name 			if (tid >= OL_TXRX_NUM_EXT_TIDS) {
1152*5113495bSYour Name 				qdf_print("HTT_T2H_MSG_TYPE_RX_IND, invalid tid %d\n",
1153*5113495bSYour Name 					tid);
1154*5113495bSYour Name 				WARN_ON(1);
1155*5113495bSYour Name 				break;
1156*5113495bSYour Name 			}
1157*5113495bSYour Name 			num_msdu_bytes =
1158*5113495bSYour Name 				HTT_RX_IND_FW_RX_DESC_BYTES_GET(
1159*5113495bSYour Name 				*(msg_word + 2 +
1160*5113495bSYour Name 				  HTT_RX_PPDU_DESC_SIZE32));
1161*5113495bSYour Name 			/*
1162*5113495bSYour Name 			 * 1 word for the message header,
1163*5113495bSYour Name 			 * HTT_RX_PPDU_DESC_SIZE32 words for the FW
1164*5113495bSYour Name 			 * rx PPDU desc.
1165*5113495bSYour Name 			 * 1 word to specify the number of MSDU bytes,
1166*5113495bSYour Name 			 * 1 word for every 4 MSDU bytes (round up),
1167*5113495bSYour Name 			 * 1 word for the MPDU range header
1168*5113495bSYour Name 			 */
1169*5113495bSYour Name 			rx_mpdu_range_offset_bytes =
1170*5113495bSYour Name 				(HTT_RX_IND_HDR_BYTES + num_msdu_bytes + 3);
1171*5113495bSYour Name 			if (qdf_unlikely(num_msdu_bytes >
1172*5113495bSYour Name 					 rx_mpdu_range_offset_bytes)) {
1173*5113495bSYour Name 				qdf_print("HTT_T2H_MSG_TYPE_RX_IND, %s %u\n",
1174*5113495bSYour Name 					  "invalid num_msdu_bytes",
1175*5113495bSYour Name 					  num_msdu_bytes);
1176*5113495bSYour Name 				WARN_ON(1);
1177*5113495bSYour Name 				break;
1178*5113495bSYour Name 			}
1179*5113495bSYour Name 			pdev->rx_mpdu_range_offset_words =
1180*5113495bSYour Name 				rx_mpdu_range_offset_bytes >> 2;
1181*5113495bSYour Name 			num_mpdu_ranges =
1182*5113495bSYour Name 				HTT_RX_IND_NUM_MPDU_RANGES_GET(*(msg_word
1183*5113495bSYour Name 								 + 1));
1184*5113495bSYour Name 			pdev->rx_ind_msdu_byte_idx = 0;
1185*5113495bSYour Name 			if (qdf_unlikely(rx_mpdu_range_offset_bytes >
1186*5113495bSYour Name 					 msg_len)) {
1187*5113495bSYour Name 				qdf_print("HTT_T2H_MSG_TYPE_RX_IND, %s %d\n",
1188*5113495bSYour Name 					  "invalid rx_mpdu_range_offset_words",
1189*5113495bSYour Name 					  pdev->rx_mpdu_range_offset_words);
1190*5113495bSYour Name 				WARN_ON(1);
1191*5113495bSYour Name 				break;
1192*5113495bSYour Name 			}
1193*5113495bSYour Name 			calculated_msg_len = rx_mpdu_range_offset_bytes +
1194*5113495bSYour Name 					     (num_mpdu_ranges *
1195*5113495bSYour Name 					     (int)sizeof(uint32_t));
1196*5113495bSYour Name 			/*
1197*5113495bSYour Name 			 * Check that the addition and multiplication
1198*5113495bSYour Name 			 * do not cause integer overflow
1199*5113495bSYour Name 			 */
1200*5113495bSYour Name 			if (qdf_unlikely(calculated_msg_len <
1201*5113495bSYour Name 					 rx_mpdu_range_offset_bytes)) {
1202*5113495bSYour Name 				qdf_print("HTT_T2H_MSG_TYPE_RX_IND, %s %u\n",
1203*5113495bSYour Name 					  "invalid num_mpdu_ranges",
1204*5113495bSYour Name 					  (num_mpdu_ranges *
1205*5113495bSYour Name 					   (int)sizeof(uint32_t)));
1206*5113495bSYour Name 				WARN_ON(1);
1207*5113495bSYour Name 				break;
1208*5113495bSYour Name 			}
1209*5113495bSYour Name 			if (qdf_unlikely(calculated_msg_len > msg_len)) {
1210*5113495bSYour Name 				qdf_print("HTT_T2H_MSG_TYPE_RX_IND, %s %u\n",
1211*5113495bSYour Name 					  "invalid offset_words + mpdu_ranges",
1212*5113495bSYour Name 					  calculated_msg_len);
1213*5113495bSYour Name 				WARN_ON(1);
1214*5113495bSYour Name 				break;
1215*5113495bSYour Name 			}
1216*5113495bSYour Name 			ol_rx_indication_handler(pdev->txrx_pdev, htt_t2h_msg,
1217*5113495bSYour Name 						 peer_id, tid, num_mpdu_ranges);
1218*5113495bSYour Name 			break;
1219*5113495bSYour Name 		}
1220*5113495bSYour Name 		case HTT_T2H_MSG_TYPE_TX_COMPL_IND:
1221*5113495bSYour Name 		{
1222*5113495bSYour Name 			int num_msdus;
1223*5113495bSYour Name 			enum htt_tx_status status;
1224*5113495bSYour Name 
1225*5113495bSYour Name 			/* status - no enum translation needed */
1226*5113495bSYour Name 			status = HTT_TX_COMPL_IND_STATUS_GET(*msg_word);
1227*5113495bSYour Name 			num_msdus = HTT_TX_COMPL_IND_NUM_GET(*msg_word);
1228*5113495bSYour Name 
1229*5113495bSYour Name 			/*
1230*5113495bSYour Name 			 * each desc id will occupy 2 bytes.
1231*5113495bSYour Name 			 * the 4 is for htt msg header
1232*5113495bSYour Name 			 */
1233*5113495bSYour Name 			if ((num_msdus * HTT_TX_COMPL_BYTES_PER_MSDU_ID +
1234*5113495bSYour Name 				HTT_TX_COMPL_HEAD_SZ) > msg_len) {
1235*5113495bSYour Name 				qdf_print("%s: num_msdus(%d) is invalid,"
1236*5113495bSYour Name 					"adf_nbuf_len = %d\n",
1237*5113495bSYour Name 					__FUNCTION__,
1238*5113495bSYour Name 					num_msdus,
1239*5113495bSYour Name 					msg_len);
1240*5113495bSYour Name 				break;
1241*5113495bSYour Name 			}
1242*5113495bSYour Name 
1243*5113495bSYour Name 			if (num_msdus & 0x1) {
1244*5113495bSYour Name 				struct htt_tx_compl_ind_base *compl =
1245*5113495bSYour Name 					(void *)msg_word;
1246*5113495bSYour Name 
1247*5113495bSYour Name 				/*
1248*5113495bSYour Name 				 * Host CPU endianness can be different
1249*5113495bSYour Name 				 * from FW CPU. This can result in even
1250*5113495bSYour Name 				 * and odd MSDU IDs being switched. If
1251*5113495bSYour Name 				 * this happens, copy the switched final
1252*5113495bSYour Name 				 * odd MSDU ID from location
1253*5113495bSYour Name 				 * payload[size], to location
1254*5113495bSYour Name 				 * payload[size-1],where the message
1255*5113495bSYour Name 				 * handler function expects to find it
1256*5113495bSYour Name 				 */
1257*5113495bSYour Name 				if (compl->payload[num_msdus] !=
1258*5113495bSYour Name 				    HTT_TX_COMPL_INV_MSDU_ID) {
1259*5113495bSYour Name 					compl->payload[num_msdus - 1] =
1260*5113495bSYour Name 						compl->payload[num_msdus];
1261*5113495bSYour Name 				}
1262*5113495bSYour Name 			}
1263*5113495bSYour Name 			ol_tx_completion_handler(pdev->txrx_pdev, num_msdus,
1264*5113495bSYour Name 						 status, msg_word);
1265*5113495bSYour Name 
1266*5113495bSYour Name 			break;
1267*5113495bSYour Name 		}
1268*5113495bSYour Name 		case HTT_T2H_MSG_TYPE_TX_OFFLOAD_DELIVER_IND:
1269*5113495bSYour Name 		{
1270*5113495bSYour Name 			struct htt_tx_offload_deliver_ind_hdr_t
1271*5113495bSYour Name 							*offload_deliver_msg;
1272*5113495bSYour Name 			uint8_t vdev_id;
1273*5113495bSYour Name 			struct ol_txrx_vdev_t *vdev;
1274*5113495bSYour Name 			bool is_pkt_during_roam = false;
1275*5113495bSYour Name 			struct ol_txrx_pdev_t *txrx_pdev = pdev->txrx_pdev;
1276*5113495bSYour Name 			struct ol_txrx_peer_t *peer;
1277*5113495bSYour Name 			uint8_t bssid[QDF_MAC_ADDR_SIZE];
1278*5113495bSYour Name 			uint32_t freq = 0;
1279*5113495bSYour Name 
1280*5113495bSYour Name 			if (!(ucfg_pkt_capture_get_pktcap_mode((void *)soc->psoc) &
1281*5113495bSYour Name 			      PKT_CAPTURE_MODE_DATA_ONLY))
1282*5113495bSYour Name 				break;
1283*5113495bSYour Name 
1284*5113495bSYour Name 			offload_deliver_msg =
1285*5113495bSYour Name 			(struct htt_tx_offload_deliver_ind_hdr_t *)msg_word;
1286*5113495bSYour Name 			is_pkt_during_roam =
1287*5113495bSYour Name 			(offload_deliver_msg->reserved_2 ? true : false);
1288*5113495bSYour Name 
1289*5113495bSYour Name 			if (qdf_unlikely(
1290*5113495bSYour Name 				!pdev->cfg.is_full_reorder_offload)) {
1291*5113495bSYour Name 				break;
1292*5113495bSYour Name 			}
1293*5113495bSYour Name 
1294*5113495bSYour Name 			/* Is FW sends offload data during roaming */
1295*5113495bSYour Name 			if (is_pkt_during_roam) {
1296*5113495bSYour Name 				vdev_id = HTT_INVALID_VDEV;
1297*5113495bSYour Name 				freq =
1298*5113495bSYour Name 				(uint32_t)offload_deliver_msg->reserved_3;
1299*5113495bSYour Name 				htt_rx_mon_note_capture_channel(
1300*5113495bSYour Name 						pdev, cds_freq_to_chan(freq));
1301*5113495bSYour Name 			} else {
1302*5113495bSYour Name 				vdev_id = offload_deliver_msg->vdev_id;
1303*5113495bSYour Name 				vdev = (struct ol_txrx_vdev_t *)
1304*5113495bSYour Name 					ol_txrx_get_vdev_from_vdev_id(vdev_id);
1305*5113495bSYour Name 
1306*5113495bSYour Name 				if (vdev) {
1307*5113495bSYour Name 					qdf_spin_lock_bh(
1308*5113495bSYour Name 						&txrx_pdev->peer_ref_mutex);
1309*5113495bSYour Name 					peer = TAILQ_FIRST(&vdev->peer_list);
1310*5113495bSYour Name 					qdf_spin_unlock_bh(
1311*5113495bSYour Name 						&txrx_pdev->peer_ref_mutex);
1312*5113495bSYour Name 					if (peer) {
1313*5113495bSYour Name 						qdf_spin_lock_bh(
1314*5113495bSYour Name 							&peer->peer_info_lock);
1315*5113495bSYour Name 						qdf_mem_copy(
1316*5113495bSYour Name 							bssid,
1317*5113495bSYour Name 							&peer->mac_addr.raw,
1318*5113495bSYour Name 							QDF_MAC_ADDR_SIZE);
1319*5113495bSYour Name 						qdf_spin_unlock_bh(
1320*5113495bSYour Name 							&peer->peer_info_lock);
1321*5113495bSYour Name 					} else {
1322*5113495bSYour Name 						break;
1323*5113495bSYour Name 					}
1324*5113495bSYour Name 				} else {
1325*5113495bSYour Name 					break;
1326*5113495bSYour Name 				}
1327*5113495bSYour Name 			}
1328*5113495bSYour Name 			ucfg_pkt_capture_offload_deliver_indication_handler(
1329*5113495bSYour Name 							msg_word,
1330*5113495bSYour Name 							vdev_id, bssid, pdev);
1331*5113495bSYour Name 			break;
1332*5113495bSYour Name 		}
1333*5113495bSYour Name 		case HTT_T2H_MSG_TYPE_RX_PN_IND:
1334*5113495bSYour Name 		{
1335*5113495bSYour Name 			u_int16_t peer_id;
1336*5113495bSYour Name 			u_int8_t tid, pn_ie_cnt, *pn_ie = NULL;
1337*5113495bSYour Name 			int seq_num_start, seq_num_end;
1338*5113495bSYour Name 			int msg_len = qdf_nbuf_len(htt_t2h_msg);
1339*5113495bSYour Name 
1340*5113495bSYour Name 			if (msg_len < HTT_RX_PN_IND_BYTES) {
1341*5113495bSYour Name 				qdf_print("invalid nbuff len");
1342*5113495bSYour Name 				WARN_ON(1);
1343*5113495bSYour Name 				break;
1344*5113495bSYour Name 			}
1345*5113495bSYour Name 
1346*5113495bSYour Name 			/*First dword */
1347*5113495bSYour Name 			peer_id = HTT_RX_PN_IND_PEER_ID_GET(*msg_word);
1348*5113495bSYour Name 			tid = HTT_RX_PN_IND_EXT_TID_GET(*msg_word);
1349*5113495bSYour Name 
1350*5113495bSYour Name 			msg_word++;
1351*5113495bSYour Name 			/*Second dword */
1352*5113495bSYour Name 			seq_num_start =
1353*5113495bSYour Name 				HTT_RX_PN_IND_SEQ_NUM_START_GET(*msg_word);
1354*5113495bSYour Name 			seq_num_end =
1355*5113495bSYour Name 				HTT_RX_PN_IND_SEQ_NUM_END_GET(*msg_word);
1356*5113495bSYour Name 			pn_ie_cnt =
1357*5113495bSYour Name 				HTT_RX_PN_IND_PN_IE_CNT_GET(*msg_word);
1358*5113495bSYour Name 
1359*5113495bSYour Name 			if (msg_len - HTT_RX_PN_IND_BYTES <
1360*5113495bSYour Name 				pn_ie_cnt * sizeof(uint8_t)) {
1361*5113495bSYour Name 				qdf_print("invalid pn_ie len");
1362*5113495bSYour Name 				WARN_ON(1);
1363*5113495bSYour Name 				break;
1364*5113495bSYour Name 			}
1365*5113495bSYour Name 
1366*5113495bSYour Name 			msg_word++;
1367*5113495bSYour Name 			/*Third dword*/
1368*5113495bSYour Name 			if (pn_ie_cnt)
1369*5113495bSYour Name 				pn_ie = (u_int8_t *)msg_word;
1370*5113495bSYour Name 
1371*5113495bSYour Name 			ol_rx_pn_ind_handler(pdev->txrx_pdev, peer_id, tid,
1372*5113495bSYour Name 				seq_num_start, seq_num_end, pn_ie_cnt, pn_ie);
1373*5113495bSYour Name 
1374*5113495bSYour Name 			break;
1375*5113495bSYour Name 		}
1376*5113495bSYour Name 		case HTT_T2H_MSG_TYPE_TX_INSPECT_IND:
1377*5113495bSYour Name 		{
1378*5113495bSYour Name 			int num_msdus;
1379*5113495bSYour Name 
1380*5113495bSYour Name 			num_msdus = HTT_TX_COMPL_IND_NUM_GET(*msg_word);
1381*5113495bSYour Name 			/*
1382*5113495bSYour Name 			 * each desc id will occupy 2 bytes.
1383*5113495bSYour Name 			 * the 4 is for htt msg header
1384*5113495bSYour Name 			 */
1385*5113495bSYour Name 			if ((num_msdus * HTT_TX_COMPL_BYTES_PER_MSDU_ID +
1386*5113495bSYour Name 				HTT_TX_COMPL_HEAD_SZ) > msg_len) {
1387*5113495bSYour Name 				qdf_print("%s: num_msdus(%d) is invalid,"
1388*5113495bSYour Name 					"adf_nbuf_len = %d\n",
1389*5113495bSYour Name 					__FUNCTION__,
1390*5113495bSYour Name 					num_msdus,
1391*5113495bSYour Name 					msg_len);
1392*5113495bSYour Name 				break;
1393*5113495bSYour Name 			}
1394*5113495bSYour Name 
1395*5113495bSYour Name 			if (num_msdus & 0x1) {
1396*5113495bSYour Name 				struct htt_tx_compl_ind_base *compl =
1397*5113495bSYour Name 					(void *)msg_word;
1398*5113495bSYour Name 
1399*5113495bSYour Name 				/*
1400*5113495bSYour Name 				 * Host CPU endianness can be different
1401*5113495bSYour Name 				 * from FW CPU. This * can result in
1402*5113495bSYour Name 				 * even and odd MSDU IDs being switched.
1403*5113495bSYour Name 				 * If this happens, copy the switched
1404*5113495bSYour Name 				 * final odd MSDU ID from location
1405*5113495bSYour Name 				 * payload[size], to location
1406*5113495bSYour Name 				 * payload[size-1], where the message
1407*5113495bSYour Name 				 * handler function expects to find it
1408*5113495bSYour Name 				 */
1409*5113495bSYour Name 				if (compl->payload[num_msdus] !=
1410*5113495bSYour Name 				    HTT_TX_COMPL_INV_MSDU_ID) {
1411*5113495bSYour Name 					compl->payload[num_msdus - 1] =
1412*5113495bSYour Name 					compl->payload[num_msdus];
1413*5113495bSYour Name 				}
1414*5113495bSYour Name 			}
1415*5113495bSYour Name 			ol_tx_inspect_handler(pdev->txrx_pdev,
1416*5113495bSYour Name 					      num_msdus, msg_word + 1);
1417*5113495bSYour Name 			break;
1418*5113495bSYour Name 		}
1419*5113495bSYour Name 		case HTT_T2H_MSG_TYPE_RX_IN_ORD_PADDR_IND:
1420*5113495bSYour Name 		{
1421*5113495bSYour Name 			u_int16_t peer_id;
1422*5113495bSYour Name 			u_int8_t tid;
1423*5113495bSYour Name 			u_int8_t offload_ind, frag_ind;
1424*5113495bSYour Name 
1425*5113495bSYour Name 			if (qdf_unlikely(
1426*5113495bSYour Name 				  !pdev->cfg.is_full_reorder_offload)) {
1427*5113495bSYour Name 				qdf_print("HTT_T2H_MSG_TYPE_RX_IN_ORD_PADDR_IND not supported when full reorder offload is disabled\n");
1428*5113495bSYour Name 				break;
1429*5113495bSYour Name 			}
1430*5113495bSYour Name 
1431*5113495bSYour Name 			if (qdf_unlikely(
1432*5113495bSYour Name 				pdev->txrx_pdev->cfg.is_high_latency)) {
1433*5113495bSYour Name 				qdf_print("HTT_T2H_MSG_TYPE_RX_IN_ORD_PADDR_IND not supported on high latency\n");
1434*5113495bSYour Name 				break;
1435*5113495bSYour Name 			}
1436*5113495bSYour Name 
1437*5113495bSYour Name 			peer_id = HTT_RX_IN_ORD_PADDR_IND_PEER_ID_GET(
1438*5113495bSYour Name 							*msg_word);
1439*5113495bSYour Name 			tid = HTT_RX_IN_ORD_PADDR_IND_EXT_TID_GET(
1440*5113495bSYour Name 							*msg_word);
1441*5113495bSYour Name 			offload_ind =
1442*5113495bSYour Name 				HTT_RX_IN_ORD_PADDR_IND_OFFLOAD_GET(
1443*5113495bSYour Name 							*msg_word);
1444*5113495bSYour Name 			frag_ind = HTT_RX_IN_ORD_PADDR_IND_FRAG_GET(
1445*5113495bSYour Name 							*msg_word);
1446*5113495bSYour Name 
1447*5113495bSYour Name 			if (qdf_unlikely(frag_ind)) {
1448*5113495bSYour Name 				ol_rx_frag_indication_handler(
1449*5113495bSYour Name 				pdev->txrx_pdev, htt_t2h_msg, peer_id,
1450*5113495bSYour Name 				tid);
1451*5113495bSYour Name 				break;
1452*5113495bSYour Name 			}
1453*5113495bSYour Name 
1454*5113495bSYour Name 			ol_rx_in_order_indication_handler(
1455*5113495bSYour Name 					pdev->txrx_pdev, htt_t2h_msg,
1456*5113495bSYour Name 					peer_id, tid, offload_ind);
1457*5113495bSYour Name 			break;
1458*5113495bSYour Name 		}
1459*5113495bSYour Name 		default:
1460*5113495bSYour Name 			htt_t2h_lp_msg_handler(context, htt_t2h_msg, false);
1461*5113495bSYour Name 			break;
1462*5113495bSYour Name 		};
1463*5113495bSYour Name 
1464*5113495bSYour Name 		/* Re-initialize the indication buffer */
1465*5113495bSYour Name 		HTT_T2H_MSG_BUF_REINIT(htt_t2h_msg, pdev->osdev);
1466*5113495bSYour Name 		qdf_nbuf_set_pktlen(htt_t2h_msg, 0);
1467*5113495bSYour Name 	}
1468*5113495bSYour Name }
1469*5113495bSYour Name #endif /* WLAN_FEATURE_FASTPATH */
1470*5113495bSYour Name 
1471*5113495bSYour Name /*--- target->host HTT message Info Element access methods ------------------*/
1472*5113495bSYour Name 
1473*5113495bSYour Name /*--- tx completion message ---*/
1474*5113495bSYour Name 
htt_tx_compl_desc_id(void * iterator,int num)1475*5113495bSYour Name uint16_t htt_tx_compl_desc_id(void *iterator, int num)
1476*5113495bSYour Name {
1477*5113495bSYour Name 	/*
1478*5113495bSYour Name 	 * The MSDU IDs are packed , 2 per 32-bit word.
1479*5113495bSYour Name 	 * Iterate on them as an array of 16-bit elements.
1480*5113495bSYour Name 	 * This will work fine if the host endianness matches
1481*5113495bSYour Name 	 * the target endianness.
1482*5113495bSYour Name 	 * If the host endianness is opposite of the target's,
1483*5113495bSYour Name 	 * this iterator will produce descriptor IDs in a different
1484*5113495bSYour Name 	 * order than the target inserted them into the message -
1485*5113495bSYour Name 	 * if the target puts in [0, 1, 2, 3, ...] the host will
1486*5113495bSYour Name 	 * put out [1, 0, 3, 2, ...].
1487*5113495bSYour Name 	 * This is fine, except for the last ID if there are an
1488*5113495bSYour Name 	 * odd number of IDs.  But the TX_COMPL_IND handling code
1489*5113495bSYour Name 	 * in the htt_t2h_msg_handler already added a duplicate
1490*5113495bSYour Name 	 * of the final ID, if there were an odd number of IDs,
1491*5113495bSYour Name 	 * so this function can safely treat the IDs as an array
1492*5113495bSYour Name 	 * of 16-bit elements.
1493*5113495bSYour Name 	 */
1494*5113495bSYour Name 	return *(((uint16_t *) iterator) + num);
1495*5113495bSYour Name }
1496*5113495bSYour Name 
1497*5113495bSYour Name /*--- rx indication message ---*/
1498*5113495bSYour Name 
htt_rx_ind_flush(htt_pdev_handle pdev,qdf_nbuf_t rx_ind_msg)1499*5113495bSYour Name int htt_rx_ind_flush(htt_pdev_handle pdev, qdf_nbuf_t rx_ind_msg)
1500*5113495bSYour Name {
1501*5113495bSYour Name 	uint32_t *msg_word;
1502*5113495bSYour Name 
1503*5113495bSYour Name 	msg_word = (uint32_t *) qdf_nbuf_data(rx_ind_msg);
1504*5113495bSYour Name 	return HTT_RX_IND_FLUSH_VALID_GET(*msg_word);
1505*5113495bSYour Name }
1506*5113495bSYour Name 
1507*5113495bSYour Name void
htt_rx_ind_flush_seq_num_range(htt_pdev_handle pdev,qdf_nbuf_t rx_ind_msg,unsigned int * seq_num_start,unsigned int * seq_num_end)1508*5113495bSYour Name htt_rx_ind_flush_seq_num_range(htt_pdev_handle pdev,
1509*5113495bSYour Name 			       qdf_nbuf_t rx_ind_msg,
1510*5113495bSYour Name 			       unsigned int *seq_num_start,
1511*5113495bSYour Name 			       unsigned int *seq_num_end)
1512*5113495bSYour Name {
1513*5113495bSYour Name 	uint32_t *msg_word;
1514*5113495bSYour Name 
1515*5113495bSYour Name 	msg_word = (uint32_t *) qdf_nbuf_data(rx_ind_msg);
1516*5113495bSYour Name 	msg_word++;
1517*5113495bSYour Name 	*seq_num_start = HTT_RX_IND_FLUSH_SEQ_NUM_START_GET(*msg_word);
1518*5113495bSYour Name 	*seq_num_end = HTT_RX_IND_FLUSH_SEQ_NUM_END_GET(*msg_word);
1519*5113495bSYour Name }
1520*5113495bSYour Name 
htt_rx_ind_release(htt_pdev_handle pdev,qdf_nbuf_t rx_ind_msg)1521*5113495bSYour Name int htt_rx_ind_release(htt_pdev_handle pdev, qdf_nbuf_t rx_ind_msg)
1522*5113495bSYour Name {
1523*5113495bSYour Name 	uint32_t *msg_word;
1524*5113495bSYour Name 
1525*5113495bSYour Name 	msg_word = (uint32_t *) qdf_nbuf_data(rx_ind_msg);
1526*5113495bSYour Name 	return HTT_RX_IND_REL_VALID_GET(*msg_word);
1527*5113495bSYour Name }
1528*5113495bSYour Name 
1529*5113495bSYour Name void
htt_rx_ind_release_seq_num_range(htt_pdev_handle pdev,qdf_nbuf_t rx_ind_msg,unsigned int * seq_num_start,unsigned int * seq_num_end)1530*5113495bSYour Name htt_rx_ind_release_seq_num_range(htt_pdev_handle pdev,
1531*5113495bSYour Name 				 qdf_nbuf_t rx_ind_msg,
1532*5113495bSYour Name 				 unsigned int *seq_num_start,
1533*5113495bSYour Name 				 unsigned int *seq_num_end)
1534*5113495bSYour Name {
1535*5113495bSYour Name 	uint32_t *msg_word;
1536*5113495bSYour Name 
1537*5113495bSYour Name 	msg_word = (uint32_t *) qdf_nbuf_data(rx_ind_msg);
1538*5113495bSYour Name 	msg_word++;
1539*5113495bSYour Name 	*seq_num_start = HTT_RX_IND_REL_SEQ_NUM_START_GET(*msg_word);
1540*5113495bSYour Name 	*seq_num_end = HTT_RX_IND_REL_SEQ_NUM_END_GET(*msg_word);
1541*5113495bSYour Name }
1542*5113495bSYour Name 
1543*5113495bSYour Name void
htt_rx_ind_mpdu_range_info(struct htt_pdev_t * pdev,qdf_nbuf_t rx_ind_msg,int mpdu_range_num,enum htt_rx_status * status,int * mpdu_count)1544*5113495bSYour Name htt_rx_ind_mpdu_range_info(struct htt_pdev_t *pdev,
1545*5113495bSYour Name 			   qdf_nbuf_t rx_ind_msg,
1546*5113495bSYour Name 			   int mpdu_range_num,
1547*5113495bSYour Name 			   enum htt_rx_status *status, int *mpdu_count)
1548*5113495bSYour Name {
1549*5113495bSYour Name 	uint32_t *msg_word;
1550*5113495bSYour Name 
1551*5113495bSYour Name 	msg_word = (uint32_t *) qdf_nbuf_data(rx_ind_msg);
1552*5113495bSYour Name 	msg_word += pdev->rx_mpdu_range_offset_words + mpdu_range_num;
1553*5113495bSYour Name 	*status = HTT_RX_IND_MPDU_STATUS_GET(*msg_word);
1554*5113495bSYour Name 	*mpdu_count = HTT_RX_IND_MPDU_COUNT_GET(*msg_word);
1555*5113495bSYour Name }
1556*5113495bSYour Name 
1557*5113495bSYour Name /**
1558*5113495bSYour Name  * htt_rx_ind_rssi_dbm() - Return the RSSI provided in a rx indication message.
1559*5113495bSYour Name  *
1560*5113495bSYour Name  * @pdev:       the HTT instance the rx data was received on
1561*5113495bSYour Name  * @rx_ind_msg: the netbuf containing the rx indication message
1562*5113495bSYour Name  *
1563*5113495bSYour Name  * Return the RSSI from an rx indication message, in dBm units.
1564*5113495bSYour Name  *
1565*5113495bSYour Name  * Return: RSSI in dBm, or HTT_INVALID_RSSI
1566*5113495bSYour Name  */
htt_rx_ind_rssi_dbm(htt_pdev_handle pdev,qdf_nbuf_t rx_ind_msg)1567*5113495bSYour Name int16_t htt_rx_ind_rssi_dbm(htt_pdev_handle pdev, qdf_nbuf_t rx_ind_msg)
1568*5113495bSYour Name {
1569*5113495bSYour Name 	int8_t rssi;
1570*5113495bSYour Name 	uint32_t *msg_word;
1571*5113495bSYour Name 
1572*5113495bSYour Name 	msg_word = (uint32_t *)
1573*5113495bSYour Name 		   (qdf_nbuf_data(rx_ind_msg) +
1574*5113495bSYour Name 		    HTT_RX_IND_FW_RX_PPDU_DESC_BYTE_OFFSET);
1575*5113495bSYour Name 
1576*5113495bSYour Name 	/* check if the RX_IND message contains valid rx PPDU start info */
1577*5113495bSYour Name 	if (!HTT_RX_IND_START_VALID_GET(*msg_word))
1578*5113495bSYour Name 		return HTT_RSSI_INVALID;
1579*5113495bSYour Name 
1580*5113495bSYour Name 	rssi = HTT_RX_IND_RSSI_CMB_GET(*msg_word);
1581*5113495bSYour Name 	return (HTT_TGT_RSSI_INVALID == rssi) ?
1582*5113495bSYour Name 	       HTT_RSSI_INVALID : rssi;
1583*5113495bSYour Name }
1584*5113495bSYour Name 
1585*5113495bSYour Name /**
1586*5113495bSYour Name  * htt_rx_ind_rssi_dbm_chain() - Return the RSSI for a chain provided in a rx
1587*5113495bSYour Name  *              indication message.
1588*5113495bSYour Name  * @pdev:       the HTT instance the rx data was received on
1589*5113495bSYour Name  * @rx_ind_msg: the netbuf containing the rx indication message
1590*5113495bSYour Name  * @chain:      the index of the chain (0-4)
1591*5113495bSYour Name  *
1592*5113495bSYour Name  * Return the RSSI for a chain from an rx indication message, in dBm units.
1593*5113495bSYour Name  *
1594*5113495bSYour Name  * Return: RSSI, or HTT_INVALID_RSSI
1595*5113495bSYour Name  */
1596*5113495bSYour Name int16_t
htt_rx_ind_rssi_dbm_chain(htt_pdev_handle pdev,qdf_nbuf_t rx_ind_msg,int8_t chain)1597*5113495bSYour Name htt_rx_ind_rssi_dbm_chain(htt_pdev_handle pdev, qdf_nbuf_t rx_ind_msg,
1598*5113495bSYour Name 		      int8_t chain)
1599*5113495bSYour Name {
1600*5113495bSYour Name 	int8_t rssi;
1601*5113495bSYour Name 	uint32_t *msg_word;
1602*5113495bSYour Name 
1603*5113495bSYour Name 	if (chain < 0 || chain > 3)
1604*5113495bSYour Name 		return HTT_RSSI_INVALID;
1605*5113495bSYour Name 
1606*5113495bSYour Name 	msg_word = (uint32_t *)
1607*5113495bSYour Name 		(qdf_nbuf_data(rx_ind_msg) +
1608*5113495bSYour Name 		 HTT_RX_IND_FW_RX_PPDU_DESC_BYTE_OFFSET);
1609*5113495bSYour Name 
1610*5113495bSYour Name 	/* check if the RX_IND message contains valid rx PPDU start info */
1611*5113495bSYour Name 	if (!HTT_RX_IND_START_VALID_GET(*msg_word))
1612*5113495bSYour Name 		return HTT_RSSI_INVALID;
1613*5113495bSYour Name 
1614*5113495bSYour Name 	msg_word += 1 + chain;
1615*5113495bSYour Name 
1616*5113495bSYour Name 	rssi = HTT_RX_IND_RSSI_PRI20_GET(*msg_word);
1617*5113495bSYour Name 	return (HTT_TGT_RSSI_INVALID == rssi) ?
1618*5113495bSYour Name 		HTT_RSSI_INVALID :
1619*5113495bSYour Name 		rssi;
1620*5113495bSYour Name }
1621*5113495bSYour Name 
1622*5113495bSYour Name /**
1623*5113495bSYour Name  * htt_rx_ind_legacy_rate() - Return the data rate
1624*5113495bSYour Name  * @pdev:        the HTT instance the rx data was received on
1625*5113495bSYour Name  * @rx_ind_msg:  the netbuf containing the rx indication message
1626*5113495bSYour Name  * @legacy_rate: (output) the data rate
1627*5113495bSYour Name  *      The legacy_rate parameter's value depends on the
1628*5113495bSYour Name  *      legacy_rate_sel value.
1629*5113495bSYour Name  *      If legacy_rate_sel is 0:
1630*5113495bSYour Name  *              0x8: OFDM 48 Mbps
1631*5113495bSYour Name  *              0x9: OFDM 24 Mbps
1632*5113495bSYour Name  *              0xA: OFDM 12 Mbps
1633*5113495bSYour Name  *              0xB: OFDM 6 Mbps
1634*5113495bSYour Name  *              0xC: OFDM 54 Mbps
1635*5113495bSYour Name  *              0xD: OFDM 36 Mbps
1636*5113495bSYour Name  *              0xE: OFDM 18 Mbps
1637*5113495bSYour Name  *              0xF: OFDM 9 Mbps
1638*5113495bSYour Name  *      If legacy_rate_sel is 1:
1639*5113495bSYour Name  *              0x8: CCK 11 Mbps long preamble
1640*5113495bSYour Name  *              0x9: CCK 5.5 Mbps long preamble
1641*5113495bSYour Name  *              0xA: CCK 2 Mbps long preamble
1642*5113495bSYour Name  *              0xB: CCK 1 Mbps long preamble
1643*5113495bSYour Name  *              0xC: CCK 11 Mbps short preamble
1644*5113495bSYour Name  *              0xD: CCK 5.5 Mbps short preamble
1645*5113495bSYour Name  *              0xE: CCK 2 Mbps short preamble
1646*5113495bSYour Name  *      -1 on error.
1647*5113495bSYour Name  * @legacy_rate_sel: (output) 0 to indicate OFDM, 1 to indicate CCK.
1648*5113495bSYour Name  *      -1 on error.
1649*5113495bSYour Name  *
1650*5113495bSYour Name  * Return the data rate provided in a rx indication message.
1651*5113495bSYour Name  */
1652*5113495bSYour Name void
htt_rx_ind_legacy_rate(htt_pdev_handle pdev,qdf_nbuf_t rx_ind_msg,uint8_t * legacy_rate,uint8_t * legacy_rate_sel)1653*5113495bSYour Name htt_rx_ind_legacy_rate(htt_pdev_handle pdev, qdf_nbuf_t rx_ind_msg,
1654*5113495bSYour Name 		       uint8_t *legacy_rate, uint8_t *legacy_rate_sel)
1655*5113495bSYour Name {
1656*5113495bSYour Name 	uint32_t *msg_word;
1657*5113495bSYour Name 
1658*5113495bSYour Name 	msg_word = (uint32_t *)
1659*5113495bSYour Name 		(qdf_nbuf_data(rx_ind_msg) +
1660*5113495bSYour Name 		 HTT_RX_IND_FW_RX_PPDU_DESC_BYTE_OFFSET);
1661*5113495bSYour Name 
1662*5113495bSYour Name 	/* check if the RX_IND message contains valid rx PPDU start info */
1663*5113495bSYour Name 	if (!HTT_RX_IND_START_VALID_GET(*msg_word)) {
1664*5113495bSYour Name 		*legacy_rate = -1;
1665*5113495bSYour Name 		*legacy_rate_sel = -1;
1666*5113495bSYour Name 		return;
1667*5113495bSYour Name 	}
1668*5113495bSYour Name 
1669*5113495bSYour Name 	*legacy_rate = HTT_RX_IND_LEGACY_RATE_GET(*msg_word);
1670*5113495bSYour Name 	*legacy_rate_sel = HTT_RX_IND_LEGACY_RATE_SEL_GET(*msg_word);
1671*5113495bSYour Name }
1672*5113495bSYour Name 
1673*5113495bSYour Name /**
1674*5113495bSYour Name  * htt_rx_ind_timestamp() - Return the timestamp
1675*5113495bSYour Name  * @pdev:                  the HTT instance the rx data was received on
1676*5113495bSYour Name  * @rx_ind_msg:            the netbuf containing the rx indication message
1677*5113495bSYour Name  * @timestamp_microsec:    (output) the timestamp to microsecond resolution.
1678*5113495bSYour Name  *                         -1 on error.
1679*5113495bSYour Name  * @timestamp_submicrosec: the submicrosecond portion of the
1680*5113495bSYour Name  *                         timestamp. -1 on error.
1681*5113495bSYour Name  *
1682*5113495bSYour Name  * Return the timestamp provided in a rx indication message.
1683*5113495bSYour Name  */
1684*5113495bSYour Name void
htt_rx_ind_timestamp(htt_pdev_handle pdev,qdf_nbuf_t rx_ind_msg,uint32_t * timestamp_microsec,uint8_t * timestamp_submicrosec)1685*5113495bSYour Name htt_rx_ind_timestamp(htt_pdev_handle pdev, qdf_nbuf_t rx_ind_msg,
1686*5113495bSYour Name 		     uint32_t *timestamp_microsec,
1687*5113495bSYour Name 		     uint8_t *timestamp_submicrosec)
1688*5113495bSYour Name {
1689*5113495bSYour Name 	uint32_t *msg_word;
1690*5113495bSYour Name 
1691*5113495bSYour Name 	msg_word = (uint32_t *)
1692*5113495bSYour Name 		(qdf_nbuf_data(rx_ind_msg) +
1693*5113495bSYour Name 		 HTT_RX_IND_FW_RX_PPDU_DESC_BYTE_OFFSET);
1694*5113495bSYour Name 
1695*5113495bSYour Name 	/* check if the RX_IND message contains valid rx PPDU start info */
1696*5113495bSYour Name 	if (!HTT_RX_IND_END_VALID_GET(*msg_word)) {
1697*5113495bSYour Name 		*timestamp_microsec = -1;
1698*5113495bSYour Name 		*timestamp_submicrosec = -1;
1699*5113495bSYour Name 		return;
1700*5113495bSYour Name 	}
1701*5113495bSYour Name 
1702*5113495bSYour Name 	*timestamp_microsec = *(msg_word + 6);
1703*5113495bSYour Name 	*timestamp_submicrosec =
1704*5113495bSYour Name 		HTT_RX_IND_TIMESTAMP_SUBMICROSEC_GET(*msg_word);
1705*5113495bSYour Name }
1706*5113495bSYour Name 
1707*5113495bSYour Name #define INVALID_TSF -1
1708*5113495bSYour Name /**
1709*5113495bSYour Name  * htt_rx_ind_tsf32() - Return the TSF timestamp
1710*5113495bSYour Name  * @pdev:       the HTT instance the rx data was received on
1711*5113495bSYour Name  * @rx_ind_msg: the netbuf containing the rx indication message
1712*5113495bSYour Name  *
1713*5113495bSYour Name  * Return the TSF timestamp provided in a rx indication message.
1714*5113495bSYour Name  *
1715*5113495bSYour Name  * Return: TSF timestamp
1716*5113495bSYour Name  */
1717*5113495bSYour Name uint32_t
htt_rx_ind_tsf32(htt_pdev_handle pdev,qdf_nbuf_t rx_ind_msg)1718*5113495bSYour Name htt_rx_ind_tsf32(htt_pdev_handle pdev, qdf_nbuf_t rx_ind_msg)
1719*5113495bSYour Name {
1720*5113495bSYour Name 	uint32_t *msg_word;
1721*5113495bSYour Name 
1722*5113495bSYour Name 	msg_word = (uint32_t *)
1723*5113495bSYour Name 		(qdf_nbuf_data(rx_ind_msg) +
1724*5113495bSYour Name 		 HTT_RX_IND_FW_RX_PPDU_DESC_BYTE_OFFSET);
1725*5113495bSYour Name 
1726*5113495bSYour Name 	/* check if the RX_IND message contains valid rx PPDU start info */
1727*5113495bSYour Name 	if (!HTT_RX_IND_END_VALID_GET(*msg_word))
1728*5113495bSYour Name 		return INVALID_TSF;
1729*5113495bSYour Name 
1730*5113495bSYour Name 	return *(msg_word + 5);
1731*5113495bSYour Name }
1732*5113495bSYour Name 
1733*5113495bSYour Name /**
1734*5113495bSYour Name  * htt_rx_ind_ext_tid() - Return the extended traffic ID provided in a rx
1735*5113495bSYour Name  *			  indication message.
1736*5113495bSYour Name  * @pdev:       the HTT instance the rx data was received on
1737*5113495bSYour Name  * @rx_ind_msg: the netbuf containing the rx indication message
1738*5113495bSYour Name  *
1739*5113495bSYour Name  * Return the extended traffic ID in a rx indication message.
1740*5113495bSYour Name  *
1741*5113495bSYour Name  * Return: Extended TID
1742*5113495bSYour Name  */
1743*5113495bSYour Name uint8_t
htt_rx_ind_ext_tid(htt_pdev_handle pdev,qdf_nbuf_t rx_ind_msg)1744*5113495bSYour Name htt_rx_ind_ext_tid(htt_pdev_handle pdev, qdf_nbuf_t rx_ind_msg)
1745*5113495bSYour Name {
1746*5113495bSYour Name 	uint32_t *msg_word;
1747*5113495bSYour Name 
1748*5113495bSYour Name 	msg_word = (uint32_t *)
1749*5113495bSYour Name 		(qdf_nbuf_data(rx_ind_msg));
1750*5113495bSYour Name 
1751*5113495bSYour Name 	return HTT_RX_IND_EXT_TID_GET(*msg_word);
1752*5113495bSYour Name }
1753*5113495bSYour Name 
1754*5113495bSYour Name /*--- stats confirmation message ---*/
1755*5113495bSYour Name 
1756*5113495bSYour Name void
htt_t2h_dbg_stats_hdr_parse(uint8_t * stats_info_list,enum htt_dbg_stats_type * type,enum htt_dbg_stats_status * status,int * length,uint8_t ** stats_data)1757*5113495bSYour Name htt_t2h_dbg_stats_hdr_parse(uint8_t *stats_info_list,
1758*5113495bSYour Name 			    enum htt_dbg_stats_type *type,
1759*5113495bSYour Name 			    enum htt_dbg_stats_status *status,
1760*5113495bSYour Name 			    int *length, uint8_t **stats_data)
1761*5113495bSYour Name {
1762*5113495bSYour Name 	uint32_t *msg_word = (uint32_t *) stats_info_list;
1763*5113495bSYour Name 	*type = HTT_T2H_STATS_CONF_TLV_TYPE_GET(*msg_word);
1764*5113495bSYour Name 	*status = HTT_T2H_STATS_CONF_TLV_STATUS_GET(*msg_word);
1765*5113495bSYour Name 	*length = HTT_T2H_STATS_CONF_TLV_HDR_SIZE +     /* header length */
1766*5113495bSYour Name 		HTT_T2H_STATS_CONF_TLV_LENGTH_GET(*msg_word); /* data len */
1767*5113495bSYour Name 	*stats_data = stats_info_list + HTT_T2H_STATS_CONF_TLV_HDR_SIZE;
1768*5113495bSYour Name }
1769*5113495bSYour Name 
1770*5113495bSYour Name void
htt_rx_frag_ind_flush_seq_num_range(htt_pdev_handle pdev,qdf_nbuf_t rx_frag_ind_msg,uint16_t * seq_num_start,uint16_t * seq_num_end)1771*5113495bSYour Name htt_rx_frag_ind_flush_seq_num_range(htt_pdev_handle pdev,
1772*5113495bSYour Name 				    qdf_nbuf_t rx_frag_ind_msg,
1773*5113495bSYour Name 				    uint16_t *seq_num_start, uint16_t *seq_num_end)
1774*5113495bSYour Name {
1775*5113495bSYour Name 	uint32_t *msg_word;
1776*5113495bSYour Name 
1777*5113495bSYour Name 	msg_word = (uint32_t *) qdf_nbuf_data(rx_frag_ind_msg);
1778*5113495bSYour Name 	msg_word++;
1779*5113495bSYour Name 	*seq_num_start = HTT_RX_FRAG_IND_FLUSH_SEQ_NUM_START_GET(*msg_word);
1780*5113495bSYour Name 	*seq_num_end = HTT_RX_FRAG_IND_FLUSH_SEQ_NUM_END_GET(*msg_word);
1781*5113495bSYour Name }
1782