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