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