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 * 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 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 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 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 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 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 * 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 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 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 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 */ 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 */ 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 */ 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 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 */ 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 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 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