1 /*
2  * Copyright (c) 2011-2021 The Linux Foundation. All rights reserved.
3  * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.
4  *
5  * Permission to use, copy, modify, and/or distribute this software for
6  * any purpose with or without fee is hereby granted, provided that the
7  * above copyright notice and this permission notice appear in all
8  * copies.
9  *
10  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
11  * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
12  * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
13  * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
14  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
15  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
16  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17  * PERFORMANCE OF THIS SOFTWARE.
18  */
19 
20 /**
21  * @file htt_h2t.c
22  * @brief Provide functions to send host->target HTT messages.
23  * @details
24  *  This file contains functions related to host->target HTT messages.
25  *  There are a couple aspects of this host->target messaging:
26  *  1.  This file contains the function that is called by HTC when
27  *      a host->target send completes.
28  *      This send-completion callback is primarily relevant to HL,
29  *      to invoke the download scheduler to set up a new download,
30  *      and optionally free the tx frame whose download is completed.
31  *      For both HL and LL, this completion callback frees up the
32  *      HTC_PACKET object used to specify the download.
33  *  2.  This file contains functions for creating messages to send
34  *      from the host to the target.
35  */
36 
37 #include <qdf_mem.h>         /* qdf_mem_copy */
38 #include <qdf_nbuf.h>           /* qdf_nbuf_map_single */
39 #include <htc_api.h>            /* HTC_PACKET */
40 #include <htc.h>                /* HTC_HDR_ALIGNMENT_PADDING */
41 #include <htt.h>                /* HTT host->target msg defs */
42 #include <wdi_ipa.h>            /* HTT host->target WDI IPA msg defs */
43 #include <ol_txrx_htt_api.h>    /* ol_tx_completion_handler, htt_tx_status */
44 #include <ol_htt_tx_api.h>
45 #include <ol_txrx_types.h>
46 #include <ol_tx_send.h>
47 #include <ol_htt_rx_api.h>
48 
49 #include <htt_internal.h>
50 #include <wlan_policy_mgr_api.h>
51 
52 #define HTT_MSG_BUF_SIZE(msg_bytes) \
53 	((msg_bytes) + HTC_HEADER_LEN + HTC_HDR_ALIGNMENT_PADDING)
54 
55 #ifndef container_of
56 #define container_of(ptr, type, member) \
57 	((type *)((char *)(ptr) - (char *)(&((type *)0)->member)))
58 #endif
59 
60 #ifdef ATH_11AC_TXCOMPACT
61 #define HTT_SEND_HTC_PKT(pdev, pkt)                              \
62 do {                                                             \
63 	if (htc_send_pkt(pdev->htc_pdev, &pkt->htc_pkt) ==       \
64 	    QDF_STATUS_SUCCESS) {                                \
65 		htt_htc_misc_pkt_list_add(pdev, pkt);            \
66 	} else {                                                 \
67 		qdf_nbuf_free((qdf_nbuf_t)(pkt->htc_pkt.pNetBufContext));   \
68 		htt_htc_pkt_free(pdev, pkt);                     \
69 	}                                                        \
70 } while (0)
71 #else
72 #define HTT_SEND_HTC_PKT(pdev, ppkt) \
73 	htc_send_pkt(pdev->htc_pdev, &pkt->htc_pkt);
74 #endif
75 
76 
77 static void
htt_h2t_send_complete_free_netbuf(void * pdev,QDF_STATUS status,qdf_nbuf_t netbuf,uint16_t msdu_id)78 htt_h2t_send_complete_free_netbuf(void *pdev, QDF_STATUS status,
79 				  qdf_nbuf_t netbuf, uint16_t msdu_id)
80 {
81 	qdf_nbuf_free(netbuf);
82 }
83 
84 #ifndef QCN7605_SUPPORT
htt_t2h_adjust_bus_target_delta(struct htt_pdev_t * pdev)85 static void htt_t2h_adjust_bus_target_delta(struct htt_pdev_t *pdev)
86 {
87 	int32_t credit_delta;
88 
89 	if (pdev->cfg.is_high_latency && !pdev->cfg.default_tx_comp_req) {
90 		HTT_TX_MUTEX_ACQUIRE(&pdev->credit_mutex);
91 		qdf_atomic_add(1, &pdev->htt_tx_credit.bus_delta);
92 		credit_delta = htt_tx_credit_update(pdev);
93 		HTT_TX_MUTEX_RELEASE(&pdev->credit_mutex);
94 
95 		if (credit_delta)
96 			ol_tx_credit_completion_handler(pdev->txrx_pdev,
97 							credit_delta);
98 	}
99 }
100 #else
htt_t2h_adjust_bus_target_delta(struct htt_pdev_t * pdev)101 static void htt_t2h_adjust_bus_target_delta(struct htt_pdev_t *pdev)
102 {
103 	/* UNPAUSE OS Q */
104 	ol_tx_flow_ct_unpause_os_q(pdev->txrx_pdev);
105 }
106 #endif
107 
htt_h2t_send_complete(void * context,HTC_PACKET * htc_pkt)108 void htt_h2t_send_complete(void *context, HTC_PACKET *htc_pkt)
109 {
110 	void (*send_complete_part2)(void *pdev, QDF_STATUS status,
111 				    qdf_nbuf_t msdu, uint16_t msdu_id);
112 	struct htt_pdev_t *pdev = (struct htt_pdev_t *)context;
113 	struct htt_htc_pkt *htt_pkt;
114 	qdf_nbuf_t netbuf;
115 
116 	send_complete_part2 = htc_pkt->pPktContext;
117 
118 	htt_pkt = container_of(htc_pkt, struct htt_htc_pkt, htc_pkt);
119 
120 	/* process (free or keep) the netbuf that held the message */
121 	netbuf = (qdf_nbuf_t) htc_pkt->pNetBufContext;
122 	if (send_complete_part2) {
123 		send_complete_part2(htt_pkt->pdev_ctxt, htc_pkt->Status, netbuf,
124 				    htt_pkt->msdu_id);
125 	}
126 
127 	htt_t2h_adjust_bus_target_delta(pdev);
128 	/* free the htt_htc_pkt / HTC_PACKET object */
129 	htt_htc_pkt_free(pdev, htt_pkt);
130 }
131 
htt_h2t_full(void * context,HTC_PACKET * pkt)132 enum htc_send_full_action htt_h2t_full(void *context, HTC_PACKET *pkt)
133 {
134 /* FIX THIS */
135 	return HTC_SEND_FULL_KEEP;
136 }
137 
138 #if defined(HELIUMPLUS)
htt_h2t_frag_desc_bank_cfg_msg(struct htt_pdev_t * pdev)139 QDF_STATUS htt_h2t_frag_desc_bank_cfg_msg(struct htt_pdev_t *pdev)
140 {
141 	QDF_STATUS rc = QDF_STATUS_SUCCESS;
142 
143 	struct htt_htc_pkt *pkt;
144 	qdf_nbuf_t msg;
145 	u_int32_t *msg_word;
146 	struct htt_tx_frag_desc_bank_cfg_t *bank_cfg;
147 
148 	pkt = htt_htc_pkt_alloc(pdev);
149 	if (!pkt)
150 		return QDF_STATUS_E_FAILURE; /* failure */
151 
152 	/* show that this is not a tx frame download
153 	 * (not required, but helpful)
154 	 */
155 	pkt->msdu_id = HTT_TX_COMPL_INV_MSDU_ID;
156 	pkt->pdev_ctxt = NULL; /* not used during send-done callback */
157 
158 	msg = qdf_nbuf_alloc(
159 		pdev->osdev,
160 		HTT_MSG_BUF_SIZE(sizeof(struct htt_tx_frag_desc_bank_cfg_t)),
161 		/* reserve room for the HTC header */
162 		HTC_HEADER_LEN + HTC_HDR_ALIGNMENT_PADDING, 4, true);
163 	if (!msg) {
164 		htt_htc_pkt_free(pdev, pkt);
165 		return QDF_STATUS_E_FAILURE; /* failure */
166 	}
167 
168 	/*
169 	 * Set the length of the message.
170 	 * The contribution from the HTC_HDR_ALIGNMENT_PADDING is added
171 	 * separately during the below call to adf_nbuf_push_head.
172 	 * The contribution from the HTC header is added separately inside HTC.
173 	 */
174 	qdf_nbuf_put_tail(msg, sizeof(struct htt_tx_frag_desc_bank_cfg_t));
175 
176 	/* fill in the message contents */
177 	msg_word = (u_int32_t *) qdf_nbuf_data(msg);
178 
179 	memset(msg_word, 0, sizeof(struct htt_tx_frag_desc_bank_cfg_t));
180 	/* rewind beyond alignment pad to get to the HTC header reserved area */
181 	qdf_nbuf_push_head(msg, HTC_HDR_ALIGNMENT_PADDING);
182 
183 	*msg_word = 0;
184 	HTT_H2T_MSG_TYPE_SET(*msg_word, HTT_H2T_MSG_TYPE_FRAG_DESC_BANK_CFG);
185 
186 	bank_cfg = (struct htt_tx_frag_desc_bank_cfg_t *)msg_word;
187 
188 	/** @note @todo Hard coded to 0 Assuming just one pdev for now.*/
189 	HTT_H2T_FRAG_DESC_BANK_PDEVID_SET(*msg_word, 0);
190 	/** @note Hard coded to 1.*/
191 	HTT_H2T_FRAG_DESC_BANK_NUM_BANKS_SET(*msg_word, 1);
192 	HTT_H2T_FRAG_DESC_BANK_DESC_SIZE_SET(*msg_word, pdev->frag_descs.size);
193 	HTT_H2T_FRAG_DESC_BANK_SWAP_SET(*msg_word, 0);
194 
195 	/** Bank specific data structure.*/
196 #if HTT_PADDR64
197 	bank_cfg->bank_base_address[0].lo = qdf_get_lower_32_bits(
198 			pdev->frag_descs.desc_pages.dma_pages->page_p_addr);
199 	bank_cfg->bank_base_address[0].hi = qdf_get_upper_32_bits(
200 			pdev->frag_descs.desc_pages.dma_pages->page_p_addr);
201 #else /* ! HTT_PADDR64 */
202 	bank_cfg->bank_base_address[0] =
203 		pdev->frag_descs.desc_pages.dma_pages->page_p_addr;
204 #endif /* HTT_PADDR64 */
205 	/* Logical Min index */
206 	HTT_H2T_FRAG_DESC_BANK_MIN_IDX_SET(bank_cfg->bank_info[0], 0);
207 	/* Logical Max index */
208 	HTT_H2T_FRAG_DESC_BANK_MAX_IDX_SET(bank_cfg->bank_info[0],
209 					   pdev->frag_descs.pool_elems-1);
210 
211 	SET_HTC_PACKET_INFO_TX(
212 		&pkt->htc_pkt,
213 		htt_h2t_send_complete_free_netbuf,
214 		qdf_nbuf_data(msg),
215 		qdf_nbuf_len(msg),
216 		pdev->htc_tx_endpoint,
217 		HTC_TX_PACKET_TAG_RUNTIME_PUT);
218 
219 	SET_HTC_PACKET_NET_BUF_CONTEXT(&pkt->htc_pkt, msg);
220 
221 	rc = htc_send_pkt(pdev->htc_pdev, &pkt->htc_pkt);
222 #ifdef ATH_11AC_TXCOMPACT
223 	if (rc == QDF_STATUS_SUCCESS) {
224 		htt_htc_misc_pkt_list_add(pdev, pkt);
225 	} else {
226 		qdf_nbuf_free(msg);
227 		htt_htc_pkt_free(pdev, pkt);
228 	}
229 #endif
230 
231 	return rc;
232 }
233 
234 #endif /* defined(HELIUMPLUS) */
235 
htt_h2t_ver_req_msg(struct htt_pdev_t * pdev)236 QDF_STATUS htt_h2t_ver_req_msg(struct htt_pdev_t *pdev)
237 {
238 	struct htt_htc_pkt *pkt;
239 	qdf_nbuf_t msg;
240 	uint32_t *msg_word;
241 	uint32_t msg_size;
242 	uint32_t max_tx_group;
243 
244 	pkt = htt_htc_pkt_alloc(pdev);
245 	if (!pkt)
246 		return QDF_STATUS_E_FAILURE; /* failure */
247 
248 	max_tx_group = ol_tx_get_max_tx_groups_supported(pdev->txrx_pdev);
249 
250 	if (max_tx_group)
251 		msg_size = HTT_VER_REQ_BYTES +
252 			sizeof(struct htt_option_tlv_mac_tx_queue_groups_t);
253 	else
254 		msg_size = HTT_VER_REQ_BYTES;
255 
256 	/* show that this is not a tx frame download
257 	 * (not required, but helpful)
258 	 */
259 	pkt->msdu_id = HTT_TX_COMPL_INV_MSDU_ID;
260 	pkt->pdev_ctxt = NULL;  /* not used during send-done callback */
261 
262 	/* reserve room for the HTC header */
263 	msg = qdf_nbuf_alloc(pdev->osdev, HTT_MSG_BUF_SIZE(msg_size),
264 			     HTC_HEADER_LEN + HTC_HDR_ALIGNMENT_PADDING, 4,
265 			     true);
266 	if (!msg) {
267 		htt_htc_pkt_free(pdev, pkt);
268 		return QDF_STATUS_E_FAILURE; /* failure */
269 	}
270 
271 	/*
272 	 * Set the length of the message.
273 	 * The contribution from the HTC_HDR_ALIGNMENT_PADDING is added
274 	 * separately during the below call to qdf_nbuf_push_head.
275 	 * The contribution from the HTC header is added separately inside HTC.
276 	 */
277 	qdf_nbuf_put_tail(msg, msg_size);
278 
279 	/* fill in the message contents */
280 	msg_word = (uint32_t *) qdf_nbuf_data(msg);
281 
282 	/* rewind beyond alignment pad to get to the HTC header reserved area */
283 	qdf_nbuf_push_head(msg, HTC_HDR_ALIGNMENT_PADDING);
284 
285 	*msg_word = 0;
286 	HTT_H2T_MSG_TYPE_SET(*msg_word, HTT_H2T_MSG_TYPE_VERSION_REQ);
287 
288 	if (max_tx_group) {
289 		*(msg_word + 1) = 0;
290 
291 		/* Fill Group Info */
292 		HTT_OPTION_TLV_TAG_SET(*(msg_word+1),
293 				       HTT_OPTION_TLV_TAG_MAX_TX_QUEUE_GROUPS);
294 		HTT_OPTION_TLV_LENGTH_SET(*(msg_word+1),
295 			(sizeof(struct htt_option_tlv_mac_tx_queue_groups_t)/
296 			 sizeof(uint32_t)));
297 		HTT_OPTION_TLV_VALUE0_SET(*(msg_word+1), max_tx_group);
298 	}
299 
300 	SET_HTC_PACKET_INFO_TX(&pkt->htc_pkt,
301 			       htt_h2t_send_complete_free_netbuf,
302 			       qdf_nbuf_data(msg), qdf_nbuf_len(msg),
303 			       pdev->htc_tx_endpoint,
304 			       HTC_TX_PACKET_TAG_RTPM_PUT_RC);
305 
306 	SET_HTC_PACKET_NET_BUF_CONTEXT(&pkt->htc_pkt, msg);
307 	HTT_SEND_HTC_PKT(pdev, pkt);
308 
309 	ol_tx_deduct_one_credit(pdev->txrx_pdev);
310 
311 	return QDF_STATUS_SUCCESS;
312 }
313 
314 #if defined(HELIUMPLUS)
315 /**
316  * htt_h2t_rx_ring_rfs_cfg_msg_ll() - Configure receive flow steering
317  * @pdev: handle to the HTT instance
318  *
319  * Return: QDF_STATUS_SUCCESS on success
320  *         A_NO_MEMORY No memory fail
321  */
htt_h2t_rx_ring_rfs_cfg_msg_ll(struct htt_pdev_t * pdev)322 QDF_STATUS htt_h2t_rx_ring_rfs_cfg_msg_ll(struct htt_pdev_t *pdev)
323 {
324 	struct htt_htc_pkt *pkt;
325 	qdf_nbuf_t msg;
326 	uint32_t *msg_word;
327 	uint32_t  msg_local;
328 	struct cds_config_info *cds_cfg;
329 
330 	QDF_TRACE(QDF_MODULE_ID_HTT, QDF_TRACE_LEVEL_INFO_LOW,
331 		  "Receive flow steering configuration, disable gEnableFlowSteering(=0) in ini if FW does not support it\n");
332 	pkt = htt_htc_pkt_alloc(pdev);
333 	if (!pkt)
334 		return QDF_STATUS_E_NOMEM; /* failure */
335 
336 	pkt->msdu_id = HTT_TX_COMPL_INV_MSDU_ID;
337 	pkt->pdev_ctxt = NULL;  /* not used during send-done callback */
338 
339 	/* reserve room for the HTC header */
340 	msg = qdf_nbuf_alloc(pdev->osdev,
341 			     HTT_MSG_BUF_SIZE(HTT_RFS_CFG_REQ_BYTES),
342 			     HTC_HEADER_LEN + HTC_HDR_ALIGNMENT_PADDING, 4,
343 			     true);
344 	if (!msg) {
345 		htt_htc_pkt_free(pdev, pkt);
346 		return QDF_STATUS_E_NOMEM; /* failure */
347 	}
348 	/*
349 	 * Set the length of the message.
350 	 * The contribution from the HTC_HDR_ALIGNMENT_PADDING is added
351 	 * separately during the below call to qdf_nbuf_push_head.
352 	 * The contribution from the HTC header is added separately inside HTC.
353 	 */
354 	qdf_nbuf_put_tail(msg, HTT_RFS_CFG_REQ_BYTES);
355 
356 	/* fill in the message contents */
357 	msg_word = (uint32_t *) qdf_nbuf_data(msg);
358 
359 	/* rewind beyond alignment pad to get to the HTC header reserved area */
360 	qdf_nbuf_push_head(msg, HTC_HDR_ALIGNMENT_PADDING);
361 
362 	msg_local = 0;
363 	HTT_H2T_MSG_TYPE_SET(msg_local, HTT_H2T_MSG_TYPE_RFS_CONFIG);
364 	if (ol_cfg_is_flow_steering_enabled(pdev->ctrl_pdev)) {
365 		HTT_RX_RFS_CONFIG_SET(msg_local, 1);
366 		QDF_TRACE(QDF_MODULE_ID_HTT, QDF_TRACE_LEVEL_INFO_LOW,
367 			  "Enable Rx flow steering");
368 	} else {
369 	    QDF_TRACE(QDF_MODULE_ID_HTT, QDF_TRACE_LEVEL_INFO_LOW,
370 		      "Disable Rx flow steering");
371 	}
372 	cds_cfg = cds_get_ini_config();
373 	if (cds_cfg) {
374 		msg_local |= ((cds_cfg->max_msdus_per_rxinorderind & 0xff)
375 			      << 16);
376 		QDF_TRACE(QDF_MODULE_ID_HTT, QDF_TRACE_LEVEL_INFO_LOW,
377 			  "Updated maxMSDUsPerRxInd");
378 	}
379 
380 	*msg_word = msg_local;
381 	QDF_TRACE(QDF_MODULE_ID_HTT, QDF_TRACE_LEVEL_INFO_LOW,
382 		  "%s: Sending msg_word: 0x%08x",
383 		  __func__, *msg_word);
384 
385 	SET_HTC_PACKET_INFO_TX(&pkt->htc_pkt,
386 			       htt_h2t_send_complete_free_netbuf,
387 			       qdf_nbuf_data(msg), qdf_nbuf_len(msg),
388 			       pdev->htc_tx_endpoint,
389 			       HTC_TX_PACKET_TAG_RUNTIME_PUT);
390 
391 	SET_HTC_PACKET_NET_BUF_CONTEXT(&pkt->htc_pkt, msg);
392 	HTT_SEND_HTC_PKT(pdev, pkt);
393 	return QDF_STATUS_SUCCESS;
394 }
395 #else
396 /**
397  * htt_h2t_rx_ring_rfs_cfg_msg_ll() - Configure receive flow steering
398  * @pdev: handle to the HTT instance
399  *
400  * Return: QDF_STATUS_SUCCESS on success
401  *         A_NO_MEMORY No memory fail
402  */
htt_h2t_rx_ring_rfs_cfg_msg_ll(struct htt_pdev_t * pdev)403 QDF_STATUS htt_h2t_rx_ring_rfs_cfg_msg_ll(struct htt_pdev_t *pdev)
404 {
405 	QDF_TRACE(QDF_MODULE_ID_HTT, QDF_TRACE_LEVEL_INFO,
406 		  "Does not support receive flow steering configuration\n");
407 	return QDF_STATUS_SUCCESS;
408 }
409 #endif /* HELIUMPLUS */
410 
htt_h2t_rx_ring_cfg_msg_ll(struct htt_pdev_t * pdev)411 QDF_STATUS htt_h2t_rx_ring_cfg_msg_ll(struct htt_pdev_t *pdev)
412 {
413 	struct htt_htc_pkt *pkt;
414 	qdf_nbuf_t msg;
415 	uint32_t *msg_word;
416 	int enable_ctrl_data, enable_mgmt_data,
417 	    enable_null_data, enable_phy_data, enable_hdr,
418 	    enable_ppdu_start, enable_ppdu_end;
419 
420 	pkt = htt_htc_pkt_alloc(pdev);
421 	if (!pkt)
422 		return QDF_STATUS_E_FAILURE; /* failure */
423 
424 	/*
425 	 * show that this is not a tx frame download
426 	 *  (not required, but helpful)
427 	 */
428 	pkt->msdu_id = HTT_TX_COMPL_INV_MSDU_ID;
429 	pkt->pdev_ctxt = NULL;  /* not used during send-done callback */
430 
431 	/* reserve room for the HTC header */
432 	msg = qdf_nbuf_alloc(pdev->osdev,
433 			     HTT_MSG_BUF_SIZE(HTT_RX_RING_CFG_BYTES(1)),
434 			     HTC_HEADER_LEN + HTC_HDR_ALIGNMENT_PADDING, 4,
435 			     true);
436 	if (!msg) {
437 		htt_htc_pkt_free(pdev, pkt);
438 		return QDF_STATUS_E_FAILURE; /* failure */
439 	}
440 	/*
441 	 * Set the length of the message.
442 	 * The contribution from the HTC_HDR_ALIGNMENT_PADDING is added
443 	 * separately during the below call to qdf_nbuf_push_head.
444 	 * The contribution from the HTC header is added separately inside HTC.
445 	 */
446 	qdf_nbuf_put_tail(msg, HTT_RX_RING_CFG_BYTES(1));
447 
448 	/* fill in the message contents */
449 	msg_word = (uint32_t *) qdf_nbuf_data(msg);
450 
451 	/* rewind beyond alignment pad to get to the HTC header reserved area */
452 	qdf_nbuf_push_head(msg, HTC_HDR_ALIGNMENT_PADDING);
453 
454 	*msg_word = 0;
455 	HTT_H2T_MSG_TYPE_SET(*msg_word, HTT_H2T_MSG_TYPE_RX_RING_CFG);
456 	HTT_RX_RING_CFG_NUM_RINGS_SET(*msg_word, 1);
457 
458 	msg_word++;
459 	*msg_word = 0;
460 #if HTT_PADDR64
461 	HTT_RX_RING_CFG_IDX_SHADOW_REG_PADDR_LO_SET(
462 			*msg_word,
463 			qdf_get_lower_32_bits(pdev->rx_ring.alloc_idx.paddr));
464 	msg_word++;
465 	HTT_RX_RING_CFG_IDX_SHADOW_REG_PADDR_HI_SET(
466 			*msg_word,
467 			qdf_get_upper_32_bits(pdev->rx_ring.alloc_idx.paddr));
468 #else /* ! HTT_PADDR64 */
469 	HTT_RX_RING_CFG_IDX_SHADOW_REG_PADDR_SET(*msg_word,
470 						 pdev->rx_ring.alloc_idx.paddr);
471 #endif /* HTT_PADDR64 */
472 
473 	msg_word++;
474 	*msg_word = 0;
475 #if HTT_PADDR64
476 	HTT_RX_RING_CFG_BASE_PADDR_LO_SET(*msg_word,
477 					  pdev->rx_ring.base_paddr);
478 	{
479 		uint32_t tmp;
480 
481 		tmp = qdf_get_upper_32_bits(pdev->rx_ring.base_paddr);
482 		if (tmp & 0xfffffe0) {
483 			QDF_TRACE(QDF_MODULE_ID_HTT, QDF_TRACE_LEVEL_INFO,
484 				  "%s:%d paddr > 37 bits!. Trimmed.",
485 				  __func__, __LINE__);
486 			tmp &= 0x01f;
487 		}
488 
489 
490 		msg_word++;
491 		HTT_RX_RING_CFG_BASE_PADDR_HI_SET(*msg_word, tmp);
492 	}
493 #else /* ! HTT_PADDR64 */
494 	HTT_RX_RING_CFG_BASE_PADDR_SET(*msg_word, pdev->rx_ring.base_paddr);
495 #endif /* HTT_PADDR64 */
496 
497 	msg_word++;
498 	*msg_word = 0;
499 	HTT_RX_RING_CFG_LEN_SET(*msg_word, pdev->rx_ring.size);
500 	HTT_RX_RING_CFG_BUF_SZ_SET(*msg_word, HTT_RX_BUF_SIZE);
501 
502 /* FIX THIS: if the FW creates a complete translated rx descriptor,
503  * then the MAC DMA of the HW rx descriptor should be disabled.
504  */
505 	msg_word++;
506 	*msg_word = 0;
507 #ifndef REMOVE_PKT_LOG
508 	if (ol_cfg_is_packet_log_enabled(pdev->ctrl_pdev)) {
509 		enable_ctrl_data = 1;
510 		enable_mgmt_data = 1;
511 		enable_null_data = 1;
512 		enable_phy_data = 1;
513 		enable_hdr = 1;
514 		enable_ppdu_start = 1;
515 		enable_ppdu_end = 1;
516 		QDF_TRACE(QDF_MODULE_ID_HTT, QDF_TRACE_LEVEL_INFO_LOW,
517 			  "%s : %d Pkt log is enabled\n",  __func__, __LINE__);
518 	} else {
519 		QDF_TRACE(QDF_MODULE_ID_HTT, QDF_TRACE_LEVEL_INFO,
520 			  "%s : %d Pkt log is disabled\n",  __func__, __LINE__);
521 		enable_ctrl_data = 0;
522 		enable_mgmt_data = 0;
523 		enable_null_data = 0;
524 		enable_phy_data = 0;
525 		enable_hdr = 0;
526 		enable_ppdu_start = 0;
527 		enable_ppdu_end = 0;
528 	}
529 #else
530 	enable_ctrl_data = 0;
531 	enable_mgmt_data = 0;
532 	enable_null_data = 0;
533 	enable_phy_data = 0;
534 	enable_hdr = 0;
535 	enable_ppdu_start = 0;
536 	enable_ppdu_end = 0;
537 #endif
538 	if (QDF_GLOBAL_MONITOR_MODE == cds_get_conparam()) {
539 		enable_ctrl_data  = 1;
540 		enable_mgmt_data  = 1;
541 		enable_null_data  = 1;
542 		enable_phy_data   = 1;
543 		enable_hdr        = 1;
544 		enable_ppdu_start = 1;
545 		enable_ppdu_end   = 1;
546 		/* Disable ASPM for monitor mode */
547 		QDF_TRACE(QDF_MODULE_ID_HTT, QDF_TRACE_LEVEL_INFO,
548 			  "%s : %d Monitor mode is enabled\n",
549 			  __func__, __LINE__);
550 	}
551 
552 	htt_rx_enable_ppdu_end(&enable_ppdu_end);
553 	HTT_RX_RING_CFG_ENABLED_802_11_HDR_SET(*msg_word, enable_hdr);
554 	HTT_RX_RING_CFG_ENABLED_MSDU_PAYLD_SET(*msg_word, 1);
555 	HTT_RX_RING_CFG_ENABLED_PPDU_START_SET(*msg_word, enable_ppdu_start);
556 	HTT_RX_RING_CFG_ENABLED_PPDU_END_SET(*msg_word, enable_ppdu_end);
557 	HTT_RX_RING_CFG_ENABLED_MPDU_START_SET(*msg_word, 1);
558 	HTT_RX_RING_CFG_ENABLED_MPDU_END_SET(*msg_word, 1);
559 	HTT_RX_RING_CFG_ENABLED_MSDU_START_SET(*msg_word, 1);
560 	HTT_RX_RING_CFG_ENABLED_MSDU_END_SET(*msg_word, 1);
561 	HTT_RX_RING_CFG_ENABLED_RX_ATTN_SET(*msg_word, 1);
562 	/* always present? */
563 	HTT_RX_RING_CFG_ENABLED_FRAG_INFO_SET(*msg_word, 1);
564 	HTT_RX_RING_CFG_ENABLED_UCAST_SET(*msg_word, 1);
565 	HTT_RX_RING_CFG_ENABLED_MCAST_SET(*msg_word, 1);
566 	/* Must change to dynamic enable at run time
567 	 * rather than at compile time
568 	 */
569 	HTT_RX_RING_CFG_ENABLED_CTRL_SET(*msg_word, enable_ctrl_data);
570 	HTT_RX_RING_CFG_ENABLED_MGMT_SET(*msg_word, enable_mgmt_data);
571 	HTT_RX_RING_CFG_ENABLED_NULL_SET(*msg_word, enable_null_data);
572 	HTT_RX_RING_CFG_ENABLED_PHY_SET(*msg_word, enable_phy_data);
573 	HTT_RX_RING_CFG_IDX_INIT_VAL_SET(*msg_word,
574 					 *pdev->rx_ring.alloc_idx.vaddr);
575 
576 	msg_word++;
577 	*msg_word = 0;
578 	HTT_RX_RING_CFG_OFFSET_802_11_HDR_SET(*msg_word,
579 					      RX_DESC_HDR_STATUS_OFFSET32);
580 	HTT_RX_RING_CFG_OFFSET_MSDU_PAYLD_SET(*msg_word,
581 					      HTT_RX_DESC_RESERVATION32);
582 
583 	msg_word++;
584 	*msg_word = 0;
585 	HTT_RX_RING_CFG_OFFSET_PPDU_START_SET(*msg_word,
586 					      RX_DESC_PPDU_START_OFFSET32);
587 	HTT_RX_RING_CFG_OFFSET_PPDU_END_SET(*msg_word,
588 					    RX_DESC_PPDU_END_OFFSET32);
589 
590 	msg_word++;
591 	*msg_word = 0;
592 	HTT_RX_RING_CFG_OFFSET_MPDU_START_SET(*msg_word,
593 					      RX_DESC_MPDU_START_OFFSET32);
594 	HTT_RX_RING_CFG_OFFSET_MPDU_END_SET(*msg_word,
595 					    RX_DESC_MPDU_END_OFFSET32);
596 
597 	msg_word++;
598 	*msg_word = 0;
599 	HTT_RX_RING_CFG_OFFSET_MSDU_START_SET(*msg_word,
600 					      RX_DESC_MSDU_START_OFFSET32);
601 	HTT_RX_RING_CFG_OFFSET_MSDU_END_SET(*msg_word,
602 					    RX_DESC_MSDU_END_OFFSET32);
603 
604 	msg_word++;
605 	*msg_word = 0;
606 	HTT_RX_RING_CFG_OFFSET_RX_ATTN_SET(*msg_word,
607 					   RX_DESC_ATTN_OFFSET32);
608 	HTT_RX_RING_CFG_OFFSET_FRAG_INFO_SET(*msg_word,
609 					     RX_DESC_FRAG_INFO_OFFSET32);
610 
611 	SET_HTC_PACKET_INFO_TX(&pkt->htc_pkt,
612 			       htt_h2t_send_complete_free_netbuf,
613 			       qdf_nbuf_data(msg),
614 			       qdf_nbuf_len(msg),
615 			       pdev->htc_tx_endpoint,
616 			       HTC_TX_PACKET_TAG_RUNTIME_PUT);
617 
618 	SET_HTC_PACKET_NET_BUF_CONTEXT(&pkt->htc_pkt, msg);
619 	HTT_SEND_HTC_PKT(pdev, pkt);
620 	return QDF_STATUS_SUCCESS;
621 }
622 
623 QDF_STATUS
htt_h2t_rx_ring_cfg_msg_hl(struct htt_pdev_t * pdev)624 htt_h2t_rx_ring_cfg_msg_hl(struct htt_pdev_t *pdev)
625 {
626 	struct htt_htc_pkt *pkt;
627 	qdf_nbuf_t msg;
628 	u_int32_t *msg_word;
629 
630 	pkt = htt_htc_pkt_alloc(pdev);
631 	if (!pkt)
632 		return A_ERROR; /* failure */
633 
634 	/*
635 	 * show that this is not a tx frame download
636 	 * (not required, but helpful)
637 	 */
638 	pkt->msdu_id = HTT_TX_COMPL_INV_MSDU_ID;
639 	pkt->pdev_ctxt = NULL; /* not used during send-done callback */
640 
641 	msg = qdf_nbuf_alloc(
642 		pdev->osdev,
643 		HTT_MSG_BUF_SIZE(HTT_RX_RING_CFG_BYTES(1)),
644 		/* reserve room for the HTC header */
645 		HTC_HEADER_LEN + HTC_HDR_ALIGNMENT_PADDING, 4, true);
646 	if (!msg) {
647 		htt_htc_pkt_free(pdev, pkt);
648 		return A_ERROR; /* failure */
649 	}
650 	/*
651 	 * Set the length of the message.
652 	 * The contribution from the HTC_HDR_ALIGNMENT_PADDING is added
653 	 * separately during the below call to adf_nbuf_push_head.
654 	 * The contribution from the HTC header is added separately inside HTC.
655 	 */
656 	qdf_nbuf_put_tail(msg, HTT_RX_RING_CFG_BYTES(1));
657 
658 	/* fill in the message contents */
659 	msg_word = (u_int32_t *)qdf_nbuf_data(msg);
660 
661 	/* rewind beyond alignment pad to get to the HTC header reserved area */
662 	qdf_nbuf_push_head(msg, HTC_HDR_ALIGNMENT_PADDING);
663 
664 	*msg_word = 0;
665 	HTT_H2T_MSG_TYPE_SET(*msg_word, HTT_H2T_MSG_TYPE_RX_RING_CFG);
666 	HTT_RX_RING_CFG_NUM_RINGS_SET(*msg_word, 1);
667 
668 	msg_word++;
669 	*msg_word = 0;
670 	HTT_RX_RING_CFG_IDX_SHADOW_REG_PADDR_SET(
671 			*msg_word, pdev->rx_ring.alloc_idx.paddr);
672 
673 	msg_word++;
674 	*msg_word = 0;
675 	HTT_RX_RING_CFG_BASE_PADDR_SET(*msg_word, pdev->rx_ring.base_paddr);
676 
677 	msg_word++;
678 	*msg_word = 0;
679 	HTT_RX_RING_CFG_LEN_SET(*msg_word, pdev->rx_ring.size);
680 	HTT_RX_RING_CFG_BUF_SZ_SET(*msg_word, HTT_RX_BUF_SIZE);
681 
682 	/* FIX THIS: if the FW creates a complete translated rx descriptor,
683 	 * then the MAC DMA of the HW rx descriptor should be disabled. */
684 	msg_word++;
685 	*msg_word = 0;
686 
687 	HTT_RX_RING_CFG_ENABLED_802_11_HDR_SET(*msg_word, 0);
688 	HTT_RX_RING_CFG_ENABLED_MSDU_PAYLD_SET(*msg_word, 1);
689 	HTT_RX_RING_CFG_ENABLED_PPDU_START_SET(*msg_word, 0);
690 	HTT_RX_RING_CFG_ENABLED_PPDU_END_SET(*msg_word, 0);
691 	HTT_RX_RING_CFG_ENABLED_MPDU_START_SET(*msg_word, 0);
692 	HTT_RX_RING_CFG_ENABLED_MPDU_END_SET(*msg_word,   0);
693 	HTT_RX_RING_CFG_ENABLED_MSDU_START_SET(*msg_word, 0);
694 	HTT_RX_RING_CFG_ENABLED_MSDU_END_SET(*msg_word,   0);
695 	HTT_RX_RING_CFG_ENABLED_RX_ATTN_SET(*msg_word,    0);
696 	/* always present? */
697 	HTT_RX_RING_CFG_ENABLED_FRAG_INFO_SET(*msg_word,  0);
698 	HTT_RX_RING_CFG_ENABLED_UCAST_SET(*msg_word, 1);
699 	HTT_RX_RING_CFG_ENABLED_MCAST_SET(*msg_word, 1);
700 	/* Must change to dynamic enable at run time
701 	 * rather than at compile time
702 	 */
703 	HTT_RX_RING_CFG_ENABLED_CTRL_SET(*msg_word, 0);
704 	HTT_RX_RING_CFG_ENABLED_MGMT_SET(*msg_word, 0);
705 	HTT_RX_RING_CFG_ENABLED_NULL_SET(*msg_word, 0);
706 	HTT_RX_RING_CFG_ENABLED_PHY_SET(*msg_word, 0);
707 
708 	msg_word++;
709 	*msg_word = 0;
710 	HTT_RX_RING_CFG_OFFSET_802_11_HDR_SET(*msg_word,
711 					      0);
712 	HTT_RX_RING_CFG_OFFSET_MSDU_PAYLD_SET(*msg_word,
713 					      0);
714 
715 	msg_word++;
716 	*msg_word = 0;
717 	HTT_RX_RING_CFG_OFFSET_PPDU_START_SET(*msg_word,
718 					      0);
719 	HTT_RX_RING_CFG_OFFSET_PPDU_END_SET(*msg_word,
720 					    0);
721 
722 	msg_word++;
723 	*msg_word = 0;
724 	HTT_RX_RING_CFG_OFFSET_MPDU_START_SET(*msg_word,
725 					      0);
726 	HTT_RX_RING_CFG_OFFSET_MPDU_END_SET(*msg_word,
727 					    0);
728 
729 	msg_word++;
730 	*msg_word = 0;
731 	HTT_RX_RING_CFG_OFFSET_MSDU_START_SET(*msg_word,
732 					      0);
733 	HTT_RX_RING_CFG_OFFSET_MSDU_END_SET(*msg_word,
734 					    0);
735 
736 	msg_word++;
737 	*msg_word = 0;
738 	HTT_RX_RING_CFG_OFFSET_RX_ATTN_SET(*msg_word,
739 					   0);
740 	HTT_RX_RING_CFG_OFFSET_FRAG_INFO_SET(*msg_word,
741 					     0);
742 
743 	SET_HTC_PACKET_INFO_TX(
744 		&pkt->htc_pkt,
745 		htt_h2t_send_complete_free_netbuf,
746 		qdf_nbuf_data(msg),
747 		qdf_nbuf_len(msg),
748 		pdev->htc_tx_endpoint,
749 		1); /* tag - not relevant here */
750 
751 	SET_HTC_PACKET_NET_BUF_CONTEXT(&pkt->htc_pkt, msg);
752 
753 #ifdef ATH_11AC_TXCOMPACT
754 	if (htc_send_pkt(pdev->htc_pdev, &pkt->htc_pkt) == QDF_STATUS_SUCCESS) {
755 		htt_htc_misc_pkt_list_add(pdev, pkt);
756 	} else {
757 		qdf_nbuf_free(msg);
758 		htt_htc_pkt_free(pdev, pkt);
759 	}
760 #else
761 	htc_send_pkt(pdev->htc_pdev, &pkt->htc_pkt);
762 #endif
763 
764 	ol_tx_deduct_one_credit(pdev->txrx_pdev);
765 
766 	return QDF_STATUS_SUCCESS;
767 }
768 
769 /**
770  * htt_h2t_rx_ring_rfs_cfg_msg_hl() - Configure receive flow steering
771  * @pdev: handle to the HTT instance
772  *
773  * Return: QDF_STATUS_SUCCESS on success
774  *         A_NO_MEMORY No memory fail
775  */
htt_h2t_rx_ring_rfs_cfg_msg_hl(struct htt_pdev_t * pdev)776 QDF_STATUS htt_h2t_rx_ring_rfs_cfg_msg_hl(struct htt_pdev_t *pdev)
777 {
778 	QDF_TRACE(QDF_MODULE_ID_HTT, QDF_TRACE_LEVEL_INFO,
779 		  "Does not support Receive flow steering configuration\n");
780 	return QDF_STATUS_SUCCESS;
781 }
782 
783 int
htt_h2t_dbg_stats_get(struct htt_pdev_t * pdev,uint32_t stats_type_upload_mask,uint32_t stats_type_reset_mask,uint8_t cfg_stat_type,uint32_t cfg_val,uint8_t cookie)784 htt_h2t_dbg_stats_get(struct htt_pdev_t *pdev,
785 		      uint32_t stats_type_upload_mask,
786 		      uint32_t stats_type_reset_mask,
787 		      uint8_t cfg_stat_type, uint32_t cfg_val, uint8_t cookie)
788 {
789 	struct htt_htc_pkt *pkt;
790 	qdf_nbuf_t msg;
791 	uint32_t *msg_word;
792 	uint16_t htc_tag = 1;
793 
794 	pkt = htt_htc_pkt_alloc(pdev);
795 	if (!pkt)
796 		return -EINVAL;      /* failure */
797 
798 	if (stats_type_upload_mask >= 1 << HTT_DBG_NUM_STATS ||
799 	    stats_type_reset_mask >= 1 << HTT_DBG_NUM_STATS) {
800 		/* FIX THIS - add more details? */
801 		QDF_TRACE(QDF_MODULE_ID_HTT, QDF_TRACE_LEVEL_ERROR,
802 			  "%#x %#x stats not supported\n",
803 			  stats_type_upload_mask, stats_type_reset_mask);
804 		htt_htc_pkt_free(pdev, pkt);
805 		return -EINVAL;      /* failure */
806 	}
807 
808 	if (stats_type_reset_mask)
809 		htc_tag = HTC_TX_PACKET_TAG_RUNTIME_PUT;
810 
811 	/* show that this is not a tx frame download
812 	 * (not required, but helpful)
813 	 */
814 	pkt->msdu_id = HTT_TX_COMPL_INV_MSDU_ID;
815 	pkt->pdev_ctxt = NULL;  /* not used during send-done callback */
816 
817 
818 	msg = qdf_nbuf_alloc(pdev->osdev,
819 			     HTT_MSG_BUF_SIZE(HTT_H2T_STATS_REQ_MSG_SZ),
820 			     /* reserve room for HTC header */
821 			     HTC_HEADER_LEN + HTC_HDR_ALIGNMENT_PADDING, 4,
822 			     false);
823 	if (!msg) {
824 		htt_htc_pkt_free(pdev, pkt);
825 		return -EINVAL;      /* failure */
826 	}
827 	/* set the length of the message */
828 	qdf_nbuf_put_tail(msg, HTT_H2T_STATS_REQ_MSG_SZ);
829 
830 	/* fill in the message contents */
831 	msg_word = (uint32_t *) qdf_nbuf_data(msg);
832 
833 	/* rewind beyond alignment pad to get to the HTC header reserved area */
834 	qdf_nbuf_push_head(msg, HTC_HDR_ALIGNMENT_PADDING);
835 
836 	*msg_word = 0;
837 	HTT_H2T_MSG_TYPE_SET(*msg_word, HTT_H2T_MSG_TYPE_STATS_REQ);
838 	HTT_H2T_STATS_REQ_UPLOAD_TYPES_SET(*msg_word, stats_type_upload_mask);
839 
840 	msg_word++;
841 	*msg_word = 0;
842 	HTT_H2T_STATS_REQ_RESET_TYPES_SET(*msg_word, stats_type_reset_mask);
843 
844 	msg_word++;
845 	*msg_word = 0;
846 	HTT_H2T_STATS_REQ_CFG_VAL_SET(*msg_word, cfg_val);
847 	HTT_H2T_STATS_REQ_CFG_STAT_TYPE_SET(*msg_word, cfg_stat_type);
848 
849 	/* cookie LSBs */
850 	msg_word++;
851 	*msg_word = cookie;
852 
853 	/* cookie MSBs */
854 	msg_word++;
855 	*msg_word = 0;
856 
857 	SET_HTC_PACKET_INFO_TX(&pkt->htc_pkt,
858 			       htt_h2t_send_complete_free_netbuf,
859 			       qdf_nbuf_data(msg),
860 			       qdf_nbuf_len(msg),
861 			       pdev->htc_tx_endpoint,
862 			       htc_tag); /* tag - not relevant here */
863 
864 	SET_HTC_PACKET_NET_BUF_CONTEXT(&pkt->htc_pkt, msg);
865 
866 #ifdef ATH_11AC_TXCOMPACT
867 	if (htc_send_pkt(pdev->htc_pdev, &pkt->htc_pkt) == QDF_STATUS_SUCCESS) {
868 		htt_htc_misc_pkt_list_add(pdev, pkt);
869 	} else {
870 		qdf_nbuf_free(msg);
871 		htt_htc_pkt_free(pdev, pkt);
872 	}
873 #else
874 	htc_send_pkt(pdev->htc_pdev, &pkt->htc_pkt);
875 #endif
876 
877 	ol_tx_deduct_one_credit(pdev->txrx_pdev);
878 
879 	return 0;
880 }
881 
htt_h2t_sync_msg(struct htt_pdev_t * pdev,uint8_t sync_cnt)882 A_STATUS htt_h2t_sync_msg(struct htt_pdev_t *pdev, uint8_t sync_cnt)
883 {
884 	struct htt_htc_pkt *pkt;
885 	qdf_nbuf_t msg;
886 	uint32_t *msg_word;
887 
888 	pkt = htt_htc_pkt_alloc(pdev);
889 	if (!pkt)
890 		return A_NO_MEMORY;
891 
892 	/* show that this is not a tx frame download
893 	   (not required, but helpful)
894 	*/
895 	pkt->msdu_id = HTT_TX_COMPL_INV_MSDU_ID;
896 	pkt->pdev_ctxt = NULL;  /* not used during send-done callback */
897 
898 	/* reserve room for HTC header */
899 	msg = qdf_nbuf_alloc(pdev->osdev, HTT_MSG_BUF_SIZE(HTT_H2T_SYNC_MSG_SZ),
900 			     HTC_HEADER_LEN + HTC_HDR_ALIGNMENT_PADDING, 4,
901 			     false);
902 	if (!msg) {
903 		htt_htc_pkt_free(pdev, pkt);
904 		return A_NO_MEMORY;
905 	}
906 	/* set the length of the message */
907 	qdf_nbuf_put_tail(msg, HTT_H2T_SYNC_MSG_SZ);
908 
909 	/* fill in the message contents */
910 	msg_word = (uint32_t *) qdf_nbuf_data(msg);
911 
912 	/* rewind beyond alignment pad to get to the HTC header reserved area */
913 	qdf_nbuf_push_head(msg, HTC_HDR_ALIGNMENT_PADDING);
914 
915 	*msg_word = 0;
916 	HTT_H2T_MSG_TYPE_SET(*msg_word, HTT_H2T_MSG_TYPE_SYNC);
917 	HTT_H2T_SYNC_COUNT_SET(*msg_word, sync_cnt);
918 
919 	SET_HTC_PACKET_INFO_TX(&pkt->htc_pkt,
920 			       htt_h2t_send_complete_free_netbuf,
921 			       qdf_nbuf_data(msg),
922 			       qdf_nbuf_len(msg),
923 			       pdev->htc_tx_endpoint,
924 			       HTC_TX_PACKET_TAG_RUNTIME_PUT);
925 
926 	SET_HTC_PACKET_NET_BUF_CONTEXT(&pkt->htc_pkt, msg);
927 	HTT_SEND_HTC_PKT(pdev, pkt);
928 
929 	ol_tx_deduct_one_credit(pdev->txrx_pdev);
930 
931 	return A_OK;
932 }
933 
934 int
htt_h2t_aggr_cfg_msg(struct htt_pdev_t * pdev,int max_subfrms_ampdu,int max_subfrms_amsdu)935 htt_h2t_aggr_cfg_msg(struct htt_pdev_t *pdev,
936 		     int max_subfrms_ampdu, int max_subfrms_amsdu)
937 {
938 	struct htt_htc_pkt *pkt;
939 	qdf_nbuf_t msg;
940 	uint32_t *msg_word;
941 
942 	pkt = htt_htc_pkt_alloc(pdev);
943 	if (!pkt)
944 		return -EINVAL;      /* failure */
945 
946 	/* show that this is not a tx frame download
947 	 * (not required, but helpful)
948 	 */
949 	pkt->msdu_id = HTT_TX_COMPL_INV_MSDU_ID;
950 	pkt->pdev_ctxt = NULL;  /* not used during send-done callback */
951 
952 	/* reserve room for HTC header */
953 	msg = qdf_nbuf_alloc(pdev->osdev, HTT_MSG_BUF_SIZE(HTT_AGGR_CFG_MSG_SZ),
954 			     HTC_HEADER_LEN + HTC_HDR_ALIGNMENT_PADDING, 4,
955 			     false);
956 	if (!msg) {
957 		htt_htc_pkt_free(pdev, pkt);
958 		return -EINVAL;      /* failure */
959 	}
960 	/* set the length of the message */
961 	qdf_nbuf_put_tail(msg, HTT_AGGR_CFG_MSG_SZ);
962 
963 	/* fill in the message contents */
964 	msg_word = (uint32_t *) qdf_nbuf_data(msg);
965 
966 	/* rewind beyond alignment pad to get to the HTC header reserved area */
967 	qdf_nbuf_push_head(msg, HTC_HDR_ALIGNMENT_PADDING);
968 
969 	*msg_word = 0;
970 	HTT_H2T_MSG_TYPE_SET(*msg_word, HTT_H2T_MSG_TYPE_AGGR_CFG);
971 
972 	if (max_subfrms_ampdu && (max_subfrms_ampdu <= 64)) {
973 		HTT_AGGR_CFG_MAX_NUM_AMPDU_SUBFRM_SET(*msg_word,
974 						      max_subfrms_ampdu);
975 	}
976 
977 	if (max_subfrms_amsdu && (max_subfrms_amsdu < 32)) {
978 		HTT_AGGR_CFG_MAX_NUM_AMSDU_SUBFRM_SET(*msg_word,
979 						      max_subfrms_amsdu);
980 	}
981 
982 	SET_HTC_PACKET_INFO_TX(&pkt->htc_pkt,
983 			       htt_h2t_send_complete_free_netbuf,
984 			       qdf_nbuf_data(msg),
985 			       qdf_nbuf_len(msg),
986 			       pdev->htc_tx_endpoint,
987 			       HTC_TX_PACKET_TAG_RUNTIME_PUT);
988 
989 	SET_HTC_PACKET_NET_BUF_CONTEXT(&pkt->htc_pkt, msg);
990 
991 #ifdef ATH_11AC_TXCOMPACT
992 	if (htc_send_pkt(pdev->htc_pdev, &pkt->htc_pkt) == QDF_STATUS_SUCCESS) {
993 		htt_htc_misc_pkt_list_add(pdev, pkt);
994 	} else {
995 		qdf_nbuf_free(msg);
996 		htt_htc_pkt_free(pdev, pkt);
997 	}
998 #else
999 	htc_send_pkt(pdev->htc_pdev, &pkt->htc_pkt);
1000 #endif
1001 
1002 	ol_tx_deduct_one_credit(pdev->txrx_pdev);
1003 
1004 	return 0;
1005 }
1006 
1007 #ifdef IPA_OFFLOAD
1008 /**
1009  * htt_h2t_ipa_uc_rsc_cfg_msg() - Send WDI IPA config message to firmware
1010  * @pdev: handle to the HTT instance
1011  *
1012  * Return: 0 success
1013  *         A_NO_MEMORY No memory fail
1014  */
1015 #ifdef QCA_WIFI_3_0
htt_h2t_ipa_uc_rsc_cfg_msg(struct htt_pdev_t * pdev)1016 int htt_h2t_ipa_uc_rsc_cfg_msg(struct htt_pdev_t *pdev)
1017 {
1018 	struct htt_htc_pkt *pkt;
1019 	qdf_nbuf_t msg;
1020 	uint32_t *msg_word;
1021 	unsigned int tx_count = 0;
1022 	uint32_t addr;
1023 	qdf_mem_info_t *mem_info_t;
1024 
1025 	pkt = htt_htc_pkt_alloc(pdev);
1026 	if (!pkt)
1027 		return -A_NO_MEMORY;
1028 
1029 	/* show that this is not a tx frame download
1030 	 * (not required, but helpful)
1031 	 */
1032 	pkt->msdu_id = HTT_TX_COMPL_INV_MSDU_ID;
1033 	pkt->pdev_ctxt = NULL;  /* not used during send-done callback */
1034 
1035 	/* reserve room for HTC header */
1036 	msg = qdf_nbuf_alloc(pdev->osdev, HTT_MSG_BUF_SIZE(HTT_WDI_IPA_CFG_SZ),
1037 			     HTC_HEADER_LEN + HTC_HDR_ALIGNMENT_PADDING, 4,
1038 			     false);
1039 	if (!msg) {
1040 		htt_htc_pkt_free(pdev, pkt);
1041 		return -A_NO_MEMORY;
1042 	}
1043 	/* set the length of the message */
1044 	qdf_nbuf_put_tail(msg, HTT_WDI_IPA_CFG_SZ);
1045 
1046 	/* fill in the message contents */
1047 	msg_word = (uint32_t *) qdf_nbuf_data(msg);
1048 
1049 	/* rewind beyond alignment pad to get to the HTC header reserved area */
1050 	qdf_nbuf_push_head(msg, HTC_HDR_ALIGNMENT_PADDING);
1051 
1052 	*msg_word = 0;
1053 	HTT_WDI_IPA_CFG_TX_PKT_POOL_SIZE_SET(*msg_word,
1054 		pdev->ipa_uc_tx_rsc.alloc_tx_buf_cnt);
1055 	HTT_H2T_MSG_TYPE_SET(*msg_word, HTT_H2T_MSG_TYPE_WDI_IPA_CFG);
1056 
1057 	msg_word++;
1058 	*msg_word = 0;
1059 	HTT_WDI_IPA_CFG_TX_COMP_RING_BASE_ADDR_LO_SET(*msg_word,
1060 		(unsigned int)qdf_mem_get_dma_addr(pdev->osdev,
1061 			&pdev->ipa_uc_tx_rsc.tx_comp_ring->mem_info));
1062 	msg_word++;
1063 	*msg_word = 0;
1064 	mem_info_t = &pdev->ipa_uc_tx_rsc.tx_comp_ring->mem_info;
1065 	addr = (uint64_t)qdf_mem_get_dma_addr(pdev->osdev, mem_info_t) >> 32;
1066 	HTT_WDI_IPA_CFG_TX_COMP_RING_BASE_ADDR_HI_SET(*msg_word, addr);
1067 
1068 	msg_word++;
1069 	*msg_word = 0;
1070 	tx_count = qdf_get_pwr2(ol_cfg_ipa_uc_tx_max_buf_cnt(pdev->ctrl_pdev));
1071 	HTT_WDI_IPA_CFG_TX_COMP_RING_SIZE_SET(*msg_word, tx_count);
1072 
1073 	msg_word++;
1074 	*msg_word = 0;
1075 	HTT_WDI_IPA_CFG_TX_COMP_WR_IDX_ADDR_LO_SET(*msg_word,
1076 		(unsigned int)pdev->ipa_uc_tx_rsc.tx_comp_idx_paddr);
1077 	msg_word++;
1078 	*msg_word = 0;
1079 	addr = (uint64_t)pdev->ipa_uc_tx_rsc.tx_comp_idx_paddr >> 32;
1080 	HTT_WDI_IPA_CFG_TX_COMP_WR_IDX_ADDR_HI_SET(*msg_word, addr);
1081 
1082 	msg_word++;
1083 	*msg_word = 0;
1084 	HTT_WDI_IPA_CFG_TX_CE_WR_IDX_ADDR_LO_SET(*msg_word,
1085 		(unsigned int)qdf_mem_get_dma_addr(pdev->osdev,
1086 			&pdev->ipa_uc_tx_rsc.tx_ce_idx->mem_info));
1087 	msg_word++;
1088 	*msg_word = 0;
1089 	mem_info_t = &pdev->ipa_uc_tx_rsc.tx_ce_idx->mem_info;
1090 	addr = (uint64_t)qdf_mem_get_dma_addr(pdev->osdev, mem_info_t) >> 32;
1091 	HTT_WDI_IPA_CFG_TX_CE_WR_IDX_ADDR_HI_SET(*msg_word, addr);
1092 
1093 	msg_word++;
1094 	*msg_word = 0;
1095 	HTT_WDI_IPA_CFG_RX_IND_RING_BASE_ADDR_LO_SET(*msg_word,
1096 		(unsigned int)qdf_mem_get_dma_addr(pdev->osdev,
1097 			&pdev->ipa_uc_rx_rsc.rx_ind_ring->mem_info));
1098 	msg_word++;
1099 	*msg_word = 0;
1100 	mem_info_t = &pdev->ipa_uc_rx_rsc.rx_ind_ring->mem_info;
1101 	addr = (uint64_t)qdf_mem_get_dma_addr(pdev->osdev, mem_info_t) >> 32;
1102 	HTT_WDI_IPA_CFG_RX_IND_RING_BASE_ADDR_HI_SET(*msg_word, addr);
1103 
1104 	msg_word++;
1105 	*msg_word = 0;
1106 	HTT_WDI_IPA_CFG_RX_IND_RING_SIZE_SET(*msg_word,
1107 		(unsigned int)qdf_get_pwr2(pdev->rx_ring.fill_level));
1108 
1109 	msg_word++;
1110 	*msg_word = 0;
1111 	HTT_WDI_IPA_CFG_RX_IND_RD_IDX_ADDR_LO_SET(*msg_word,
1112 		(unsigned int)qdf_mem_get_dma_addr(pdev->osdev,
1113 			&pdev->ipa_uc_rx_rsc.rx_ipa_prc_done_idx->mem_info));
1114 	msg_word++;
1115 	*msg_word = 0;
1116 	mem_info_t = &pdev->ipa_uc_rx_rsc.rx_ipa_prc_done_idx->mem_info;
1117 	addr = (uint64_t)qdf_mem_get_dma_addr(pdev->osdev, mem_info_t) >> 32;
1118 	HTT_WDI_IPA_CFG_RX_IND_RD_IDX_ADDR_HI_SET(*msg_word, addr);
1119 
1120 	msg_word++;
1121 	*msg_word = 0;
1122 	HTT_WDI_IPA_CFG_RX_IND_WR_IDX_ADDR_LO_SET(*msg_word,
1123 		(unsigned int)pdev->ipa_uc_rx_rsc.rx_rdy_idx_paddr);
1124 	msg_word++;
1125 	*msg_word = 0;
1126 	addr = (uint64_t)pdev->ipa_uc_rx_rsc.rx_rdy_idx_paddr >> 32;
1127 	HTT_WDI_IPA_CFG_RX_IND_WR_IDX_ADDR_HI_SET(*msg_word, addr);
1128 
1129 	msg_word++;
1130 	*msg_word = 0;
1131 	HTT_WDI_IPA_CFG_RX_RING2_BASE_ADDR_LO_SET(*msg_word,
1132 		(unsigned int)qdf_mem_get_dma_addr(pdev->osdev,
1133 			&pdev->ipa_uc_rx_rsc.rx2_ind_ring->mem_info));
1134 	msg_word++;
1135 	*msg_word = 0;
1136 	mem_info_t = &pdev->ipa_uc_rx_rsc.rx2_ind_ring->mem_info;
1137 	addr = (uint64_t)qdf_mem_get_dma_addr(pdev->osdev, mem_info_t) >> 32;
1138 	HTT_WDI_IPA_CFG_RX_RING2_BASE_ADDR_HI_SET(*msg_word, addr);
1139 
1140 	msg_word++;
1141 	*msg_word = 0;
1142 	HTT_WDI_IPA_CFG_RX_RING2_SIZE_SET(*msg_word,
1143 		(unsigned int)qdf_get_pwr2(pdev->rx_ring.fill_level));
1144 
1145 	msg_word++;
1146 	*msg_word = 0;
1147 	HTT_WDI_IPA_CFG_RX_RING2_RD_IDX_ADDR_LO_SET(*msg_word,
1148 		(unsigned int)qdf_mem_get_dma_addr(pdev->osdev,
1149 			&pdev->ipa_uc_rx_rsc.rx2_ipa_prc_done_idx->mem_info));
1150 	msg_word++;
1151 	*msg_word = 0;
1152 	mem_info_t = &pdev->ipa_uc_rx_rsc.rx2_ipa_prc_done_idx->mem_info;
1153 	addr = (uint64_t)qdf_mem_get_dma_addr(pdev->osdev, mem_info_t) >> 32;
1154 	HTT_WDI_IPA_CFG_RX_RING2_RD_IDX_ADDR_HI_SET(*msg_word, addr);
1155 
1156 	msg_word++;
1157 	*msg_word = 0;
1158 	HTT_WDI_IPA_CFG_RX_RING2_WR_IDX_ADDR_LO_SET(*msg_word,
1159 		(unsigned int)qdf_mem_get_dma_addr(pdev->osdev,
1160 			&pdev->ipa_uc_rx_rsc.rx2_ipa_prc_done_idx->mem_info));
1161 	msg_word++;
1162 	*msg_word = 0;
1163 	mem_info_t = &pdev->ipa_uc_rx_rsc.rx2_ipa_prc_done_idx->mem_info;
1164 	addr = (uint64_t)qdf_mem_get_dma_addr(pdev->osdev, mem_info_t) >> 32;
1165 	HTT_WDI_IPA_CFG_RX_RING2_WR_IDX_ADDR_HI_SET(*msg_word, addr);
1166 
1167 	SET_HTC_PACKET_INFO_TX(&pkt->htc_pkt,
1168 			       htt_h2t_send_complete_free_netbuf,
1169 			       qdf_nbuf_data(msg),
1170 			       qdf_nbuf_len(msg),
1171 			       pdev->htc_tx_endpoint,
1172 			       HTC_TX_PACKET_TAG_RUNTIME_PUT);
1173 
1174 	SET_HTC_PACKET_NET_BUF_CONTEXT(&pkt->htc_pkt, msg);
1175 	HTT_SEND_HTC_PKT(pdev, pkt);
1176 	return A_OK;
1177 }
1178 #else
1179 /* Rome Support only WDI 1.0 */
htt_h2t_ipa_uc_rsc_cfg_msg(struct htt_pdev_t * pdev)1180 int htt_h2t_ipa_uc_rsc_cfg_msg(struct htt_pdev_t *pdev)
1181 {
1182 	struct htt_htc_pkt *pkt;
1183 	qdf_nbuf_t msg;
1184 	uint32_t *msg_word;
1185 
1186 	pkt = htt_htc_pkt_alloc(pdev);
1187 	if (!pkt)
1188 		return A_NO_MEMORY;
1189 
1190 	/* show that this is not a tx frame download
1191 	 * (not required, but helpful)
1192 	 */
1193 	pkt->msdu_id = HTT_TX_COMPL_INV_MSDU_ID;
1194 	pkt->pdev_ctxt = NULL;  /* not used during send-done callback */
1195 
1196 	/* reserve room for HTC header */
1197 	msg = qdf_nbuf_alloc(pdev->osdev, HTT_MSG_BUF_SIZE(HTT_WDI_IPA_CFG_SZ),
1198 			     HTC_HEADER_LEN + HTC_HDR_ALIGNMENT_PADDING, 4,
1199 			     false);
1200 	if (!msg) {
1201 		htt_htc_pkt_free(pdev, pkt);
1202 		return A_NO_MEMORY;
1203 	}
1204 	/* set the length of the message */
1205 	qdf_nbuf_put_tail(msg, HTT_WDI_IPA_CFG_SZ);
1206 
1207 	/* fill in the message contents */
1208 	msg_word = (uint32_t *) qdf_nbuf_data(msg);
1209 
1210 	/* rewind beyond alignment pad to get to the HTC header reserved area */
1211 	qdf_nbuf_push_head(msg, HTC_HDR_ALIGNMENT_PADDING);
1212 
1213 	*msg_word = 0;
1214 	HTT_WDI_IPA_CFG_TX_PKT_POOL_SIZE_SET(*msg_word,
1215 				pdev->ipa_uc_tx_rsc.alloc_tx_buf_cnt);
1216 	HTT_H2T_MSG_TYPE_SET(*msg_word, HTT_H2T_MSG_TYPE_WDI_IPA_CFG);
1217 
1218 	msg_word++;
1219 	*msg_word = 0;
1220 	HTT_WDI_IPA_CFG_TX_COMP_RING_BASE_ADDR_SET(*msg_word,
1221 		(unsigned int)qdf_mem_get_dma_addr(pdev->osdev,
1222 			&pdev->ipa_uc_tx_rsc.tx_comp_ring->mem_info));
1223 
1224 	msg_word++;
1225 	*msg_word = 0;
1226 	HTT_WDI_IPA_CFG_TX_COMP_RING_SIZE_SET(
1227 		*msg_word,
1228 		(unsigned int)ol_cfg_ipa_uc_tx_max_buf_cnt(pdev->ctrl_pdev));
1229 
1230 	msg_word++;
1231 	*msg_word = 0;
1232 	HTT_WDI_IPA_CFG_TX_COMP_WR_IDX_ADDR_SET(*msg_word,
1233 		(unsigned int)pdev->ipa_uc_tx_rsc.tx_comp_idx_paddr);
1234 
1235 	msg_word++;
1236 	*msg_word = 0;
1237 	HTT_WDI_IPA_CFG_TX_CE_WR_IDX_ADDR_SET(*msg_word,
1238 		(unsigned int)qdf_mem_get_dma_addr(pdev->osdev,
1239 			&pdev->ipa_uc_tx_rsc.tx_ce_idx->mem_info));
1240 
1241 	msg_word++;
1242 	*msg_word = 0;
1243 	HTT_WDI_IPA_CFG_RX_IND_RING_BASE_ADDR_SET(*msg_word,
1244 		(unsigned int)qdf_mem_get_dma_addr(pdev->osdev,
1245 			&pdev->ipa_uc_rx_rsc.rx_ind_ring->mem_info));
1246 
1247 	msg_word++;
1248 	*msg_word = 0;
1249 	HTT_WDI_IPA_CFG_RX_IND_RING_SIZE_SET(*msg_word,
1250 		(unsigned int)qdf_get_pwr2(pdev->rx_ring.fill_level));
1251 
1252 	msg_word++;
1253 	*msg_word = 0;
1254 	HTT_WDI_IPA_CFG_RX_IND_RD_IDX_ADDR_SET(*msg_word,
1255 		(unsigned int)qdf_mem_get_dma_addr(pdev->osdev,
1256 			&pdev->ipa_uc_rx_rsc.rx_ipa_prc_done_idx->mem_info));
1257 
1258 	msg_word++;
1259 	*msg_word = 0;
1260 	HTT_WDI_IPA_CFG_RX_IND_WR_IDX_ADDR_SET(*msg_word,
1261 	       (unsigned int)pdev->ipa_uc_rx_rsc.rx_rdy_idx_paddr);
1262 
1263 	SET_HTC_PACKET_INFO_TX(&pkt->htc_pkt,
1264 			       htt_h2t_send_complete_free_netbuf,
1265 			       qdf_nbuf_data(msg),
1266 			       qdf_nbuf_len(msg),
1267 			       pdev->htc_tx_endpoint,
1268 			       HTC_TX_PACKET_TAG_RUNTIME_PUT);
1269 
1270 	SET_HTC_PACKET_NET_BUF_CONTEXT(&pkt->htc_pkt, msg);
1271 	HTT_SEND_HTC_PKT(pdev, pkt);
1272 	return A_OK;
1273 }
1274 #endif
1275 
1276 /**
1277  * htt_h2t_ipa_uc_set_active() - Propagate WDI path enable/disable to firmware
1278  * @pdev: handle to the HTT instance
1279  * @uc_active: WDI UC path enable or not
1280  * @is_tx: TX path or RX path
1281  *
1282  * Return: 0 success
1283  *         A_NO_MEMORY No memory fail
1284  */
htt_h2t_ipa_uc_set_active(struct htt_pdev_t * pdev,bool uc_active,bool is_tx)1285 int htt_h2t_ipa_uc_set_active(struct htt_pdev_t *pdev,
1286 			      bool uc_active, bool is_tx)
1287 {
1288 	struct htt_htc_pkt *pkt;
1289 	qdf_nbuf_t msg;
1290 	uint32_t *msg_word;
1291 	uint8_t active_target = 0;
1292 
1293 	pkt = htt_htc_pkt_alloc(pdev);
1294 	if (!pkt)
1295 		return -A_NO_MEMORY;
1296 
1297 	/* show that this is not a tx frame download
1298 	 * (not required, but helpful)
1299 	 */
1300 	pkt->msdu_id = HTT_TX_COMPL_INV_MSDU_ID;
1301 	pkt->pdev_ctxt = NULL;  /* not used during send-done callback */
1302 
1303 	/* reserve room for HTC header */
1304 	msg = qdf_nbuf_alloc(pdev->osdev,
1305 			     HTT_MSG_BUF_SIZE(HTT_WDI_IPA_OP_REQUEST_SZ),
1306 			     HTC_HEADER_LEN + HTC_HDR_ALIGNMENT_PADDING, 4,
1307 			     false);
1308 	if (!msg) {
1309 		htt_htc_pkt_free(pdev, pkt);
1310 		return -A_NO_MEMORY;
1311 	}
1312 	/* set the length of the message */
1313 	qdf_nbuf_put_tail(msg, HTT_WDI_IPA_OP_REQUEST_SZ);
1314 
1315 	/* fill in the message contents */
1316 	msg_word = (uint32_t *) qdf_nbuf_data(msg);
1317 
1318 	/* rewind beyond alignment pad to get to the HTC header reserved area */
1319 	qdf_nbuf_push_head(msg, HTC_HDR_ALIGNMENT_PADDING);
1320 
1321 	*msg_word = 0;
1322 	if (uc_active && is_tx)
1323 		active_target = HTT_WDI_IPA_OPCODE_TX_RESUME;
1324 	else if (!uc_active && is_tx)
1325 		active_target = HTT_WDI_IPA_OPCODE_TX_SUSPEND;
1326 	else if (uc_active && !is_tx)
1327 		active_target = HTT_WDI_IPA_OPCODE_RX_RESUME;
1328 	else if (!uc_active && !is_tx)
1329 		active_target = HTT_WDI_IPA_OPCODE_RX_SUSPEND;
1330 
1331 	QDF_TRACE(QDF_MODULE_ID_HTT, QDF_TRACE_LEVEL_INFO,
1332 			"%s: HTT_H2T_MSG_TYPE_WDI_IPA_OP_REQ (%d)\n",
1333 			__func__, active_target);
1334 
1335 	HTT_WDI_IPA_OP_REQUEST_OP_CODE_SET(*msg_word, active_target);
1336 	HTT_H2T_MSG_TYPE_SET(*msg_word, HTT_H2T_MSG_TYPE_WDI_IPA_OP_REQ);
1337 
1338 	SET_HTC_PACKET_INFO_TX(&pkt->htc_pkt,
1339 			       htt_h2t_send_complete_free_netbuf,
1340 			       qdf_nbuf_data(msg),
1341 			       qdf_nbuf_len(msg),
1342 			       pdev->htc_tx_endpoint,
1343 			       1); /* tag - not relevant here */
1344 
1345 	SET_HTC_PACKET_NET_BUF_CONTEXT(&pkt->htc_pkt, msg);
1346 	HTT_SEND_HTC_PKT(pdev, pkt);
1347 	return A_OK;
1348 }
1349 
1350 /**
1351  * htt_h2t_ipa_uc_get_stats() - WDI UC state query request to firmware
1352  * @pdev: handle to the HTT instance
1353  *
1354  * Return: 0 success
1355  *         A_NO_MEMORY No memory fail
1356  */
htt_h2t_ipa_uc_get_stats(struct htt_pdev_t * pdev)1357 int htt_h2t_ipa_uc_get_stats(struct htt_pdev_t *pdev)
1358 {
1359 	struct htt_htc_pkt *pkt;
1360 	qdf_nbuf_t msg;
1361 	uint32_t *msg_word;
1362 
1363 	pkt = htt_htc_pkt_alloc(pdev);
1364 	if (!pkt)
1365 		return -A_NO_MEMORY;
1366 
1367 	/* show that this is not a tx frame download
1368 	 * (not required, but helpful)
1369 	 */
1370 	pkt->msdu_id = HTT_TX_COMPL_INV_MSDU_ID;
1371 	pkt->pdev_ctxt = NULL;  /* not used during send-done callback */
1372 
1373 	/* reserve room for HTC header */
1374 	msg = qdf_nbuf_alloc(pdev->osdev,
1375 			     HTT_MSG_BUF_SIZE(HTT_WDI_IPA_OP_REQUEST_SZ),
1376 			     HTC_HEADER_LEN + HTC_HDR_ALIGNMENT_PADDING, 4,
1377 			     false);
1378 	if (!msg) {
1379 		htt_htc_pkt_free(pdev, pkt);
1380 		return -A_NO_MEMORY;
1381 	}
1382 	/* set the length of the message */
1383 	qdf_nbuf_put_tail(msg, HTT_WDI_IPA_OP_REQUEST_SZ);
1384 
1385 	/* fill in the message contents */
1386 	msg_word = (uint32_t *) qdf_nbuf_data(msg);
1387 
1388 	/* rewind beyond alignment pad to get to the HTC header reserved area */
1389 	qdf_nbuf_push_head(msg, HTC_HDR_ALIGNMENT_PADDING);
1390 
1391 	*msg_word = 0;
1392 	HTT_WDI_IPA_OP_REQUEST_OP_CODE_SET(*msg_word,
1393 					   HTT_WDI_IPA_OPCODE_DBG_STATS);
1394 	HTT_H2T_MSG_TYPE_SET(*msg_word, HTT_H2T_MSG_TYPE_WDI_IPA_OP_REQ);
1395 
1396 	SET_HTC_PACKET_INFO_TX(&pkt->htc_pkt,
1397 			       htt_h2t_send_complete_free_netbuf,
1398 			       qdf_nbuf_data(msg),
1399 			       qdf_nbuf_len(msg),
1400 			       pdev->htc_tx_endpoint,
1401 			       1); /* tag - not relevant here */
1402 
1403 	SET_HTC_PACKET_NET_BUF_CONTEXT(&pkt->htc_pkt, msg);
1404 	HTT_SEND_HTC_PKT(pdev, pkt);
1405 	return A_OK;
1406 }
1407 
1408 /**
1409  * htt_h2t_ipa_uc_get_share_stats() - WDI UC wifi sharing state request to FW
1410  * @pdev: handle to the HTT instance
1411  *
1412  * Return: A_OK success
1413  *         A_NO_MEMORY No memory fail
1414  */
htt_h2t_ipa_uc_get_share_stats(struct htt_pdev_t * pdev,uint8_t reset_stats)1415 int htt_h2t_ipa_uc_get_share_stats(struct htt_pdev_t *pdev, uint8_t reset_stats)
1416 {
1417 	struct htt_htc_pkt *pkt;
1418 	qdf_nbuf_t msg;
1419 	uint32_t *msg_word;
1420 
1421 	pkt = htt_htc_pkt_alloc(pdev);
1422 	if (!pkt)
1423 		return -A_NO_MEMORY;
1424 
1425 	/* show that this is not a tx frame download
1426 	 * (not required, but helpful)
1427 	 */
1428 	pkt->msdu_id = HTT_TX_COMPL_INV_MSDU_ID;
1429 	pkt->pdev_ctxt = NULL;  /* not used during send-done callback */
1430 
1431 	/* reserve room for HTC header */
1432 	msg = qdf_nbuf_alloc(pdev->osdev,
1433 		HTT_MSG_BUF_SIZE(HTT_WDI_IPA_OP_REQUEST_SZ)+
1434 		HTT_MSG_BUF_SIZE(WLAN_WDI_IPA_GET_SHARING_STATS_REQ_SZ),
1435 		HTC_HEADER_LEN + HTC_HDR_ALIGNMENT_PADDING, 4, false);
1436 	if (!msg) {
1437 		htt_htc_pkt_free(pdev, pkt);
1438 		return -A_NO_MEMORY;
1439 	}
1440 	/* set the length of the message */
1441 	qdf_nbuf_put_tail(msg, HTT_WDI_IPA_OP_REQUEST_SZ+
1442 			  WLAN_WDI_IPA_GET_SHARING_STATS_REQ_SZ);
1443 
1444 	/* fill in the message contents */
1445 	msg_word = (uint32_t *) qdf_nbuf_data(msg);
1446 
1447 	/* rewind beyond alignment pad to get to the HTC header reserved area */
1448 	qdf_nbuf_push_head(msg, HTC_HDR_ALIGNMENT_PADDING);
1449 
1450 	*msg_word = 0;
1451 	HTT_WDI_IPA_OP_REQUEST_OP_CODE_SET(*msg_word,
1452 				   HTT_WDI_IPA_OPCODE_GET_SHARING_STATS);
1453 	HTT_H2T_MSG_TYPE_SET(*msg_word, HTT_H2T_MSG_TYPE_WDI_IPA_OP_REQ);
1454 
1455 	msg_word++;
1456 	*msg_word = 0;
1457 	WLAN_WDI_IPA_GET_SHARING_STATS_REQ_RESET_STATS_SET(*msg_word,
1458 							     reset_stats);
1459 
1460 	SET_HTC_PACKET_INFO_TX(&pkt->htc_pkt,
1461 			       htt_h2t_send_complete_free_netbuf,
1462 			       qdf_nbuf_data(msg),
1463 			       qdf_nbuf_len(msg),
1464 			       pdev->htc_tx_endpoint,
1465 			       1); /* tag - not relevant here */
1466 
1467 	SET_HTC_PACKET_NET_BUF_CONTEXT(&pkt->htc_pkt, msg);
1468 	HTT_SEND_HTC_PKT(pdev, pkt);
1469 	return A_OK;
1470 }
1471 
1472 /**
1473  * htt_h2t_ipa_uc_set_quota() - WDI UC state query request to firmware
1474  * @pdev: handle to the HTT instance
1475  *
1476  * Return: A_OK success
1477  *         A_NO_MEMORY No memory fail
1478  */
htt_h2t_ipa_uc_set_quota(struct htt_pdev_t * pdev,uint64_t quota_bytes)1479 int htt_h2t_ipa_uc_set_quota(struct htt_pdev_t *pdev, uint64_t quota_bytes)
1480 {
1481 	struct htt_htc_pkt *pkt;
1482 	qdf_nbuf_t msg;
1483 	uint32_t *msg_word;
1484 
1485 	pkt = htt_htc_pkt_alloc(pdev);
1486 	if (!pkt)
1487 		return -A_NO_MEMORY;
1488 
1489 	/* show that this is not a tx frame download
1490 	 * (not required, but helpful)
1491 	 */
1492 	pkt->msdu_id = HTT_TX_COMPL_INV_MSDU_ID;
1493 	pkt->pdev_ctxt = NULL;  /* not used during send-done callback */
1494 
1495 	/* reserve room for HTC header */
1496 	msg = qdf_nbuf_alloc(pdev->osdev,
1497 		HTT_MSG_BUF_SIZE(HTT_WDI_IPA_OP_REQUEST_SZ)+
1498 		HTT_MSG_BUF_SIZE(WLAN_WDI_IPA_SET_QUOTA_REQ_SZ),
1499 		HTC_HEADER_LEN + HTC_HDR_ALIGNMENT_PADDING, 4, false);
1500 	if (!msg) {
1501 		htt_htc_pkt_free(pdev, pkt);
1502 		return -A_NO_MEMORY;
1503 	}
1504 	/* set the length of the message */
1505 	qdf_nbuf_put_tail(msg, HTT_WDI_IPA_OP_REQUEST_SZ+
1506 			  WLAN_WDI_IPA_SET_QUOTA_REQ_SZ);
1507 
1508 	/* fill in the message contents */
1509 	msg_word = (uint32_t *) qdf_nbuf_data(msg);
1510 
1511 	/* rewind beyond alignment pad to get to the HTC header reserved area */
1512 	qdf_nbuf_push_head(msg, HTC_HDR_ALIGNMENT_PADDING);
1513 
1514 	*msg_word = 0;
1515 	HTT_WDI_IPA_OP_REQUEST_OP_CODE_SET(*msg_word,
1516 					   HTT_WDI_IPA_OPCODE_SET_QUOTA);
1517 	HTT_H2T_MSG_TYPE_SET(*msg_word, HTT_H2T_MSG_TYPE_WDI_IPA_OP_REQ);
1518 
1519 	msg_word++;
1520 	*msg_word = 0;
1521 	WLAN_WDI_IPA_SET_QUOTA_REQ_SET_QUOTA_SET(*msg_word, quota_bytes > 0);
1522 
1523 	msg_word++;
1524 	*msg_word = 0;
1525 	WLAN_WDI_IPA_SET_QUOTA_REQ_QUOTA_LO_SET(*msg_word,
1526 			(uint32_t)(quota_bytes &
1527 				   WLAN_WDI_IPA_SET_QUOTA_REQ_QUOTA_LO_M));
1528 
1529 	msg_word++;
1530 	*msg_word = 0;
1531 	WLAN_WDI_IPA_SET_QUOTA_REQ_QUOTA_HI_SET(*msg_word,
1532 			(uint32_t)(quota_bytes>>32 &
1533 				   WLAN_WDI_IPA_SET_QUOTA_REQ_QUOTA_HI_M));
1534 
1535 	SET_HTC_PACKET_INFO_TX(&pkt->htc_pkt,
1536 			       htt_h2t_send_complete_free_netbuf,
1537 			       qdf_nbuf_data(msg),
1538 			       qdf_nbuf_len(msg),
1539 			       pdev->htc_tx_endpoint,
1540 			       1); /* tag - not relevant here */
1541 
1542 	SET_HTC_PACKET_NET_BUF_CONTEXT(&pkt->htc_pkt, msg);
1543 	HTT_SEND_HTC_PKT(pdev, pkt);
1544 	return A_OK;
1545 }
1546 #endif /* IPA_OFFLOAD */
1547