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