1 // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause 2 /* 3 * Copyright (C) 2012-2014, 2018-2023 Intel Corporation 4 * Copyright (C) 2013-2015 Intel Mobile Communications GmbH 5 * Copyright (C) 2016-2017 Intel Deutschland GmbH 6 */ 7 #include <linux/vmalloc.h> 8 #include <linux/err.h> 9 #include <linux/ieee80211.h> 10 #include <linux/netdevice.h> 11 #include <linux/dmi.h> 12 13 #include "mvm.h" 14 #include "sta.h" 15 #include "iwl-io.h" 16 #include "debugfs.h" 17 #include "iwl-modparams.h" 18 #include "iwl-drv.h" 19 #include "fw/error-dump.h" 20 #include "fw/api/phy-ctxt.h" 21 22 static ssize_t iwl_dbgfs_ctdp_budget_read(struct file *file, 23 char __user *user_buf, 24 size_t count, loff_t *ppos) 25 { 26 struct iwl_mvm *mvm = file->private_data; 27 char buf[16]; 28 int pos, budget; 29 30 if (!iwl_mvm_is_ctdp_supported(mvm)) 31 return -EOPNOTSUPP; 32 33 if (!iwl_mvm_firmware_running(mvm) || 34 mvm->fwrt.cur_fw_img != IWL_UCODE_REGULAR) 35 return -EIO; 36 37 mutex_lock(&mvm->mutex); 38 budget = iwl_mvm_ctdp_command(mvm, CTDP_CMD_OPERATION_REPORT, 0); 39 mutex_unlock(&mvm->mutex); 40 41 if (budget < 0) 42 return budget; 43 44 pos = scnprintf(buf, sizeof(buf), "%d\n", budget); 45 46 return simple_read_from_buffer(user_buf, count, ppos, buf, pos); 47 } 48 49 static ssize_t iwl_dbgfs_stop_ctdp_write(struct iwl_mvm *mvm, char *buf, 50 size_t count, loff_t *ppos) 51 { 52 int ret; 53 bool force; 54 55 if (!kstrtobool(buf, &force)) 56 IWL_DEBUG_INFO(mvm, 57 "force start is %d [0=disabled, 1=enabled]\n", 58 force); 59 60 /* we allow skipping cap support check and force stop ctdp 61 * statistics collection and with guerantee that it is 62 * safe to use. 63 */ 64 if (!force && !iwl_mvm_is_ctdp_supported(mvm)) 65 return -EOPNOTSUPP; 66 67 if (!iwl_mvm_firmware_running(mvm) || 68 mvm->fwrt.cur_fw_img != IWL_UCODE_REGULAR) 69 return -EIO; 70 71 mutex_lock(&mvm->mutex); 72 ret = iwl_mvm_ctdp_command(mvm, CTDP_CMD_OPERATION_STOP, 0); 73 mutex_unlock(&mvm->mutex); 74 75 return ret ?: count; 76 } 77 78 static ssize_t iwl_dbgfs_start_ctdp_write(struct iwl_mvm *mvm, 79 char *buf, size_t count, 80 loff_t *ppos) 81 { 82 int ret; 83 bool force; 84 85 if (!kstrtobool(buf, &force)) 86 IWL_DEBUG_INFO(mvm, 87 "force start is %d [0=disabled, 1=enabled]\n", 88 force); 89 90 /* we allow skipping cap support check and force enable ctdp 91 * for statistics collection and with guerantee that it is 92 * safe to use. 93 */ 94 if (!force && !iwl_mvm_is_ctdp_supported(mvm)) 95 return -EOPNOTSUPP; 96 97 if (!iwl_mvm_firmware_running(mvm) || 98 mvm->fwrt.cur_fw_img != IWL_UCODE_REGULAR) 99 return -EIO; 100 101 mutex_lock(&mvm->mutex); 102 ret = iwl_mvm_ctdp_command(mvm, CTDP_CMD_OPERATION_START, 0); 103 mutex_unlock(&mvm->mutex); 104 105 return ret ?: count; 106 } 107 108 static ssize_t iwl_dbgfs_force_ctkill_write(struct iwl_mvm *mvm, char *buf, 109 size_t count, loff_t *ppos) 110 { 111 if (!iwl_mvm_firmware_running(mvm) || 112 mvm->fwrt.cur_fw_img != IWL_UCODE_REGULAR) 113 return -EIO; 114 115 iwl_mvm_enter_ctkill(mvm); 116 117 return count; 118 } 119 120 static ssize_t iwl_dbgfs_tx_flush_write(struct iwl_mvm *mvm, char *buf, 121 size_t count, loff_t *ppos) 122 { 123 int ret; 124 u32 flush_arg; 125 126 if (!iwl_mvm_firmware_running(mvm) || 127 mvm->fwrt.cur_fw_img != IWL_UCODE_REGULAR) 128 return -EIO; 129 130 if (kstrtou32(buf, 0, &flush_arg)) 131 return -EINVAL; 132 133 if (iwl_mvm_has_new_tx_api(mvm)) { 134 IWL_DEBUG_TX_QUEUES(mvm, 135 "FLUSHING all tids queues on sta_id = %d\n", 136 flush_arg); 137 mutex_lock(&mvm->mutex); 138 ret = iwl_mvm_flush_sta_tids(mvm, flush_arg, 0xFFFF) 139 ? : count; 140 mutex_unlock(&mvm->mutex); 141 return ret; 142 } 143 144 IWL_DEBUG_TX_QUEUES(mvm, "FLUSHING queues mask to flush = 0x%x\n", 145 flush_arg); 146 147 mutex_lock(&mvm->mutex); 148 ret = iwl_mvm_flush_tx_path(mvm, flush_arg) ? : count; 149 mutex_unlock(&mvm->mutex); 150 151 return ret; 152 } 153 154 static ssize_t iwl_dbgfs_sram_read(struct file *file, char __user *user_buf, 155 size_t count, loff_t *ppos) 156 { 157 struct iwl_mvm *mvm = file->private_data; 158 const struct fw_img *img; 159 unsigned int ofs, len; 160 size_t ret; 161 u8 *ptr; 162 163 if (!iwl_mvm_firmware_running(mvm)) 164 return -EINVAL; 165 166 /* default is to dump the entire data segment */ 167 img = &mvm->fw->img[mvm->fwrt.cur_fw_img]; 168 ofs = img->sec[IWL_UCODE_SECTION_DATA].offset; 169 len = img->sec[IWL_UCODE_SECTION_DATA].len; 170 171 if (mvm->dbgfs_sram_len) { 172 ofs = mvm->dbgfs_sram_offset; 173 len = mvm->dbgfs_sram_len; 174 } 175 176 ptr = kzalloc(len, GFP_KERNEL); 177 if (!ptr) 178 return -ENOMEM; 179 180 iwl_trans_read_mem_bytes(mvm->trans, ofs, ptr, len); 181 182 ret = simple_read_from_buffer(user_buf, count, ppos, ptr, len); 183 184 kfree(ptr); 185 186 return ret; 187 } 188 189 static ssize_t iwl_dbgfs_sram_write(struct iwl_mvm *mvm, char *buf, 190 size_t count, loff_t *ppos) 191 { 192 const struct fw_img *img; 193 u32 offset, len; 194 u32 img_offset, img_len; 195 196 if (!iwl_mvm_firmware_running(mvm)) 197 return -EINVAL; 198 199 img = &mvm->fw->img[mvm->fwrt.cur_fw_img]; 200 img_offset = img->sec[IWL_UCODE_SECTION_DATA].offset; 201 img_len = img->sec[IWL_UCODE_SECTION_DATA].len; 202 203 if (sscanf(buf, "%x,%x", &offset, &len) == 2) { 204 if ((offset & 0x3) || (len & 0x3)) 205 return -EINVAL; 206 207 if (offset + len > img_offset + img_len) 208 return -EINVAL; 209 210 mvm->dbgfs_sram_offset = offset; 211 mvm->dbgfs_sram_len = len; 212 } else { 213 mvm->dbgfs_sram_offset = 0; 214 mvm->dbgfs_sram_len = 0; 215 } 216 217 return count; 218 } 219 220 static ssize_t iwl_dbgfs_set_nic_temperature_read(struct file *file, 221 char __user *user_buf, 222 size_t count, loff_t *ppos) 223 { 224 struct iwl_mvm *mvm = file->private_data; 225 char buf[16]; 226 int pos; 227 228 if (!mvm->temperature_test) 229 pos = scnprintf(buf, sizeof(buf), "disabled\n"); 230 else 231 pos = scnprintf(buf, sizeof(buf), "%d\n", mvm->temperature); 232 233 return simple_read_from_buffer(user_buf, count, ppos, buf, pos); 234 } 235 236 /* 237 * Set NIC Temperature 238 * Cause the driver to ignore the actual NIC temperature reported by the FW 239 * Enable: any value between IWL_MVM_DEBUG_SET_TEMPERATURE_MIN - 240 * IWL_MVM_DEBUG_SET_TEMPERATURE_MAX 241 * Disable: IWL_MVM_DEBUG_SET_TEMPERATURE_DISABLE 242 */ 243 static ssize_t iwl_dbgfs_set_nic_temperature_write(struct iwl_mvm *mvm, 244 char *buf, size_t count, 245 loff_t *ppos) 246 { 247 int temperature; 248 249 if (!iwl_mvm_firmware_running(mvm) && !mvm->temperature_test) 250 return -EIO; 251 252 if (kstrtoint(buf, 10, &temperature)) 253 return -EINVAL; 254 /* not a legal temperature */ 255 if ((temperature > IWL_MVM_DEBUG_SET_TEMPERATURE_MAX && 256 temperature != IWL_MVM_DEBUG_SET_TEMPERATURE_DISABLE) || 257 temperature < IWL_MVM_DEBUG_SET_TEMPERATURE_MIN) 258 return -EINVAL; 259 260 mutex_lock(&mvm->mutex); 261 if (temperature == IWL_MVM_DEBUG_SET_TEMPERATURE_DISABLE) { 262 if (!mvm->temperature_test) 263 goto out; 264 265 mvm->temperature_test = false; 266 /* Since we can't read the temp while awake, just set 267 * it to zero until we get the next RX stats from the 268 * firmware. 269 */ 270 mvm->temperature = 0; 271 } else { 272 mvm->temperature_test = true; 273 mvm->temperature = temperature; 274 } 275 IWL_DEBUG_TEMP(mvm, "%sabling debug set temperature (temp = %d)\n", 276 mvm->temperature_test ? "En" : "Dis", 277 mvm->temperature); 278 /* handle the temperature change */ 279 iwl_mvm_tt_handler(mvm); 280 281 out: 282 mutex_unlock(&mvm->mutex); 283 284 return count; 285 } 286 287 static ssize_t iwl_dbgfs_nic_temp_read(struct file *file, 288 char __user *user_buf, 289 size_t count, loff_t *ppos) 290 { 291 struct iwl_mvm *mvm = file->private_data; 292 char buf[16]; 293 int pos, ret; 294 s32 temp; 295 296 if (!iwl_mvm_firmware_running(mvm)) 297 return -EIO; 298 299 mutex_lock(&mvm->mutex); 300 ret = iwl_mvm_get_temp(mvm, &temp); 301 mutex_unlock(&mvm->mutex); 302 303 if (ret) 304 return -EIO; 305 306 pos = scnprintf(buf, sizeof(buf), "%d\n", temp); 307 308 return simple_read_from_buffer(user_buf, count, ppos, buf, pos); 309 } 310 311 #ifdef CONFIG_ACPI 312 static ssize_t iwl_dbgfs_sar_geo_profile_read(struct file *file, 313 char __user *user_buf, 314 size_t count, loff_t *ppos) 315 { 316 struct iwl_mvm *mvm = file->private_data; 317 char buf[256]; 318 int pos = 0; 319 int bufsz = sizeof(buf); 320 int tbl_idx; 321 322 if (!iwl_mvm_firmware_running(mvm)) 323 return -EIO; 324 325 mutex_lock(&mvm->mutex); 326 tbl_idx = iwl_mvm_get_sar_geo_profile(mvm); 327 if (tbl_idx < 0) { 328 mutex_unlock(&mvm->mutex); 329 return tbl_idx; 330 } 331 332 if (!tbl_idx) { 333 pos = scnprintf(buf, bufsz, 334 "SAR geographic profile disabled\n"); 335 } else { 336 pos += scnprintf(buf + pos, bufsz - pos, 337 "Use geographic profile %d\n", tbl_idx); 338 pos += scnprintf(buf + pos, bufsz - pos, 339 "2.4GHz:\n\tChain A offset: %u dBm\n\tChain B offset: %u dBm\n\tmax tx power: %u dBm\n", 340 mvm->fwrt.geo_profiles[tbl_idx - 1].bands[0].chains[0], 341 mvm->fwrt.geo_profiles[tbl_idx - 1].bands[0].chains[1], 342 mvm->fwrt.geo_profiles[tbl_idx - 1].bands[0].max); 343 pos += scnprintf(buf + pos, bufsz - pos, 344 "5.2GHz:\n\tChain A offset: %u dBm\n\tChain B offset: %u dBm\n\tmax tx power: %u dBm\n", 345 mvm->fwrt.geo_profiles[tbl_idx - 1].bands[1].chains[0], 346 mvm->fwrt.geo_profiles[tbl_idx - 1].bands[1].chains[1], 347 mvm->fwrt.geo_profiles[tbl_idx - 1].bands[1].max); 348 } 349 mutex_unlock(&mvm->mutex); 350 351 return simple_read_from_buffer(user_buf, count, ppos, buf, pos); 352 } 353 354 static ssize_t iwl_dbgfs_wifi_6e_enable_read(struct file *file, 355 char __user *user_buf, 356 size_t count, loff_t *ppos) 357 { 358 struct iwl_mvm *mvm = file->private_data; 359 int err, pos; 360 char buf[12]; 361 u32 value; 362 363 err = iwl_bios_get_dsm(&mvm->fwrt, DSM_FUNC_ENABLE_6E, &value); 364 if (err) 365 return err; 366 367 pos = sprintf(buf, "0x%08x\n", value); 368 369 return simple_read_from_buffer(user_buf, count, ppos, buf, pos); 370 } 371 #endif 372 373 static ssize_t iwl_dbgfs_stations_read(struct file *file, char __user *user_buf, 374 size_t count, loff_t *ppos) 375 { 376 struct iwl_mvm *mvm = file->private_data; 377 struct ieee80211_sta *sta; 378 char buf[400]; 379 int i, pos = 0, bufsz = sizeof(buf); 380 381 mutex_lock(&mvm->mutex); 382 383 for (i = 0; i < mvm->fw->ucode_capa.num_stations; i++) { 384 pos += scnprintf(buf + pos, bufsz - pos, "%.2d: ", i); 385 sta = rcu_dereference_protected(mvm->fw_id_to_mac_id[i], 386 lockdep_is_held(&mvm->mutex)); 387 if (!sta) 388 pos += scnprintf(buf + pos, bufsz - pos, "N/A\n"); 389 else if (IS_ERR(sta)) 390 pos += scnprintf(buf + pos, bufsz - pos, "%ld\n", 391 PTR_ERR(sta)); 392 else 393 pos += scnprintf(buf + pos, bufsz - pos, "%pM\n", 394 sta->addr); 395 } 396 397 mutex_unlock(&mvm->mutex); 398 399 return simple_read_from_buffer(user_buf, count, ppos, buf, pos); 400 } 401 402 static ssize_t iwl_dbgfs_rs_data_read(struct ieee80211_link_sta *link_sta, 403 struct iwl_mvm_sta *mvmsta, 404 struct iwl_mvm *mvm, 405 struct iwl_mvm_link_sta *mvm_link_sta, 406 char __user *user_buf, 407 size_t count, loff_t *ppos) 408 { 409 struct iwl_lq_sta_rs_fw *lq_sta = &mvm_link_sta->lq_sta.rs_fw; 410 static const size_t bufsz = 2048; 411 char *buff; 412 int desc = 0; 413 ssize_t ret; 414 415 buff = kmalloc(bufsz, GFP_KERNEL); 416 if (!buff) 417 return -ENOMEM; 418 419 desc += scnprintf(buff + desc, bufsz - desc, "sta_id %d\n", 420 lq_sta->pers.sta_id); 421 desc += scnprintf(buff + desc, bufsz - desc, 422 "fixed rate 0x%X\n", 423 lq_sta->pers.dbg_fixed_rate); 424 desc += scnprintf(buff + desc, bufsz - desc, 425 "A-MPDU size limit %d\n", 426 lq_sta->pers.dbg_agg_frame_count_lim); 427 desc += scnprintf(buff + desc, bufsz - desc, 428 "valid_tx_ant %s%s\n", 429 (iwl_mvm_get_valid_tx_ant(mvm) & ANT_A) ? "ANT_A," : "", 430 (iwl_mvm_get_valid_tx_ant(mvm) & ANT_B) ? "ANT_B," : ""); 431 desc += scnprintf(buff + desc, bufsz - desc, 432 "last tx rate=0x%X ", 433 lq_sta->last_rate_n_flags); 434 435 desc += rs_pretty_print_rate(buff + desc, bufsz - desc, 436 lq_sta->last_rate_n_flags); 437 if (desc < bufsz - 1) 438 buff[desc++] = '\n'; 439 440 ret = simple_read_from_buffer(user_buf, count, ppos, buff, desc); 441 kfree(buff); 442 return ret; 443 } 444 445 static ssize_t iwl_dbgfs_amsdu_len_write(struct ieee80211_link_sta *link_sta, 446 struct iwl_mvm_sta *mvmsta, 447 struct iwl_mvm *mvm, 448 struct iwl_mvm_link_sta *mvm_link_sta, 449 char *buf, size_t count, 450 loff_t *ppos) 451 { 452 int i; 453 u16 amsdu_len; 454 455 if (kstrtou16(buf, 0, &amsdu_len)) 456 return -EINVAL; 457 458 /* only change from debug set <-> debug unset */ 459 if (amsdu_len && mvm_link_sta->orig_amsdu_len) 460 return -EBUSY; 461 462 if (amsdu_len) { 463 mvm_link_sta->orig_amsdu_len = link_sta->agg.max_amsdu_len; 464 link_sta->agg.max_amsdu_len = amsdu_len; 465 link_sta->agg.max_amsdu_len = amsdu_len; 466 for (i = 0; i < ARRAY_SIZE(link_sta->agg.max_tid_amsdu_len); i++) 467 link_sta->agg.max_tid_amsdu_len[i] = amsdu_len; 468 } else { 469 link_sta->agg.max_amsdu_len = mvm_link_sta->orig_amsdu_len; 470 mvm_link_sta->orig_amsdu_len = 0; 471 } 472 473 ieee80211_sta_recalc_aggregates(link_sta->sta); 474 475 return count; 476 } 477 478 static ssize_t iwl_dbgfs_amsdu_len_read(struct ieee80211_link_sta *link_sta, 479 struct iwl_mvm_sta *mvmsta, 480 struct iwl_mvm *mvm, 481 struct iwl_mvm_link_sta *mvm_link_sta, 482 char __user *user_buf, 483 size_t count, loff_t *ppos) 484 { 485 char buf[32]; 486 int pos; 487 488 pos = scnprintf(buf, sizeof(buf), "current %d ", 489 link_sta->agg.max_amsdu_len); 490 pos += scnprintf(buf + pos, sizeof(buf) - pos, "stored %d\n", 491 mvm_link_sta->orig_amsdu_len); 492 493 return simple_read_from_buffer(user_buf, count, ppos, buf, pos); 494 } 495 496 static ssize_t iwl_dbgfs_disable_power_off_read(struct file *file, 497 char __user *user_buf, 498 size_t count, loff_t *ppos) 499 { 500 struct iwl_mvm *mvm = file->private_data; 501 char buf[64]; 502 int bufsz = sizeof(buf); 503 int pos = 0; 504 505 pos += scnprintf(buf+pos, bufsz-pos, "disable_power_off_d0=%d\n", 506 mvm->disable_power_off); 507 pos += scnprintf(buf+pos, bufsz-pos, "disable_power_off_d3=%d\n", 508 mvm->disable_power_off_d3); 509 510 return simple_read_from_buffer(user_buf, count, ppos, buf, pos); 511 } 512 513 static ssize_t iwl_dbgfs_disable_power_off_write(struct iwl_mvm *mvm, char *buf, 514 size_t count, loff_t *ppos) 515 { 516 int ret, val; 517 518 if (!iwl_mvm_firmware_running(mvm)) 519 return -EIO; 520 521 if (!strncmp("disable_power_off_d0=", buf, 21)) { 522 if (sscanf(buf + 21, "%d", &val) != 1) 523 return -EINVAL; 524 mvm->disable_power_off = val; 525 } else if (!strncmp("disable_power_off_d3=", buf, 21)) { 526 if (sscanf(buf + 21, "%d", &val) != 1) 527 return -EINVAL; 528 mvm->disable_power_off_d3 = val; 529 } else { 530 return -EINVAL; 531 } 532 533 mutex_lock(&mvm->mutex); 534 ret = iwl_mvm_power_update_device(mvm); 535 mutex_unlock(&mvm->mutex); 536 537 return ret ?: count; 538 } 539 540 static ssize_t iwl_dbgfs_fw_ver_read(struct file *file, char __user *user_buf, 541 size_t count, loff_t *ppos) 542 { 543 struct iwl_mvm *mvm = file->private_data; 544 char *buff, *pos, *endpos; 545 static const size_t bufsz = 1024; 546 int ret; 547 548 buff = kmalloc(bufsz, GFP_KERNEL); 549 if (!buff) 550 return -ENOMEM; 551 552 pos = buff; 553 endpos = pos + bufsz; 554 555 pos += scnprintf(pos, endpos - pos, "FW id: %s\n", 556 mvm->fwrt.fw->fw_version); 557 pos += scnprintf(pos, endpos - pos, "FW: %s\n", 558 mvm->fwrt.fw->human_readable); 559 pos += scnprintf(pos, endpos - pos, "Device: %s\n", 560 mvm->fwrt.trans->name); 561 pos += scnprintf(pos, endpos - pos, "Bus: %s\n", 562 #if defined(__linux__) 563 mvm->fwrt.dev->bus->name); 564 #elif defined(__FreeBSD__) 565 "<bus>"); 566 #endif 567 568 ret = simple_read_from_buffer(user_buf, count, ppos, buff, pos - buff); 569 kfree(buff); 570 571 return ret; 572 } 573 574 static ssize_t iwl_dbgfs_tas_get_status_read(struct file *file, 575 char __user *user_buf, 576 size_t count, loff_t *ppos) 577 { 578 struct iwl_mvm *mvm = file->private_data; 579 struct iwl_mvm_tas_status_resp tas_rsp; 580 struct iwl_mvm_tas_status_resp *rsp = &tas_rsp; 581 static const size_t bufsz = 1024; 582 char *buff, *pos, *endpos; 583 const char * const tas_dis_reason[TAS_DISABLED_REASON_MAX] = { 584 [TAS_DISABLED_DUE_TO_BIOS] = 585 "Due To BIOS", 586 [TAS_DISABLED_DUE_TO_SAR_6DBM] = 587 "Due To SAR Limit Less Than 6 dBm", 588 [TAS_DISABLED_REASON_INVALID] = 589 "N/A", 590 }; 591 const char * const tas_current_status[TAS_DYNA_STATUS_MAX] = { 592 [TAS_DYNA_INACTIVE] = "INACTIVE", 593 [TAS_DYNA_INACTIVE_MVM_MODE] = 594 "inactive due to mvm mode", 595 [TAS_DYNA_INACTIVE_TRIGGER_MODE] = 596 "inactive due to trigger mode", 597 [TAS_DYNA_INACTIVE_BLOCK_LISTED] = 598 "inactive due to block listed", 599 [TAS_DYNA_INACTIVE_UHB_NON_US] = 600 "inactive due to uhb non US", 601 [TAS_DYNA_ACTIVE] = "ACTIVE", 602 }; 603 struct iwl_host_cmd hcmd = { 604 .id = WIDE_ID(DEBUG_GROUP, GET_TAS_STATUS), 605 .flags = CMD_WANT_SKB, 606 .len = { 0, }, 607 .data = { NULL, }, 608 }; 609 int ret, i, tmp; 610 bool tas_enabled = false; 611 unsigned long dyn_status; 612 613 if (!iwl_mvm_firmware_running(mvm)) 614 return -ENODEV; 615 616 mutex_lock(&mvm->mutex); 617 ret = iwl_mvm_send_cmd(mvm, &hcmd); 618 mutex_unlock(&mvm->mutex); 619 if (ret < 0) 620 return ret; 621 622 buff = kzalloc(bufsz, GFP_KERNEL); 623 if (!buff) 624 return -ENOMEM; 625 pos = buff; 626 endpos = pos + bufsz; 627 628 rsp = (void *)hcmd.resp_pkt->data; 629 630 pos += scnprintf(pos, endpos - pos, "TAS Conclusion:\n"); 631 for (i = 0; i < rsp->in_dual_radio + 1; i++) { 632 if (rsp->tas_status_mac[i].band != TAS_LMAC_BAND_INVALID && 633 rsp->tas_status_mac[i].dynamic_status & BIT(TAS_DYNA_ACTIVE)) { 634 pos += scnprintf(pos, endpos - pos, "\tON for "); 635 switch (rsp->tas_status_mac[i].band) { 636 case TAS_LMAC_BAND_HB: 637 pos += scnprintf(pos, endpos - pos, "HB\n"); 638 break; 639 case TAS_LMAC_BAND_LB: 640 pos += scnprintf(pos, endpos - pos, "LB\n"); 641 break; 642 case TAS_LMAC_BAND_UHB: 643 pos += scnprintf(pos, endpos - pos, "UHB\n"); 644 break; 645 case TAS_LMAC_BAND_INVALID: 646 pos += scnprintf(pos, endpos - pos, 647 "INVALID BAND\n"); 648 break; 649 default: 650 pos += scnprintf(pos, endpos - pos, 651 "Unsupported band (%d)\n", 652 rsp->tas_status_mac[i].band); 653 goto out; 654 } 655 tas_enabled = true; 656 } 657 } 658 if (!tas_enabled) 659 pos += scnprintf(pos, endpos - pos, "\tOFF\n"); 660 661 pos += scnprintf(pos, endpos - pos, "TAS Report\n"); 662 pos += scnprintf(pos, endpos - pos, "TAS FW version: %d\n", 663 rsp->tas_fw_version); 664 pos += scnprintf(pos, endpos - pos, "Is UHB enabled for USA?: %s\n", 665 rsp->is_uhb_for_usa_enable ? "True" : "False"); 666 pos += scnprintf(pos, endpos - pos, "Current MCC: 0x%x\n", 667 le16_to_cpu(rsp->curr_mcc)); 668 669 pos += scnprintf(pos, endpos - pos, "Block list entries:"); 670 for (i = 0; i < IWL_WTAS_BLACK_LIST_MAX; i++) 671 pos += scnprintf(pos, endpos - pos, " 0x%x", 672 le16_to_cpu(rsp->block_list[i])); 673 674 pos += scnprintf(pos, endpos - pos, "\nOEM name: %s\n", 675 dmi_get_system_info(DMI_SYS_VENDOR) ?: "<unknown>"); 676 pos += scnprintf(pos, endpos - pos, "\tVendor In Approved List: %s\n", 677 iwl_is_tas_approved() ? "YES" : "NO"); 678 pos += scnprintf(pos, endpos - pos, 679 "\tDo TAS Support Dual Radio?: %s\n", 680 rsp->in_dual_radio ? "TRUE" : "FALSE"); 681 682 for (i = 0; i < rsp->in_dual_radio + 1; i++) { 683 if (rsp->tas_status_mac[i].static_status == 0) { 684 pos += scnprintf(pos, endpos - pos, 685 "Static status: disabled\n"); 686 pos += scnprintf(pos, endpos - pos, 687 "Static disabled reason: %s (0)\n", 688 tas_dis_reason[0]); 689 goto out; 690 } 691 692 pos += scnprintf(pos, endpos - pos, "TAS status for "); 693 switch (rsp->tas_status_mac[i].band) { 694 case TAS_LMAC_BAND_HB: 695 pos += scnprintf(pos, endpos - pos, "High band\n"); 696 break; 697 case TAS_LMAC_BAND_LB: 698 pos += scnprintf(pos, endpos - pos, "Low band\n"); 699 break; 700 case TAS_LMAC_BAND_UHB: 701 pos += scnprintf(pos, endpos - pos, 702 "Ultra high band\n"); 703 break; 704 case TAS_LMAC_BAND_INVALID: 705 pos += scnprintf(pos, endpos - pos, 706 "INVALID band\n"); 707 break; 708 default: 709 pos += scnprintf(pos, endpos - pos, 710 "Unsupported band (%d)\n", 711 rsp->tas_status_mac[i].band); 712 goto out; 713 } 714 pos += scnprintf(pos, endpos - pos, "Static status: %sabled\n", 715 rsp->tas_status_mac[i].static_status ? 716 "En" : "Dis"); 717 pos += scnprintf(pos, endpos - pos, 718 "\tStatic Disabled Reason: "); 719 if (rsp->tas_status_mac[i].static_dis_reason < TAS_DISABLED_REASON_MAX) 720 pos += scnprintf(pos, endpos - pos, "%s (%d)\n", 721 tas_dis_reason[rsp->tas_status_mac[i].static_dis_reason], 722 rsp->tas_status_mac[i].static_dis_reason); 723 else 724 pos += scnprintf(pos, endpos - pos, 725 "unsupported value (%d)\n", 726 rsp->tas_status_mac[i].static_dis_reason); 727 728 pos += scnprintf(pos, endpos - pos, "Dynamic status:\n"); 729 dyn_status = (rsp->tas_status_mac[i].dynamic_status); 730 for_each_set_bit(tmp, &dyn_status, sizeof(dyn_status)) { 731 if (tmp >= 0 && tmp < TAS_DYNA_STATUS_MAX) 732 pos += scnprintf(pos, endpos - pos, 733 "\t%s (%d)\n", 734 tas_current_status[tmp], tmp); 735 } 736 737 pos += scnprintf(pos, endpos - pos, 738 "Is near disconnection?: %s\n", 739 rsp->tas_status_mac[i].near_disconnection ? 740 "True" : "False"); 741 tmp = le16_to_cpu(rsp->tas_status_mac[i].max_reg_pwr_limit); 742 pos += scnprintf(pos, endpos - pos, 743 "Max. regulatory pwr limit (dBm): %d.%03d\n", 744 tmp / 8, 125 * (tmp % 8)); 745 tmp = le16_to_cpu(rsp->tas_status_mac[i].sar_limit); 746 pos += scnprintf(pos, endpos - pos, 747 "SAR limit (dBm): %d.%03d\n", 748 tmp / 8, 125 * (tmp % 8)); 749 } 750 751 out: 752 ret = simple_read_from_buffer(user_buf, count, ppos, buff, pos - buff); 753 kfree(buff); 754 iwl_free_resp(&hcmd); 755 return ret; 756 } 757 758 static ssize_t iwl_dbgfs_phy_integration_ver_read(struct file *file, 759 char __user *user_buf, 760 size_t count, loff_t *ppos) 761 { 762 struct iwl_mvm *mvm = file->private_data; 763 char *buf; 764 size_t bufsz; 765 int pos; 766 ssize_t ret; 767 768 bufsz = mvm->fw->phy_integration_ver_len + 2; 769 buf = kmalloc(bufsz, GFP_KERNEL); 770 if (!buf) 771 return -ENOMEM; 772 773 pos = scnprintf(buf, bufsz, "%.*s\n", mvm->fw->phy_integration_ver_len, 774 mvm->fw->phy_integration_ver); 775 776 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); 777 778 kfree(buf); 779 return ret; 780 } 781 782 #define PRINT_STATS_LE32(_struct, _memb) \ 783 pos += scnprintf(buf + pos, bufsz - pos, \ 784 fmt_table, #_memb, \ 785 le32_to_cpu(_struct->_memb)) 786 787 static ssize_t iwl_dbgfs_fw_rx_stats_read(struct file *file, 788 char __user *user_buf, size_t count, 789 loff_t *ppos) 790 { 791 struct iwl_mvm *mvm = file->private_data; 792 static const char *fmt_table = "\t%-30s %10u\n"; 793 static const char *fmt_header = "%-32s\n"; 794 int pos = 0; 795 char *buf; 796 int ret; 797 size_t bufsz; 798 u8 cmd_ver = iwl_fw_lookup_cmd_ver(mvm->fw, 799 WIDE_ID(SYSTEM_GROUP, 800 SYSTEM_STATISTICS_CMD), 801 IWL_FW_CMD_VER_UNKNOWN); 802 803 if (cmd_ver != IWL_FW_CMD_VER_UNKNOWN) 804 return -EOPNOTSUPP; 805 806 if (iwl_mvm_has_new_rx_stats_api(mvm)) 807 bufsz = ((sizeof(struct mvm_statistics_rx) / 808 sizeof(__le32)) * 43) + (4 * 33) + 1; 809 else 810 /* 43 = size of each data line; 33 = size of each header */ 811 bufsz = ((sizeof(struct mvm_statistics_rx_v3) / 812 sizeof(__le32)) * 43) + (4 * 33) + 1; 813 814 buf = kzalloc(bufsz, GFP_KERNEL); 815 if (!buf) 816 return -ENOMEM; 817 818 mutex_lock(&mvm->mutex); 819 820 if (iwl_mvm_firmware_running(mvm)) 821 iwl_mvm_request_statistics(mvm, false); 822 823 pos += scnprintf(buf + pos, bufsz - pos, fmt_header, 824 "Statistics_Rx - OFDM"); 825 if (!iwl_mvm_has_new_rx_stats_api(mvm)) { 826 struct mvm_statistics_rx_phy_v2 *ofdm = &mvm->rx_stats_v3.ofdm; 827 828 PRINT_STATS_LE32(ofdm, ina_cnt); 829 PRINT_STATS_LE32(ofdm, fina_cnt); 830 PRINT_STATS_LE32(ofdm, plcp_err); 831 PRINT_STATS_LE32(ofdm, crc32_err); 832 PRINT_STATS_LE32(ofdm, overrun_err); 833 PRINT_STATS_LE32(ofdm, early_overrun_err); 834 PRINT_STATS_LE32(ofdm, crc32_good); 835 PRINT_STATS_LE32(ofdm, false_alarm_cnt); 836 PRINT_STATS_LE32(ofdm, fina_sync_err_cnt); 837 PRINT_STATS_LE32(ofdm, sfd_timeout); 838 PRINT_STATS_LE32(ofdm, fina_timeout); 839 PRINT_STATS_LE32(ofdm, unresponded_rts); 840 PRINT_STATS_LE32(ofdm, rxe_frame_lmt_overrun); 841 PRINT_STATS_LE32(ofdm, sent_ack_cnt); 842 PRINT_STATS_LE32(ofdm, sent_cts_cnt); 843 PRINT_STATS_LE32(ofdm, sent_ba_rsp_cnt); 844 PRINT_STATS_LE32(ofdm, dsp_self_kill); 845 PRINT_STATS_LE32(ofdm, mh_format_err); 846 PRINT_STATS_LE32(ofdm, re_acq_main_rssi_sum); 847 PRINT_STATS_LE32(ofdm, reserved); 848 } else { 849 struct mvm_statistics_rx_phy *ofdm = &mvm->rx_stats.ofdm; 850 851 PRINT_STATS_LE32(ofdm, unresponded_rts); 852 PRINT_STATS_LE32(ofdm, rxe_frame_lmt_overrun); 853 PRINT_STATS_LE32(ofdm, sent_ba_rsp_cnt); 854 PRINT_STATS_LE32(ofdm, dsp_self_kill); 855 PRINT_STATS_LE32(ofdm, reserved); 856 } 857 858 pos += scnprintf(buf + pos, bufsz - pos, fmt_header, 859 "Statistics_Rx - CCK"); 860 if (!iwl_mvm_has_new_rx_stats_api(mvm)) { 861 struct mvm_statistics_rx_phy_v2 *cck = &mvm->rx_stats_v3.cck; 862 863 PRINT_STATS_LE32(cck, ina_cnt); 864 PRINT_STATS_LE32(cck, fina_cnt); 865 PRINT_STATS_LE32(cck, plcp_err); 866 PRINT_STATS_LE32(cck, crc32_err); 867 PRINT_STATS_LE32(cck, overrun_err); 868 PRINT_STATS_LE32(cck, early_overrun_err); 869 PRINT_STATS_LE32(cck, crc32_good); 870 PRINT_STATS_LE32(cck, false_alarm_cnt); 871 PRINT_STATS_LE32(cck, fina_sync_err_cnt); 872 PRINT_STATS_LE32(cck, sfd_timeout); 873 PRINT_STATS_LE32(cck, fina_timeout); 874 PRINT_STATS_LE32(cck, unresponded_rts); 875 PRINT_STATS_LE32(cck, rxe_frame_lmt_overrun); 876 PRINT_STATS_LE32(cck, sent_ack_cnt); 877 PRINT_STATS_LE32(cck, sent_cts_cnt); 878 PRINT_STATS_LE32(cck, sent_ba_rsp_cnt); 879 PRINT_STATS_LE32(cck, dsp_self_kill); 880 PRINT_STATS_LE32(cck, mh_format_err); 881 PRINT_STATS_LE32(cck, re_acq_main_rssi_sum); 882 PRINT_STATS_LE32(cck, reserved); 883 } else { 884 struct mvm_statistics_rx_phy *cck = &mvm->rx_stats.cck; 885 886 PRINT_STATS_LE32(cck, unresponded_rts); 887 PRINT_STATS_LE32(cck, rxe_frame_lmt_overrun); 888 PRINT_STATS_LE32(cck, sent_ba_rsp_cnt); 889 PRINT_STATS_LE32(cck, dsp_self_kill); 890 PRINT_STATS_LE32(cck, reserved); 891 } 892 893 pos += scnprintf(buf + pos, bufsz - pos, fmt_header, 894 "Statistics_Rx - GENERAL"); 895 if (!iwl_mvm_has_new_rx_stats_api(mvm)) { 896 struct mvm_statistics_rx_non_phy_v3 *general = 897 &mvm->rx_stats_v3.general; 898 899 PRINT_STATS_LE32(general, bogus_cts); 900 PRINT_STATS_LE32(general, bogus_ack); 901 PRINT_STATS_LE32(general, non_bssid_frames); 902 PRINT_STATS_LE32(general, filtered_frames); 903 PRINT_STATS_LE32(general, non_channel_beacons); 904 PRINT_STATS_LE32(general, channel_beacons); 905 PRINT_STATS_LE32(general, num_missed_bcon); 906 PRINT_STATS_LE32(general, adc_rx_saturation_time); 907 PRINT_STATS_LE32(general, ina_detection_search_time); 908 PRINT_STATS_LE32(general, beacon_silence_rssi_a); 909 PRINT_STATS_LE32(general, beacon_silence_rssi_b); 910 PRINT_STATS_LE32(general, beacon_silence_rssi_c); 911 PRINT_STATS_LE32(general, interference_data_flag); 912 PRINT_STATS_LE32(general, channel_load); 913 PRINT_STATS_LE32(general, dsp_false_alarms); 914 PRINT_STATS_LE32(general, beacon_rssi_a); 915 PRINT_STATS_LE32(general, beacon_rssi_b); 916 PRINT_STATS_LE32(general, beacon_rssi_c); 917 PRINT_STATS_LE32(general, beacon_energy_a); 918 PRINT_STATS_LE32(general, beacon_energy_b); 919 PRINT_STATS_LE32(general, beacon_energy_c); 920 PRINT_STATS_LE32(general, num_bt_kills); 921 PRINT_STATS_LE32(general, mac_id); 922 PRINT_STATS_LE32(general, directed_data_mpdu); 923 } else { 924 struct mvm_statistics_rx_non_phy *general = 925 &mvm->rx_stats.general; 926 927 PRINT_STATS_LE32(general, bogus_cts); 928 PRINT_STATS_LE32(general, bogus_ack); 929 PRINT_STATS_LE32(general, non_channel_beacons); 930 PRINT_STATS_LE32(general, channel_beacons); 931 PRINT_STATS_LE32(general, num_missed_bcon); 932 PRINT_STATS_LE32(general, adc_rx_saturation_time); 933 PRINT_STATS_LE32(general, ina_detection_search_time); 934 PRINT_STATS_LE32(general, beacon_silence_rssi_a); 935 PRINT_STATS_LE32(general, beacon_silence_rssi_b); 936 PRINT_STATS_LE32(general, beacon_silence_rssi_c); 937 PRINT_STATS_LE32(general, interference_data_flag); 938 PRINT_STATS_LE32(general, channel_load); 939 PRINT_STATS_LE32(general, beacon_rssi_a); 940 PRINT_STATS_LE32(general, beacon_rssi_b); 941 PRINT_STATS_LE32(general, beacon_rssi_c); 942 PRINT_STATS_LE32(general, beacon_energy_a); 943 PRINT_STATS_LE32(general, beacon_energy_b); 944 PRINT_STATS_LE32(general, beacon_energy_c); 945 PRINT_STATS_LE32(general, num_bt_kills); 946 PRINT_STATS_LE32(general, mac_id); 947 } 948 949 pos += scnprintf(buf + pos, bufsz - pos, fmt_header, 950 "Statistics_Rx - HT"); 951 if (!iwl_mvm_has_new_rx_stats_api(mvm)) { 952 struct mvm_statistics_rx_ht_phy_v1 *ht = 953 &mvm->rx_stats_v3.ofdm_ht; 954 955 PRINT_STATS_LE32(ht, plcp_err); 956 PRINT_STATS_LE32(ht, overrun_err); 957 PRINT_STATS_LE32(ht, early_overrun_err); 958 PRINT_STATS_LE32(ht, crc32_good); 959 PRINT_STATS_LE32(ht, crc32_err); 960 PRINT_STATS_LE32(ht, mh_format_err); 961 PRINT_STATS_LE32(ht, agg_crc32_good); 962 PRINT_STATS_LE32(ht, agg_mpdu_cnt); 963 PRINT_STATS_LE32(ht, agg_cnt); 964 PRINT_STATS_LE32(ht, unsupport_mcs); 965 } else { 966 struct mvm_statistics_rx_ht_phy *ht = 967 &mvm->rx_stats.ofdm_ht; 968 969 PRINT_STATS_LE32(ht, mh_format_err); 970 PRINT_STATS_LE32(ht, agg_mpdu_cnt); 971 PRINT_STATS_LE32(ht, agg_cnt); 972 PRINT_STATS_LE32(ht, unsupport_mcs); 973 } 974 975 mutex_unlock(&mvm->mutex); 976 977 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); 978 kfree(buf); 979 980 return ret; 981 } 982 #undef PRINT_STAT_LE32 983 984 static ssize_t iwl_dbgfs_fw_system_stats_read(struct file *file, 985 char __user *user_buf, 986 size_t count, loff_t *ppos) 987 { 988 char *buff, *pos, *endpos; 989 int ret; 990 size_t bufsz; 991 int i; 992 struct iwl_mvm_vif *mvmvif; 993 struct ieee80211_vif *vif; 994 struct iwl_mvm *mvm = file->private_data; 995 u8 cmd_ver = iwl_fw_lookup_cmd_ver(mvm->fw, 996 WIDE_ID(SYSTEM_GROUP, 997 SYSTEM_STATISTICS_CMD), 998 IWL_FW_CMD_VER_UNKNOWN); 999 1000 /* in case of a wrong cmd version, allocate buffer only for error msg */ 1001 bufsz = (cmd_ver == 1) ? 4096 : 64; 1002 1003 buff = kzalloc(bufsz, GFP_KERNEL); 1004 if (!buff) 1005 return -ENOMEM; 1006 1007 pos = buff; 1008 endpos = pos + bufsz; 1009 1010 if (cmd_ver != 1) { 1011 pos += scnprintf(pos, endpos - pos, 1012 "System stats not supported:%d\n", cmd_ver); 1013 goto send_out; 1014 } 1015 1016 mutex_lock(&mvm->mutex); 1017 if (iwl_mvm_firmware_running(mvm)) 1018 iwl_mvm_request_statistics(mvm, false); 1019 1020 for (i = 0; i < NUM_MAC_INDEX_DRIVER; i++) { 1021 vif = iwl_mvm_rcu_dereference_vif_id(mvm, i, false); 1022 if (!vif) 1023 continue; 1024 1025 if (vif->type == NL80211_IFTYPE_STATION) 1026 break; 1027 } 1028 1029 if (i == NUM_MAC_INDEX_DRIVER || !vif) { 1030 pos += scnprintf(pos, endpos - pos, "vif is NULL\n"); 1031 goto release_send_out; 1032 } 1033 1034 mvmvif = iwl_mvm_vif_from_mac80211(vif); 1035 if (!mvmvif) { 1036 pos += scnprintf(pos, endpos - pos, "mvmvif is NULL\n"); 1037 goto release_send_out; 1038 } 1039 1040 for_each_mvm_vif_valid_link(mvmvif, i) { 1041 struct iwl_mvm_vif_link_info *link_info = mvmvif->link[i]; 1042 1043 pos += scnprintf(pos, endpos - pos, 1044 "link_id %d", i); 1045 pos += scnprintf(pos, endpos - pos, 1046 " num_beacons %d", 1047 link_info->beacon_stats.num_beacons); 1048 pos += scnprintf(pos, endpos - pos, 1049 " accu_num_beacons %d", 1050 link_info->beacon_stats.accu_num_beacons); 1051 pos += scnprintf(pos, endpos - pos, 1052 " avg_signal %d\n", 1053 link_info->beacon_stats.avg_signal); 1054 } 1055 1056 pos += scnprintf(pos, endpos - pos, 1057 "radio_stats.rx_time %lld\n", 1058 mvm->radio_stats.rx_time); 1059 pos += scnprintf(pos, endpos - pos, 1060 "radio_stats.tx_time %lld\n", 1061 mvm->radio_stats.tx_time); 1062 pos += scnprintf(pos, endpos - pos, 1063 "accu_radio_stats.rx_time %lld\n", 1064 mvm->accu_radio_stats.rx_time); 1065 pos += scnprintf(pos, endpos - pos, 1066 "accu_radio_stats.tx_time %lld\n", 1067 mvm->accu_radio_stats.tx_time); 1068 1069 release_send_out: 1070 mutex_unlock(&mvm->mutex); 1071 1072 send_out: 1073 ret = simple_read_from_buffer(user_buf, count, ppos, buff, pos - buff); 1074 kfree(buff); 1075 1076 return ret; 1077 } 1078 1079 static ssize_t iwl_dbgfs_frame_stats_read(struct iwl_mvm *mvm, 1080 char __user *user_buf, size_t count, 1081 loff_t *ppos, 1082 struct iwl_mvm_frame_stats *stats) 1083 { 1084 char *buff, *pos, *endpos; 1085 int idx, i; 1086 int ret; 1087 static const size_t bufsz = 1024; 1088 1089 buff = kmalloc(bufsz, GFP_KERNEL); 1090 if (!buff) 1091 return -ENOMEM; 1092 1093 spin_lock_bh(&mvm->drv_stats_lock); 1094 1095 pos = buff; 1096 endpos = pos + bufsz; 1097 1098 pos += scnprintf(pos, endpos - pos, 1099 "Legacy/HT/VHT\t:\t%d/%d/%d\n", 1100 stats->legacy_frames, 1101 stats->ht_frames, 1102 stats->vht_frames); 1103 pos += scnprintf(pos, endpos - pos, "20/40/80\t:\t%d/%d/%d\n", 1104 stats->bw_20_frames, 1105 stats->bw_40_frames, 1106 stats->bw_80_frames); 1107 pos += scnprintf(pos, endpos - pos, "NGI/SGI\t\t:\t%d/%d\n", 1108 stats->ngi_frames, 1109 stats->sgi_frames); 1110 pos += scnprintf(pos, endpos - pos, "SISO/MIMO2\t:\t%d/%d\n", 1111 stats->siso_frames, 1112 stats->mimo2_frames); 1113 pos += scnprintf(pos, endpos - pos, "FAIL/SCSS\t:\t%d/%d\n", 1114 stats->fail_frames, 1115 stats->success_frames); 1116 pos += scnprintf(pos, endpos - pos, "MPDUs agg\t:\t%d\n", 1117 stats->agg_frames); 1118 pos += scnprintf(pos, endpos - pos, "A-MPDUs\t\t:\t%d\n", 1119 stats->ampdu_count); 1120 pos += scnprintf(pos, endpos - pos, "Avg MPDUs/A-MPDU:\t%d\n", 1121 stats->ampdu_count > 0 ? 1122 (stats->agg_frames / stats->ampdu_count) : 0); 1123 1124 pos += scnprintf(pos, endpos - pos, "Last Rates\n"); 1125 1126 idx = stats->last_frame_idx - 1; 1127 for (i = 0; i < ARRAY_SIZE(stats->last_rates); i++) { 1128 idx = (idx + 1) % ARRAY_SIZE(stats->last_rates); 1129 if (stats->last_rates[idx] == 0) 1130 continue; 1131 pos += scnprintf(pos, endpos - pos, "Rate[%d]: ", 1132 (int)(ARRAY_SIZE(stats->last_rates) - i)); 1133 pos += rs_pretty_print_rate_v1(pos, endpos - pos, 1134 stats->last_rates[idx]); 1135 if (pos < endpos - 1) 1136 *pos++ = '\n'; 1137 } 1138 spin_unlock_bh(&mvm->drv_stats_lock); 1139 1140 ret = simple_read_from_buffer(user_buf, count, ppos, buff, pos - buff); 1141 kfree(buff); 1142 1143 return ret; 1144 } 1145 1146 static ssize_t iwl_dbgfs_drv_rx_stats_read(struct file *file, 1147 char __user *user_buf, size_t count, 1148 loff_t *ppos) 1149 { 1150 struct iwl_mvm *mvm = file->private_data; 1151 1152 return iwl_dbgfs_frame_stats_read(mvm, user_buf, count, ppos, 1153 &mvm->drv_rx_stats); 1154 } 1155 1156 static ssize_t iwl_dbgfs_fw_restart_write(struct iwl_mvm *mvm, char *buf, 1157 size_t count, loff_t *ppos) 1158 { 1159 int __maybe_unused ret; 1160 1161 if (!iwl_mvm_firmware_running(mvm)) 1162 return -EIO; 1163 1164 mutex_lock(&mvm->mutex); 1165 1166 /* allow one more restart that we're provoking here */ 1167 if (mvm->fw_restart >= 0) 1168 mvm->fw_restart++; 1169 1170 if (count == 6 && !strcmp(buf, "nolog\n")) { 1171 set_bit(IWL_MVM_STATUS_SUPPRESS_ERROR_LOG_ONCE, &mvm->status); 1172 set_bit(STATUS_SUPPRESS_CMD_ERROR_ONCE, &mvm->trans->status); 1173 } 1174 1175 /* take the return value to make compiler happy - it will fail anyway */ 1176 ret = iwl_mvm_send_cmd_pdu(mvm, 1177 WIDE_ID(LONG_GROUP, REPLY_ERROR), 1178 0, 0, NULL); 1179 1180 mutex_unlock(&mvm->mutex); 1181 1182 return count; 1183 } 1184 1185 static ssize_t iwl_dbgfs_fw_nmi_write(struct iwl_mvm *mvm, char *buf, 1186 size_t count, loff_t *ppos) 1187 { 1188 if (!iwl_mvm_firmware_running(mvm)) 1189 return -EIO; 1190 1191 IWL_ERR(mvm, "Triggering an NMI from debugfs\n"); 1192 1193 if (count == 6 && !strcmp(buf, "nolog\n")) 1194 set_bit(IWL_MVM_STATUS_SUPPRESS_ERROR_LOG_ONCE, &mvm->status); 1195 1196 iwl_force_nmi(mvm->trans); 1197 1198 return count; 1199 } 1200 1201 static ssize_t 1202 iwl_dbgfs_scan_ant_rxchain_read(struct file *file, 1203 char __user *user_buf, 1204 size_t count, loff_t *ppos) 1205 { 1206 struct iwl_mvm *mvm = file->private_data; 1207 int pos = 0; 1208 char buf[32]; 1209 const size_t bufsz = sizeof(buf); 1210 1211 /* print which antennas were set for the scan command by the user */ 1212 pos += scnprintf(buf + pos, bufsz - pos, "Antennas for scan: "); 1213 if (mvm->scan_rx_ant & ANT_A) 1214 pos += scnprintf(buf + pos, bufsz - pos, "A"); 1215 if (mvm->scan_rx_ant & ANT_B) 1216 pos += scnprintf(buf + pos, bufsz - pos, "B"); 1217 pos += scnprintf(buf + pos, bufsz - pos, " (%x)\n", mvm->scan_rx_ant); 1218 1219 return simple_read_from_buffer(user_buf, count, ppos, buf, pos); 1220 } 1221 1222 static ssize_t 1223 iwl_dbgfs_scan_ant_rxchain_write(struct iwl_mvm *mvm, char *buf, 1224 size_t count, loff_t *ppos) 1225 { 1226 u8 scan_rx_ant; 1227 1228 if (!iwl_mvm_firmware_running(mvm)) 1229 return -EIO; 1230 1231 if (sscanf(buf, "%hhx", &scan_rx_ant) != 1) 1232 return -EINVAL; 1233 if (scan_rx_ant > ANT_ABC) 1234 return -EINVAL; 1235 if (scan_rx_ant & ~(iwl_mvm_get_valid_rx_ant(mvm))) 1236 return -EINVAL; 1237 1238 if (mvm->scan_rx_ant != scan_rx_ant) { 1239 mvm->scan_rx_ant = scan_rx_ant; 1240 if (fw_has_capa(&mvm->fw->ucode_capa, 1241 IWL_UCODE_TLV_CAPA_UMAC_SCAN)) 1242 iwl_mvm_config_scan(mvm); 1243 } 1244 1245 return count; 1246 } 1247 1248 static ssize_t iwl_dbgfs_indirection_tbl_write(struct iwl_mvm *mvm, 1249 char *buf, size_t count, 1250 loff_t *ppos) 1251 { 1252 struct iwl_rss_config_cmd cmd = { 1253 .flags = cpu_to_le32(IWL_RSS_ENABLE), 1254 .hash_mask = IWL_RSS_HASH_TYPE_IPV4_TCP | 1255 IWL_RSS_HASH_TYPE_IPV4_UDP | 1256 IWL_RSS_HASH_TYPE_IPV4_PAYLOAD | 1257 IWL_RSS_HASH_TYPE_IPV6_TCP | 1258 IWL_RSS_HASH_TYPE_IPV6_UDP | 1259 IWL_RSS_HASH_TYPE_IPV6_PAYLOAD, 1260 }; 1261 int ret, i, num_repeats, nbytes = count / 2; 1262 1263 ret = hex2bin(cmd.indirection_table, buf, nbytes); 1264 if (ret) 1265 return ret; 1266 1267 /* 1268 * The input is the redirection table, partial or full. 1269 * Repeat the pattern if needed. 1270 * For example, input of 01020F will be repeated 42 times, 1271 * indirecting RSS hash results to queues 1, 2, 15 (skipping 1272 * queues 3 - 14). 1273 */ 1274 num_repeats = ARRAY_SIZE(cmd.indirection_table) / nbytes; 1275 for (i = 1; i < num_repeats; i++) 1276 memcpy(&cmd.indirection_table[i * nbytes], 1277 cmd.indirection_table, nbytes); 1278 /* handle cut in the middle pattern for the last places */ 1279 memcpy(&cmd.indirection_table[i * nbytes], cmd.indirection_table, 1280 ARRAY_SIZE(cmd.indirection_table) % nbytes); 1281 1282 netdev_rss_key_fill(cmd.secret_key, sizeof(cmd.secret_key)); 1283 1284 mutex_lock(&mvm->mutex); 1285 if (iwl_mvm_firmware_running(mvm)) 1286 ret = iwl_mvm_send_cmd_pdu(mvm, RSS_CONFIG_CMD, 0, 1287 sizeof(cmd), &cmd); 1288 else 1289 ret = 0; 1290 mutex_unlock(&mvm->mutex); 1291 1292 return ret ?: count; 1293 } 1294 1295 static ssize_t iwl_dbgfs_inject_packet_write(struct iwl_mvm *mvm, 1296 char *buf, size_t count, 1297 loff_t *ppos) 1298 { 1299 struct iwl_op_mode *opmode = container_of((void *)mvm, 1300 struct iwl_op_mode, 1301 op_mode_specific); 1302 struct iwl_rx_cmd_buffer rxb = { 1303 ._rx_page_order = 0, 1304 .truesize = 0, /* not used */ 1305 ._offset = 0, 1306 }; 1307 struct iwl_rx_packet *pkt; 1308 int bin_len = count / 2; 1309 int ret = -EINVAL; 1310 1311 if (!iwl_mvm_firmware_running(mvm)) 1312 return -EIO; 1313 1314 /* supporting only MQ RX */ 1315 if (!mvm->trans->trans_cfg->mq_rx_supported) 1316 return -EOPNOTSUPP; 1317 1318 rxb._page = alloc_pages(GFP_ATOMIC, 0); 1319 if (!rxb._page) 1320 return -ENOMEM; 1321 pkt = rxb_addr(&rxb); 1322 1323 ret = hex2bin(page_address(rxb._page), buf, bin_len); 1324 if (ret) 1325 goto out; 1326 1327 /* avoid invalid memory access and malformed packet */ 1328 if (bin_len < sizeof(*pkt) || 1329 bin_len != sizeof(*pkt) + iwl_rx_packet_payload_len(pkt)) 1330 goto out; 1331 1332 local_bh_disable(); 1333 iwl_mvm_rx_mq(opmode, NULL, &rxb); 1334 local_bh_enable(); 1335 ret = 0; 1336 1337 out: 1338 iwl_free_rxb(&rxb); 1339 1340 return ret ?: count; 1341 } 1342 1343 static int _iwl_dbgfs_inject_beacon_ie(struct iwl_mvm *mvm, char *bin, int len) 1344 { 1345 struct ieee80211_vif *vif; 1346 struct iwl_mvm_vif *mvmvif; 1347 struct sk_buff *beacon; 1348 struct ieee80211_tx_info *info; 1349 struct iwl_mac_beacon_cmd beacon_cmd = {}; 1350 unsigned int link_id; 1351 u8 rate; 1352 int i; 1353 1354 len /= 2; 1355 1356 /* Element len should be represented by u8 */ 1357 if (len >= U8_MAX) 1358 return -EINVAL; 1359 1360 if (!iwl_mvm_firmware_running(mvm)) 1361 return -EIO; 1362 1363 if (!iwl_mvm_has_new_tx_api(mvm) && 1364 !fw_has_api(&mvm->fw->ucode_capa, 1365 IWL_UCODE_TLV_API_NEW_BEACON_TEMPLATE)) 1366 return -EINVAL; 1367 1368 mutex_lock(&mvm->mutex); 1369 1370 for (i = 0; i < NUM_MAC_INDEX_DRIVER; i++) { 1371 vif = iwl_mvm_rcu_dereference_vif_id(mvm, i, false); 1372 if (!vif) 1373 continue; 1374 1375 if (vif->type == NL80211_IFTYPE_AP) 1376 break; 1377 } 1378 1379 if (i == NUM_MAC_INDEX_DRIVER || !vif) 1380 goto out_err; 1381 1382 mvm->hw->extra_beacon_tailroom = len; 1383 1384 beacon = ieee80211_beacon_get_template(mvm->hw, vif, NULL, 0); 1385 if (!beacon) 1386 goto out_err; 1387 1388 if (len && hex2bin(skb_put_zero(beacon, len), bin, len)) { 1389 dev_kfree_skb(beacon); 1390 goto out_err; 1391 } 1392 1393 mvm->beacon_inject_active = true; 1394 1395 mvmvif = iwl_mvm_vif_from_mac80211(vif); 1396 info = IEEE80211_SKB_CB(beacon); 1397 rate = iwl_mvm_mac_ctxt_get_beacon_rate(mvm, info, vif); 1398 1399 for_each_mvm_vif_valid_link(mvmvif, link_id) { 1400 beacon_cmd.flags = 1401 cpu_to_le16(iwl_mvm_mac_ctxt_get_beacon_flags(mvm->fw, 1402 rate)); 1403 beacon_cmd.byte_cnt = cpu_to_le16((u16)beacon->len); 1404 if (iwl_fw_lookup_cmd_ver(mvm->fw, BEACON_TEMPLATE_CMD, 0) > 12) 1405 beacon_cmd.link_id = 1406 cpu_to_le32(mvmvif->link[link_id]->fw_link_id); 1407 else 1408 beacon_cmd.link_id = cpu_to_le32((u32)mvmvif->id); 1409 1410 iwl_mvm_mac_ctxt_set_tim(mvm, &beacon_cmd.tim_idx, 1411 &beacon_cmd.tim_size, 1412 beacon->data, beacon->len); 1413 1414 if (iwl_fw_lookup_cmd_ver(mvm->fw, 1415 BEACON_TEMPLATE_CMD, 0) >= 14) { 1416 u32 offset = iwl_mvm_find_ie_offset(beacon->data, 1417 WLAN_EID_S1G_TWT, 1418 beacon->len); 1419 1420 beacon_cmd.btwt_offset = cpu_to_le32(offset); 1421 } 1422 1423 iwl_mvm_mac_ctxt_send_beacon_cmd(mvm, beacon, &beacon_cmd, 1424 sizeof(beacon_cmd)); 1425 } 1426 mutex_unlock(&mvm->mutex); 1427 1428 dev_kfree_skb(beacon); 1429 1430 return 0; 1431 1432 out_err: 1433 mutex_unlock(&mvm->mutex); 1434 return -EINVAL; 1435 } 1436 1437 static ssize_t iwl_dbgfs_inject_beacon_ie_write(struct iwl_mvm *mvm, 1438 char *buf, size_t count, 1439 loff_t *ppos) 1440 { 1441 int ret = _iwl_dbgfs_inject_beacon_ie(mvm, buf, count); 1442 1443 mvm->hw->extra_beacon_tailroom = 0; 1444 return ret ?: count; 1445 } 1446 1447 static ssize_t iwl_dbgfs_inject_beacon_ie_restore_write(struct iwl_mvm *mvm, 1448 char *buf, 1449 size_t count, 1450 loff_t *ppos) 1451 { 1452 int ret = _iwl_dbgfs_inject_beacon_ie(mvm, NULL, 0); 1453 1454 mvm->hw->extra_beacon_tailroom = 0; 1455 mvm->beacon_inject_active = false; 1456 return ret ?: count; 1457 } 1458 1459 static ssize_t iwl_dbgfs_fw_dbg_conf_read(struct file *file, 1460 char __user *user_buf, 1461 size_t count, loff_t *ppos) 1462 { 1463 struct iwl_mvm *mvm = file->private_data; 1464 int conf; 1465 char buf[8]; 1466 const size_t bufsz = sizeof(buf); 1467 int pos = 0; 1468 1469 mutex_lock(&mvm->mutex); 1470 conf = mvm->fwrt.dump.conf; 1471 mutex_unlock(&mvm->mutex); 1472 1473 pos += scnprintf(buf + pos, bufsz - pos, "%d\n", conf); 1474 1475 return simple_read_from_buffer(user_buf, count, ppos, buf, pos); 1476 } 1477 1478 static ssize_t iwl_dbgfs_fw_dbg_conf_write(struct iwl_mvm *mvm, 1479 char *buf, size_t count, 1480 loff_t *ppos) 1481 { 1482 unsigned int conf_id; 1483 int ret; 1484 1485 if (!iwl_mvm_firmware_running(mvm)) 1486 return -EIO; 1487 1488 ret = kstrtouint(buf, 0, &conf_id); 1489 if (ret) 1490 return ret; 1491 1492 if (WARN_ON(conf_id >= FW_DBG_CONF_MAX)) 1493 return -EINVAL; 1494 1495 mutex_lock(&mvm->mutex); 1496 ret = iwl_fw_start_dbg_conf(&mvm->fwrt, conf_id); 1497 mutex_unlock(&mvm->mutex); 1498 1499 return ret ?: count; 1500 } 1501 1502 static ssize_t iwl_dbgfs_fw_dbg_collect_write(struct iwl_mvm *mvm, 1503 char *buf, size_t count, 1504 loff_t *ppos) 1505 { 1506 if (count == 0) 1507 return 0; 1508 1509 iwl_dbg_tlv_time_point(&mvm->fwrt, IWL_FW_INI_TIME_POINT_USER_TRIGGER, 1510 NULL); 1511 1512 iwl_fw_dbg_collect(&mvm->fwrt, FW_DBG_TRIGGER_USER, buf, 1513 (count - 1), NULL); 1514 1515 return count; 1516 } 1517 1518 static ssize_t iwl_dbgfs_fw_dbg_clear_write(struct iwl_mvm *mvm, 1519 char *buf, size_t count, 1520 loff_t *ppos) 1521 { 1522 if (mvm->trans->trans_cfg->device_family < IWL_DEVICE_FAMILY_9000) 1523 return -EOPNOTSUPP; 1524 1525 mutex_lock(&mvm->mutex); 1526 iwl_fw_dbg_clear_monitor_buf(&mvm->fwrt); 1527 mutex_unlock(&mvm->mutex); 1528 1529 return count; 1530 } 1531 1532 static ssize_t iwl_dbgfs_dbg_time_point_write(struct iwl_mvm *mvm, 1533 char *buf, size_t count, 1534 loff_t *ppos) 1535 { 1536 u32 timepoint; 1537 1538 if (kstrtou32(buf, 0, &timepoint)) 1539 return -EINVAL; 1540 1541 if (timepoint == IWL_FW_INI_TIME_POINT_INVALID || 1542 timepoint >= IWL_FW_INI_TIME_POINT_NUM) 1543 return -EINVAL; 1544 1545 iwl_dbg_tlv_time_point(&mvm->fwrt, timepoint, NULL); 1546 1547 return count; 1548 } 1549 1550 #define MVM_DEBUGFS_WRITE_FILE_OPS(name, bufsz) \ 1551 _MVM_DEBUGFS_WRITE_FILE_OPS(name, bufsz, struct iwl_mvm) 1552 #define MVM_DEBUGFS_READ_WRITE_FILE_OPS(name, bufsz) \ 1553 _MVM_DEBUGFS_READ_WRITE_FILE_OPS(name, bufsz, struct iwl_mvm) 1554 #define MVM_DEBUGFS_ADD_FILE_ALIAS(alias, name, parent, mode) do { \ 1555 debugfs_create_file(alias, mode, parent, mvm, \ 1556 &iwl_dbgfs_##name##_ops); \ 1557 } while (0) 1558 #define MVM_DEBUGFS_ADD_FILE(name, parent, mode) \ 1559 MVM_DEBUGFS_ADD_FILE_ALIAS(#name, name, parent, mode) 1560 1561 static ssize_t 1562 _iwl_dbgfs_link_sta_wrap_write(ssize_t (*real)(struct ieee80211_link_sta *, 1563 struct iwl_mvm_sta *, 1564 struct iwl_mvm *, 1565 struct iwl_mvm_link_sta *, 1566 char *, 1567 size_t, loff_t *), 1568 struct file *file, 1569 char *buf, size_t buf_size, loff_t *ppos) 1570 { 1571 struct ieee80211_link_sta *link_sta = file->private_data; 1572 struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(link_sta->sta); 1573 struct iwl_mvm *mvm = iwl_mvm_vif_from_mac80211(mvmsta->vif)->mvm; 1574 struct iwl_mvm_link_sta *mvm_link_sta; 1575 ssize_t ret; 1576 1577 mutex_lock(&mvm->mutex); 1578 1579 mvm_link_sta = rcu_dereference_protected(mvmsta->link[link_sta->link_id], 1580 lockdep_is_held(&mvm->mutex)); 1581 if (WARN_ON(!mvm_link_sta)) { 1582 mutex_unlock(&mvm->mutex); 1583 return -ENODEV; 1584 } 1585 1586 ret = real(link_sta, mvmsta, mvm, mvm_link_sta, buf, buf_size, ppos); 1587 1588 mutex_unlock(&mvm->mutex); 1589 1590 return ret; 1591 } 1592 1593 static ssize_t 1594 _iwl_dbgfs_link_sta_wrap_read(ssize_t (*real)(struct ieee80211_link_sta *, 1595 struct iwl_mvm_sta *, 1596 struct iwl_mvm *, 1597 struct iwl_mvm_link_sta *, 1598 char __user *, 1599 size_t, loff_t *), 1600 struct file *file, 1601 char __user *user_buf, size_t count, loff_t *ppos) 1602 { 1603 struct ieee80211_link_sta *link_sta = file->private_data; 1604 struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(link_sta->sta); 1605 struct iwl_mvm *mvm = iwl_mvm_vif_from_mac80211(mvmsta->vif)->mvm; 1606 struct iwl_mvm_link_sta *mvm_link_sta; 1607 ssize_t ret; 1608 1609 mutex_lock(&mvm->mutex); 1610 1611 mvm_link_sta = rcu_dereference_protected(mvmsta->link[link_sta->link_id], 1612 lockdep_is_held(&mvm->mutex)); 1613 if (WARN_ON(!mvm_link_sta)) { 1614 mutex_unlock(&mvm->mutex); 1615 return -ENODEV; 1616 } 1617 1618 ret = real(link_sta, mvmsta, mvm, mvm_link_sta, user_buf, count, ppos); 1619 1620 mutex_unlock(&mvm->mutex); 1621 1622 return ret; 1623 } 1624 1625 #define MVM_DEBUGFS_LINK_STA_WRITE_WRAPPER(name, buflen) \ 1626 static ssize_t _iwl_dbgfs_link_sta_##name##_write(struct file *file, \ 1627 const char __user *user_buf, \ 1628 size_t count, loff_t *ppos) \ 1629 { \ 1630 char buf[buflen] = {}; \ 1631 size_t buf_size = min(count, sizeof(buf) - 1); \ 1632 \ 1633 if (copy_from_user(buf, user_buf, buf_size)) \ 1634 return -EFAULT; \ 1635 \ 1636 return _iwl_dbgfs_link_sta_wrap_write(iwl_dbgfs_##name##_write, \ 1637 file, \ 1638 buf, buf_size, ppos); \ 1639 } \ 1640 1641 #define MVM_DEBUGFS_LINK_STA_READ_WRAPPER(name) \ 1642 static ssize_t _iwl_dbgfs_link_sta_##name##_read(struct file *file, \ 1643 char __user *user_buf, \ 1644 size_t count, loff_t *ppos) \ 1645 { \ 1646 return _iwl_dbgfs_link_sta_wrap_read(iwl_dbgfs_##name##_read, \ 1647 file, \ 1648 user_buf, count, ppos); \ 1649 } \ 1650 1651 #define MVM_DEBUGFS_WRITE_LINK_STA_FILE_OPS(name, bufsz) \ 1652 MVM_DEBUGFS_LINK_STA_WRITE_WRAPPER(name, bufsz) \ 1653 static const struct file_operations iwl_dbgfs_link_sta_##name##_ops = { \ 1654 .write = _iwl_dbgfs_link_sta_##name##_write, \ 1655 .open = simple_open, \ 1656 .llseek = generic_file_llseek, \ 1657 } 1658 1659 #define MVM_DEBUGFS_READ_LINK_STA_FILE_OPS(name) \ 1660 MVM_DEBUGFS_LINK_STA_READ_WRAPPER(name) \ 1661 static const struct file_operations iwl_dbgfs_link_sta_##name##_ops = { \ 1662 .read = _iwl_dbgfs_link_sta_##name##_read, \ 1663 .open = simple_open, \ 1664 .llseek = generic_file_llseek, \ 1665 } 1666 1667 #define MVM_DEBUGFS_READ_WRITE_LINK_STA_FILE_OPS(name, bufsz) \ 1668 MVM_DEBUGFS_LINK_STA_READ_WRAPPER(name) \ 1669 MVM_DEBUGFS_LINK_STA_WRITE_WRAPPER(name, bufsz) \ 1670 static const struct file_operations iwl_dbgfs_link_sta_##name##_ops = { \ 1671 .read = _iwl_dbgfs_link_sta_##name##_read, \ 1672 .write = _iwl_dbgfs_link_sta_##name##_write, \ 1673 .open = simple_open, \ 1674 .llseek = generic_file_llseek, \ 1675 } 1676 1677 #define MVM_DEBUGFS_ADD_LINK_STA_FILE_ALIAS(alias, name, parent, mode) \ 1678 debugfs_create_file(alias, mode, parent, link_sta, \ 1679 &iwl_dbgfs_link_sta_##name##_ops) 1680 #define MVM_DEBUGFS_ADD_LINK_STA_FILE(name, parent, mode) \ 1681 MVM_DEBUGFS_ADD_LINK_STA_FILE_ALIAS(#name, name, parent, mode) 1682 1683 static ssize_t 1684 iwl_dbgfs_prph_reg_read(struct file *file, 1685 char __user *user_buf, 1686 size_t count, loff_t *ppos) 1687 { 1688 struct iwl_mvm *mvm = file->private_data; 1689 int pos = 0; 1690 char buf[32]; 1691 const size_t bufsz = sizeof(buf); 1692 1693 if (!mvm->dbgfs_prph_reg_addr) 1694 return -EINVAL; 1695 1696 pos += scnprintf(buf + pos, bufsz - pos, "Reg 0x%x: (0x%x)\n", 1697 mvm->dbgfs_prph_reg_addr, 1698 iwl_read_prph(mvm->trans, mvm->dbgfs_prph_reg_addr)); 1699 1700 return simple_read_from_buffer(user_buf, count, ppos, buf, pos); 1701 } 1702 1703 static ssize_t 1704 iwl_dbgfs_prph_reg_write(struct iwl_mvm *mvm, char *buf, 1705 size_t count, loff_t *ppos) 1706 { 1707 u8 args; 1708 u32 value; 1709 1710 args = sscanf(buf, "%i %i", &mvm->dbgfs_prph_reg_addr, &value); 1711 /* if we only want to set the reg address - nothing more to do */ 1712 if (args == 1) 1713 goto out; 1714 1715 /* otherwise, make sure we have both address and value */ 1716 if (args != 2) 1717 return -EINVAL; 1718 1719 iwl_write_prph(mvm->trans, mvm->dbgfs_prph_reg_addr, value); 1720 1721 out: 1722 return count; 1723 } 1724 1725 static ssize_t 1726 iwl_dbgfs_send_echo_cmd_write(struct iwl_mvm *mvm, char *buf, 1727 size_t count, loff_t *ppos) 1728 { 1729 int ret; 1730 1731 if (!iwl_mvm_firmware_running(mvm)) 1732 return -EIO; 1733 1734 mutex_lock(&mvm->mutex); 1735 ret = iwl_mvm_send_cmd_pdu(mvm, ECHO_CMD, 0, 0, NULL); 1736 mutex_unlock(&mvm->mutex); 1737 1738 return ret ?: count; 1739 } 1740 1741 struct iwl_mvm_sniffer_apply { 1742 struct iwl_mvm *mvm; 1743 u8 *bssid; 1744 u16 aid; 1745 }; 1746 1747 static bool iwl_mvm_sniffer_apply(struct iwl_notif_wait_data *notif_data, 1748 struct iwl_rx_packet *pkt, void *data) 1749 { 1750 struct iwl_mvm_sniffer_apply *apply = data; 1751 1752 apply->mvm->cur_aid = cpu_to_le16(apply->aid); 1753 memcpy(apply->mvm->cur_bssid, apply->bssid, 1754 sizeof(apply->mvm->cur_bssid)); 1755 1756 return true; 1757 } 1758 1759 static ssize_t 1760 iwl_dbgfs_he_sniffer_params_write(struct iwl_mvm *mvm, char *buf, 1761 size_t count, loff_t *ppos) 1762 { 1763 struct iwl_notification_wait wait; 1764 struct iwl_he_monitor_cmd he_mon_cmd = {}; 1765 struct iwl_mvm_sniffer_apply apply = { 1766 .mvm = mvm, 1767 }; 1768 u16 wait_cmds[] = { 1769 WIDE_ID(DATA_PATH_GROUP, HE_AIR_SNIFFER_CONFIG_CMD), 1770 }; 1771 u32 aid; 1772 int ret; 1773 1774 if (!iwl_mvm_firmware_running(mvm)) 1775 return -EIO; 1776 1777 ret = sscanf(buf, "%x %2hhx:%2hhx:%2hhx:%2hhx:%2hhx:%2hhx", &aid, 1778 &he_mon_cmd.bssid[0], &he_mon_cmd.bssid[1], 1779 &he_mon_cmd.bssid[2], &he_mon_cmd.bssid[3], 1780 &he_mon_cmd.bssid[4], &he_mon_cmd.bssid[5]); 1781 if (ret != 7) 1782 return -EINVAL; 1783 1784 he_mon_cmd.aid = cpu_to_le16(aid); 1785 1786 apply.aid = aid; 1787 apply.bssid = (void *)he_mon_cmd.bssid; 1788 1789 mutex_lock(&mvm->mutex); 1790 1791 /* 1792 * Use the notification waiter to get our function triggered 1793 * in sequence with other RX. This ensures that frames we get 1794 * on the RX queue _before_ the new configuration is applied 1795 * still have mvm->cur_aid pointing to the old AID, and that 1796 * frames on the RX queue _after_ the firmware processed the 1797 * new configuration (and sent the response, synchronously) 1798 * get mvm->cur_aid correctly set to the new AID. 1799 */ 1800 iwl_init_notification_wait(&mvm->notif_wait, &wait, 1801 wait_cmds, ARRAY_SIZE(wait_cmds), 1802 iwl_mvm_sniffer_apply, &apply); 1803 1804 ret = iwl_mvm_send_cmd_pdu(mvm, 1805 WIDE_ID(DATA_PATH_GROUP, HE_AIR_SNIFFER_CONFIG_CMD), 1806 0, 1807 sizeof(he_mon_cmd), &he_mon_cmd); 1808 1809 /* no need to really wait, we already did anyway */ 1810 iwl_remove_notification(&mvm->notif_wait, &wait); 1811 1812 mutex_unlock(&mvm->mutex); 1813 1814 return ret ?: count; 1815 } 1816 1817 static ssize_t 1818 iwl_dbgfs_he_sniffer_params_read(struct file *file, char __user *user_buf, 1819 size_t count, loff_t *ppos) 1820 { 1821 struct iwl_mvm *mvm = file->private_data; 1822 u8 buf[32]; 1823 int len; 1824 1825 len = scnprintf(buf, sizeof(buf), 1826 "%d %02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx\n", 1827 le16_to_cpu(mvm->cur_aid), mvm->cur_bssid[0], 1828 mvm->cur_bssid[1], mvm->cur_bssid[2], mvm->cur_bssid[3], 1829 mvm->cur_bssid[4], mvm->cur_bssid[5]); 1830 1831 return simple_read_from_buffer(user_buf, count, ppos, buf, len); 1832 } 1833 1834 static ssize_t 1835 iwl_dbgfs_uapsd_noagg_bssids_read(struct file *file, char __user *user_buf, 1836 size_t count, loff_t *ppos) 1837 { 1838 struct iwl_mvm *mvm = file->private_data; 1839 u8 buf[IWL_MVM_UAPSD_NOAGG_BSSIDS_NUM * ETH_ALEN * 3 + 1]; 1840 unsigned int pos = 0; 1841 size_t bufsz = sizeof(buf); 1842 int i; 1843 1844 mutex_lock(&mvm->mutex); 1845 1846 for (i = 0; i < IWL_MVM_UAPSD_NOAGG_LIST_LEN; i++) 1847 pos += scnprintf(buf + pos, bufsz - pos, "%pM\n", 1848 mvm->uapsd_noagg_bssids[i].addr); 1849 1850 mutex_unlock(&mvm->mutex); 1851 1852 return simple_read_from_buffer(user_buf, count, ppos, buf, pos); 1853 } 1854 1855 static ssize_t 1856 iwl_dbgfs_ltr_config_write(struct iwl_mvm *mvm, 1857 char *buf, size_t count, loff_t *ppos) 1858 { 1859 int ret; 1860 struct iwl_ltr_config_cmd ltr_config = {0}; 1861 1862 if (!iwl_mvm_firmware_running(mvm)) 1863 return -EIO; 1864 1865 if (sscanf(buf, "%x,%x,%x,%x,%x,%x,%x", 1866 <r_config.flags, 1867 <r_config.static_long, 1868 <r_config.static_short, 1869 <r_config.ltr_cfg_values[0], 1870 <r_config.ltr_cfg_values[1], 1871 <r_config.ltr_cfg_values[2], 1872 <r_config.ltr_cfg_values[3]) != 7) { 1873 return -EINVAL; 1874 } 1875 1876 mutex_lock(&mvm->mutex); 1877 ret = iwl_mvm_send_cmd_pdu(mvm, LTR_CONFIG, 0, sizeof(ltr_config), 1878 <r_config); 1879 mutex_unlock(&mvm->mutex); 1880 1881 if (ret) 1882 IWL_ERR(mvm, "failed to send ltr configuration cmd\n"); 1883 1884 return ret ?: count; 1885 } 1886 1887 static ssize_t iwl_dbgfs_rfi_freq_table_write(struct iwl_mvm *mvm, char *buf, 1888 size_t count, loff_t *ppos) 1889 { 1890 int ret = 0; 1891 u16 op_id; 1892 1893 if (kstrtou16(buf, 10, &op_id)) 1894 return -EINVAL; 1895 1896 /* value zero triggers re-sending the default table to the device */ 1897 if (!op_id) { 1898 mutex_lock(&mvm->mutex); 1899 ret = iwl_rfi_send_config_cmd(mvm, NULL); 1900 mutex_unlock(&mvm->mutex); 1901 } else { 1902 ret = -EOPNOTSUPP; /* in the future a new table will be added */ 1903 } 1904 1905 return ret ?: count; 1906 } 1907 1908 /* The size computation is as follows: 1909 * each number needs at most 3 characters, number of rows is the size of 1910 * the table; So, need 5 chars for the "freq: " part and each tuple afterwards 1911 * needs 6 characters for numbers and 5 for the punctuation around. 1912 */ 1913 #define IWL_RFI_BUF_SIZE (IWL_RFI_LUT_INSTALLED_SIZE *\ 1914 (5 + IWL_RFI_LUT_ENTRY_CHANNELS_NUM * (6 + 5))) 1915 1916 static ssize_t iwl_dbgfs_rfi_freq_table_read(struct file *file, 1917 char __user *user_buf, 1918 size_t count, loff_t *ppos) 1919 { 1920 struct iwl_mvm *mvm = file->private_data; 1921 struct iwl_rfi_freq_table_resp_cmd *resp; 1922 u32 status; 1923 char buf[IWL_RFI_BUF_SIZE]; 1924 int i, j, pos = 0; 1925 1926 resp = iwl_rfi_get_freq_table(mvm); 1927 if (IS_ERR(resp)) 1928 return PTR_ERR(resp); 1929 1930 status = le32_to_cpu(resp->status); 1931 if (status != RFI_FREQ_TABLE_OK) { 1932 scnprintf(buf, IWL_RFI_BUF_SIZE, "status = %d\n", status); 1933 goto out; 1934 } 1935 1936 for (i = 0; i < ARRAY_SIZE(resp->table); i++) { 1937 pos += scnprintf(buf + pos, IWL_RFI_BUF_SIZE - pos, "%d: ", 1938 resp->table[i].freq); 1939 1940 for (j = 0; j < ARRAY_SIZE(resp->table[i].channels); j++) 1941 pos += scnprintf(buf + pos, IWL_RFI_BUF_SIZE - pos, 1942 "(%d, %d) ", 1943 resp->table[i].channels[j], 1944 resp->table[i].bands[j]); 1945 pos += scnprintf(buf + pos, IWL_RFI_BUF_SIZE - pos, "\n"); 1946 } 1947 1948 out: 1949 kfree(resp); 1950 return simple_read_from_buffer(user_buf, count, ppos, buf, pos); 1951 } 1952 1953 MVM_DEBUGFS_READ_WRITE_FILE_OPS(prph_reg, 64); 1954 1955 /* Device wide debugfs entries */ 1956 MVM_DEBUGFS_READ_FILE_OPS(ctdp_budget); 1957 MVM_DEBUGFS_WRITE_FILE_OPS(stop_ctdp, 8); 1958 MVM_DEBUGFS_WRITE_FILE_OPS(start_ctdp, 8); 1959 MVM_DEBUGFS_WRITE_FILE_OPS(force_ctkill, 8); 1960 MVM_DEBUGFS_WRITE_FILE_OPS(tx_flush, 16); 1961 MVM_DEBUGFS_WRITE_FILE_OPS(send_echo_cmd, 8); 1962 MVM_DEBUGFS_READ_WRITE_FILE_OPS(sram, 64); 1963 MVM_DEBUGFS_READ_WRITE_FILE_OPS(set_nic_temperature, 64); 1964 MVM_DEBUGFS_READ_FILE_OPS(nic_temp); 1965 MVM_DEBUGFS_READ_FILE_OPS(stations); 1966 MVM_DEBUGFS_READ_LINK_STA_FILE_OPS(rs_data); 1967 MVM_DEBUGFS_READ_WRITE_FILE_OPS(disable_power_off, 64); 1968 MVM_DEBUGFS_READ_FILE_OPS(fw_rx_stats); 1969 MVM_DEBUGFS_READ_FILE_OPS(drv_rx_stats); 1970 MVM_DEBUGFS_READ_FILE_OPS(fw_system_stats); 1971 MVM_DEBUGFS_READ_FILE_OPS(fw_ver); 1972 MVM_DEBUGFS_READ_FILE_OPS(phy_integration_ver); 1973 MVM_DEBUGFS_READ_FILE_OPS(tas_get_status); 1974 MVM_DEBUGFS_WRITE_FILE_OPS(fw_restart, 10); 1975 MVM_DEBUGFS_WRITE_FILE_OPS(fw_nmi, 10); 1976 MVM_DEBUGFS_READ_WRITE_FILE_OPS(scan_ant_rxchain, 8); 1977 MVM_DEBUGFS_READ_WRITE_FILE_OPS(fw_dbg_conf, 8); 1978 MVM_DEBUGFS_WRITE_FILE_OPS(fw_dbg_collect, 64); 1979 MVM_DEBUGFS_WRITE_FILE_OPS(fw_dbg_clear, 64); 1980 MVM_DEBUGFS_WRITE_FILE_OPS(dbg_time_point, 64); 1981 MVM_DEBUGFS_WRITE_FILE_OPS(indirection_tbl, 1982 (IWL_RSS_INDIRECTION_TABLE_SIZE * 2)); 1983 MVM_DEBUGFS_WRITE_FILE_OPS(inject_packet, 512); 1984 MVM_DEBUGFS_WRITE_FILE_OPS(inject_beacon_ie, 512); 1985 MVM_DEBUGFS_WRITE_FILE_OPS(inject_beacon_ie_restore, 512); 1986 1987 MVM_DEBUGFS_READ_FILE_OPS(uapsd_noagg_bssids); 1988 1989 #ifdef CONFIG_ACPI 1990 MVM_DEBUGFS_READ_FILE_OPS(sar_geo_profile); 1991 MVM_DEBUGFS_READ_FILE_OPS(wifi_6e_enable); 1992 #endif 1993 1994 MVM_DEBUGFS_READ_WRITE_LINK_STA_FILE_OPS(amsdu_len, 16); 1995 1996 MVM_DEBUGFS_READ_WRITE_FILE_OPS(he_sniffer_params, 32); 1997 1998 MVM_DEBUGFS_WRITE_FILE_OPS(ltr_config, 512); 1999 MVM_DEBUGFS_READ_WRITE_FILE_OPS(rfi_freq_table, 16); 2000 2001 static ssize_t iwl_dbgfs_mem_read(struct file *file, char __user *user_buf, 2002 size_t count, loff_t *ppos) 2003 { 2004 struct iwl_mvm *mvm = file->private_data; 2005 struct iwl_dbg_mem_access_cmd cmd = {}; 2006 struct iwl_dbg_mem_access_rsp *rsp; 2007 struct iwl_host_cmd hcmd = { 2008 .flags = CMD_WANT_SKB | CMD_SEND_IN_RFKILL, 2009 .data = { &cmd, }, 2010 .len = { sizeof(cmd) }, 2011 }; 2012 size_t delta; 2013 ssize_t ret, len; 2014 2015 if (!iwl_mvm_firmware_running(mvm)) 2016 return -EIO; 2017 2018 hcmd.id = WIDE_ID(DEBUG_GROUP, *ppos >> 24 ? UMAC_RD_WR : LMAC_RD_WR); 2019 cmd.op = cpu_to_le32(DEBUG_MEM_OP_READ); 2020 2021 /* Take care of alignment of both the position and the length */ 2022 delta = *ppos & 0x3; 2023 cmd.addr = cpu_to_le32(*ppos - delta); 2024 cmd.len = cpu_to_le32(min(ALIGN(count + delta, 4) / 4, 2025 (size_t)DEBUG_MEM_MAX_SIZE_DWORDS)); 2026 2027 mutex_lock(&mvm->mutex); 2028 ret = iwl_mvm_send_cmd(mvm, &hcmd); 2029 mutex_unlock(&mvm->mutex); 2030 2031 if (ret < 0) 2032 return ret; 2033 2034 if (iwl_rx_packet_payload_len(hcmd.resp_pkt) < sizeof(*rsp)) { 2035 ret = -EIO; 2036 goto out; 2037 } 2038 2039 rsp = (void *)hcmd.resp_pkt->data; 2040 if (le32_to_cpu(rsp->status) != DEBUG_MEM_STATUS_SUCCESS) { 2041 ret = -ENXIO; 2042 goto out; 2043 } 2044 2045 len = min((size_t)le32_to_cpu(rsp->len) << 2, 2046 iwl_rx_packet_payload_len(hcmd.resp_pkt) - sizeof(*rsp)); 2047 len = min(len - delta, count); 2048 if (len < 0) { 2049 ret = -EFAULT; 2050 goto out; 2051 } 2052 2053 ret = len - copy_to_user(user_buf, (u8 *)rsp->data + delta, len); 2054 *ppos += ret; 2055 2056 out: 2057 iwl_free_resp(&hcmd); 2058 return ret; 2059 } 2060 2061 static ssize_t iwl_dbgfs_mem_write(struct file *file, 2062 const char __user *user_buf, size_t count, 2063 loff_t *ppos) 2064 { 2065 struct iwl_mvm *mvm = file->private_data; 2066 struct iwl_dbg_mem_access_cmd *cmd; 2067 struct iwl_dbg_mem_access_rsp *rsp; 2068 struct iwl_host_cmd hcmd = {}; 2069 size_t cmd_size; 2070 size_t data_size; 2071 u32 op, len; 2072 ssize_t ret; 2073 2074 if (!iwl_mvm_firmware_running(mvm)) 2075 return -EIO; 2076 2077 hcmd.id = WIDE_ID(DEBUG_GROUP, *ppos >> 24 ? UMAC_RD_WR : LMAC_RD_WR); 2078 2079 if (*ppos & 0x3 || count < 4) { 2080 op = DEBUG_MEM_OP_WRITE_BYTES; 2081 len = min(count, (size_t)(4 - (*ppos & 0x3))); 2082 data_size = len; 2083 } else { 2084 op = DEBUG_MEM_OP_WRITE; 2085 len = min(count >> 2, (size_t)DEBUG_MEM_MAX_SIZE_DWORDS); 2086 data_size = len << 2; 2087 } 2088 2089 cmd_size = sizeof(*cmd) + ALIGN(data_size, 4); 2090 cmd = kzalloc(cmd_size, GFP_KERNEL); 2091 if (!cmd) 2092 return -ENOMEM; 2093 2094 cmd->op = cpu_to_le32(op); 2095 cmd->len = cpu_to_le32(len); 2096 cmd->addr = cpu_to_le32(*ppos); 2097 if (copy_from_user((void *)cmd->data, user_buf, data_size)) { 2098 kfree(cmd); 2099 return -EFAULT; 2100 } 2101 2102 hcmd.flags = CMD_WANT_SKB | CMD_SEND_IN_RFKILL, 2103 hcmd.data[0] = (void *)cmd; 2104 hcmd.len[0] = cmd_size; 2105 2106 mutex_lock(&mvm->mutex); 2107 ret = iwl_mvm_send_cmd(mvm, &hcmd); 2108 mutex_unlock(&mvm->mutex); 2109 2110 kfree(cmd); 2111 2112 if (ret < 0) 2113 return ret; 2114 2115 if (iwl_rx_packet_payload_len(hcmd.resp_pkt) < sizeof(*rsp)) { 2116 ret = -EIO; 2117 goto out; 2118 } 2119 2120 rsp = (void *)hcmd.resp_pkt->data; 2121 if (rsp->status != DEBUG_MEM_STATUS_SUCCESS) { 2122 ret = -ENXIO; 2123 goto out; 2124 } 2125 2126 ret = data_size; 2127 *ppos += ret; 2128 2129 out: 2130 iwl_free_resp(&hcmd); 2131 return ret; 2132 } 2133 2134 static const struct file_operations iwl_dbgfs_mem_ops = { 2135 .read = iwl_dbgfs_mem_read, 2136 .write = iwl_dbgfs_mem_write, 2137 .open = simple_open, 2138 .llseek = default_llseek, 2139 }; 2140 2141 void iwl_mvm_link_sta_add_debugfs(struct ieee80211_hw *hw, 2142 struct ieee80211_vif *vif, 2143 struct ieee80211_link_sta *link_sta, 2144 struct dentry *dir) 2145 { 2146 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); 2147 2148 if (iwl_mvm_has_tlc_offload(mvm)) { 2149 MVM_DEBUGFS_ADD_LINK_STA_FILE(rs_data, dir, 0400); 2150 } 2151 2152 MVM_DEBUGFS_ADD_LINK_STA_FILE(amsdu_len, dir, 0600); 2153 } 2154 2155 void iwl_mvm_dbgfs_register(struct iwl_mvm *mvm) 2156 { 2157 struct dentry *bcast_dir __maybe_unused; 2158 2159 spin_lock_init(&mvm->drv_stats_lock); 2160 2161 MVM_DEBUGFS_ADD_FILE(tx_flush, mvm->debugfs_dir, 0200); 2162 MVM_DEBUGFS_ADD_FILE(sram, mvm->debugfs_dir, 0600); 2163 MVM_DEBUGFS_ADD_FILE(set_nic_temperature, mvm->debugfs_dir, 0600); 2164 MVM_DEBUGFS_ADD_FILE(nic_temp, mvm->debugfs_dir, 0400); 2165 MVM_DEBUGFS_ADD_FILE(ctdp_budget, mvm->debugfs_dir, 0400); 2166 MVM_DEBUGFS_ADD_FILE(stop_ctdp, mvm->debugfs_dir, 0200); 2167 MVM_DEBUGFS_ADD_FILE(start_ctdp, mvm->debugfs_dir, 0200); 2168 MVM_DEBUGFS_ADD_FILE(force_ctkill, mvm->debugfs_dir, 0200); 2169 MVM_DEBUGFS_ADD_FILE(stations, mvm->debugfs_dir, 0400); 2170 MVM_DEBUGFS_ADD_FILE(disable_power_off, mvm->debugfs_dir, 0600); 2171 MVM_DEBUGFS_ADD_FILE(fw_ver, mvm->debugfs_dir, 0400); 2172 MVM_DEBUGFS_ADD_FILE(fw_rx_stats, mvm->debugfs_dir, 0400); 2173 MVM_DEBUGFS_ADD_FILE(drv_rx_stats, mvm->debugfs_dir, 0400); 2174 MVM_DEBUGFS_ADD_FILE(fw_system_stats, mvm->debugfs_dir, 0400); 2175 MVM_DEBUGFS_ADD_FILE(fw_restart, mvm->debugfs_dir, 0200); 2176 MVM_DEBUGFS_ADD_FILE(fw_nmi, mvm->debugfs_dir, 0200); 2177 MVM_DEBUGFS_ADD_FILE(scan_ant_rxchain, mvm->debugfs_dir, 0600); 2178 MVM_DEBUGFS_ADD_FILE(prph_reg, mvm->debugfs_dir, 0600); 2179 MVM_DEBUGFS_ADD_FILE(fw_dbg_conf, mvm->debugfs_dir, 0600); 2180 MVM_DEBUGFS_ADD_FILE(fw_dbg_collect, mvm->debugfs_dir, 0200); 2181 MVM_DEBUGFS_ADD_FILE(fw_dbg_clear, mvm->debugfs_dir, 0200); 2182 MVM_DEBUGFS_ADD_FILE(dbg_time_point, mvm->debugfs_dir, 0200); 2183 MVM_DEBUGFS_ADD_FILE(send_echo_cmd, mvm->debugfs_dir, 0200); 2184 MVM_DEBUGFS_ADD_FILE(indirection_tbl, mvm->debugfs_dir, 0200); 2185 MVM_DEBUGFS_ADD_FILE(inject_packet, mvm->debugfs_dir, 0200); 2186 MVM_DEBUGFS_ADD_FILE(inject_beacon_ie, mvm->debugfs_dir, 0200); 2187 MVM_DEBUGFS_ADD_FILE(inject_beacon_ie_restore, mvm->debugfs_dir, 0200); 2188 MVM_DEBUGFS_ADD_FILE(rfi_freq_table, mvm->debugfs_dir, 0600); 2189 2190 if (mvm->fw->phy_integration_ver) 2191 MVM_DEBUGFS_ADD_FILE(phy_integration_ver, mvm->debugfs_dir, 0400); 2192 MVM_DEBUGFS_ADD_FILE(tas_get_status, mvm->debugfs_dir, 0400); 2193 #ifdef CONFIG_ACPI 2194 MVM_DEBUGFS_ADD_FILE(sar_geo_profile, mvm->debugfs_dir, 0400); 2195 MVM_DEBUGFS_ADD_FILE(wifi_6e_enable, mvm->debugfs_dir, 0400); 2196 #endif 2197 MVM_DEBUGFS_ADD_FILE(he_sniffer_params, mvm->debugfs_dir, 0600); 2198 2199 if (fw_has_capa(&mvm->fw->ucode_capa, IWL_UCODE_TLV_CAPA_SET_LTR_GEN2)) 2200 MVM_DEBUGFS_ADD_FILE(ltr_config, mvm->debugfs_dir, 0200); 2201 2202 debugfs_create_bool("enable_scan_iteration_notif", 0600, 2203 mvm->debugfs_dir, &mvm->scan_iter_notif_enabled); 2204 debugfs_create_bool("drop_bcn_ap_mode", 0600, mvm->debugfs_dir, 2205 &mvm->drop_bcn_ap_mode); 2206 2207 MVM_DEBUGFS_ADD_FILE(uapsd_noagg_bssids, mvm->debugfs_dir, S_IRUSR); 2208 2209 #ifdef CONFIG_PM_SLEEP 2210 MVM_DEBUGFS_ADD_FILE(d3_test, mvm->debugfs_dir, 0400); 2211 debugfs_create_bool("d3_wake_sysassert", 0600, mvm->debugfs_dir, 2212 &mvm->d3_wake_sysassert); 2213 debugfs_create_u32("last_netdetect_scans", 0400, mvm->debugfs_dir, 2214 &mvm->last_netdetect_scans); 2215 #endif 2216 2217 debugfs_create_u8("ps_disabled", 0400, mvm->debugfs_dir, 2218 &mvm->ps_disabled); 2219 debugfs_create_blob("nvm_hw", 0400, mvm->debugfs_dir, 2220 &mvm->nvm_hw_blob); 2221 debugfs_create_blob("nvm_sw", 0400, mvm->debugfs_dir, 2222 &mvm->nvm_sw_blob); 2223 debugfs_create_blob("nvm_calib", 0400, mvm->debugfs_dir, 2224 &mvm->nvm_calib_blob); 2225 debugfs_create_blob("nvm_prod", 0400, mvm->debugfs_dir, 2226 &mvm->nvm_prod_blob); 2227 debugfs_create_blob("nvm_phy_sku", 0400, mvm->debugfs_dir, 2228 &mvm->nvm_phy_sku_blob); 2229 debugfs_create_blob("nvm_reg", S_IRUSR, 2230 mvm->debugfs_dir, &mvm->nvm_reg_blob); 2231 2232 debugfs_create_file("mem", 0600, mvm->debugfs_dir, mvm, 2233 &iwl_dbgfs_mem_ops); 2234 2235 debugfs_create_bool("rx_ts_ptp", 0600, mvm->debugfs_dir, 2236 &mvm->rx_ts_ptp); 2237 2238 #if defined(__linux__) 2239 /* 2240 * Create a symlink with mac80211. It will be removed when mac80211 2241 * exists (before the opmode exists which removes the target.) 2242 */ 2243 if (!IS_ERR(mvm->debugfs_dir)) { 2244 char buf[100]; 2245 2246 snprintf(buf, 100, "../../%pd2", mvm->debugfs_dir->d_parent); 2247 debugfs_create_symlink("iwlwifi", mvm->hw->wiphy->debugfsdir, 2248 buf); 2249 } 2250 #endif 2251 } 2252