1 /* 2 * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved. 3 * 4 * Permission to use, copy, modify, and/or distribute this software for 5 * any purpose with or without fee is hereby granted, provided that the 6 * above copyright notice and this permission notice appear in all 7 * copies. 8 * 9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL 10 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED 11 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE 12 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL 13 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR 14 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 15 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 16 * PERFORMANCE OF THIS SOFTWARE. 17 */ 18 /** 19 * DOC: wlan_dp_main.c 20 * 21 * 22 */ 23 24 #include "wlan_dp_main.h" 25 #include "wlan_dp_public_struct.h" 26 #include "cfg_ucfg_api.h" 27 #include "wlan_dp_bus_bandwidth.h" 28 #include <wlan_objmgr_psoc_obj_i.h> 29 #include <wlan_nlink_common.h> 30 #include <qdf_net_types.h> 31 #include "wlan_objmgr_vdev_obj.h" 32 #include "wlan_cm_api.h" 33 #include "wlan_dp_nud_tracking.h" 34 #include "target_if_dp_comp.h" 35 #include "wlan_dp_txrx.h" 36 #include "init_deinit_lmac.h" 37 #include <hif.h> 38 #include <htc_api.h> 39 #include <cdp_txrx_cmn_reg.h> 40 #include <cdp_txrx_bus.h> 41 #if defined(WLAN_DP_PROFILE_SUPPORT) || defined(FEATURE_DIRECT_LINK) 42 #include "cdp_txrx_ctrl.h" 43 #endif 44 #ifdef FEATURE_DIRECT_LINK 45 #include "dp_internal.h" 46 #endif 47 #include <cdp_txrx_ctrl.h> 48 49 #ifdef WLAN_DP_PROFILE_SUPPORT 50 /* Memory profile table based on supported caps */ 51 static struct wlan_dp_memory_profile_ctx wlan_dp_1x1_he80_1kqam[] = { 52 {DP_TX_DESC_NUM_CFG, 1024}, 53 {DP_TX_EXT_DESC_NUM_CFG, 1024}, 54 {DP_TX_RING_SIZE_CFG, 1024}, 55 {DP_TX_COMPL_RING_SIZE_CFG, 1024}, 56 {DP_RX_SW_DESC_NUM_CFG, 1024}, 57 {DP_REO_DST_RING_SIZE_CFG, 1024}, 58 {DP_RXDMA_BUF_RING_SIZE_CFG, 1024}, 59 {DP_RXDMA_REFILL_RING_SIZE_CFG, 1024}, 60 {DP_RX_REFILL_POOL_NUM_CFG, 1024}, 61 }; 62 63 /* Global data structure to save profile info */ 64 static struct wlan_dp_memory_profile_info g_dp_profile_info; 65 #endif 66 #include <wlan_dp_fisa_rx.h> 67 68 /* Global DP context */ 69 static struct wlan_dp_psoc_context *gp_dp_ctx; 70 71 QDF_STATUS dp_allocate_ctx(void) 72 { 73 struct wlan_dp_psoc_context *dp_ctx; 74 75 dp_ctx = qdf_mem_malloc(sizeof(*dp_ctx)); 76 if (!dp_ctx) { 77 dp_err("Failed to create DP context"); 78 return QDF_STATUS_E_NOMEM; 79 } 80 81 qdf_spinlock_create(&dp_ctx->intf_list_lock); 82 qdf_list_create(&dp_ctx->intf_list, 0); 83 84 dp_attach_ctx(dp_ctx); 85 86 return QDF_STATUS_SUCCESS; 87 } 88 89 void dp_free_ctx(void) 90 { 91 struct wlan_dp_psoc_context *dp_ctx; 92 93 dp_ctx = dp_get_context(); 94 95 qdf_spinlock_destroy(&dp_ctx->intf_list_lock); 96 qdf_list_destroy(&dp_ctx->intf_list); 97 dp_detach_ctx(); 98 qdf_mem_free(dp_ctx); 99 } 100 101 QDF_STATUS dp_get_front_intf_no_lock(struct wlan_dp_psoc_context *dp_ctx, 102 struct wlan_dp_intf **out_intf) 103 { 104 QDF_STATUS status; 105 qdf_list_node_t *node; 106 107 *out_intf = NULL; 108 109 status = qdf_list_peek_front(&dp_ctx->intf_list, &node); 110 111 if (QDF_IS_STATUS_ERROR(status)) 112 return status; 113 114 *out_intf = qdf_container_of(node, struct wlan_dp_intf, node); 115 116 return QDF_STATUS_SUCCESS; 117 } 118 119 QDF_STATUS dp_get_next_intf_no_lock(struct wlan_dp_psoc_context *dp_ctx, 120 struct wlan_dp_intf *cur_intf, 121 struct wlan_dp_intf **out_intf) 122 { 123 QDF_STATUS status; 124 qdf_list_node_t *node; 125 126 if (!cur_intf) 127 return QDF_STATUS_E_INVAL; 128 129 *out_intf = NULL; 130 131 status = qdf_list_peek_next(&dp_ctx->intf_list, 132 &cur_intf->node, 133 &node); 134 135 if (QDF_IS_STATUS_ERROR(status)) 136 return status; 137 138 *out_intf = qdf_container_of(node, struct wlan_dp_intf, node); 139 140 return status; 141 } 142 143 struct wlan_dp_intf* 144 dp_get_intf_by_macaddr(struct wlan_dp_psoc_context *dp_ctx, 145 struct qdf_mac_addr *addr) 146 { 147 struct wlan_dp_intf *dp_intf; 148 149 qdf_spin_lock_bh(&dp_ctx->intf_list_lock); 150 for (dp_get_front_intf_no_lock(dp_ctx, &dp_intf); dp_intf; 151 dp_get_next_intf_no_lock(dp_ctx, dp_intf, &dp_intf)) { 152 if (qdf_is_macaddr_equal(&dp_intf->mac_addr, addr)) { 153 qdf_spin_unlock_bh(&dp_ctx->intf_list_lock); 154 return dp_intf; 155 } 156 } 157 qdf_spin_unlock_bh(&dp_ctx->intf_list_lock); 158 159 return NULL; 160 } 161 162 struct wlan_dp_intf* 163 dp_get_intf_by_netdev(struct wlan_dp_psoc_context *dp_ctx, qdf_netdev_t dev) 164 { 165 struct wlan_dp_intf *dp_intf; 166 167 qdf_spin_lock_bh(&dp_ctx->intf_list_lock); 168 for (dp_get_front_intf_no_lock(dp_ctx, &dp_intf); dp_intf; 169 dp_get_next_intf_no_lock(dp_ctx, dp_intf, &dp_intf)) { 170 if (dp_intf->dev == dev) { 171 qdf_spin_unlock_bh(&dp_ctx->intf_list_lock); 172 return dp_intf; 173 } 174 } 175 qdf_spin_unlock_bh(&dp_ctx->intf_list_lock); 176 177 return NULL; 178 } 179 180 /** 181 * validate_link_id() - Check if link ID is valid 182 * @link_id: DP link ID 183 * 184 * Return: true on success, false on failure 185 */ 186 static bool validate_link_id(uint8_t link_id) 187 { 188 if (link_id == WLAN_UMAC_VDEV_ID_MAX) { 189 dp_err("Interface is not up: %ps", QDF_RET_IP); 190 return false; 191 } 192 193 if (link_id >= WLAN_MAX_VDEVS) { 194 dp_err("Bad interface id:%u", link_id); 195 return false; 196 } 197 198 return true; 199 } 200 201 int is_dp_intf_valid(struct wlan_dp_intf *dp_intf) 202 { 203 if (!dp_intf) { 204 dp_err("Interface is NULL"); 205 return -EINVAL; 206 } 207 208 if (!dp_intf->dev) { 209 dp_err("DP interface net_device is null"); 210 return -EINVAL; 211 } 212 213 if (!(dp_intf->dev->flags & IFF_UP)) { 214 dp_info_rl("DP interface '%s' is not up %ps", 215 dp_intf->dev->name, QDF_RET_IP); 216 return -EAGAIN; 217 } 218 219 return 0; 220 } 221 222 bool is_dp_link_valid(struct wlan_dp_link *dp_link) 223 { 224 struct wlan_dp_intf *dp_intf; 225 int ret; 226 227 if (!dp_link) { 228 dp_err("link is NULL"); 229 return false; 230 } 231 232 dp_intf = dp_link->dp_intf; 233 ret = is_dp_intf_valid(dp_intf); 234 if (ret) 235 return false; 236 237 return validate_link_id(dp_link->link_id); 238 } 239 240 QDF_STATUS dp_get_front_link_no_lock(struct wlan_dp_intf *dp_intf, 241 struct wlan_dp_link **out_link) 242 { 243 QDF_STATUS status; 244 qdf_list_node_t *node; 245 246 *out_link = NULL; 247 248 status = qdf_list_peek_front(&dp_intf->dp_link_list, &node); 249 250 if (QDF_IS_STATUS_ERROR(status)) 251 return status; 252 253 *out_link = qdf_container_of(node, struct wlan_dp_link, node); 254 255 return QDF_STATUS_SUCCESS; 256 } 257 258 QDF_STATUS dp_get_next_link_no_lock(struct wlan_dp_intf *dp_intf, 259 struct wlan_dp_link *cur_link, 260 struct wlan_dp_link **out_link) 261 { 262 QDF_STATUS status; 263 qdf_list_node_t *node; 264 265 if (!cur_link) 266 return QDF_STATUS_E_INVAL; 267 268 *out_link = NULL; 269 270 status = qdf_list_peek_next(&dp_intf->dp_link_list, 271 &cur_link->node, 272 &node); 273 274 if (QDF_IS_STATUS_ERROR(status)) 275 return status; 276 277 *out_link = qdf_container_of(node, struct wlan_dp_link, node); 278 279 return status; 280 } 281 282 static QDF_STATUS 283 dp_intf_wait_for_task_complete(struct wlan_dp_intf *dp_intf) 284 { 285 int count = DP_TASK_MAX_WAIT_CNT; 286 int r; 287 288 while (count) { 289 r = atomic_read(&dp_intf->num_active_task); 290 291 if (!r) 292 return QDF_STATUS_SUCCESS; 293 294 if (--count) { 295 dp_err_rl("Waiting for DP task to complete: %d", count); 296 qdf_sleep(DP_TASK_WAIT_TIME); 297 } 298 } 299 300 dp_err("Timed-out waiting for DP task completion"); 301 return QDF_STATUS_E_TIMEOUT; 302 } 303 304 void dp_wait_complete_tasks(struct wlan_dp_psoc_context *dp_ctx) 305 { 306 struct wlan_dp_intf *dp_intf, *dp_intf_next = NULL; 307 308 dp_for_each_intf_held_safe(dp_ctx, dp_intf, dp_intf_next) { 309 /* 310 * If timeout happens for one interface better to bail out 311 * instead of waiting for other intefaces task completion 312 */ 313 if (qdf_atomic_read(&dp_intf->num_active_task)) 314 if (dp_intf_wait_for_task_complete(dp_intf)) 315 break; 316 } 317 } 318 319 #ifdef CONFIG_DP_TRACE 320 /** 321 * dp_convert_string_to_array() - used to convert string into u8 array 322 * @str: String to be converted 323 * @array: Array where converted value is stored 324 * @len: Length of the populated array 325 * @array_max_len: Maximum length of the array 326 * @to_hex: true, if conversion required for hex string 327 * 328 * This API is called to convert string (each byte separated by 329 * a comma) into an u8 array 330 * 331 * Return: QDF_STATUS 332 */ 333 static QDF_STATUS dp_convert_string_to_array(char *str, uint8_t *array, 334 uint8_t *len, 335 uint16_t array_max_len, 336 bool to_hex) 337 { 338 char *format, *s = str; 339 340 if (!str || !array || !len) 341 return QDF_STATUS_E_INVAL; 342 343 format = (to_hex) ? "%02x" : "%d"; 344 345 *len = 0; 346 while ((s) && (*len < array_max_len)) { 347 int val; 348 /* Increment length only if sscanf successfully extracted 349 * one element. Any other return value means error. 350 * Ignore it. 351 */ 352 if (sscanf(s, format, &val) == 1) { 353 array[*len] = (uint8_t)val; 354 *len += 1; 355 } 356 357 s = strpbrk(s, ","); 358 if (s) 359 s++; 360 } 361 362 return QDF_STATUS_SUCCESS; 363 } 364 365 /** 366 * dp_string_to_u8_array() - used to convert string into u8 array 367 * @str: String to be converted 368 * @array: Array where converted value is stored 369 * @len: Length of the populated array 370 * @array_max_len: Maximum length of the array 371 * 372 * Return: QDF_STATUS 373 */ 374 static 375 QDF_STATUS dp_string_to_u8_array(char *str, uint8_t *array, 376 uint8_t *len, uint16_t array_max_len) 377 { 378 return dp_convert_string_to_array(str, array, len, 379 array_max_len, false); 380 } 381 382 void dp_trace_init(struct wlan_objmgr_psoc *psoc) 383 { 384 struct wlan_dp_psoc_context *dp_ctx; 385 struct wlan_dp_psoc_cfg *config; 386 bool live_mode = DP_TRACE_CONFIG_DEFAULT_LIVE_MODE; 387 uint8_t thresh = DP_TRACE_CONFIG_DEFAULT_THRESH; 388 uint16_t thresh_time_limit = DP_TRACE_CONFIG_DEFAULT_THRESH_TIME_LIMIT; 389 uint8_t verbosity = DP_TRACE_CONFIG_DEFAULT_VERBOSTY; 390 uint32_t proto_bitmap = DP_TRACE_CONFIG_DEFAULT_BITMAP; 391 uint8_t config_params[DP_TRACE_CONFIG_NUM_PARAMS]; 392 uint8_t num_entries = 0; 393 uint32_t bw_compute_interval; 394 395 dp_ctx = dp_psoc_get_priv(psoc); 396 if (!dp_ctx) { 397 dp_err("Unable to get DP context"); 398 return; 399 } 400 401 config = &dp_ctx->dp_cfg; 402 403 qdf_dp_set_proto_event_bitmap(config->dp_proto_event_bitmap); 404 405 if (!config->enable_dp_trace) { 406 dp_err("dp trace is disabled from ini"); 407 return; 408 } 409 410 dp_string_to_u8_array(config->dp_trace_config, config_params, 411 &num_entries, sizeof(config_params)); 412 413 /* calculating, num bw timer intervals in a second (1000ms) */ 414 bw_compute_interval = DP_BUS_BW_CFG(config->bus_bw_compute_interval); 415 416 if (bw_compute_interval <= 1000 && bw_compute_interval > 0) { 417 thresh_time_limit = 1000 / bw_compute_interval; 418 } else if (bw_compute_interval > 1000) { 419 dp_err("busBandwidthComputeInterval > 1000, using 1000"); 420 thresh_time_limit = 1; 421 } else { 422 dp_err("busBandwidthComputeInterval is 0, using defaults"); 423 } 424 425 switch (num_entries) { 426 case 4: 427 proto_bitmap = config_params[3]; 428 fallthrough; 429 case 3: 430 verbosity = config_params[2]; 431 fallthrough; 432 case 2: 433 thresh = config_params[1]; 434 fallthrough; 435 case 1: 436 live_mode = config_params[0]; 437 fallthrough; 438 default: 439 dp_debug("live_mode %u thresh %u time_limit %u verbosity %u bitmap 0x%x", 440 live_mode, thresh, thresh_time_limit, 441 verbosity, proto_bitmap); 442 }; 443 444 qdf_dp_trace_init(live_mode, thresh, thresh_time_limit, 445 verbosity, proto_bitmap); 446 } 447 448 void dp_set_dump_dp_trace(uint16_t cmd_type, uint16_t count) 449 { 450 dp_debug("DUMP_DP_TRACE_LEVEL: %d %d", 451 cmd_type, count); 452 if (cmd_type == DUMP_DP_TRACE) 453 qdf_dp_trace_dump_all(count, QDF_TRACE_DEFAULT_PDEV_ID); 454 else if (cmd_type == ENABLE_DP_TRACE_LIVE_MODE) 455 qdf_dp_trace_enable_live_mode(); 456 else if (cmd_type == CLEAR_DP_TRACE_BUFFER) 457 qdf_dp_trace_clear_buffer(); 458 else if (cmd_type == DISABLE_DP_TRACE_LIVE_MODE) 459 qdf_dp_trace_disable_live_mode(); 460 } 461 #else 462 void dp_trace_init(struct wlan_objmgr_psoc *psoc) 463 { 464 } 465 466 void dp_set_dump_dp_trace(uint16_t cmd_type, uint16_t count) 467 { 468 } 469 #endif 470 #ifdef WLAN_FEATURE_DP_BUS_BANDWIDTH 471 /** 472 * dp_ini_bus_bandwidth() - Initialize INIs concerned about bus bandwidth 473 * @config: pointer to dp config 474 * @psoc: pointer to psoc obj 475 * 476 * Return: none 477 */ 478 static void dp_ini_bus_bandwidth(struct wlan_dp_psoc_cfg *config, 479 struct wlan_objmgr_psoc *psoc) 480 { 481 config->bus_bw_super_high_threshold = 482 cfg_get(psoc, CFG_DP_BUS_BANDWIDTH_SUPER_HIGH_THRESHOLD); 483 config->bus_bw_ultra_high_threshold = 484 cfg_get(psoc, CFG_DP_BUS_BANDWIDTH_ULTRA_HIGH_THRESHOLD); 485 config->bus_bw_very_high_threshold = 486 cfg_get(psoc, CFG_DP_BUS_BANDWIDTH_VERY_HIGH_THRESHOLD); 487 config->bus_bw_dbs_threshold = 488 cfg_get(psoc, CFG_DP_BUS_BANDWIDTH_DBS_THRESHOLD); 489 config->bus_bw_mid_high_threshold = 490 cfg_get(psoc, CFG_DP_BUS_BANDWIDTH_MID_HIGH_THRESHOLD); 491 config->bus_bw_high_threshold = 492 cfg_get(psoc, CFG_DP_BUS_BANDWIDTH_HIGH_THRESHOLD); 493 config->bus_bw_medium_threshold = 494 cfg_get(psoc, CFG_DP_BUS_BANDWIDTH_MEDIUM_THRESHOLD); 495 config->bus_bw_low_threshold = 496 cfg_get(psoc, CFG_DP_BUS_BANDWIDTH_LOW_THRESHOLD); 497 config->bus_bw_compute_interval = 498 cfg_get(psoc, CFG_DP_BUS_BANDWIDTH_COMPUTE_INTERVAL); 499 config->bus_low_cnt_threshold = 500 cfg_get(psoc, CFG_DP_BUS_LOW_BW_CNT_THRESHOLD); 501 config->enable_latency_crit_clients = 502 cfg_get(psoc, CFG_DP_BUS_HANDLE_LATENCY_CRITICAL_CLIENTS); 503 } 504 505 /** 506 * dp_ini_tcp_settings() - Initialize INIs concerned about tcp settings 507 * @config: pointer to dp config 508 * @psoc: pointer to psoc obj 509 * 510 * Return: none 511 */ 512 static void dp_ini_tcp_settings(struct wlan_dp_psoc_cfg *config, 513 struct wlan_objmgr_psoc *psoc) 514 { 515 config->enable_tcp_limit_output = 516 cfg_get(psoc, CFG_DP_ENABLE_TCP_LIMIT_OUTPUT); 517 config->enable_tcp_adv_win_scale = 518 cfg_get(psoc, CFG_DP_ENABLE_TCP_ADV_WIN_SCALE); 519 config->enable_tcp_delack = 520 cfg_get(psoc, CFG_DP_ENABLE_TCP_DELACK); 521 config->tcp_delack_thres_high = 522 cfg_get(psoc, CFG_DP_TCP_DELACK_THRESHOLD_HIGH); 523 config->tcp_delack_thres_low = 524 cfg_get(psoc, CFG_DP_TCP_DELACK_THRESHOLD_LOW); 525 config->tcp_delack_timer_count = 526 cfg_get(psoc, CFG_DP_TCP_DELACK_TIMER_COUNT); 527 config->tcp_tx_high_tput_thres = 528 cfg_get(psoc, CFG_DP_TCP_TX_HIGH_TPUT_THRESHOLD); 529 config->enable_tcp_param_update = 530 cfg_get(psoc, CFG_DP_ENABLE_TCP_PARAM_UPDATE); 531 } 532 533 #else 534 static void dp_ini_bus_bandwidth(struct wlan_dp_psoc_cfg *config, 535 struct wlan_objmgr_psoc *psoc) 536 { 537 } 538 539 static void dp_ini_tcp_settings(struct wlan_dp_psoc_cfg *config, 540 struct wlan_objmgr_psoc *psoc) 541 { 542 } 543 #endif /*WLAN_FEATURE_DP_BUS_BANDWIDTH*/ 544 545 #ifdef CONFIG_DP_TRACE 546 /** 547 * dp_trace_cfg_update() - initialize DP Trace config 548 * @config : Configuration parameters 549 * @psoc: psoc handle 550 */ 551 static void 552 dp_trace_cfg_update(struct wlan_dp_psoc_cfg *config, 553 struct wlan_objmgr_psoc *psoc) 554 { 555 qdf_size_t array_out_size; 556 557 config->enable_dp_trace = cfg_get(psoc, CFG_DP_ENABLE_DP_TRACE); 558 qdf_uint8_array_parse(cfg_get(psoc, CFG_DP_DP_TRACE_CONFIG), 559 config->dp_trace_config, 560 sizeof(config->dp_trace_config), &array_out_size); 561 config->dp_proto_event_bitmap = cfg_get(psoc, 562 CFG_DP_PROTO_EVENT_BITMAP); 563 } 564 #else 565 static void 566 dp_trace_cfg_update(struct wlan_dp_psoc_cfg *config, 567 struct wlan_objmgr_psoc *psoc) 568 { 569 } 570 #endif 571 #ifdef WLAN_NUD_TRACKING 572 /** 573 * dp_nud_tracking_cfg_update() - initialize NUD Tracking config 574 * @config : Configuration parameters 575 * @psoc: psoc handle 576 */ 577 static void 578 dp_nud_tracking_cfg_update(struct wlan_dp_psoc_cfg *config, 579 struct wlan_objmgr_psoc *psoc) 580 { 581 config->enable_nud_tracking = cfg_get(psoc, CFG_DP_ENABLE_NUD_TRACKING); 582 } 583 #else 584 static void 585 dp_nud_tracking_cfg_update(struct wlan_dp_psoc_cfg *config, 586 struct wlan_objmgr_psoc *psoc) 587 { 588 } 589 #endif 590 591 #ifdef QCA_SUPPORT_TXRX_DRIVER_TCP_DEL_ACK 592 /** 593 * dp_ini_tcp_del_ack_settings() - initialize TCP delack config 594 * @config : Configuration parameters 595 * @psoc: psoc handle 596 */ 597 static void dp_ini_tcp_del_ack_settings(struct wlan_dp_psoc_cfg *config, 598 struct wlan_objmgr_psoc *psoc) 599 { 600 config->del_ack_threshold_high = 601 cfg_get(psoc, CFG_DP_DRIVER_TCP_DELACK_HIGH_THRESHOLD); 602 config->del_ack_threshold_low = 603 cfg_get(psoc, CFG_DP_DRIVER_TCP_DELACK_LOW_THRESHOLD); 604 config->del_ack_enable = 605 cfg_get(psoc, CFG_DP_DRIVER_TCP_DELACK_ENABLE); 606 config->del_ack_pkt_count = 607 cfg_get(psoc, CFG_DP_DRIVER_TCP_DELACK_PKT_CNT); 608 config->del_ack_timer_value = 609 cfg_get(psoc, CFG_DP_DRIVER_TCP_DELACK_TIMER_VALUE); 610 } 611 #else 612 static void dp_ini_tcp_del_ack_settings(struct wlan_dp_psoc_cfg *config, 613 struct wlan_objmgr_psoc *psoc) 614 { 615 } 616 #endif 617 618 #ifdef WLAN_SUPPORT_TXRX_HL_BUNDLE 619 /** 620 * dp_hl_bundle_cfg_update() - initialize TxRx HL bundle config 621 * @config : Configuration parameters 622 * @psoc: psoc handle 623 */ 624 static void dp_hl_bundle_cfg_update(struct wlan_dp_psoc_cfg *config, 625 struct wlan_objmgr_psoc *psoc) 626 { 627 config->pkt_bundle_threshold_high = 628 cfg_get(psoc, CFG_DP_HL_BUNDLE_HIGH_TH); 629 config->pkt_bundle_threshold_low = 630 cfg_get(psoc, CFG_DP_HL_BUNDLE_LOW_TH); 631 config->pkt_bundle_timer_value = 632 cfg_get(psoc, CFG_DP_HL_BUNDLE_TIMER_VALUE); 633 config->pkt_bundle_size = 634 cfg_get(psoc, CFG_DP_HL_BUNDLE_SIZE); 635 } 636 #else 637 static void dp_hl_bundle_cfg_update(struct wlan_dp_psoc_cfg *config, 638 struct wlan_objmgr_psoc *psoc) 639 { 640 } 641 #endif 642 643 /** 644 * dp_set_rx_mode_value() - set rx_mode values 645 * @dp_ctx: DP context 646 * 647 * Return: none 648 */ 649 static void dp_set_rx_mode_value(struct wlan_dp_psoc_context *dp_ctx) 650 { 651 uint32_t rx_mode = dp_ctx->dp_cfg.rx_mode; 652 enum QDF_GLOBAL_MODE con_mode = 0; 653 654 con_mode = cds_get_conparam(); 655 656 /* RPS has higher priority than dynamic RPS when both bits are set */ 657 if (rx_mode & CFG_ENABLE_RPS && rx_mode & CFG_ENABLE_DYNAMIC_RPS) 658 rx_mode &= ~CFG_ENABLE_DYNAMIC_RPS; 659 660 if (rx_mode & CFG_ENABLE_RX_THREAD && rx_mode & CFG_ENABLE_RPS) { 661 dp_warn("rx_mode wrong configuration. Make it default"); 662 rx_mode = CFG_RX_MODE_DEFAULT; 663 } 664 665 if (rx_mode & CFG_ENABLE_RX_THREAD) { 666 dp_ctx->enable_rxthread = true; 667 } else if (rx_mode & CFG_ENABLE_DP_RX_THREADS) { 668 if (con_mode == QDF_GLOBAL_MONITOR_MODE) 669 dp_ctx->enable_dp_rx_threads = false; 670 else 671 dp_ctx->enable_dp_rx_threads = true; 672 } 673 674 if (rx_mode & CFG_ENABLE_RPS) 675 dp_ctx->rps = true; 676 677 if (rx_mode & CFG_ENABLE_NAPI) 678 dp_ctx->napi_enable = true; 679 680 if (rx_mode & CFG_ENABLE_DYNAMIC_RPS) 681 dp_ctx->dynamic_rps = true; 682 683 dp_info("rx_mode:%u dp_rx_threads:%u rx_thread:%u napi:%u rps:%u dynamic rps %u", 684 rx_mode, dp_ctx->enable_dp_rx_threads, 685 dp_ctx->enable_rxthread, dp_ctx->napi_enable, 686 dp_ctx->rps, dp_ctx->dynamic_rps); 687 } 688 689 /** 690 * dp_cfg_init() - initialize target specific configuration 691 * @ctx: dp context handle 692 */ 693 static void dp_cfg_init(struct wlan_dp_psoc_context *ctx) 694 { 695 struct wlan_dp_psoc_cfg *config = &ctx->dp_cfg; 696 struct wlan_objmgr_psoc *psoc = ctx->psoc; 697 uint16_t cfg_len; 698 699 cfg_len = qdf_str_len(cfg_get(psoc, CFG_DP_RPS_RX_QUEUE_CPU_MAP_LIST)) 700 + 1; 701 dp_ini_bus_bandwidth(config, psoc); 702 dp_ini_tcp_settings(config, psoc); 703 704 dp_ini_tcp_del_ack_settings(config, psoc); 705 706 dp_hl_bundle_cfg_update(config, psoc); 707 708 config->rx_thread_ul_affinity_mask = 709 cfg_get(psoc, CFG_DP_RX_THREAD_UL_CPU_MASK); 710 config->rx_thread_affinity_mask = 711 cfg_get(psoc, CFG_DP_RX_THREAD_CPU_MASK); 712 if (cfg_len < CFG_DP_RPS_RX_QUEUE_CPU_MAP_LIST_LEN) { 713 qdf_str_lcopy(config->cpu_map_list, 714 cfg_get(psoc, CFG_DP_RPS_RX_QUEUE_CPU_MAP_LIST), 715 cfg_len); 716 } else { 717 dp_err("ini string length greater than max size %d", 718 CFG_DP_RPS_RX_QUEUE_CPU_MAP_LIST_LEN); 719 cfg_len = qdf_str_len(cfg_default(CFG_DP_RPS_RX_QUEUE_CPU_MAP_LIST)); 720 qdf_str_lcopy(config->cpu_map_list, 721 cfg_default(CFG_DP_RPS_RX_QUEUE_CPU_MAP_LIST), 722 cfg_len); 723 } 724 config->tx_orphan_enable = cfg_get(psoc, CFG_DP_TX_ORPHAN_ENABLE); 725 config->rx_mode = cfg_get(psoc, CFG_DP_RX_MODE); 726 dp_set_rx_mode_value(ctx); 727 config->multicast_replay_filter = 728 cfg_get(psoc, CFG_DP_FILTER_MULTICAST_REPLAY); 729 config->rx_wakelock_timeout = 730 cfg_get(psoc, CFG_DP_RX_WAKELOCK_TIMEOUT); 731 config->num_dp_rx_threads = cfg_get(psoc, CFG_DP_NUM_DP_RX_THREADS); 732 config->icmp_req_to_fw_mark_interval = 733 cfg_get(psoc, CFG_DP_ICMP_REQ_TO_FW_MARK_INTERVAL); 734 735 config->rx_softirq_max_yield_duration_ns = 736 cfg_get(psoc, 737 CFG_DP_RX_SOFTIRQ_MAX_YIELD_TIME_NS); 738 739 dp_trace_cfg_update(config, psoc); 740 dp_nud_tracking_cfg_update(config, psoc); 741 dp_trace_cfg_update(config, psoc); 742 dp_fisa_cfg_init(config, psoc); 743 } 744 745 /** 746 * __dp_process_mic_error() - Indicate mic error to supplicant 747 * @dp_intf: Pointer to dp interface 748 * 749 * Return: None 750 */ 751 static void 752 __dp_process_mic_error(struct wlan_dp_intf *dp_intf) 753 { 754 struct wlan_dp_psoc_callbacks *ops = &dp_intf->dp_ctx->dp_ops; 755 struct wlan_objmgr_vdev *vdev; 756 757 vdev = dp_objmgr_get_vdev_by_user(dp_intf->def_link, WLAN_DP_ID); 758 if (!vdev) { 759 return; 760 } 761 762 if ((dp_intf->device_mode == QDF_STA_MODE || 763 dp_intf->device_mode == QDF_P2P_CLIENT_MODE) && 764 wlan_cm_is_vdev_active(vdev)) 765 ops->osif_dp_process_mic_error(dp_intf->mic_work.info, 766 vdev); 767 else if (dp_intf->device_mode == QDF_SAP_MODE || 768 dp_intf->device_mode == QDF_P2P_GO_MODE) 769 ops->osif_dp_process_mic_error(dp_intf->mic_work.info, 770 vdev); 771 else 772 dp_err("Invalid interface type:%d", dp_intf->device_mode); 773 774 dp_objmgr_put_vdev_by_user(vdev, WLAN_DP_ID); 775 } 776 777 /** 778 * dp_process_mic_error() - process mic error work 779 * @data: void pointer to dp interface 780 * 781 * Return: None 782 */ 783 static void 784 dp_process_mic_error(void *data) 785 { 786 struct wlan_dp_intf *dp_intf = data; 787 788 if (is_dp_intf_valid(dp_intf)) 789 goto exit; 790 791 __dp_process_mic_error(dp_intf); 792 793 exit: 794 qdf_spin_lock_bh(&dp_intf->mic_work.lock); 795 if (dp_intf->mic_work.info) { 796 qdf_mem_free(dp_intf->mic_work.info); 797 dp_intf->mic_work.info = NULL; 798 } 799 if (dp_intf->mic_work.status == DP_MIC_SCHEDULED) 800 dp_intf->mic_work.status = DP_MIC_INITIALIZED; 801 qdf_spin_unlock_bh(&dp_intf->mic_work.lock); 802 } 803 804 void 805 dp_rx_mic_error_ind(struct cdp_ctrl_objmgr_psoc *psoc, uint8_t pdev_id, 806 struct cdp_rx_mic_err_info *mic_failure_info) 807 { 808 struct dp_mic_error_info *dp_mic_info; 809 struct wlan_objmgr_vdev *vdev; 810 struct wlan_dp_intf *dp_intf; 811 struct wlan_dp_link *dp_link; 812 813 if (!psoc) 814 return; 815 816 vdev = wlan_objmgr_get_vdev_by_id_from_psoc((struct wlan_objmgr_psoc *)psoc, 817 mic_failure_info->vdev_id, 818 WLAN_DP_ID); 819 if (!vdev) 820 return; 821 dp_link = dp_get_vdev_priv_obj(vdev); 822 if (!dp_link) { 823 dp_comp_vdev_put_ref(vdev); 824 return; 825 } 826 827 dp_intf = dp_link->dp_intf; 828 dp_mic_info = qdf_mem_malloc(sizeof(*dp_mic_info)); 829 if (!dp_mic_info) { 830 dp_comp_vdev_put_ref(vdev); 831 return; 832 } 833 834 qdf_copy_macaddr(&dp_mic_info->ta_mac_addr, 835 &mic_failure_info->ta_mac_addr); 836 dp_mic_info->multicast = mic_failure_info->multicast; 837 dp_mic_info->key_id = mic_failure_info->key_id; 838 qdf_mem_copy(&dp_mic_info->tsc, &mic_failure_info->tsc, 839 SIR_CIPHER_SEQ_CTR_SIZE); 840 dp_mic_info->vdev_id = mic_failure_info->vdev_id; 841 842 qdf_spin_lock_bh(&dp_intf->mic_work.lock); 843 if (dp_intf->mic_work.status != DP_MIC_INITIALIZED) { 844 qdf_spin_unlock_bh(&dp_intf->mic_work.lock); 845 qdf_mem_free(dp_mic_info); 846 dp_comp_vdev_put_ref(vdev); 847 return; 848 } 849 /* 850 * Store mic error info pointer in dp_intf 851 * for freeing up the allocated memory in case 852 * the work scheduled below is flushed or deinitialized. 853 */ 854 dp_intf->mic_work.status = DP_MIC_SCHEDULED; 855 dp_intf->mic_work.info = dp_mic_info; 856 qdf_sched_work(0, &dp_intf->mic_work.work); 857 qdf_spin_unlock_bh(&dp_intf->mic_work.lock); 858 dp_comp_vdev_put_ref(vdev); 859 } 860 861 /** 862 * dp_mic_flush_work() - disable and flush pending mic work 863 * @dp_intf: Pointer to dp interface 864 * 865 * Return: None 866 */ 867 static void 868 dp_mic_flush_work(struct wlan_dp_intf *dp_intf) 869 { 870 dp_info("Flush the MIC error work"); 871 872 qdf_spin_lock_bh(&dp_intf->mic_work.lock); 873 if (dp_intf->mic_work.status != DP_MIC_SCHEDULED) { 874 qdf_spin_unlock_bh(&dp_intf->mic_work.lock); 875 return; 876 } 877 dp_intf->mic_work.status = DP_MIC_DISABLED; 878 qdf_spin_unlock_bh(&dp_intf->mic_work.lock); 879 880 qdf_flush_work(&dp_intf->mic_work.work); 881 } 882 883 /** 884 * dp_mic_enable_work() - enable mic error work 885 * @dp_intf: Pointer to dp interface 886 * 887 * Return: None 888 */ 889 static void dp_mic_enable_work(struct wlan_dp_intf *dp_intf) 890 { 891 dp_info("Enable the MIC error work"); 892 893 qdf_spin_lock_bh(&dp_intf->mic_work.lock); 894 if (dp_intf->mic_work.status == DP_MIC_DISABLED) 895 dp_intf->mic_work.status = DP_MIC_INITIALIZED; 896 qdf_spin_unlock_bh(&dp_intf->mic_work.lock); 897 } 898 899 void dp_mic_deinit_work(struct wlan_dp_intf *dp_intf) 900 { 901 dp_info("DeInitialize the MIC error work"); 902 903 if (dp_intf->mic_work.status != DP_MIC_UNINITIALIZED) { 904 qdf_destroy_work(NULL, &dp_intf->mic_work.work); 905 906 qdf_spin_lock_bh(&dp_intf->mic_work.lock); 907 dp_intf->mic_work.status = DP_MIC_UNINITIALIZED; 908 if (dp_intf->mic_work.info) { 909 qdf_mem_free(dp_intf->mic_work.info); 910 dp_intf->mic_work.info = NULL; 911 } 912 qdf_spin_unlock_bh(&dp_intf->mic_work.lock); 913 qdf_spinlock_destroy(&dp_intf->mic_work.lock); 914 } 915 } 916 917 void dp_mic_init_work(struct wlan_dp_intf *dp_intf) 918 { 919 qdf_spinlock_create(&dp_intf->mic_work.lock); 920 qdf_create_work(0, &dp_intf->mic_work.work, 921 dp_process_mic_error, dp_intf); 922 dp_intf->mic_work.status = DP_MIC_INITIALIZED; 923 dp_intf->mic_work.info = NULL; 924 } 925 926 #ifdef WLAN_FEATURE_11BE_MLO 927 /** 928 * dp_intf_get_next_deflink_candidate() - Get a candidate link from the list of 929 * links available in the dp interface. 930 * @dp_intf: DP interface handle 931 * @cur_def_link: Handle to current def_link in the DP interface 932 * 933 * Return: Handle of the candidate for next def_link 934 * NULL, if there is no other suitable candidate found. 935 */ 936 static struct wlan_dp_link * 937 dp_intf_get_next_deflink_candidate(struct wlan_dp_intf *dp_intf, 938 struct wlan_dp_link *cur_def_link) 939 { 940 struct wlan_dp_link *dp_link, *dp_link_next; 941 942 dp_for_each_link_held_safe(dp_intf, dp_link, dp_link_next) { 943 /* 944 * dp_link is removed from the list when its deleted. 945 * But check if its valid or not. Additional check to make 946 * sure that the next deflink is valid. 947 */ 948 if (!is_dp_link_valid(dp_link)) 949 continue; 950 951 if (dp_link != cur_def_link) 952 return dp_link; 953 } 954 955 return NULL; 956 } 957 958 /** 959 * dp_change_def_link() - Change default link for the dp_intf 960 * @dp_intf: DP interface for which default link is to be changed 961 * @dp_link: link on which link switch notification arrived. 962 * @lswitch_req: Link switch request params 963 * 964 * This API is called only when dp_intf->def_link == dp_link, 965 * and there is a need to change the def_link of the dp_intf, 966 * due to any reason. 967 * 968 * Return: QDF_STATUS 969 */ 970 static inline QDF_STATUS 971 dp_change_def_link(struct wlan_dp_intf *dp_intf, 972 struct wlan_dp_link *dp_link, 973 struct wlan_mlo_link_switch_req *lswitch_req) 974 { 975 struct wlan_dp_psoc_context *dp_ctx = dp_intf->dp_ctx; 976 struct wlan_dp_link *next_def_link; 977 cdp_config_param_type peer_param = {0}; 978 QDF_STATUS status; 979 980 next_def_link = dp_intf_get_next_deflink_candidate(dp_intf, dp_link); 981 if (!is_dp_link_valid(next_def_link)) { 982 /* Unable to get candidate for next def_link */ 983 dp_info("Unable to get next def link %pK", next_def_link); 984 return QDF_STATUS_E_FAILURE; 985 } 986 987 /* 988 * Switch dp_vdev related params 989 * - Change vdev of MLD peer. 990 */ 991 dp_info("Peer " QDF_MAC_ADDR_FMT ", change vdev %d -> %d", 992 QDF_MAC_ADDR_REF(lswitch_req->peer_mld_addr.bytes), 993 dp_link->link_id, next_def_link->link_id); 994 peer_param.new_vdev_id = next_def_link->link_id; 995 status = cdp_txrx_set_peer_param(dp_ctx->cdp_soc, 996 /* Current vdev for remote MLD peer */ 997 dp_link->link_id, 998 lswitch_req->peer_mld_addr.bytes, 999 CDP_CONFIG_MLD_PEER_VDEV, 1000 peer_param); 1001 1002 /* 1003 * DP link switch checks and process is completed successfully. 1004 * Change the def_link to the partner link 1005 */ 1006 if (QDF_IS_STATUS_SUCCESS(status)) 1007 dp_intf->def_link = next_def_link; 1008 1009 return status; 1010 } 1011 1012 QDF_STATUS 1013 dp_link_switch_notification(struct wlan_objmgr_vdev *vdev, 1014 struct wlan_mlo_link_switch_req *lswitch_req) 1015 { 1016 /* Add prints to string and print it at last, so we have only 1 print */ 1017 struct wlan_dp_psoc_context *dp_ctx; 1018 struct wlan_dp_intf *dp_intf; 1019 struct wlan_dp_link *dp_link; 1020 QDF_STATUS status = QDF_STATUS_SUCCESS; 1021 1022 dp_ctx = dp_get_context(); 1023 1024 dp_link = dp_get_vdev_priv_obj(vdev); 1025 if (!is_dp_link_valid(dp_link)) { 1026 dp_err("dp_link from vdev %pK is invalid", vdev); 1027 return QDF_STATUS_E_INVAL; 1028 } 1029 1030 dp_intf = dp_link->dp_intf; 1031 dp_info("Link switch req for dp_link %pK id %d (" QDF_MAC_ADDR_FMT 1032 "), dp_intf %pK (" QDF_MAC_ADDR_FMT 1033 ") cur_def_link %pK id %d device_mode %d num_links %d", 1034 dp_link, dp_link->link_id, 1035 QDF_MAC_ADDR_REF(dp_link->mac_addr.bytes), 1036 dp_intf, QDF_MAC_ADDR_REF(dp_intf->mac_addr.bytes), 1037 dp_intf->def_link, dp_intf->def_link->link_id, 1038 dp_intf->device_mode, dp_intf->num_links); 1039 1040 if (dp_intf->device_mode != QDF_STA_MODE) { 1041 /* Link switch supported only for STA mode */ 1042 status = QDF_STATUS_E_INVAL; 1043 goto exit; 1044 } 1045 1046 if (dp_intf->num_links == 1) { 1047 /* There is only one link, so we cannot switch */ 1048 status = QDF_STATUS_E_CANCELED; 1049 goto exit; 1050 } 1051 1052 if (dp_link != dp_intf->def_link) { 1053 /* default link is not being switched, so DP is fine */ 1054 goto exit; 1055 } 1056 1057 /* Recipe to be done before switching a default link */ 1058 status = dp_change_def_link(dp_intf, dp_link, lswitch_req); 1059 if (QDF_IS_STATUS_ERROR(status)) { 1060 /* Failed to switch default link */ 1061 dp_info("Failed to change def_link for dp_intf %pK", dp_intf); 1062 goto exit; 1063 } 1064 1065 exit: 1066 dp_info("Link switch req %s (ret %d) for dp_link %pK id %d (" 1067 QDF_MAC_ADDR_FMT "), dp_intf %pK (" QDF_MAC_ADDR_FMT 1068 ") cur_def_link %pK id %d device_mode %d num_links %d", 1069 QDF_IS_STATUS_ERROR(status) ? "Failed" : "Successful", 1070 status, dp_link, dp_link->link_id, 1071 QDF_MAC_ADDR_REF(dp_link->mac_addr.bytes), 1072 dp_intf, QDF_MAC_ADDR_REF(dp_intf->mac_addr.bytes), 1073 dp_intf->def_link, dp_intf->def_link->link_id, 1074 dp_intf->device_mode, dp_intf->num_links); 1075 1076 return status; 1077 } 1078 #else 1079 static struct wlan_dp_link * 1080 dp_intf_get_next_deflink_candidate(struct wlan_dp_intf *dp_intf, 1081 struct wlan_dp_link *cur_def_link) 1082 { 1083 return NULL; 1084 } 1085 #endif 1086 1087 QDF_STATUS 1088 dp_peer_obj_create_notification(struct wlan_objmgr_peer *peer, void *arg) 1089 { 1090 struct wlan_dp_sta_info *sta_info; 1091 QDF_STATUS status; 1092 1093 sta_info = qdf_mem_malloc(sizeof(*sta_info)); 1094 if (!sta_info) 1095 return QDF_STATUS_E_NOMEM; 1096 1097 status = wlan_objmgr_peer_component_obj_attach(peer, WLAN_COMP_DP, 1098 sta_info, 1099 QDF_STATUS_SUCCESS); 1100 if (QDF_IS_STATUS_ERROR(status)) { 1101 dp_err("DP peer ("QDF_MAC_ADDR_FMT") attach failed", 1102 QDF_MAC_ADDR_REF(peer->macaddr)); 1103 qdf_mem_free(sta_info); 1104 return status; 1105 } 1106 1107 qdf_mem_copy(sta_info->sta_mac.bytes, peer->macaddr, 1108 QDF_MAC_ADDR_SIZE); 1109 sta_info->pending_eap_frm_type = 0; 1110 sta_info->dhcp_phase = DHCP_PHASE_ACK; 1111 sta_info->dhcp_nego_status = DHCP_NEGO_STOP; 1112 1113 dp_info("sta info created mac:" QDF_MAC_ADDR_FMT, 1114 QDF_MAC_ADDR_REF(sta_info->sta_mac.bytes)); 1115 1116 return status; 1117 } 1118 1119 QDF_STATUS 1120 dp_peer_obj_destroy_notification(struct wlan_objmgr_peer *peer, void *arg) 1121 { 1122 struct wlan_dp_sta_info *sta_info; 1123 QDF_STATUS status; 1124 1125 sta_info = dp_get_peer_priv_obj(peer); 1126 if (!sta_info) { 1127 dp_err("DP_peer_obj is NULL"); 1128 return QDF_STATUS_E_FAULT; 1129 } 1130 1131 status = wlan_objmgr_peer_component_obj_detach(peer, WLAN_COMP_DP, 1132 sta_info); 1133 if (QDF_IS_STATUS_ERROR(status)) 1134 dp_err("DP peer ("QDF_MAC_ADDR_FMT") detach failed", 1135 QDF_MAC_ADDR_REF(peer->macaddr)); 1136 1137 qdf_mem_free(sta_info); 1138 1139 return status; 1140 } 1141 1142 QDF_STATUS 1143 dp_vdev_obj_create_notification(struct wlan_objmgr_vdev *vdev, void *arg) 1144 { 1145 struct wlan_objmgr_psoc *psoc; 1146 struct wlan_dp_psoc_context *dp_ctx; 1147 struct wlan_dp_intf *dp_intf; 1148 struct wlan_dp_link *dp_link; 1149 QDF_STATUS status = QDF_STATUS_SUCCESS; 1150 struct qdf_mac_addr *mac_addr; 1151 qdf_netdev_t dev; 1152 1153 dp_info("DP VDEV OBJ create notification, vdev_id %d", 1154 wlan_vdev_get_id(vdev)); 1155 1156 psoc = wlan_vdev_get_psoc(vdev); 1157 if (!psoc) { 1158 dp_err("Failed to get psoc"); 1159 return QDF_STATUS_E_INVAL; 1160 } 1161 1162 dp_ctx = dp_psoc_get_priv(psoc); 1163 mac_addr = (struct qdf_mac_addr *)wlan_vdev_mlme_get_macaddr(vdev); 1164 1165 dev = dp_ctx->dp_ops.dp_get_netdev_by_vdev_mac(mac_addr); 1166 if (!dev) { 1167 dp_err("Failed to get intf mac:" QDF_MAC_ADDR_FMT, 1168 QDF_MAC_ADDR_REF(mac_addr->bytes)); 1169 return QDF_STATUS_E_INVAL; 1170 } 1171 1172 dp_intf = dp_get_intf_by_netdev(dp_ctx, dev); 1173 if (!dp_intf) { 1174 dp_err("Failed to get dp intf dev: %s", 1175 qdf_netdev_get_devname(dev)); 1176 1177 return QDF_STATUS_E_INVAL; 1178 } 1179 1180 dp_link = qdf_mem_malloc(sizeof(*dp_link)); 1181 if (!dp_link) { 1182 dp_err("DP link(" QDF_MAC_ADDR_FMT ") memory alloc failed", 1183 QDF_MAC_ADDR_REF(mac_addr->bytes)); 1184 return QDF_STATUS_E_NOMEM; 1185 } 1186 1187 /* Update Parent interface details */ 1188 dp_link->dp_intf = dp_intf; 1189 qdf_spin_lock_bh(&dp_intf->dp_link_list_lock); 1190 qdf_list_insert_front(&dp_intf->dp_link_list, &dp_link->node); 1191 dp_intf->num_links++; 1192 qdf_spin_unlock_bh(&dp_intf->dp_link_list_lock); 1193 1194 qdf_copy_macaddr(&dp_link->mac_addr, mac_addr); 1195 qdf_spinlock_create(&dp_link->vdev_lock); 1196 1197 qdf_spin_lock_bh(&dp_link->vdev_lock); 1198 dp_link->link_id = vdev->vdev_objmgr.vdev_id; 1199 dp_link->vdev = vdev; 1200 qdf_spin_unlock_bh(&dp_link->vdev_lock); 1201 1202 status = wlan_objmgr_vdev_component_obj_attach(vdev, 1203 WLAN_COMP_DP, 1204 (void *)dp_link, 1205 QDF_STATUS_SUCCESS); 1206 if (QDF_IS_STATUS_ERROR(status)) { 1207 dp_err("Failed to attach dp_link with vdev"); 1208 return status; 1209 } 1210 1211 if (dp_intf->num_links == 1) { 1212 /* 1213 * Interface level operations to be done only 1214 * when the first link is created 1215 */ 1216 dp_intf->def_link = dp_link; 1217 dp_intf->device_mode = wlan_vdev_mlme_get_opmode(vdev); 1218 qdf_atomic_init(&dp_intf->num_active_task); 1219 dp_nud_ignore_tracking(dp_intf, false); 1220 dp_mic_enable_work(dp_intf); 1221 1222 if (dp_intf->device_mode == QDF_SAP_MODE || 1223 dp_intf->device_mode == QDF_P2P_GO_MODE) { 1224 dp_intf->sap_tx_block_mask = DP_TX_FN_CLR | 1225 DP_TX_SAP_STOP; 1226 1227 status = qdf_event_create(&dp_intf->qdf_sta_eap_frm_done_event); 1228 if (!QDF_IS_STATUS_SUCCESS(status)) { 1229 dp_err("eap frm done event init failed!!"); 1230 return status; 1231 } 1232 qdf_mem_zero(&dp_intf->stats, 1233 sizeof(qdf_net_dev_stats)); 1234 } 1235 } 1236 1237 return status; 1238 } 1239 1240 QDF_STATUS 1241 dp_vdev_obj_destroy_notification(struct wlan_objmgr_vdev *vdev, void *arg) 1242 1243 { 1244 struct wlan_dp_intf *dp_intf; 1245 struct wlan_dp_link *dp_link; 1246 QDF_STATUS status = QDF_STATUS_SUCCESS; 1247 1248 dp_info("DP VDEV OBJ destroy notification, vdev_id %d", 1249 wlan_vdev_get_id(vdev)); 1250 1251 dp_link = dp_get_vdev_priv_obj(vdev); 1252 if (!dp_link) { 1253 dp_err("Failed to get DP link obj"); 1254 return QDF_STATUS_E_INVAL; 1255 } 1256 1257 dp_intf = dp_link->dp_intf; 1258 1259 qdf_spin_lock_bh(&dp_intf->dp_link_list_lock); 1260 qdf_list_remove_node(&dp_intf->dp_link_list, &dp_link->node); 1261 dp_intf->num_links--; 1262 qdf_spin_unlock_bh(&dp_intf->dp_link_list_lock); 1263 1264 if (dp_intf->num_links == 0) { 1265 /* 1266 * Interface level operations are stopped when last 1267 * link is deleted 1268 */ 1269 dp_nud_ignore_tracking(dp_intf, true); 1270 dp_nud_reset_tracking(dp_intf); 1271 dp_nud_flush_work(dp_intf); 1272 dp_mic_flush_work(dp_intf); 1273 1274 if (dp_intf->device_mode == QDF_SAP_MODE || 1275 dp_intf->device_mode == QDF_P2P_GO_MODE) { 1276 status = qdf_event_destroy(&dp_intf->qdf_sta_eap_frm_done_event); 1277 if (!QDF_IS_STATUS_SUCCESS(status)) { 1278 dp_err("eap frm done event destroy failed!!"); 1279 return status; 1280 } 1281 dp_intf->txrx_ops.tx.tx = NULL; 1282 dp_intf->sap_tx_block_mask |= DP_TX_FN_CLR; 1283 } 1284 } 1285 1286 qdf_mem_zero(&dp_link->conn_info, sizeof(struct wlan_dp_conn_info)); 1287 1288 /* 1289 * If the dp_link which is being destroyed is the default link, 1290 * then find a new link to be made the default link 1291 */ 1292 if (dp_intf->def_link == dp_link) 1293 dp_intf->def_link = 1294 dp_intf_get_next_deflink_candidate(dp_intf, dp_link); 1295 1296 /* 1297 * Change this to link level, since during link switch, 1298 * it might not go to 0 1299 */ 1300 status = dp_intf_wait_for_task_complete(dp_intf); 1301 if (QDF_IS_STATUS_ERROR(status)) 1302 return status; 1303 1304 qdf_spin_lock_bh(&dp_link->vdev_lock); 1305 dp_link->vdev = NULL; 1306 qdf_spin_unlock_bh(&dp_link->vdev_lock); 1307 1308 qdf_spinlock_destroy(&dp_link->vdev_lock); 1309 1310 status = wlan_objmgr_vdev_component_obj_detach(vdev, 1311 WLAN_COMP_DP, 1312 (void *)dp_link); 1313 if (QDF_IS_STATUS_ERROR(status)) { 1314 dp_err("Failed to detach dp_link with vdev"); 1315 return status; 1316 } 1317 1318 qdf_mem_free(dp_link); 1319 return status; 1320 } 1321 1322 QDF_STATUS 1323 dp_pdev_obj_create_notification(struct wlan_objmgr_pdev *pdev, void *arg) 1324 { 1325 struct wlan_objmgr_psoc *psoc; 1326 struct wlan_dp_psoc_context *dp_ctx; 1327 QDF_STATUS status; 1328 1329 dp_info("DP PDEV OBJ create notification"); 1330 psoc = wlan_pdev_get_psoc(pdev); 1331 if (!psoc) { 1332 obj_mgr_err("psoc is NULL in pdev"); 1333 return QDF_STATUS_E_FAILURE; 1334 } 1335 dp_ctx = dp_psoc_get_priv(psoc); 1336 if (!dp_ctx) { 1337 dp_err("Failed to get dp_ctx from psoc"); 1338 return QDF_STATUS_E_FAILURE; 1339 } 1340 status = wlan_objmgr_pdev_component_obj_attach(pdev, 1341 WLAN_COMP_DP, 1342 (void *)dp_ctx, 1343 QDF_STATUS_SUCCESS); 1344 if (QDF_IS_STATUS_ERROR(status)) { 1345 dp_err("Failed to attach dp_ctx to pdev"); 1346 return status; 1347 } 1348 1349 dp_ctx->pdev = pdev; 1350 return status; 1351 } 1352 1353 QDF_STATUS 1354 dp_pdev_obj_destroy_notification(struct wlan_objmgr_pdev *pdev, void *arg) 1355 { 1356 struct wlan_objmgr_psoc *psoc; 1357 struct wlan_dp_psoc_context *dp_ctx; 1358 QDF_STATUS status; 1359 1360 dp_info("DP PDEV OBJ destroy notification"); 1361 psoc = wlan_pdev_get_psoc(pdev); 1362 if (!psoc) { 1363 obj_mgr_err("psoc is NULL in pdev"); 1364 return QDF_STATUS_E_FAILURE; 1365 } 1366 1367 dp_ctx = wlan_objmgr_pdev_get_comp_private_obj(pdev, WLAN_COMP_DP); 1368 if (!dp_ctx) { 1369 dp_err("Failed to get dp_ctx from pdev"); 1370 return QDF_STATUS_E_FAILURE; 1371 } 1372 status = wlan_objmgr_pdev_component_obj_detach(pdev, 1373 WLAN_COMP_DP, 1374 dp_ctx); 1375 if (QDF_IS_STATUS_ERROR(status)) { 1376 dp_err("Failed to detach dp_ctx from pdev"); 1377 return status; 1378 } 1379 if (!dp_ctx->pdev) 1380 dp_err("DP Pdev is NULL"); 1381 1382 dp_ctx->pdev = NULL; 1383 return status; 1384 } 1385 1386 QDF_STATUS 1387 dp_psoc_obj_create_notification(struct wlan_objmgr_psoc *psoc, void *arg) 1388 { 1389 struct wlan_dp_psoc_context *dp_ctx = gp_dp_ctx; 1390 QDF_STATUS status; 1391 1392 status = wlan_objmgr_psoc_component_obj_attach( 1393 psoc, WLAN_COMP_DP, 1394 dp_ctx, QDF_STATUS_SUCCESS); 1395 if (QDF_IS_STATUS_ERROR(status)) { 1396 dp_err("Failed to attach psoc component obj"); 1397 return status; 1398 } 1399 1400 dp_ctx->psoc = psoc; 1401 dp_cfg_init(dp_ctx); 1402 target_if_dp_register_tx_ops(&dp_ctx->sb_ops); 1403 target_if_dp_register_rx_ops(&dp_ctx->nb_ops); 1404 1405 return status; 1406 } 1407 1408 QDF_STATUS 1409 dp_psoc_obj_destroy_notification(struct wlan_objmgr_psoc *psoc, void *arg) 1410 { 1411 struct wlan_dp_psoc_context *dp_ctx; 1412 QDF_STATUS status; 1413 1414 dp_ctx = dp_psoc_get_priv(psoc); 1415 if (!dp_ctx) { 1416 dp_err("psoc priv is NULL"); 1417 return QDF_STATUS_E_FAILURE; 1418 } 1419 1420 status = wlan_objmgr_psoc_component_obj_detach( 1421 psoc, WLAN_COMP_DP, 1422 dp_ctx); 1423 if (QDF_IS_STATUS_ERROR(status)) { 1424 dp_err("Failed to detach psoc component obj"); 1425 return status; 1426 } 1427 1428 dp_reset_all_intfs_connectivity_stats(dp_ctx); 1429 1430 return status; 1431 } 1432 1433 void dp_attach_ctx(struct wlan_dp_psoc_context *dp_ctx) 1434 { 1435 if (gp_dp_ctx) 1436 dp_debug("already attached global dp ctx"); 1437 gp_dp_ctx = dp_ctx; 1438 } 1439 1440 void dp_detach_ctx(void) 1441 { 1442 if (!gp_dp_ctx) { 1443 dp_err("global dp ctx is already detached"); 1444 return; 1445 } 1446 gp_dp_ctx = NULL; 1447 } 1448 1449 struct wlan_dp_psoc_context *dp_get_context(void) 1450 { 1451 return gp_dp_ctx; 1452 } 1453 1454 /** 1455 * dp_hex_string_to_u16_array() - convert a hex string to a uint16 array 1456 * @str: input string 1457 * @int_array: pointer to input array of type uint16 1458 * @len: pointer to number of elements which the function adds to the array 1459 * @int_array_max_len: maximum number of elements in input uint16 array 1460 * 1461 * This function is used to convert a space separated hex string to an array of 1462 * uint16_t. For example, an input string str = "a b c d" would be converted to 1463 * a unint16 array, int_array = {0xa, 0xb, 0xc, 0xd}, *len = 4. 1464 * This assumes that input value int_array_max_len >= 4. 1465 * 1466 * Return: QDF_STATUS_SUCCESS - if the conversion is successful 1467 * non zero value - if the conversion is a failure 1468 */ 1469 static QDF_STATUS 1470 dp_hex_string_to_u16_array(char *str, uint16_t *int_array, uint8_t *len, 1471 uint8_t int_array_max_len) 1472 { 1473 char *s = str; 1474 uint32_t val = 0; 1475 1476 if (!str || !int_array || !len) 1477 return QDF_STATUS_E_INVAL; 1478 1479 dp_debug("str %pK intArray %pK intArrayMaxLen %d", 1480 s, int_array, int_array_max_len); 1481 1482 *len = 0; 1483 1484 while ((s) && (*len < int_array_max_len)) { 1485 /* 1486 * Increment length only if sscanf successfully extracted one 1487 * element. Any other return value means error. Ignore it. 1488 */ 1489 if (sscanf(s, "%x", &val) == 1) { 1490 int_array[*len] = (uint16_t)val; 1491 dp_debug("s %pK val %x intArray[%d]=0x%x", 1492 s, val, *len, int_array[*len]); 1493 *len += 1; 1494 } 1495 s = strpbrk(s, " "); 1496 if (s) 1497 s++; 1498 } 1499 return QDF_STATUS_SUCCESS; 1500 } 1501 1502 /** 1503 * dp_get_interface() - to get dp interface matching the mode 1504 * @dp_ctx: dp context 1505 * @mode: interface mode 1506 * 1507 * This routine will return the pointer to dp interface matching 1508 * with the passed mode. 1509 * 1510 * Return: pointer to interface or null 1511 */ 1512 static struct 1513 wlan_dp_intf *dp_get_interface(struct wlan_dp_psoc_context *dp_ctx, 1514 enum QDF_OPMODE mode) 1515 { 1516 struct wlan_dp_intf *dp_intf; 1517 struct wlan_dp_intf *dp_intf_next; 1518 1519 dp_for_each_intf_held_safe(dp_ctx, dp_intf, dp_intf_next) { 1520 if (!dp_intf) 1521 continue; 1522 1523 if (dp_intf->device_mode == mode) 1524 return dp_intf; 1525 } 1526 1527 return NULL; 1528 } 1529 1530 void dp_send_rps_ind(struct wlan_dp_intf *dp_intf) 1531 { 1532 int i; 1533 uint8_t cpu_map_list_len = 0; 1534 struct wlan_dp_psoc_context *dp_ctx = dp_intf->dp_ctx; 1535 struct wlan_rps_data rps_data; 1536 struct cds_config_info *cds_cfg; 1537 1538 cds_cfg = cds_get_ini_config(); 1539 if (!cds_cfg) { 1540 dp_err("cds_cfg is NULL"); 1541 return; 1542 } 1543 1544 rps_data.num_queues = NUM_RX_QUEUES; 1545 1546 dp_info("cpu_map_list '%s'", dp_ctx->dp_cfg.cpu_map_list); 1547 1548 /* in case no cpu map list is provided, simply return */ 1549 if (!strlen(dp_ctx->dp_cfg.cpu_map_list)) { 1550 dp_info("no cpu map list found"); 1551 goto err; 1552 } 1553 1554 if (QDF_STATUS_SUCCESS != 1555 dp_hex_string_to_u16_array(dp_ctx->dp_cfg.cpu_map_list, 1556 rps_data.cpu_map_list, 1557 &cpu_map_list_len, 1558 WLAN_SVC_IFACE_NUM_QUEUES)) { 1559 dp_err("invalid cpu map list"); 1560 goto err; 1561 } 1562 1563 rps_data.num_queues = 1564 (cpu_map_list_len < rps_data.num_queues) ? 1565 cpu_map_list_len : rps_data.num_queues; 1566 1567 for (i = 0; i < rps_data.num_queues; i++) { 1568 dp_info("cpu_map_list[%d] = 0x%x", 1569 i, rps_data.cpu_map_list[i]); 1570 } 1571 1572 strlcpy(rps_data.ifname, qdf_netdev_get_devname(dp_intf->dev), 1573 sizeof(rps_data.ifname)); 1574 dp_ctx->dp_ops.dp_send_svc_nlink_msg(cds_get_radio_index(), 1575 WLAN_SVC_RPS_ENABLE_IND, 1576 &rps_data, sizeof(rps_data)); 1577 1578 cds_cfg->rps_enabled = true; 1579 1580 return; 1581 1582 err: 1583 dp_info("Wrong RPS configuration. enabling rx_thread"); 1584 cds_cfg->rps_enabled = false; 1585 } 1586 1587 void dp_try_send_rps_ind(struct wlan_objmgr_vdev *vdev) 1588 { 1589 struct wlan_dp_link *dp_link = dp_get_vdev_priv_obj(vdev); 1590 struct wlan_dp_intf *dp_intf; 1591 1592 if (!dp_link) { 1593 dp_err("dp link is NULL"); 1594 return; 1595 } 1596 1597 dp_intf = dp_link->dp_intf; 1598 if (dp_intf->dp_ctx->rps) 1599 dp_send_rps_ind(dp_intf); 1600 } 1601 1602 void dp_send_rps_disable_ind(struct wlan_dp_intf *dp_intf) 1603 { 1604 struct wlan_rps_data rps_data; 1605 struct cds_config_info *cds_cfg; 1606 1607 cds_cfg = cds_get_ini_config(); 1608 1609 if (!cds_cfg) { 1610 dp_err("cds_cfg is NULL"); 1611 return; 1612 } 1613 1614 rps_data.num_queues = NUM_RX_QUEUES; 1615 1616 dp_info("Set cpu_map_list 0"); 1617 1618 qdf_mem_zero(&rps_data.cpu_map_list, sizeof(rps_data.cpu_map_list)); 1619 1620 strlcpy(rps_data.ifname, qdf_netdev_get_devname(dp_intf->dev), 1621 sizeof(rps_data.ifname)); 1622 dp_intf->dp_ctx->dp_ops.dp_send_svc_nlink_msg(cds_get_radio_index(), 1623 WLAN_SVC_RPS_ENABLE_IND, 1624 &rps_data, sizeof(rps_data)); 1625 1626 cds_cfg->rps_enabled = false; 1627 } 1628 1629 #ifdef QCA_CONFIG_RPS 1630 void dp_set_rps(uint8_t vdev_id, bool enable) 1631 { 1632 struct wlan_objmgr_vdev *vdev; 1633 struct wlan_dp_psoc_context *dp_ctx; 1634 struct wlan_dp_intf *dp_intf; 1635 struct wlan_dp_link *dp_link; 1636 1637 dp_ctx = dp_get_context(); 1638 if (!dp_ctx) 1639 return; 1640 1641 vdev = wlan_objmgr_get_vdev_by_id_from_psoc(dp_ctx->psoc, 1642 vdev_id, WLAN_DP_ID); 1643 if (!vdev) 1644 return; 1645 1646 dp_link = dp_get_vdev_priv_obj(vdev); 1647 if (!dp_link) { 1648 dp_comp_vdev_put_ref(vdev); 1649 dp_err_rl("DP link not found for vdev_id: %d", vdev_id); 1650 return; 1651 } 1652 1653 dp_intf = dp_link->dp_intf; 1654 1655 dp_info("Set RPS to %d for vdev_id %d", enable, vdev_id); 1656 if (!dp_ctx->rps) { 1657 if (enable) 1658 dp_send_rps_ind(dp_intf); 1659 else 1660 dp_send_rps_disable_ind(dp_intf); 1661 } 1662 dp_comp_vdev_put_ref(vdev); 1663 } 1664 #endif 1665 1666 void dp_set_rx_mode_rps(bool enable) 1667 { 1668 struct wlan_dp_psoc_context *dp_ctx; 1669 struct wlan_dp_intf *dp_intf; 1670 struct cds_config_info *cds_cfg; 1671 1672 dp_ctx = dp_get_context(); 1673 cds_cfg = cds_get_ini_config(); 1674 if (!dp_ctx || !cds_cfg) 1675 return; 1676 1677 dp_intf = dp_get_interface(dp_ctx, QDF_SAP_MODE); 1678 if (!dp_intf) 1679 return; 1680 1681 if (!dp_intf->dp_ctx->rps && cds_cfg->uc_offload_enabled) { 1682 if (enable && !cds_cfg->rps_enabled) 1683 dp_send_rps_ind(dp_intf); 1684 else if (!enable && cds_cfg->rps_enabled) 1685 dp_send_rps_disable_ind(dp_intf); 1686 } 1687 } 1688 1689 void dp_set_rps_cpu_mask(struct wlan_dp_psoc_context *dp_ctx) 1690 { 1691 struct wlan_dp_intf *dp_intf; 1692 struct wlan_dp_intf *dp_intf_next; 1693 1694 dp_for_each_intf_held_safe(dp_ctx, dp_intf, dp_intf_next) { 1695 if (!dp_intf) 1696 continue; 1697 1698 dp_send_rps_ind(dp_intf); 1699 } 1700 } 1701 1702 void dp_try_set_rps_cpu_mask(struct wlan_objmgr_psoc *psoc) 1703 { 1704 struct wlan_dp_psoc_context *dp_ctx = dp_psoc_get_priv(psoc); 1705 1706 if (!dp_ctx) { 1707 dp_err("dp context is NULL"); 1708 return; 1709 } 1710 1711 if (dp_ctx->dynamic_rps) 1712 dp_set_rps_cpu_mask(dp_ctx); 1713 } 1714 1715 void dp_clear_rps_cpu_mask(struct wlan_dp_psoc_context *dp_ctx) 1716 { 1717 struct wlan_dp_intf *dp_intf; 1718 struct wlan_dp_intf *dp_intf_next; 1719 1720 dp_for_each_intf_held_safe(dp_ctx, dp_intf, dp_intf_next) { 1721 if (!dp_intf) 1722 continue; 1723 1724 dp_send_rps_disable_ind(dp_intf); 1725 } 1726 } 1727 1728 QDF_STATUS dp_get_arp_stats_event_handler(struct wlan_objmgr_psoc *psoc, 1729 struct dp_rsp_stats *rsp) 1730 { 1731 struct wlan_dp_intf *dp_intf; 1732 struct wlan_dp_link *dp_link; 1733 struct wlan_objmgr_vdev *vdev; 1734 1735 vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, 1736 rsp->vdev_id, 1737 WLAN_DP_ID); 1738 if (!vdev) { 1739 dp_err("Can't get vdev by vdev_id:%d", rsp->vdev_id); 1740 return QDF_STATUS_E_INVAL; 1741 } 1742 1743 dp_link = dp_get_vdev_priv_obj(vdev); 1744 if (!dp_link) { 1745 dp_err("Unable to get DP link for vdev_id %d", rsp->vdev_id); 1746 wlan_objmgr_vdev_release_ref(vdev, WLAN_DP_ID); 1747 return QDF_STATUS_E_INVAL; 1748 } 1749 1750 dp_intf = dp_link->dp_intf; 1751 1752 dp_info("rsp->arp_req_enqueue :%x", rsp->arp_req_enqueue); 1753 dp_info("rsp->arp_req_tx_success :%x", rsp->arp_req_tx_success); 1754 dp_info("rsp->arp_req_tx_failure :%x", rsp->arp_req_tx_failure); 1755 dp_info("rsp->arp_rsp_recvd :%x", rsp->arp_rsp_recvd); 1756 dp_info("rsp->out_of_order_arp_rsp_drop_cnt :%x", 1757 rsp->out_of_order_arp_rsp_drop_cnt); 1758 dp_info("rsp->dad_detected :%x", rsp->dad_detected); 1759 dp_info("rsp->connect_status :%x", rsp->connect_status); 1760 dp_info("rsp->ba_session_establishment_status :%x", 1761 rsp->ba_session_establishment_status); 1762 1763 dp_intf->dp_stats.arp_stats.rx_fw_cnt = rsp->arp_rsp_recvd; 1764 dp_intf->dad |= rsp->dad_detected; 1765 dp_intf->con_status = rsp->connect_status; 1766 1767 /* Flag true indicates connectivity check stats present. */ 1768 if (rsp->connect_stats_present) { 1769 dp_info("rsp->tcp_ack_recvd :%x", rsp->tcp_ack_recvd); 1770 dp_info("rsp->icmpv4_rsp_recvd :%x", rsp->icmpv4_rsp_recvd); 1771 dp_intf->dp_stats.tcp_stats.rx_fw_cnt = rsp->tcp_ack_recvd; 1772 dp_intf->dp_stats.icmpv4_stats.rx_fw_cnt = 1773 rsp->icmpv4_rsp_recvd; 1774 } 1775 1776 wlan_objmgr_vdev_release_ref(vdev, WLAN_DP_ID); 1777 return QDF_STATUS_SUCCESS; 1778 } 1779 1780 #ifdef WLAN_OBJMGR_REF_ID_TRACE 1781 struct wlan_objmgr_vdev * 1782 __dp_objmgr_get_vdev_by_user(struct wlan_dp_link *dp_link, 1783 wlan_objmgr_ref_dbgid id, 1784 const char *func, int line) 1785 { 1786 struct wlan_objmgr_vdev *vdev; 1787 QDF_STATUS status; 1788 1789 if (!dp_link) 1790 return NULL; 1791 1792 qdf_spin_lock_bh(&dp_link->vdev_lock); 1793 vdev = dp_link->vdev; 1794 if (vdev) { 1795 status = wlan_objmgr_vdev_try_get_ref_debug(vdev, id, func, 1796 line); 1797 if (QDF_IS_STATUS_ERROR(status)) 1798 vdev = NULL; 1799 } 1800 qdf_spin_unlock_bh(&dp_link->vdev_lock); 1801 1802 if (!vdev) 1803 dp_debug("VDEV is NULL (via %s, id %d)", func, id); 1804 1805 return vdev; 1806 } 1807 1808 void 1809 __dp_objmgr_put_vdev_by_user(struct wlan_objmgr_vdev *vdev, 1810 wlan_objmgr_ref_dbgid id, const char *func, 1811 int line) 1812 { 1813 if (!vdev) { 1814 dp_err("VDEV is NULL (via %s, id %d)", func, id); 1815 return; 1816 } 1817 1818 wlan_objmgr_vdev_release_ref_debug(vdev, id, func, line); 1819 } 1820 #else 1821 struct wlan_objmgr_vdev * 1822 __dp_objmgr_get_vdev_by_user(struct wlan_dp_link *dp_link, 1823 wlan_objmgr_ref_dbgid id, 1824 const char *func) 1825 { 1826 struct wlan_objmgr_vdev *vdev; 1827 QDF_STATUS status; 1828 1829 if (!dp_link) 1830 return NULL; 1831 1832 qdf_spin_lock_bh(&dp_link->vdev_lock); 1833 vdev = dp_link->vdev; 1834 if (vdev) { 1835 status = wlan_objmgr_vdev_try_get_ref(vdev, id); 1836 if (QDF_IS_STATUS_ERROR(status)) 1837 vdev = NULL; 1838 } 1839 qdf_spin_unlock_bh(&dp_link->vdev_lock); 1840 1841 if (!vdev) 1842 dp_debug("VDEV is NULL (via %s, id %d)", func, id); 1843 1844 return vdev; 1845 } 1846 1847 void 1848 __dp_objmgr_put_vdev_by_user(struct wlan_objmgr_vdev *vdev, 1849 wlan_objmgr_ref_dbgid id, const char *func) 1850 { 1851 if (!vdev) { 1852 dp_err("VDEV is NULL (via %s, id %d)", func, id); 1853 return; 1854 } 1855 1856 wlan_objmgr_vdev_release_ref(vdev, id); 1857 } 1858 #endif /* WLAN_OBJMGR_REF_ID_TRACE */ 1859 1860 bool dp_is_data_stall_event_enabled(uint32_t evt) 1861 { 1862 uint32_t bitmap = cdp_cfg_get(cds_get_context(QDF_MODULE_ID_SOC), 1863 cfg_dp_enable_data_stall); 1864 1865 if (bitmap & DP_DATA_STALL_ENABLE || bitmap & evt) 1866 return true; 1867 1868 return false; 1869 } 1870 1871 #ifdef WLAN_SUPPORT_RX_FISA 1872 static inline QDF_STATUS 1873 wlan_dp_rx_fisa_attach_target(struct wlan_dp_psoc_context *dp_ctx) 1874 { 1875 QDF_STATUS status; 1876 1877 status = dp_rx_fst_target_config(dp_ctx); 1878 if (status != QDF_STATUS_SUCCESS && 1879 status != QDF_STATUS_E_NOSUPPORT) { 1880 dp_err("Failed to send htt fst setup config message to target"); 1881 return status; 1882 } 1883 1884 if (status == QDF_STATUS_SUCCESS) { 1885 status = dp_rx_fisa_config(dp_ctx); 1886 if (QDF_IS_STATUS_ERROR(status)) { 1887 dp_err("Failed to send htt FISA config message to target"); 1888 return status; 1889 } 1890 } 1891 1892 return status; 1893 } 1894 1895 static inline QDF_STATUS 1896 wlan_dp_rx_fisa_attach(struct wlan_dp_psoc_context *dp_ctx) 1897 { 1898 return dp_rx_fst_attach(dp_ctx); 1899 } 1900 1901 static inline void wlan_dp_rx_fisa_detach(struct wlan_dp_psoc_context *dp_ctx) 1902 { 1903 return dp_rx_fst_detach(dp_ctx); 1904 } 1905 1906 static inline void 1907 wlan_dp_rx_fisa_cmem_attach(struct wlan_dp_psoc_context *dp_ctx) 1908 { 1909 dp_ctx->fst_cmem_base = cdp_get_fst_cem_base(dp_ctx->cdp_soc, 1910 DP_CMEM_FST_SIZE); 1911 } 1912 1913 static inline QDF_STATUS 1914 wlan_dp_fisa_suspend(struct wlan_dp_psoc_context *dp_ctx) 1915 { 1916 dp_suspend_fse_cache_flush(dp_ctx); 1917 dp_rx_fst_update_pm_suspend_status(dp_ctx, true); 1918 1919 return QDF_STATUS_SUCCESS; 1920 } 1921 1922 static inline QDF_STATUS 1923 wlan_dp_fisa_resume(struct wlan_dp_psoc_context *dp_ctx) 1924 { 1925 dp_resume_fse_cache_flush(dp_ctx); 1926 dp_rx_fst_update_pm_suspend_status(dp_ctx, false); 1927 dp_rx_fst_requeue_wq(dp_ctx); 1928 1929 return QDF_STATUS_SUCCESS; 1930 } 1931 #else 1932 static inline QDF_STATUS 1933 wlan_dp_rx_fisa_attach_target(struct wlan_dp_psoc_context *dp_ctx) 1934 { 1935 return QDF_STATUS_SUCCESS; 1936 } 1937 1938 static inline QDF_STATUS 1939 wlan_dp_rx_fisa_attach(struct wlan_dp_psoc_context *dp_ctx) 1940 { 1941 return QDF_STATUS_SUCCESS; 1942 } 1943 1944 static inline QDF_STATUS 1945 wlan_dp_rx_fisa_detach(struct wlan_dp_psoc_context *dp_ctx) 1946 { 1947 return QDF_STATUS_SUCCESS; 1948 } 1949 1950 static inline void 1951 wlan_dp_rx_fisa_cmem_attach(struct wlan_dp_psoc_context *dp_ctx) 1952 { 1953 } 1954 1955 static inline QDF_STATUS 1956 wlan_dp_fisa_suspend(struct wlan_dp_psoc_context *dp_ctx) 1957 { 1958 return QDF_STATUS_SUCCESS; 1959 } 1960 1961 static inline QDF_STATUS 1962 wlan_dp_fisa_resume(struct wlan_dp_psoc_context *dp_ctx) 1963 { 1964 return QDF_STATUS_SUCCESS; 1965 } 1966 #endif 1967 1968 QDF_STATUS __wlan_dp_runtime_suspend(ol_txrx_soc_handle soc, uint8_t pdev_id) 1969 { 1970 struct wlan_dp_psoc_context *dp_ctx; 1971 QDF_STATUS status; 1972 1973 dp_ctx = dp_get_context(); 1974 status = cdp_runtime_suspend(soc, pdev_id); 1975 if (QDF_IS_STATUS_ERROR(status)) 1976 return status; 1977 1978 dp_rx_fst_update_pm_suspend_status(dp_ctx, true); 1979 1980 return status; 1981 } 1982 1983 QDF_STATUS __wlan_dp_runtime_resume(ol_txrx_soc_handle soc, uint8_t pdev_id) 1984 { 1985 struct wlan_dp_psoc_context *dp_ctx; 1986 QDF_STATUS status; 1987 1988 dp_ctx = dp_get_context(); 1989 status = cdp_runtime_resume(soc, pdev_id); 1990 if (QDF_IS_STATUS_ERROR(status)) 1991 return status; 1992 1993 dp_rx_fst_update_pm_suspend_status(dp_ctx, false); 1994 1995 return status; 1996 } 1997 1998 QDF_STATUS __wlan_dp_bus_suspend(ol_txrx_soc_handle soc, uint8_t pdev_id) 1999 { 2000 struct wlan_dp_psoc_context *dp_ctx; 2001 QDF_STATUS status; 2002 2003 dp_ctx = dp_get_context(); 2004 2005 status = cdp_bus_suspend(soc, pdev_id); 2006 if (QDF_IS_STATUS_ERROR(status)) 2007 return status; 2008 2009 status = wlan_dp_fisa_suspend(dp_ctx); 2010 if (QDF_IS_STATUS_ERROR(status)) 2011 return status; 2012 2013 return status; 2014 } 2015 2016 QDF_STATUS __wlan_dp_bus_resume(ol_txrx_soc_handle soc, uint8_t pdev_id) 2017 { 2018 struct wlan_dp_psoc_context *dp_ctx; 2019 QDF_STATUS status; 2020 2021 dp_ctx = dp_get_context(); 2022 2023 status = cdp_bus_resume(soc, pdev_id); 2024 if (QDF_IS_STATUS_ERROR(status)) 2025 return status; 2026 2027 status = wlan_dp_fisa_resume(dp_ctx); 2028 if (QDF_IS_STATUS_ERROR(status)) 2029 return status; 2030 2031 return status; 2032 } 2033 2034 void *wlan_dp_txrx_soc_attach(struct dp_txrx_soc_attach_params *params, 2035 bool *is_wifi3_0_target) 2036 { 2037 struct wlan_dp_psoc_context *dp_ctx; 2038 void *dp_soc = NULL; 2039 struct hif_opaque_softc *hif_context; 2040 HTC_HANDLE htc_ctx = cds_get_context(QDF_MODULE_ID_HTC); 2041 qdf_device_t qdf_ctx = cds_get_context(QDF_MODULE_ID_QDF_DEVICE); 2042 2043 dp_ctx = dp_get_context(); 2044 hif_context = cds_get_context(QDF_MODULE_ID_HIF); 2045 2046 if (TARGET_TYPE_QCA6290 == params->target_type || 2047 TARGET_TYPE_QCA6390 == params->target_type || 2048 TARGET_TYPE_QCA6490 == params->target_type || 2049 TARGET_TYPE_QCA6750 == params->target_type) { 2050 dp_soc = cdp_soc_attach(LITHIUM_DP, hif_context, 2051 params->target_psoc, htc_ctx, 2052 qdf_ctx, params->dp_ol_if_ops); 2053 2054 if (dp_soc) 2055 if (!cdp_soc_init(dp_soc, LITHIUM_DP, 2056 hif_context, params->target_psoc, 2057 htc_ctx, qdf_ctx, 2058 params->dp_ol_if_ops)) 2059 goto err_soc_detach; 2060 *is_wifi3_0_target = true; 2061 } else if (params->target_type == TARGET_TYPE_KIWI || 2062 params->target_type == TARGET_TYPE_MANGO || 2063 params->target_type == TARGET_TYPE_PEACH) { 2064 dp_soc = cdp_soc_attach(BERYLLIUM_DP, hif_context, 2065 params->target_psoc, 2066 htc_ctx, qdf_ctx, 2067 params->dp_ol_if_ops); 2068 if (dp_soc) 2069 if (!cdp_soc_init(dp_soc, BERYLLIUM_DP, hif_context, 2070 params->target_psoc, htc_ctx, 2071 qdf_ctx, params->dp_ol_if_ops)) 2072 goto err_soc_detach; 2073 *is_wifi3_0_target = true; 2074 } else if (params->target_type == TARGET_TYPE_WCN6450) { 2075 dp_soc = 2076 cdp_soc_attach(RHINE_DP, hif_context, 2077 params->target_psoc, htc_ctx, 2078 qdf_ctx, params->dp_ol_if_ops); 2079 if (dp_soc) 2080 if (!cdp_soc_init(dp_soc, RHINE_DP, hif_context, 2081 params->target_psoc, htc_ctx, 2082 qdf_ctx, params->dp_ol_if_ops)) 2083 goto err_soc_detach; 2084 *is_wifi3_0_target = true; 2085 } else { 2086 dp_soc = cdp_soc_attach(MOB_DRV_LEGACY_DP, hif_context, 2087 params->target_psoc, htc_ctx, qdf_ctx, 2088 params->dp_ol_if_ops); 2089 } 2090 2091 if (!dp_soc) 2092 return NULL; 2093 2094 dp_ctx->cdp_soc = dp_soc; 2095 wlan_dp_rx_fisa_cmem_attach(dp_ctx); 2096 2097 return dp_soc; 2098 2099 err_soc_detach: 2100 cdp_soc_detach(dp_soc); 2101 dp_soc = NULL; 2102 2103 return dp_soc; 2104 } 2105 2106 void wlan_dp_txrx_soc_detach(ol_txrx_soc_handle soc) 2107 { 2108 cdp_soc_deinit(soc); 2109 cdp_soc_detach(soc); 2110 } 2111 2112 QDF_STATUS wlan_dp_txrx_attach_target(ol_txrx_soc_handle soc, uint8_t pdev_id) 2113 { 2114 struct wlan_dp_psoc_context *dp_ctx; 2115 QDF_STATUS qdf_status; 2116 int errno; 2117 2118 dp_ctx = dp_get_context(); 2119 2120 qdf_status = cdp_soc_attach_target(soc); 2121 if (QDF_IS_STATUS_ERROR(qdf_status)) { 2122 dp_err("Failed to attach soc target; status:%d", qdf_status); 2123 return qdf_status; 2124 } 2125 2126 qdf_status = wlan_dp_rx_fisa_attach_target(dp_ctx); 2127 if (QDF_IS_STATUS_ERROR(qdf_status)) 2128 return qdf_status; 2129 2130 errno = cdp_pdev_attach_target(soc, pdev_id); 2131 if (errno) { 2132 dp_err("Failed to attach pdev target; errno:%d", errno); 2133 qdf_status = QDF_STATUS_E_FAILURE; 2134 goto err_soc_detach_target; 2135 } 2136 2137 return qdf_status; 2138 2139 err_soc_detach_target: 2140 /* NOP */ 2141 return qdf_status; 2142 } 2143 2144 QDF_STATUS wlan_dp_txrx_pdev_attach(ol_txrx_soc_handle soc) 2145 { 2146 struct wlan_dp_psoc_context *dp_ctx; 2147 struct cdp_pdev_attach_params pdev_params = { 0 }; 2148 QDF_STATUS qdf_status; 2149 2150 dp_ctx = dp_get_context(); 2151 2152 pdev_params.htc_handle = cds_get_context(QDF_MODULE_ID_HTC); 2153 pdev_params.qdf_osdev = cds_get_context(QDF_MODULE_ID_QDF_DEVICE); 2154 pdev_params.pdev_id = 0; 2155 2156 qdf_status = cdp_pdev_attach(cds_get_context(QDF_MODULE_ID_SOC), 2157 &pdev_params); 2158 if (QDF_IS_STATUS_ERROR(qdf_status)) 2159 return qdf_status; 2160 2161 /* FISA Attach */ 2162 qdf_status = wlan_dp_rx_fisa_attach(dp_ctx); 2163 if (QDF_IS_STATUS_ERROR(qdf_status)) { 2164 wlan_dp_txrx_pdev_detach(cds_get_context(QDF_MODULE_ID_SOC), 2165 OL_TXRX_PDEV_ID, false); 2166 return qdf_status; 2167 } 2168 2169 return qdf_status; 2170 } 2171 2172 QDF_STATUS wlan_dp_txrx_pdev_detach(ol_txrx_soc_handle soc, uint8_t pdev_id, 2173 int force) 2174 { 2175 struct wlan_dp_psoc_context *dp_ctx; 2176 2177 dp_ctx = dp_get_context(); 2178 wlan_dp_rx_fisa_detach(dp_ctx); 2179 return cdp_pdev_detach(soc, pdev_id, force); 2180 } 2181 2182 #ifdef FEATURE_DIRECT_LINK 2183 /** 2184 * dp_lpass_h2t_tx_complete() - Copy completion handler for LPASS data 2185 * message service 2186 * @ctx: DP Direct Link context 2187 * @pkt: htc packet 2188 * 2189 * Return: None 2190 */ 2191 static void dp_lpass_h2t_tx_complete(void *ctx, HTC_PACKET *pkt) 2192 { 2193 dp_info("Unexpected lpass tx complete trigger"); 2194 qdf_assert(0); 2195 } 2196 2197 /** 2198 * dp_lpass_t2h_msg_handler() - target to host message handler for LPASS data 2199 * message service 2200 * @ctx: DP Direct Link context 2201 * @pkt: htc packet 2202 * 2203 * Return: None 2204 */ 2205 static void dp_lpass_t2h_msg_handler(void *ctx, HTC_PACKET *pkt) 2206 { 2207 dp_info("Unexpected receive msg trigger for lpass service"); 2208 qdf_assert(0); 2209 } 2210 2211 /** 2212 * dp_lpass_connect_htc_service() - Connect lpass data message htc service 2213 * @dp_direct_link_ctx: DP Direct Link context 2214 * 2215 * Return: QDF status 2216 */ 2217 static QDF_STATUS 2218 dp_lpass_connect_htc_service(struct dp_direct_link_context *dp_direct_link_ctx) 2219 { 2220 struct htc_service_connect_req connect = {0}; 2221 struct htc_service_connect_resp response = {0}; 2222 HTC_HANDLE htc_handle = cds_get_context(QDF_MODULE_ID_HTC); 2223 QDF_STATUS status; 2224 2225 if (!htc_handle) 2226 return QDF_STATUS_E_FAILURE; 2227 2228 connect.EpCallbacks.pContext = dp_direct_link_ctx; 2229 connect.EpCallbacks.EpTxComplete = dp_lpass_h2t_tx_complete; 2230 connect.EpCallbacks.EpRecv = dp_lpass_t2h_msg_handler; 2231 2232 /* disable flow control for LPASS data message service */ 2233 connect.ConnectionFlags |= HTC_CONNECT_FLAGS_DISABLE_CREDIT_FLOW_CTRL; 2234 connect.service_id = LPASS_DATA_MSG_SVC; 2235 2236 status = htc_connect_service(htc_handle, &connect, &response); 2237 2238 if (status != QDF_STATUS_SUCCESS) { 2239 dp_err("LPASS_DATA_MSG connect service failed"); 2240 return status; 2241 } 2242 2243 dp_direct_link_ctx->lpass_ep_id = response.Endpoint; 2244 2245 dp_err("LPASS_DATA_MSG connect service successful"); 2246 2247 return status; 2248 } 2249 2250 /** 2251 * dp_direct_link_refill_ring_init() - Initialize refill ring that would be used 2252 * for Direct Link DP 2253 * @direct_link_ctx: DP Direct Link context 2254 * 2255 * Return: QDF status 2256 */ 2257 static QDF_STATUS 2258 dp_direct_link_refill_ring_init(struct dp_direct_link_context *direct_link_ctx) 2259 { 2260 struct cdp_soc_t *soc = cds_get_context(QDF_MODULE_ID_SOC); 2261 uint8_t pdev_id; 2262 2263 if (!soc) 2264 return QDF_STATUS_E_FAILURE; 2265 2266 pdev_id = wlan_objmgr_pdev_get_pdev_id(direct_link_ctx->dp_ctx->pdev); 2267 2268 direct_link_ctx->direct_link_refill_ring_hdl = 2269 dp_setup_direct_link_refill_ring(soc, 2270 pdev_id); 2271 if (!direct_link_ctx->direct_link_refill_ring_hdl) { 2272 dp_err("Refill ring init for Direct Link failed"); 2273 return QDF_STATUS_E_FAILURE; 2274 } 2275 2276 return QDF_STATUS_SUCCESS; 2277 } 2278 2279 /** 2280 * dp_direct_link_refill_ring_deinit() - De-initialize refill ring that would be 2281 * used for Direct Link DP 2282 * @dlink_ctx: DP Direct Link context 2283 * 2284 * Return: None 2285 */ 2286 static void 2287 dp_direct_link_refill_ring_deinit(struct dp_direct_link_context *dlink_ctx) 2288 { 2289 struct cdp_soc_t *soc = cds_get_context(QDF_MODULE_ID_SOC); 2290 uint8_t pdev_id; 2291 2292 if (!soc) 2293 return; 2294 2295 pdev_id = wlan_objmgr_pdev_get_pdev_id(dlink_ctx->dp_ctx->pdev); 2296 dp_destroy_direct_link_refill_ring(soc, pdev_id); 2297 dlink_ctx->direct_link_refill_ring_hdl = NULL; 2298 } 2299 2300 QDF_STATUS dp_direct_link_init(struct wlan_dp_psoc_context *dp_ctx) 2301 { 2302 struct dp_direct_link_context *dp_direct_link_ctx; 2303 QDF_STATUS status; 2304 2305 if (!pld_is_direct_link_supported(dp_ctx->qdf_dev->dev)) { 2306 dp_info("FW does not support Direct Link"); 2307 return QDF_STATUS_SUCCESS; 2308 } 2309 2310 dp_direct_link_ctx = qdf_mem_malloc(sizeof(*dp_direct_link_ctx)); 2311 if (!dp_direct_link_ctx) { 2312 dp_err("Failed to allocate memory for DP Direct Link context"); 2313 return QDF_STATUS_E_NOMEM; 2314 } 2315 2316 dp_direct_link_ctx->dp_ctx = dp_ctx; 2317 2318 status = dp_lpass_connect_htc_service(dp_direct_link_ctx); 2319 if (QDF_IS_STATUS_ERROR(status)) { 2320 dp_err("Failed to connect to LPASS data msg service"); 2321 qdf_mem_free(dp_direct_link_ctx); 2322 return status; 2323 } 2324 2325 status = dp_direct_link_refill_ring_init(dp_direct_link_ctx); 2326 if (QDF_IS_STATUS_ERROR(status)) { 2327 qdf_mem_free(dp_direct_link_ctx); 2328 return status; 2329 } 2330 2331 status = dp_wfds_init(dp_direct_link_ctx); 2332 if (QDF_IS_STATUS_ERROR(status)) { 2333 dp_err("Failed to initialize QMI for Direct Link"); 2334 dp_direct_link_refill_ring_deinit(dp_ctx->dp_direct_link_ctx); 2335 qdf_mem_free(dp_direct_link_ctx); 2336 return status; 2337 } 2338 qdf_mutex_create(&dp_ctx->dp_direct_link_lock); 2339 2340 dp_ctx->dp_direct_link_ctx = dp_direct_link_ctx; 2341 2342 return status; 2343 } 2344 2345 void dp_direct_link_deinit(struct wlan_dp_psoc_context *dp_ctx, bool is_ssr) 2346 { 2347 struct wlan_dp_intf *dp_intf; 2348 2349 if (!pld_is_direct_link_supported(dp_ctx->qdf_dev->dev)) 2350 return; 2351 2352 if (!dp_ctx->dp_direct_link_ctx) 2353 return; 2354 2355 for (dp_get_front_intf_no_lock(dp_ctx, &dp_intf); dp_intf; 2356 dp_get_next_intf_no_lock(dp_ctx, dp_intf, &dp_intf)) { 2357 if (dp_intf->device_mode == QDF_SAP_MODE) 2358 dp_config_direct_link(dp_intf, false, false); 2359 } 2360 2361 dp_wfds_deinit(dp_ctx->dp_direct_link_ctx, is_ssr); 2362 dp_direct_link_refill_ring_deinit(dp_ctx->dp_direct_link_ctx); 2363 qdf_mutex_destroy(&dp_ctx->dp_direct_link_lock); 2364 qdf_mem_free(dp_ctx->dp_direct_link_ctx); 2365 dp_ctx->dp_direct_link_ctx = NULL; 2366 } 2367 2368 QDF_STATUS dp_config_direct_link(struct wlan_dp_intf *dp_intf, 2369 bool config_direct_link, 2370 bool enable_low_latency) 2371 { 2372 struct wlan_dp_psoc_context *dp_ctx = dp_intf->dp_ctx; 2373 struct direct_link_info *config = &dp_intf->direct_link_config; 2374 struct wlan_dp_link *dp_link, *dp_link_next; 2375 void *htc_handle; 2376 bool prev_ll, update_ll, vote_link; 2377 cdp_config_param_type vdev_param = {0}; 2378 QDF_STATUS status; 2379 2380 if (!dp_ctx || !dp_ctx->psoc) { 2381 dp_err("DP Handle is NULL"); 2382 return QDF_STATUS_E_CANCELED; 2383 } 2384 2385 if (!dp_ctx->dp_direct_link_ctx) { 2386 dp_err("Direct link not enabled"); 2387 return QDF_STATUS_SUCCESS; 2388 } 2389 2390 htc_handle = lmac_get_htc_hdl(dp_ctx->psoc); 2391 if (!htc_handle) { 2392 dp_err("HTC handle is NULL"); 2393 return QDF_STATUS_E_EMPTY; 2394 } 2395 2396 qdf_mutex_acquire(&dp_ctx->dp_direct_link_lock); 2397 prev_ll = config->low_latency; 2398 update_ll = config_direct_link ? enable_low_latency : prev_ll; 2399 vote_link = config->config_set ^ config_direct_link; 2400 config->config_set = config_direct_link; 2401 config->low_latency = enable_low_latency; 2402 dp_for_each_link_held_safe(dp_intf, dp_link, dp_link_next) { 2403 vdev_param.cdp_vdev_tx_to_fw = config_direct_link; 2404 status = cdp_txrx_set_vdev_param( 2405 wlan_psoc_get_dp_handle(dp_ctx->psoc), 2406 dp_link->link_id, CDP_VDEV_TX_TO_FW, 2407 vdev_param); 2408 if (QDF_IS_STATUS_ERROR(status)) 2409 break; 2410 } 2411 2412 if (config_direct_link) { 2413 if (vote_link) 2414 htc_vote_link_up(htc_handle, 2415 HTC_LINK_VOTE_DIRECT_LINK_USER_ID); 2416 if (update_ll) 2417 hif_prevent_link_low_power_states( 2418 htc_get_hif_device(htc_handle)); 2419 else if (prev_ll) 2420 hif_allow_link_low_power_states( 2421 htc_get_hif_device(htc_handle)); 2422 dp_info("Direct link config set. Low link latency enabled: %d", 2423 enable_low_latency); 2424 } else { 2425 if (vote_link) 2426 htc_vote_link_down(htc_handle, 2427 HTC_LINK_VOTE_DIRECT_LINK_USER_ID); 2428 if (update_ll) 2429 hif_allow_link_low_power_states( 2430 htc_get_hif_device(htc_handle)); 2431 dp_info("Direct link config cleared."); 2432 } 2433 qdf_mutex_release(&dp_ctx->dp_direct_link_lock); 2434 2435 return status; 2436 } 2437 #endif 2438 2439 #ifdef WLAN_DP_PROFILE_SUPPORT 2440 struct wlan_dp_memory_profile_info * 2441 wlan_dp_get_profile_info(void) 2442 { 2443 return &g_dp_profile_info; 2444 } 2445 2446 QDF_STATUS wlan_dp_select_profile_cfg(struct wlan_objmgr_psoc *psoc) 2447 { 2448 struct pld_soc_info info = {0}; 2449 struct pld_wlan_hw_cap_info *hw_cap_info; 2450 qdf_device_t qdf_dev; 2451 bool apply_profile = false; 2452 int ret; 2453 2454 apply_profile = cfg_get(psoc, 2455 CFG_DP_APPLY_MEM_PROFILE); 2456 if (!apply_profile) 2457 return QDF_STATUS_E_NOSUPPORT; 2458 2459 qdf_dev = wlan_psoc_get_qdf_dev(psoc); 2460 if (!qdf_dev) 2461 return QDF_STATUS_E_FAILURE; 2462 2463 ret = pld_get_soc_info(qdf_dev->dev, &info); 2464 if (ret) { 2465 dp_err("profile selection failed unable to H.W caps reason:%u", 2466 qdf_status_from_os_return(ret)); 2467 return qdf_status_from_os_return(ret); 2468 } 2469 2470 hw_cap_info = &info.hw_cap_info; 2471 /* Based on supported H.W caps select required memory profile */ 2472 if (hw_cap_info->nss == PLD_WLAN_HW_CAP_NSS_1x1 && 2473 hw_cap_info->bw == PLD_WLAN_HW_CHANNEL_BW_80MHZ && 2474 hw_cap_info->qam == PLD_WLAN_HW_QAM_1K) { 2475 g_dp_profile_info.is_selected = true; 2476 g_dp_profile_info.ctx = wlan_dp_1x1_he80_1kqam; 2477 g_dp_profile_info.size = QDF_ARRAY_SIZE(wlan_dp_1x1_he80_1kqam); 2478 dp_info("DP profile selected is 1x1_HE80_1KQAM based"); 2479 } 2480 2481 return QDF_STATUS_SUCCESS; 2482 } 2483 2484 #ifdef WLAN_FEATURE_RX_PREALLOC_BUFFER_POOL 2485 static void 2486 wlan_dp_rx_refill_pool_cfg_sync_profile(struct cdp_soc_t *cdp_soc, 2487 struct wlan_dp_memory_profile_ctx *profile_ctx) 2488 { 2489 cdp_config_param_type val; 2490 QDF_STATUS status; 2491 int cur_val; 2492 2493 status = cdp_txrx_get_psoc_param(cdp_soc, CDP_CFG_RX_REFILL_POOL_NUM, 2494 &val); 2495 if (QDF_IS_STATUS_SUCCESS(status) && 2496 val.cdp_rx_refill_buf_pool_size != profile_ctx->size) { 2497 cur_val = val.cdp_rx_refill_buf_pool_size; 2498 val.cdp_rx_refill_buf_pool_size = profile_ctx->size; 2499 if (cdp_txrx_set_psoc_param(cdp_soc, 2500 CDP_CFG_RX_REFILL_POOL_NUM, val)) { 2501 dp_err("unable to sync param type:%u", profile_ctx->param_type); 2502 return; 2503 } 2504 dp_info("current Rx refill pool size:%u synced with profile:%u", 2505 cur_val, profile_ctx->size); 2506 } 2507 } 2508 #else 2509 static inline void 2510 wlan_dp_rx_refill_pool_cfg_sync_profile(struct cdp_soc_t *cdp_soc, 2511 struct wlan_dp_memory_profile_ctx *profile_ctx) 2512 { 2513 } 2514 #endif 2515 2516 void wlan_dp_soc_cfg_sync_profile(struct cdp_soc_t *cdp_soc) 2517 { 2518 struct wlan_dp_memory_profile_info *profile_info; 2519 struct wlan_dp_memory_profile_ctx *profile_ctx; 2520 cdp_config_param_type val = {0}; 2521 QDF_STATUS status; 2522 int cur_val, i; 2523 2524 profile_info = wlan_dp_get_profile_info(); 2525 if (!profile_info->is_selected) 2526 return; 2527 2528 for (i = 0; i < profile_info->size; i++) { 2529 profile_ctx = &profile_info->ctx[i]; 2530 qdf_mem_zero(&val, sizeof(cdp_config_param_type)); 2531 2532 switch (profile_ctx->param_type) { 2533 case DP_TX_DESC_NUM_CFG: 2534 status = cdp_txrx_get_psoc_param(cdp_soc, 2535 CDP_CFG_TX_DESC_NUM, &val); 2536 if (QDF_IS_STATUS_SUCCESS(status) && 2537 val.cdp_tx_desc_num != profile_ctx->size) { 2538 cur_val = val.cdp_tx_desc_num; 2539 val.cdp_tx_desc_num = profile_ctx->size; 2540 if (cdp_txrx_set_psoc_param(cdp_soc, 2541 CDP_CFG_TX_DESC_NUM, val)) { 2542 dp_err("unable to sync param type:%u", profile_ctx->param_type); 2543 break; 2544 } 2545 dp_info("current Tx desc num:%u synced with profile:%u", cur_val, profile_ctx->size); 2546 } 2547 break; 2548 case DP_TX_EXT_DESC_NUM_CFG: 2549 status = cdp_txrx_get_psoc_param(cdp_soc, 2550 CDP_CFG_TX_EXT_DESC_NUM, &val); 2551 if (QDF_IS_STATUS_SUCCESS(status) && 2552 val.cdp_tx_ext_desc_num != profile_ctx->size) { 2553 cur_val = val.cdp_tx_ext_desc_num; 2554 val.cdp_tx_ext_desc_num = profile_ctx->size; 2555 if (cdp_txrx_set_psoc_param(cdp_soc, 2556 CDP_CFG_TX_EXT_DESC_NUM, val)) { 2557 dp_err("unable to sync param type:%u", profile_ctx->param_type); 2558 break; 2559 } 2560 dp_info("current Ext Tx desc num:%u synced with profile:%u", cur_val, profile_ctx->size); 2561 } 2562 break; 2563 case DP_TX_RING_SIZE_CFG: 2564 status = cdp_txrx_get_psoc_param(cdp_soc, 2565 CDP_CFG_TX_RING_SIZE, &val); 2566 if (QDF_IS_STATUS_SUCCESS(status) && 2567 val.cdp_tx_ring_size != profile_ctx->size) { 2568 cur_val = val.cdp_tx_ring_size; 2569 val.cdp_tx_ring_size = profile_ctx->size; 2570 if (cdp_txrx_set_psoc_param(cdp_soc, 2571 CDP_CFG_TX_RING_SIZE, val)) { 2572 dp_err("unable to sync param type:%u", profile_ctx->param_type); 2573 break; 2574 } 2575 dp_info("current Tx Ring size:%u synced with profile:%u", cur_val, profile_ctx->size); 2576 } 2577 break; 2578 case DP_TX_COMPL_RING_SIZE_CFG: 2579 status = cdp_txrx_get_psoc_param(cdp_soc, 2580 CDP_CFG_TX_COMPL_RING_SIZE, &val); 2581 if (QDF_IS_STATUS_SUCCESS(status) && 2582 val.cdp_tx_comp_ring_size != profile_ctx->size) { 2583 cur_val = val.cdp_tx_comp_ring_size; 2584 val.cdp_tx_comp_ring_size = profile_ctx->size; 2585 if (cdp_txrx_set_psoc_param(cdp_soc, 2586 CDP_CFG_TX_COMPL_RING_SIZE, val)) { 2587 dp_err("unable to sync param type:%u", profile_ctx->param_type); 2588 break; 2589 } 2590 dp_info("current Tx Comp Ring size:%u synced with profile:%u", cur_val, profile_ctx->size); 2591 } 2592 break; 2593 case DP_RX_SW_DESC_NUM_CFG: 2594 status = cdp_txrx_get_psoc_param(cdp_soc, 2595 CDP_CFG_RX_SW_DESC_NUM, &val); 2596 if (QDF_IS_STATUS_SUCCESS(status) && 2597 val.cdp_rx_sw_desc_num != profile_ctx->size) { 2598 cur_val = val.cdp_rx_sw_desc_num; 2599 val.cdp_rx_sw_desc_num = profile_ctx->size; 2600 if (cdp_txrx_set_psoc_param(cdp_soc, 2601 CDP_CFG_RX_SW_DESC_NUM, val)) { 2602 dp_err("unable to sync param type:%u", profile_ctx->param_type); 2603 break; 2604 } 2605 dp_info("current Rx desc num:%u synced with profile:%u", cur_val, profile_ctx->size); 2606 } 2607 break; 2608 case DP_REO_DST_RING_SIZE_CFG: 2609 status = cdp_txrx_get_psoc_param(cdp_soc, 2610 CDP_CFG_REO_DST_RING_SIZE, &val); 2611 if (QDF_IS_STATUS_SUCCESS(status) && 2612 val.cdp_reo_dst_ring_size != profile_ctx->size) { 2613 cur_val = val.cdp_reo_dst_ring_size; 2614 val.cdp_reo_dst_ring_size = profile_ctx->size; 2615 if (cdp_txrx_set_psoc_param(cdp_soc, 2616 CDP_CFG_REO_DST_RING_SIZE, val)) { 2617 dp_err("unable to sync param type:%u", profile_ctx->param_type); 2618 break; 2619 } 2620 dp_info("current Rx Ring size:%u synced with profile:%u", cur_val, profile_ctx->size); 2621 } 2622 break; 2623 case DP_RXDMA_REFILL_RING_SIZE_CFG: 2624 status = cdp_txrx_get_psoc_param(cdp_soc, 2625 CDP_CFG_RXDMA_REFILL_RING_SIZE, &val); 2626 if (QDF_IS_STATUS_SUCCESS(status) && 2627 val.cdp_rxdma_refill_ring_size != profile_ctx->size) { 2628 cur_val = val.cdp_rxdma_refill_ring_size; 2629 val.cdp_rxdma_refill_ring_size = profile_ctx->size; 2630 if (cdp_txrx_set_psoc_param(cdp_soc, 2631 CDP_CFG_RXDMA_REFILL_RING_SIZE, val)) { 2632 dp_err("unable to sync param type:%u", profile_ctx->param_type); 2633 break; 2634 } 2635 dp_info("current RXDMA refill ring size:%u synced with profile:%u", cur_val, profile_ctx->size); 2636 } 2637 case DP_RX_REFILL_POOL_NUM_CFG: 2638 wlan_dp_rx_refill_pool_cfg_sync_profile(cdp_soc, 2639 profile_ctx); 2640 default: 2641 dp_debug("Unknown profile param type:%u", profile_ctx->param_type); 2642 break; 2643 } 2644 } 2645 } 2646 2647 void wlan_dp_pdev_cfg_sync_profile(struct cdp_soc_t *cdp_soc, uint8_t pdev_id) 2648 { 2649 struct wlan_dp_memory_profile_info *profile_info; 2650 struct wlan_dp_memory_profile_ctx *profile_ctx; 2651 cdp_config_param_type val = {0}; 2652 QDF_STATUS status; 2653 int cur_val, i; 2654 2655 profile_info = wlan_dp_get_profile_info(); 2656 if (!profile_info->is_selected) 2657 return; 2658 2659 for (i = 0; i < profile_info->size; i++) { 2660 profile_ctx = &profile_info->ctx[i]; 2661 if (profile_ctx->param_type == DP_RXDMA_BUF_RING_SIZE_CFG) { 2662 status = cdp_txrx_get_pdev_param(cdp_soc, pdev_id, 2663 CDP_CONFIG_RXDMA_BUF_RING_SIZE, &val); 2664 if (QDF_IS_STATUS_SUCCESS(status) && 2665 val.cdp_rxdma_buf_ring_size != profile_ctx->size) { 2666 cur_val = val.cdp_rxdma_buf_ring_size; 2667 val.cdp_rxdma_buf_ring_size = profile_ctx->size; 2668 if (cdp_txrx_set_pdev_param(cdp_soc, pdev_id, 2669 CDP_CONFIG_RXDMA_BUF_RING_SIZE, val)) { 2670 dp_err("unable to sync param type:%u", profile_ctx->param_type); 2671 return; 2672 } 2673 dp_info("current RXDMA buf ring size:%u synced with profile:%u", cur_val, profile_ctx->size); 2674 } 2675 return; 2676 } 2677 } 2678 2679 dp_err("pdev based config item not found in profile table"); 2680 } 2681 #endif 2682