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