1 /* 2 * Copyright (c) 2017-2021 The Linux Foundation. All rights reserved. 3 * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved. 4 * 5 * Permission to use, copy, modify, and/or distribute this software for 6 * any purpose with or without fee is hereby granted, provided that the 7 * above copyright notice and this permission notice appear in all 8 * copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL 11 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED 12 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE 13 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL 14 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR 15 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 16 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 17 * PERFORMANCE OF THIS SOFTWARE. 18 */ 19 20 /** 21 * DOC: wlan_hdd_sysfs.c 22 * 23 * WLAN Host Device Driver implementation 24 * 25 */ 26 27 #include <linux/module.h> 28 #include <linux/kobject.h> 29 #include <linux/fs.h> 30 #include <linux/string.h> 31 #include "wlan_hdd_includes.h" 32 #include "wlan_hdd_sysfs.h" 33 #include "qwlan_version.h" 34 #include "cds_api.h" 35 #include <wlan_osif_request_manager.h> 36 #include <qdf_mem.h> 37 #ifdef WLAN_POWER_DEBUG 38 #include <sir_api.h> 39 #endif 40 #include "osif_sync.h" 41 #include "wlan_hdd_sysfs_sta_info.h" 42 #include "wlan_hdd_sysfs_channel.h" 43 #include <wlan_hdd_sysfs_fw_mode_config.h> 44 #include <wlan_hdd_sysfs_reassoc.h> 45 #include <wlan_hdd_sysfs_mem_stats.h> 46 #include "wlan_hdd_sysfs_crash_inject.h" 47 #include "wlan_hdd_sysfs_suspend_resume.h" 48 #include "wlan_hdd_sysfs_unit_test.h" 49 #include "wlan_hdd_sysfs_modify_acl.h" 50 #include "wlan_hdd_sysfs_connect_info.h" 51 #include <wlan_hdd_sysfs_scan_disable.h> 52 #include "wlan_hdd_sysfs_dcm.h" 53 #include <wlan_hdd_sysfs_wow_ito.h> 54 #include <wlan_hdd_sysfs_wowl_add_ptrn.h> 55 #include <wlan_hdd_sysfs_wowl_del_ptrn.h> 56 #include <wlan_hdd_sysfs_tx_stbc.h> 57 #include <wlan_hdd_sysfs_wlan_dbg.h> 58 #include <wlan_hdd_sysfs_txrx_fw_st_rst.h> 59 #include <wlan_hdd_sysfs_gtx_bw_mask.h> 60 #include <wlan_hdd_sysfs_scan_config.h> 61 #include <wlan_hdd_sysfs_monitor_mode_channel.h> 62 #include <wlan_hdd_sysfs_range_ext.h> 63 #include <wlan_hdd_sysfs_radar.h> 64 #include <wlan_hdd_sysfs_rts_cts.h> 65 #include <wlan_hdd_sysfs_he_bss_color.h> 66 #include <wlan_hdd_sysfs_txrx_fw_stats.h> 67 #include <wlan_hdd_sysfs_txrx_stats.h> 68 #include <wlan_hdd_sysfs_dp_trace.h> 69 #include <wlan_hdd_sysfs_stats.h> 70 #include <wlan_hdd_sysfs_tdls_peers.h> 71 #include <wlan_hdd_sysfs_temperature.h> 72 #include <wlan_hdd_sysfs_thermal_cfg.h> 73 #include <wlan_hdd_sysfs_motion_detection.h> 74 #include <wlan_hdd_sysfs_ipa.h> 75 #include <wlan_hdd_sysfs_pkt_log.h> 76 #include <wlan_hdd_sysfs_policy_mgr.h> 77 #include <wlan_hdd_sysfs_dp_aggregation.h> 78 #include <wlan_hdd_sysfs_dl_modes.h> 79 #include <wlan_hdd_sysfs_swlm.h> 80 #include <wlan_hdd_sysfs_dump_in_progress.h> 81 #include <wlan_hdd_sysfs_txrx_stats_console.h> 82 #include <wlan_hdd_sysfs_add_timestamp.h> 83 #include "wma_api.h" 84 #include "wlan_hdd_eht.h" 85 #include <wlan_hdd_sysfs_bmiss.h> 86 #include <wlan_hdd_sysfs_get_freq_for_pwr.h> 87 #include <wlan_hdd_sysfs_dp_tx_delay_stats.h> 88 #include <wlan_hdd_sysfs_wifi_features.h> 89 #include <wlan_hdd_sysfs_dp_traffic_end_indication.h> 90 #include <wlan_hdd_sysfs_eht_rate.h> 91 #include <wlan_hdd_sysfs_direct_link_ut_cmd.h> 92 #include <wlan_hdd_sysfs_runtime_pm.h> 93 #include <wlan_hdd_sysfs_log_buffer.h> 94 #include <wlan_hdd_sysfs_dfsnol.h> 95 96 #define MAX_PSOC_ID_SIZE 10 97 98 #ifdef MULTI_IF_NAME 99 #define DRIVER_NAME MULTI_IF_NAME 100 #else 101 #define DRIVER_NAME "wifi" 102 #endif 103 104 static struct kobject *wlan_kobject; 105 static struct kobject *driver_kobject; 106 static struct kobject *fw_kobject; 107 static struct kobject *psoc_kobject; 108 static struct kobject *wifi_kobject; 109 110 int 111 hdd_sysfs_validate_and_copy_buf(char *dest_buf, size_t dest_buf_size, 112 char const *source_buf, size_t source_buf_size) 113 { 114 if (source_buf_size > (dest_buf_size - 1)) { 115 hdd_err_rl("Command length is larger than %zu bytes", 116 dest_buf_size); 117 return -EINVAL; 118 } 119 120 /* sysfs already provides kernel space buffer so copy from user 121 * is not needed. Doing this extra copy operation just to ensure 122 * the local buf is properly null-terminated. 123 */ 124 strlcpy(dest_buf, source_buf, dest_buf_size); 125 /* default 'echo' cmd takes new line character to here */ 126 if (dest_buf[source_buf_size - 1] == '\n') 127 dest_buf[source_buf_size - 1] = '\0'; 128 129 return 0; 130 } 131 132 static ssize_t __show_driver_version(char *buf) 133 { 134 return scnprintf(buf, PAGE_SIZE, QWLAN_VERSIONSTR); 135 } 136 137 static ssize_t show_driver_version(struct kobject *kobj, 138 struct kobj_attribute *attr, 139 char *buf) 140 { 141 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); 142 struct osif_psoc_sync *psoc_sync; 143 ssize_t length; 144 int errno; 145 146 errno = wlan_hdd_validate_context(hdd_ctx); 147 if (errno) 148 return errno; 149 150 errno = osif_psoc_sync_op_start(hdd_ctx->parent_dev, &psoc_sync); 151 if (errno) 152 return errno; 153 154 length = __show_driver_version(buf); 155 156 osif_psoc_sync_op_stop(psoc_sync); 157 158 return length; 159 } 160 161 static ssize_t __show_fw_version(struct hdd_context *hdd_ctx, 162 char *buf) 163 { 164 hdd_debug("Rcvd req for FW version"); 165 166 return scnprintf(buf, PAGE_SIZE, 167 "FW:%d.%d.%d.%d.%d.%d HW:%s Board version: %x Ref design id: %x Customer id: %x Project id: %x Board Data Rev: %x\n", 168 hdd_ctx->fw_version_info.major_spid, 169 hdd_ctx->fw_version_info.minor_spid, 170 hdd_ctx->fw_version_info.siid, 171 hdd_ctx->fw_version_info.rel_id, 172 hdd_ctx->fw_version_info.crmid, 173 hdd_ctx->fw_version_info.sub_id, 174 hdd_ctx->target_hw_name, 175 hdd_ctx->hw_bd_info.bdf_version, 176 hdd_ctx->hw_bd_info.ref_design_id, 177 hdd_ctx->hw_bd_info.customer_id, 178 hdd_ctx->hw_bd_info.project_id, 179 hdd_ctx->hw_bd_info.board_data_rev); 180 } 181 182 static ssize_t show_fw_version(struct kobject *kobj, 183 struct kobj_attribute *attr, 184 char *buf) 185 { 186 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); 187 struct osif_psoc_sync *psoc_sync; 188 ssize_t length; 189 int errno; 190 191 errno = wlan_hdd_validate_context(hdd_ctx); 192 if (errno) 193 return errno; 194 195 errno = osif_psoc_sync_op_start(hdd_ctx->parent_dev, &psoc_sync); 196 if (errno) 197 return errno; 198 199 length = __show_fw_version(hdd_ctx, buf); 200 201 osif_psoc_sync_op_stop(psoc_sync); 202 203 return length; 204 }; 205 206 #ifdef WLAN_POWER_DEBUG 207 struct power_stats_priv { 208 struct power_stats_response power_stats; 209 }; 210 211 static void hdd_power_debugstats_dealloc(void *priv) 212 { 213 struct power_stats_priv *stats = priv; 214 215 qdf_mem_free(stats->power_stats.debug_registers); 216 stats->power_stats.debug_registers = NULL; 217 } 218 219 static void hdd_power_debugstats_cb(struct power_stats_response *response, 220 void *context) 221 { 222 struct osif_request *request; 223 struct power_stats_priv *priv; 224 uint32_t *debug_registers; 225 uint32_t debug_registers_len; 226 227 hdd_enter(); 228 229 request = osif_request_get(context); 230 if (!request) { 231 hdd_err("Obsolete request"); 232 return; 233 } 234 235 priv = osif_request_priv(request); 236 237 /* copy fixed-sized data */ 238 priv->power_stats = *response; 239 240 /* copy variable-size data */ 241 if (response->num_debug_register) { 242 debug_registers_len = (sizeof(response->debug_registers[0]) * 243 response->num_debug_register); 244 debug_registers = qdf_mem_malloc(debug_registers_len); 245 priv->power_stats.debug_registers = debug_registers; 246 if (debug_registers) { 247 qdf_mem_copy(debug_registers, 248 response->debug_registers, 249 debug_registers_len); 250 } else { 251 hdd_err("Power stats memory alloc fails!"); 252 priv->power_stats.num_debug_register = 0; 253 } 254 } 255 osif_request_complete(request); 256 osif_request_put(request); 257 hdd_exit(); 258 } 259 260 static ssize_t __show_device_power_stats(struct hdd_context *hdd_ctx, 261 char *buf) 262 { 263 QDF_STATUS status; 264 struct power_stats_response *chip_power_stats; 265 ssize_t ret_cnt = 0; 266 int j; 267 void *cookie; 268 struct osif_request *request; 269 struct power_stats_priv *priv; 270 static const struct osif_request_params params = { 271 .priv_size = sizeof(*priv), 272 .timeout_ms = WLAN_WAIT_TIME_STATS, 273 .dealloc = hdd_power_debugstats_dealloc, 274 }; 275 276 hdd_enter(); 277 278 request = osif_request_alloc(¶ms); 279 if (!request) { 280 hdd_err("Request allocation failure"); 281 return -ENOMEM; 282 } 283 cookie = osif_request_cookie(request); 284 285 status = sme_power_debug_stats_req(hdd_ctx->mac_handle, 286 hdd_power_debugstats_cb, 287 cookie); 288 if (QDF_IS_STATUS_ERROR(status)) { 289 hdd_err("chip power stats request failed"); 290 ret_cnt = qdf_status_to_os_return(status); 291 goto cleanup; 292 } 293 294 ret_cnt = osif_request_wait_for_response(request); 295 if (ret_cnt) { 296 hdd_err("Target response timed out Power stats"); 297 sme_reset_power_debug_stats_cb(hdd_ctx->mac_handle); 298 ret_cnt = -ETIMEDOUT; 299 goto cleanup; 300 } 301 priv = osif_request_priv(request); 302 chip_power_stats = &priv->power_stats; 303 304 ret_cnt += scnprintf(buf, PAGE_SIZE, 305 "POWER DEBUG STATS\n=================\n" 306 "cumulative_sleep_time_ms: %d\n" 307 "cumulative_total_on_time_ms: %d\n" 308 "deep_sleep_enter_counter: %d\n" 309 "last_deep_sleep_enter_tstamp_ms: %d\n" 310 "debug_register_fmt: %d\n" 311 "num_debug_register: %d\n", 312 chip_power_stats->cumulative_sleep_time_ms, 313 chip_power_stats->cumulative_total_on_time_ms, 314 chip_power_stats->deep_sleep_enter_counter, 315 chip_power_stats->last_deep_sleep_enter_tstamp_ms, 316 chip_power_stats->debug_register_fmt, 317 chip_power_stats->num_debug_register); 318 319 for (j = 0; j < chip_power_stats->num_debug_register; j++) { 320 if ((PAGE_SIZE - ret_cnt) > 0) 321 ret_cnt += scnprintf(buf + ret_cnt, 322 PAGE_SIZE - ret_cnt, 323 "debug_registers[%d]: 0x%x\n", j, 324 chip_power_stats->debug_registers[j]); 325 else 326 j = chip_power_stats->num_debug_register; 327 } 328 329 cleanup: 330 osif_request_put(request); 331 hdd_exit(); 332 return ret_cnt; 333 } 334 335 static ssize_t show_device_power_stats(struct kobject *kobj, 336 struct kobj_attribute *attr, 337 char *buf) 338 { 339 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); 340 struct osif_psoc_sync *psoc_sync; 341 ssize_t length; 342 int errno; 343 344 errno = wlan_hdd_validate_context(hdd_ctx); 345 if (errno) 346 return errno; 347 348 errno = osif_psoc_sync_op_start(hdd_ctx->parent_dev, &psoc_sync); 349 if (errno) 350 return errno; 351 352 length = __show_device_power_stats(hdd_ctx, buf); 353 354 osif_psoc_sync_op_stop(psoc_sync); 355 356 return length; 357 } 358 #endif 359 360 #ifdef WLAN_FEATURE_BEACON_RECEPTION_STATS 361 struct beacon_reception_stats_priv { 362 struct bcn_reception_stats_rsp beacon_stats; 363 }; 364 365 static void hdd_beacon_debugstats_cb(struct bcn_reception_stats_rsp 366 *response, 367 void *context) 368 { 369 struct osif_request *request; 370 struct beacon_reception_stats_priv *priv; 371 372 hdd_enter(); 373 374 request = osif_request_get(context); 375 if (!request) { 376 hdd_err("Obsolete request"); 377 return; 378 } 379 380 priv = osif_request_priv(request); 381 382 /* copy fixed-sized data */ 383 priv->beacon_stats = *response; 384 385 osif_request_complete(request); 386 osif_request_put(request); 387 hdd_exit(); 388 } 389 390 static ssize_t __show_beacon_reception_stats(struct net_device *net_dev, 391 char *buf) 392 { 393 struct hdd_adapter *adapter = netdev_priv(net_dev); 394 struct bcn_reception_stats_rsp *beacon_stats; 395 int ret_val, j; 396 void *cookie; 397 struct osif_request *request; 398 struct beacon_reception_stats_priv *priv; 399 static const struct osif_request_params params = { 400 .priv_size = sizeof(*priv), 401 .timeout_ms = WLAN_WAIT_TIME_STATS, 402 }; 403 struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); 404 QDF_STATUS status; 405 406 ret_val = wlan_hdd_validate_context(hdd_ctx); 407 if (ret_val) 408 return ret_val; 409 410 if (!adapter || adapter->magic != WLAN_HDD_ADAPTER_MAGIC) { 411 hdd_err("Invalid adapter or adapter has invalid magic"); 412 return -EINVAL; 413 } 414 415 if (!test_bit(DEVICE_IFACE_OPENED, &adapter->event_flags)) { 416 hdd_err("Interface is not enabled"); 417 return -EINVAL; 418 } 419 420 if (!(adapter->device_mode == QDF_STA_MODE || 421 adapter->device_mode == QDF_P2P_CLIENT_MODE)) { 422 hdd_err("Beacon Reception Stats only supported in STA or P2P CLI modes!"); 423 return -ENOTSUPP; 424 } 425 426 if (!hdd_cm_is_vdev_associated(adapter->deflink)) { 427 hdd_err("Adapter is not in connected state"); 428 return -EINVAL; 429 } 430 431 request = osif_request_alloc(¶ms); 432 if (!request) { 433 hdd_err("Request allocation failure"); 434 return -ENOMEM; 435 } 436 cookie = osif_request_cookie(request); 437 438 status = sme_beacon_debug_stats_req(hdd_ctx->mac_handle, 439 adapter->deflink->vdev_id, 440 hdd_beacon_debugstats_cb, 441 cookie); 442 if (QDF_IS_STATUS_ERROR(status)) { 443 hdd_err("chip power stats request failed"); 444 ret_val = -EINVAL; 445 goto cleanup; 446 } 447 448 ret_val = osif_request_wait_for_response(request); 449 if (ret_val) { 450 hdd_err("Target response timed out Power stats"); 451 ret_val = -ETIMEDOUT; 452 goto cleanup; 453 } 454 priv = osif_request_priv(request); 455 beacon_stats = &priv->beacon_stats; 456 457 ret_val += scnprintf(buf, PAGE_SIZE, 458 "BEACON RECEPTION STATS\n=================\n" 459 "vdev id: %u\n" 460 "Total Beacon Count: %u\n" 461 "Total Beacon Miss Count: %u\n", 462 beacon_stats->vdev_id, 463 beacon_stats->total_bcn_cnt, 464 beacon_stats->total_bmiss_cnt); 465 466 ret_val += scnprintf(buf + ret_val, PAGE_SIZE - ret_val, 467 "Beacon Miss Bit map "); 468 469 for (j = 0; j < MAX_BCNMISS_BITMAP; j++) { 470 if ((PAGE_SIZE - ret_val) > 0) { 471 ret_val += scnprintf(buf + ret_val, 472 PAGE_SIZE - ret_val, 473 "[0x%x] ", 474 beacon_stats->bmiss_bitmap[j]); 475 } 476 } 477 478 if ((PAGE_SIZE - ret_val) > 0) 479 ret_val += scnprintf(buf + ret_val, 480 PAGE_SIZE - ret_val, 481 "\n"); 482 cleanup: 483 osif_request_put(request); 484 hdd_exit(); 485 return ret_val; 486 } 487 488 static ssize_t show_beacon_reception_stats(struct device *dev, 489 struct device_attribute *attr, 490 char *buf) 491 { 492 struct net_device *net_dev = container_of(dev, struct net_device, dev); 493 struct osif_vdev_sync *vdev_sync; 494 ssize_t err_size; 495 496 err_size = osif_vdev_sync_op_start(net_dev, &vdev_sync); 497 if (err_size) 498 return err_size; 499 500 err_size = __show_beacon_reception_stats(net_dev, buf); 501 502 osif_vdev_sync_op_stop(vdev_sync); 503 504 return err_size; 505 } 506 507 static DEVICE_ATTR(beacon_stats, 0444, 508 show_beacon_reception_stats, NULL); 509 #endif 510 511 static struct kobj_attribute dr_ver_attribute = 512 __ATTR(driver_version, 0440, show_driver_version, NULL); 513 static struct kobj_attribute fw_ver_attribute = 514 __ATTR(version, 0440, show_fw_version, NULL); 515 #ifdef WLAN_POWER_DEBUG 516 static struct kobj_attribute power_stats_attribute = 517 __ATTR(power_stats, 0444, show_device_power_stats, NULL); 518 #endif 519 520 static void hdd_sysfs_create_version_interface(struct wlan_objmgr_psoc *psoc) 521 { 522 int error = 0; 523 uint32_t psoc_id; 524 char buf[MAX_PSOC_ID_SIZE]; 525 526 if (!driver_kobject || !wlan_kobject) { 527 hdd_err("could not get driver kobject!"); 528 return; 529 } 530 531 error = sysfs_create_file(wlan_kobject, &dr_ver_attribute.attr); 532 if (error) { 533 hdd_err("could not create wlan sysfs file"); 534 return; 535 } 536 537 fw_kobject = kobject_create_and_add("fw", wlan_kobject); 538 if (!fw_kobject) { 539 hdd_err("could not allocate fw kobject"); 540 goto free_fw_kobj; 541 } 542 543 psoc_id = wlan_psoc_get_nif_phy_version(psoc); 544 scnprintf(buf, PAGE_SIZE, "%d", psoc_id); 545 546 psoc_kobject = kobject_create_and_add(buf, fw_kobject); 547 if (!psoc_kobject) { 548 hdd_err("could not allocate psoc kobject"); 549 goto free_fw_kobj; 550 } 551 552 error = sysfs_create_file(psoc_kobject, &fw_ver_attribute.attr); 553 if (error) { 554 hdd_err("could not create fw sysfs file"); 555 goto free_psoc_kobj; 556 } 557 558 return; 559 560 free_psoc_kobj: 561 kobject_put(psoc_kobject); 562 psoc_kobject = NULL; 563 564 free_fw_kobj: 565 kobject_put(fw_kobject); 566 fw_kobject = NULL; 567 } 568 569 static void hdd_sysfs_destroy_version_interface(void) 570 { 571 if (psoc_kobject) { 572 kobject_put(psoc_kobject); 573 psoc_kobject = NULL; 574 kobject_put(fw_kobject); 575 fw_kobject = NULL; 576 } 577 } 578 579 #ifdef WLAN_POWER_DEBUG 580 static void hdd_sysfs_create_powerstats_interface(void) 581 { 582 int error; 583 584 if (!driver_kobject) { 585 hdd_err("could not get driver kobject!"); 586 return; 587 } 588 589 error = sysfs_create_file(driver_kobject, &power_stats_attribute.attr); 590 if (error) 591 hdd_err("could not create power_stats sysfs file"); 592 } 593 594 static void hdd_sysfs_destroy_powerstats_interface(void) 595 { 596 if (!driver_kobject) { 597 hdd_err("could not get driver kobject!"); 598 return; 599 } 600 sysfs_remove_file(driver_kobject, &power_stats_attribute.attr); 601 } 602 #else 603 static void hdd_sysfs_create_powerstats_interface(void) 604 { 605 } 606 607 static void hdd_sysfs_destroy_powerstats_interface(void) 608 { 609 } 610 #endif 611 612 static ssize_t 613 hdd_sysfs_wakeup_logs_to_console_store(struct kobject *kobj, 614 struct kobj_attribute *attr, 615 char const *buf, size_t count) 616 { 617 char buf_local[MAX_SYSFS_USER_COMMAND_SIZE_LENGTH + 1]; 618 int ret, value; 619 char *sptr, *token; 620 621 ret = hdd_sysfs_validate_and_copy_buf(buf_local, sizeof(buf_local), 622 buf, count); 623 if (ret) { 624 hdd_err_rl("invalid input"); 625 return ret; 626 } 627 628 sptr = buf_local; 629 token = strsep(&sptr, " "); 630 if (!token) 631 return -EINVAL; 632 if (kstrtou32(token, 0, &value)) 633 return -EINVAL; 634 635 wma_set_wakeup_logs_to_console(value); 636 637 return count; 638 } 639 640 static struct kobj_attribute wakeup_logs_to_console_attribute = 641 __ATTR(wakeup_logs_to_console, 0220, NULL, 642 hdd_sysfs_wakeup_logs_to_console_store); 643 644 static void hdd_sysfs_create_wakeup_logs_to_console(void) 645 { 646 int error; 647 648 if (!driver_kobject) { 649 hdd_err("could not get driver kobject!"); 650 return; 651 } 652 653 error = sysfs_create_file(driver_kobject, 654 &wakeup_logs_to_console_attribute.attr); 655 if (error) 656 hdd_err("could not create power_stats sysfs file"); 657 } 658 659 static void hdd_sysfs_destroy_wakeup_logs_to_console(void) 660 { 661 if (!driver_kobject) { 662 hdd_err("could not get driver kobject!"); 663 return; 664 } 665 sysfs_remove_file(driver_kobject, 666 &wakeup_logs_to_console_attribute.attr); 667 } 668 669 static void hdd_sysfs_create_driver_root_obj(void) 670 { 671 driver_kobject = kobject_create_and_add(DRIVER_NAME, kernel_kobj); 672 if (!driver_kobject) { 673 hdd_err("could not allocate driver kobject"); 674 return; 675 } 676 677 wlan_kobject = kobject_create_and_add("wlan", driver_kobject); 678 if (!wlan_kobject) { 679 hdd_err("could not allocate wlan kobject"); 680 kobject_put(driver_kobject); 681 driver_kobject = NULL; 682 } 683 } 684 685 static void hdd_sysfs_destroy_driver_root_obj(void) 686 { 687 if (wlan_kobject) { 688 kobject_put(wlan_kobject); 689 wlan_kobject = NULL; 690 } 691 692 if (driver_kobject) { 693 kobject_put(driver_kobject); 694 driver_kobject = NULL; 695 } 696 } 697 698 void hdd_sysfs_create_wifi_root_obj(void) 699 { 700 if (wifi_kobject) { 701 hdd_debug("wifi kobj already created"); 702 return; 703 } 704 wifi_kobject = pld_get_wifi_kobj(NULL); 705 if (wifi_kobject) { 706 hdd_debug("wifi_kobject created by platform"); 707 return; 708 } 709 wifi_kobject = kobject_create_and_add("wifi", NULL); 710 if (!wifi_kobject) 711 hdd_err("could not allocate wifi kobject"); 712 } 713 714 void hdd_sysfs_destroy_wifi_root_obj(void) 715 { 716 if (pld_get_wifi_kobj(NULL)) { 717 hdd_debug("wifi_kobject created by platform"); 718 wifi_kobject = NULL; 719 return; 720 } 721 722 if (!wifi_kobject) { 723 hdd_err("could not get wifi kobject!"); 724 return; 725 } 726 kobject_put(wifi_kobject); 727 wifi_kobject = NULL; 728 } 729 730 void hdd_create_wifi_feature_interface_sysfs_file(void) 731 { 732 hdd_sysfs_create_wifi_feature_interface(wifi_kobject); 733 } 734 735 void hdd_destroy_wifi_feature_interface_sysfs_file(void) 736 { 737 hdd_sysfs_destroy_wifi_feature_interface(wifi_kobject); 738 } 739 740 int hdd_sysfs_print(void *ctx, const char *fmt, ...) 741 { 742 va_list args; 743 int ret = -1; 744 struct hdd_sysfs_print_ctx *p_ctx = ctx; 745 746 va_start(args, fmt); 747 748 if (ctx) { 749 ret = vscnprintf(p_ctx->buf + p_ctx->idx, 750 PAGE_SIZE - p_ctx->idx, fmt, args); 751 p_ctx->idx += ret; 752 if (p_ctx->new_line) { 753 ret += scnprintf(p_ctx->buf + p_ctx->idx, 754 PAGE_SIZE - p_ctx->idx, 755 "\n"); 756 p_ctx->idx += ret; 757 } 758 } 759 760 va_end(args); 761 return ret; 762 } 763 764 #ifdef WLAN_FEATURE_BEACON_RECEPTION_STATS 765 static int hdd_sysfs_create_bcn_reception_interface(struct hdd_adapter 766 *adapter) 767 { 768 int error; 769 770 error = device_create_file(&adapter->dev->dev, &dev_attr_beacon_stats); 771 if (error) 772 hdd_err("could not create beacon stats sysfs file"); 773 774 return error; 775 } 776 777 static void hdd_sysfs_destroy_bcn_reception_interface(struct hdd_adapter 778 *adapter) 779 { 780 device_remove_file(&adapter->dev->dev, &dev_attr_beacon_stats); 781 } 782 #else /* !WLAN_FEATURE_BEACON_RECEPTION_STATS */ 783 static inline int 784 hdd_sysfs_create_bcn_reception_interface(struct hdd_adapter *adapter) 785 { 786 return 0; 787 } 788 789 static inline void 790 hdd_sysfs_destroy_bcn_reception_interface(struct hdd_adapter *adapter) 791 { 792 } 793 794 #endif /* WLAN_FEATURE_BEACON_RECEPTION_STATS */ 795 796 static void 797 hdd_sysfs_create_sta_adapter_root_obj(struct hdd_adapter *adapter) 798 { 799 hdd_sysfs_create_bcn_reception_interface(adapter); 800 hdd_sysfs_reassoc_create(adapter); 801 hdd_sysfs_crash_inject_create(adapter); 802 hdd_sysfs_suspend_create(adapter); 803 hdd_sysfs_resume_create(adapter); 804 hdd_sysfs_unit_test_target_create(adapter); 805 hdd_sysfs_connect_info_interface_create(adapter); 806 hdd_sysfs_dcm_create(adapter); 807 hdd_sysfs_wowl_add_ptrn_create(adapter); 808 hdd_sysfs_wowl_del_ptrn_create(adapter); 809 hdd_sysfs_tx_stbc_create(adapter); 810 hdd_sysfs_txrx_fw_st_rst_create(adapter); 811 hdd_sysfs_gtx_bw_mask_create(adapter); 812 hdd_sysfs_rts_cts_create(adapter); 813 hdd_sysfs_stats_create(adapter); 814 hdd_sysfs_txrx_fw_stats_create(adapter); 815 hdd_sysfs_txrx_stats_create(adapter); 816 hdd_sysfs_tdls_peers_interface_create(adapter); 817 hdd_sysfs_temperature_create(adapter); 818 hdd_sysfs_motion_detection_create(adapter); 819 hdd_sysfs_range_ext_create(adapter); 820 hdd_sysfs_dl_modes_create(adapter); 821 hdd_sysfs_11be_rate_create(adapter); 822 hdd_sysfs_bmiss_create(adapter); 823 hdd_sysfs_dp_tx_delay_stats_create(adapter); 824 } 825 826 static void 827 hdd_sysfs_destroy_sta_adapter_root_obj(struct hdd_adapter *adapter) 828 { 829 hdd_sysfs_dp_tx_delay_stats_destroy(adapter); 830 hdd_sysfs_bmiss_destroy(adapter); 831 hdd_sysfs_11be_rate_destroy(adapter); 832 hdd_sysfs_dl_modes_destroy(adapter); 833 hdd_sysfs_range_ext_destroy(adapter); 834 hdd_sysfs_motion_detection_destroy(adapter); 835 hdd_sysfs_temperature_destroy(adapter); 836 hdd_sysfs_tdls_peers_interface_destroy(adapter); 837 hdd_sysfs_txrx_stats_destroy(adapter); 838 hdd_sysfs_txrx_fw_stats_destroy(adapter); 839 hdd_sysfs_stats_destroy(adapter); 840 hdd_sysfs_rts_cts_destroy(adapter); 841 hdd_sysfs_gtx_bw_mask_destroy(adapter); 842 hdd_sysfs_txrx_fw_st_rst_destroy(adapter); 843 hdd_sysfs_tx_stbc_destroy(adapter); 844 hdd_sysfs_wowl_del_ptrn_destroy(adapter); 845 hdd_sysfs_wowl_add_ptrn_destroy(adapter); 846 hdd_sysfs_dcm_destroy(adapter); 847 hdd_sysfs_connect_info_interface_destroy(adapter); 848 hdd_sysfs_unit_test_target_destroy(adapter); 849 hdd_sysfs_resume_destroy(adapter); 850 hdd_sysfs_suspend_destroy(adapter); 851 hdd_sysfs_crash_inject_destroy(adapter); 852 hdd_sysfs_reassoc_destroy(adapter); 853 hdd_sysfs_destroy_bcn_reception_interface(adapter); 854 } 855 856 static void 857 hdd_sysfs_create_sap_adapter_root_obj(struct hdd_adapter *adapter) 858 { 859 hdd_sysfs_channel_interface_create(adapter); 860 hdd_sysfs_sta_info_interface_create(adapter); 861 hdd_sysfs_crash_inject_create(adapter); 862 hdd_sysfs_suspend_create(adapter); 863 hdd_sysfs_resume_create(adapter); 864 hdd_sysfs_unit_test_target_create(adapter); 865 hdd_sysfs_modify_acl_create(adapter); 866 hdd_sysfs_connect_info_interface_create(adapter); 867 hdd_sysfs_tx_stbc_create(adapter); 868 hdd_sysfs_txrx_fw_st_rst_create(adapter); 869 hdd_sysfs_gtx_bw_mask_create(adapter); 870 hdd_sysfs_dcm_create(adapter); 871 hdd_sysfs_radar_create(adapter); 872 hdd_sysfs_rts_cts_create(adapter); 873 hdd_sysfs_stats_create(adapter); 874 hdd_sysfs_he_bss_color_create(adapter); 875 hdd_sysfs_txrx_fw_stats_create(adapter); 876 hdd_sysfs_txrx_stats_create(adapter); 877 hdd_sysfs_temperature_create(adapter); 878 hdd_sysfs_range_ext_create(adapter); 879 hdd_sysfs_ipa_create(adapter); 880 hdd_sysfs_dl_modes_create(adapter); 881 hdd_sysfs_11be_rate_create(adapter); 882 hdd_sysfs_dp_tx_delay_stats_create(adapter); 883 hdd_sysfs_dp_traffic_end_indication_create(adapter); 884 hdd_sysfs_direct_link_ut_cmd_create(adapter); 885 hdd_sysfs_dfsnol_create(adapter); 886 } 887 888 static void 889 hdd_sysfs_destroy_sap_adapter_root_obj(struct hdd_adapter *adapter) 890 { 891 hdd_sysfs_dfsnol_destroy(adapter); 892 hdd_sysfs_direct_link_ut_destroy(adapter); 893 hdd_sysfs_dp_traffic_end_indication_destroy(adapter); 894 hdd_sysfs_dp_tx_delay_stats_destroy(adapter); 895 hdd_sysfs_11be_rate_destroy(adapter); 896 hdd_sysfs_dl_modes_destroy(adapter); 897 hdd_sysfs_ipa_destroy(adapter); 898 hdd_sysfs_range_ext_destroy(adapter); 899 hdd_sysfs_temperature_destroy(adapter); 900 hdd_sysfs_txrx_stats_destroy(adapter); 901 hdd_sysfs_txrx_fw_stats_destroy(adapter); 902 hdd_sysfs_he_bss_color_destroy(adapter); 903 hdd_sysfs_stats_destroy(adapter); 904 hdd_sysfs_rts_cts_destroy(adapter); 905 hdd_sysfs_radar_destroy(adapter); 906 hdd_sysfs_dcm_destroy(adapter); 907 hdd_sysfs_gtx_bw_mask_destroy(adapter); 908 hdd_sysfs_txrx_fw_st_rst_destroy(adapter); 909 hdd_sysfs_tx_stbc_destroy(adapter); 910 hdd_sysfs_connect_info_interface_destroy(adapter); 911 hdd_sysfs_modify_acl_destroy(adapter); 912 hdd_sysfs_unit_test_target_destroy(adapter); 913 hdd_sysfs_resume_destroy(adapter); 914 hdd_sysfs_suspend_destroy(adapter); 915 hdd_sysfs_crash_inject_destroy(adapter); 916 hdd_sysfs_sta_info_interface_destroy(adapter); 917 hdd_sysfs_channel_interface_destroy(adapter); 918 } 919 920 static void 921 hdd_sysfs_create_monitor_adapter_root_obj(struct hdd_adapter *adapter) 922 { 923 hdd_sysfs_monitor_mode_channel_create(adapter); 924 } 925 926 static void 927 hdd_sysfs_destroy_monitor_adapter_root_obj(struct hdd_adapter *adapter) 928 { 929 hdd_sysfs_monitor_mode_channel_destroy(adapter); 930 } 931 932 void hdd_create_sysfs_files(struct hdd_context *hdd_ctx) 933 { 934 hdd_sysfs_create_driver_root_obj(); 935 hdd_sysfs_create_version_interface(hdd_ctx->psoc); 936 hdd_sysfs_mem_stats_create(wlan_kobject); 937 if (QDF_GLOBAL_MISSION_MODE == hdd_get_conparam()) { 938 hdd_sysfs_create_powerstats_interface(); 939 hdd_sysfs_create_dump_in_progress_interface(wifi_kobject); 940 hdd_sysfs_fw_mode_config_create(driver_kobject); 941 hdd_sysfs_scan_disable_create(driver_kobject); 942 hdd_sysfs_wow_ito_create(driver_kobject); 943 hdd_sysfs_wlan_dbg_create(driver_kobject); 944 hdd_sysfs_scan_config_create(driver_kobject); 945 hdd_sysfs_dp_trace_create(driver_kobject); 946 hdd_sysfs_thermal_cfg_create(driver_kobject); 947 hdd_sysfs_pktlog_create(driver_kobject); 948 hdd_sysfs_pm_cinfo_create(driver_kobject); 949 hdd_sysfs_pm_pcl_create(driver_kobject); 950 hdd_sysfs_dp_aggregation_create(driver_kobject); 951 hdd_sysfs_dp_swlm_create(driver_kobject); 952 hdd_sysfs_create_wakeup_logs_to_console(); 953 hdd_sysfs_dp_txrx_stats_sysfs_create(driver_kobject); 954 hdd_sysfs_get_valid_freq_for_power_create(driver_kobject); 955 hdd_sysfs_dp_pkt_add_ts_create(driver_kobject); 956 hdd_sysfs_runtime_pm_create(driver_kobject); 957 hdd_sysfs_log_buffer_create(driver_kobject); 958 } 959 } 960 961 void hdd_destroy_sysfs_files(void) 962 { 963 if (QDF_GLOBAL_MISSION_MODE == hdd_get_conparam()) { 964 hdd_sysfs_log_buffer_destroy(driver_kobject); 965 hdd_sysfs_runtime_pm_destroy(driver_kobject); 966 hdd_sysfs_dp_pkt_add_ts_destroy(driver_kobject); 967 hdd_sysfs_get_valid_freq_for_power_destroy(driver_kobject); 968 hdd_sysfs_dp_txrx_stats_sysfs_destroy(driver_kobject); 969 hdd_sysfs_destroy_wakeup_logs_to_console(); 970 hdd_sysfs_dp_swlm_destroy(driver_kobject); 971 hdd_sysfs_dp_aggregation_destroy(driver_kobject); 972 hdd_sysfs_pm_pcl_destroy(driver_kobject); 973 hdd_sysfs_pm_cinfo_destroy(driver_kobject); 974 hdd_sysfs_pktlog_destroy(driver_kobject); 975 hdd_sysfs_thermal_cfg_destroy(driver_kobject); 976 hdd_sysfs_dp_trace_destroy(driver_kobject); 977 hdd_sysfs_scan_config_destroy(driver_kobject); 978 hdd_sysfs_wlan_dbg_destroy(driver_kobject); 979 hdd_sysfs_wow_ito_destroy(driver_kobject); 980 hdd_sysfs_scan_disable_destroy(driver_kobject); 981 hdd_sysfs_fw_mode_config_destroy(driver_kobject); 982 hdd_sysfs_destroy_dump_in_progress_interface(wifi_kobject); 983 hdd_sysfs_destroy_powerstats_interface(); 984 } 985 hdd_sysfs_mem_stats_destroy(wlan_kobject); 986 hdd_sysfs_destroy_version_interface(); 987 hdd_sysfs_destroy_driver_root_obj(); 988 } 989 990 static 991 void hdd_sysfs_create_ftm_adapter_root_obj(struct hdd_adapter *adapter) 992 { 993 hdd_sysfs_unit_test_target_create(adapter); 994 } 995 996 void hdd_create_adapter_sysfs_files(struct hdd_adapter *adapter) 997 { 998 int device_mode = adapter->device_mode; 999 1000 if (hdd_adapter_is_link_adapter(adapter)) { 1001 hdd_err("link adapter returning!!"); 1002 return; 1003 } 1004 1005 switch (device_mode){ 1006 case QDF_STA_MODE: 1007 case QDF_P2P_DEVICE_MODE: 1008 case QDF_P2P_CLIENT_MODE: 1009 hdd_sysfs_create_sta_adapter_root_obj(adapter); 1010 break; 1011 case QDF_SAP_MODE: 1012 case QDF_P2P_GO_MODE: 1013 hdd_sysfs_create_sap_adapter_root_obj(adapter); 1014 break; 1015 case QDF_MONITOR_MODE: 1016 hdd_sysfs_create_monitor_adapter_root_obj(adapter); 1017 break; 1018 case QDF_FTM_MODE: 1019 hdd_sysfs_create_ftm_adapter_root_obj(adapter); 1020 break; 1021 default: 1022 break; 1023 } 1024 } 1025 1026 static 1027 void hdd_sysfs_destroy_ftm_adapter_root_obj(struct hdd_adapter *adapter) 1028 { 1029 hdd_sysfs_unit_test_target_destroy(adapter); 1030 } 1031 1032 void hdd_destroy_adapter_sysfs_files(struct hdd_adapter *adapter) 1033 { 1034 int device_mode = adapter->device_mode; 1035 1036 if (hdd_adapter_is_link_adapter(adapter)) { 1037 hdd_err("link adapter returning!!"); 1038 return; 1039 } 1040 switch (device_mode){ 1041 case QDF_STA_MODE: 1042 case QDF_P2P_DEVICE_MODE: 1043 case QDF_P2P_CLIENT_MODE: 1044 hdd_sysfs_destroy_sta_adapter_root_obj(adapter); 1045 break; 1046 case QDF_SAP_MODE: 1047 case QDF_P2P_GO_MODE: 1048 hdd_sysfs_destroy_sap_adapter_root_obj(adapter); 1049 break; 1050 case QDF_MONITOR_MODE: 1051 hdd_sysfs_destroy_monitor_adapter_root_obj(adapter); 1052 break; 1053 case QDF_FTM_MODE: 1054 hdd_sysfs_destroy_ftm_adapter_root_obj(adapter); 1055 break; 1056 default: 1057 break; 1058 } 1059 } 1060