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