1 /****************************************************************************** 2 * 3 * This file is provided under a dual BSD/GPLv2 license. When using or 4 * redistributing this file, you may do so under either license. 5 * 6 * GPL LICENSE SUMMARY 7 * 8 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. 9 * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH 10 * Copyright(c) 2016 - 2017 Intel Deutschland GmbH 11 * Copyright(c) 2018 - 2019 Intel Corporation 12 * 13 * This program is free software; you can redistribute it and/or modify 14 * it under the terms of version 2 of the GNU General Public License as 15 * published by the Free Software Foundation. 16 * 17 * This program is distributed in the hope that it will be useful, but 18 * WITHOUT ANY WARRANTY; without even the implied warranty of 19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 20 * General Public License for more details. 21 * 22 * The full GNU General Public License is included in this distribution 23 * in the file called COPYING. 24 * 25 * Contact Information: 26 * Intel Linux Wireless <linuxwifi@intel.com> 27 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 28 * 29 * BSD LICENSE 30 * 31 * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. 32 * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH 33 * Copyright(c) 2016 - 2017 Intel Deutschland GmbH 34 * Copyright(c) 2018 - 2019 Intel Corporation 35 * All rights reserved. 36 * 37 * Redistribution and use in source and binary forms, with or without 38 * modification, are permitted provided that the following conditions 39 * are met: 40 * 41 * * Redistributions of source code must retain the above copyright 42 * notice, this list of conditions and the following disclaimer. 43 * * Redistributions in binary form must reproduce the above copyright 44 * notice, this list of conditions and the following disclaimer in 45 * the documentation and/or other materials provided with the 46 * distribution. 47 * * Neither the name Intel Corporation nor the names of its 48 * contributors may be used to endorse or promote products derived 49 * from this software without specific prior written permission. 50 * 51 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 52 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 53 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 54 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 55 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 56 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 57 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 58 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 59 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 60 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 61 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 62 * 63 *****************************************************************************/ 64 #include <linux/vmalloc.h> 65 #include <linux/ieee80211.h> 66 #include <linux/netdevice.h> 67 68 #include "mvm.h" 69 #include "sta.h" 70 #include "iwl-io.h" 71 #include "debugfs.h" 72 #include "iwl-modparams.h" 73 #include "fw/error-dump.h" 74 75 static ssize_t iwl_dbgfs_ctdp_budget_read(struct file *file, 76 char __user *user_buf, 77 size_t count, loff_t *ppos) 78 { 79 struct iwl_mvm *mvm = file->private_data; 80 char buf[16]; 81 int pos, budget; 82 83 if (!iwl_mvm_is_ctdp_supported(mvm)) 84 return -EOPNOTSUPP; 85 86 if (!iwl_mvm_firmware_running(mvm) || 87 mvm->fwrt.cur_fw_img != IWL_UCODE_REGULAR) 88 return -EIO; 89 90 mutex_lock(&mvm->mutex); 91 budget = iwl_mvm_ctdp_command(mvm, CTDP_CMD_OPERATION_REPORT, 0); 92 mutex_unlock(&mvm->mutex); 93 94 if (budget < 0) 95 return budget; 96 97 pos = scnprintf(buf, sizeof(buf), "%d\n", budget); 98 99 return simple_read_from_buffer(user_buf, count, ppos, buf, pos); 100 } 101 102 static ssize_t iwl_dbgfs_stop_ctdp_write(struct iwl_mvm *mvm, char *buf, 103 size_t count, loff_t *ppos) 104 { 105 int ret; 106 107 if (!iwl_mvm_is_ctdp_supported(mvm)) 108 return -EOPNOTSUPP; 109 110 if (!iwl_mvm_firmware_running(mvm) || 111 mvm->fwrt.cur_fw_img != IWL_UCODE_REGULAR) 112 return -EIO; 113 114 mutex_lock(&mvm->mutex); 115 ret = iwl_mvm_ctdp_command(mvm, CTDP_CMD_OPERATION_STOP, 0); 116 mutex_unlock(&mvm->mutex); 117 118 return ret ?: count; 119 } 120 121 static ssize_t iwl_dbgfs_force_ctkill_write(struct iwl_mvm *mvm, char *buf, 122 size_t count, loff_t *ppos) 123 { 124 if (!iwl_mvm_firmware_running(mvm) || 125 mvm->fwrt.cur_fw_img != IWL_UCODE_REGULAR) 126 return -EIO; 127 128 iwl_mvm_enter_ctkill(mvm); 129 130 return count; 131 } 132 133 static ssize_t iwl_dbgfs_tx_flush_write(struct iwl_mvm *mvm, char *buf, 134 size_t count, loff_t *ppos) 135 { 136 int ret; 137 u32 flush_arg; 138 139 if (!iwl_mvm_firmware_running(mvm) || 140 mvm->fwrt.cur_fw_img != IWL_UCODE_REGULAR) 141 return -EIO; 142 143 if (kstrtou32(buf, 0, &flush_arg)) 144 return -EINVAL; 145 146 if (iwl_mvm_has_new_tx_api(mvm)) { 147 IWL_DEBUG_TX_QUEUES(mvm, 148 "FLUSHING all tids queues on sta_id = %d\n", 149 flush_arg); 150 mutex_lock(&mvm->mutex); 151 ret = iwl_mvm_flush_sta_tids(mvm, flush_arg, 0xFFFF, 0) 152 ? : count; 153 mutex_unlock(&mvm->mutex); 154 return ret; 155 } 156 157 IWL_DEBUG_TX_QUEUES(mvm, "FLUSHING queues mask to flush = 0x%x\n", 158 flush_arg); 159 160 mutex_lock(&mvm->mutex); 161 ret = iwl_mvm_flush_tx_path(mvm, flush_arg, 0) ? : count; 162 mutex_unlock(&mvm->mutex); 163 164 return ret; 165 } 166 167 static ssize_t iwl_dbgfs_sta_drain_write(struct iwl_mvm *mvm, char *buf, 168 size_t count, loff_t *ppos) 169 { 170 struct iwl_mvm_sta *mvmsta; 171 int sta_id, drain, ret; 172 173 if (!iwl_mvm_firmware_running(mvm) || 174 mvm->fwrt.cur_fw_img != IWL_UCODE_REGULAR) 175 return -EIO; 176 177 if (sscanf(buf, "%d %d", &sta_id, &drain) != 2) 178 return -EINVAL; 179 if (sta_id < 0 || sta_id >= IWL_MVM_STATION_COUNT) 180 return -EINVAL; 181 if (drain < 0 || drain > 1) 182 return -EINVAL; 183 184 mutex_lock(&mvm->mutex); 185 186 mvmsta = iwl_mvm_sta_from_staid_protected(mvm, sta_id); 187 188 if (!mvmsta) 189 ret = -ENOENT; 190 else 191 ret = iwl_mvm_drain_sta(mvm, mvmsta, drain) ? : count; 192 193 mutex_unlock(&mvm->mutex); 194 195 return ret; 196 } 197 198 static ssize_t iwl_dbgfs_sram_read(struct file *file, char __user *user_buf, 199 size_t count, loff_t *ppos) 200 { 201 struct iwl_mvm *mvm = file->private_data; 202 const struct fw_img *img; 203 unsigned int ofs, len; 204 size_t ret; 205 u8 *ptr; 206 207 if (!iwl_mvm_firmware_running(mvm)) 208 return -EINVAL; 209 210 /* default is to dump the entire data segment */ 211 img = &mvm->fw->img[mvm->fwrt.cur_fw_img]; 212 ofs = img->sec[IWL_UCODE_SECTION_DATA].offset; 213 len = img->sec[IWL_UCODE_SECTION_DATA].len; 214 215 if (mvm->dbgfs_sram_len) { 216 ofs = mvm->dbgfs_sram_offset; 217 len = mvm->dbgfs_sram_len; 218 } 219 220 ptr = kzalloc(len, GFP_KERNEL); 221 if (!ptr) 222 return -ENOMEM; 223 224 iwl_trans_read_mem_bytes(mvm->trans, ofs, ptr, len); 225 226 ret = simple_read_from_buffer(user_buf, count, ppos, ptr, len); 227 228 kfree(ptr); 229 230 return ret; 231 } 232 233 static ssize_t iwl_dbgfs_sram_write(struct iwl_mvm *mvm, char *buf, 234 size_t count, loff_t *ppos) 235 { 236 const struct fw_img *img; 237 u32 offset, len; 238 u32 img_offset, img_len; 239 240 if (!iwl_mvm_firmware_running(mvm)) 241 return -EINVAL; 242 243 img = &mvm->fw->img[mvm->fwrt.cur_fw_img]; 244 img_offset = img->sec[IWL_UCODE_SECTION_DATA].offset; 245 img_len = img->sec[IWL_UCODE_SECTION_DATA].len; 246 247 if (sscanf(buf, "%x,%x", &offset, &len) == 2) { 248 if ((offset & 0x3) || (len & 0x3)) 249 return -EINVAL; 250 251 if (offset + len > img_offset + img_len) 252 return -EINVAL; 253 254 mvm->dbgfs_sram_offset = offset; 255 mvm->dbgfs_sram_len = len; 256 } else { 257 mvm->dbgfs_sram_offset = 0; 258 mvm->dbgfs_sram_len = 0; 259 } 260 261 return count; 262 } 263 264 static ssize_t iwl_dbgfs_set_nic_temperature_read(struct file *file, 265 char __user *user_buf, 266 size_t count, loff_t *ppos) 267 { 268 struct iwl_mvm *mvm = file->private_data; 269 char buf[16]; 270 int pos; 271 272 if (!mvm->temperature_test) 273 pos = scnprintf(buf , sizeof(buf), "disabled\n"); 274 else 275 pos = scnprintf(buf , sizeof(buf), "%d\n", mvm->temperature); 276 277 return simple_read_from_buffer(user_buf, count, ppos, buf, pos); 278 } 279 280 /* 281 * Set NIC Temperature 282 * Cause the driver to ignore the actual NIC temperature reported by the FW 283 * Enable: any value between IWL_MVM_DEBUG_SET_TEMPERATURE_MIN - 284 * IWL_MVM_DEBUG_SET_TEMPERATURE_MAX 285 * Disable: IWL_MVM_DEBUG_SET_TEMPERATURE_DISABLE 286 */ 287 static ssize_t iwl_dbgfs_set_nic_temperature_write(struct iwl_mvm *mvm, 288 char *buf, size_t count, 289 loff_t *ppos) 290 { 291 int temperature; 292 293 if (!iwl_mvm_firmware_running(mvm) && !mvm->temperature_test) 294 return -EIO; 295 296 if (kstrtoint(buf, 10, &temperature)) 297 return -EINVAL; 298 /* not a legal temperature */ 299 if ((temperature > IWL_MVM_DEBUG_SET_TEMPERATURE_MAX && 300 temperature != IWL_MVM_DEBUG_SET_TEMPERATURE_DISABLE) || 301 temperature < IWL_MVM_DEBUG_SET_TEMPERATURE_MIN) 302 return -EINVAL; 303 304 mutex_lock(&mvm->mutex); 305 if (temperature == IWL_MVM_DEBUG_SET_TEMPERATURE_DISABLE) { 306 if (!mvm->temperature_test) 307 goto out; 308 309 mvm->temperature_test = false; 310 /* Since we can't read the temp while awake, just set 311 * it to zero until we get the next RX stats from the 312 * firmware. 313 */ 314 mvm->temperature = 0; 315 } else { 316 mvm->temperature_test = true; 317 mvm->temperature = temperature; 318 } 319 IWL_DEBUG_TEMP(mvm, "%sabling debug set temperature (temp = %d)\n", 320 mvm->temperature_test ? "En" : "Dis" , 321 mvm->temperature); 322 /* handle the temperature change */ 323 iwl_mvm_tt_handler(mvm); 324 325 out: 326 mutex_unlock(&mvm->mutex); 327 328 return count; 329 } 330 331 static ssize_t iwl_dbgfs_nic_temp_read(struct file *file, 332 char __user *user_buf, 333 size_t count, loff_t *ppos) 334 { 335 struct iwl_mvm *mvm = file->private_data; 336 char buf[16]; 337 int pos, ret; 338 s32 temp; 339 340 if (!iwl_mvm_firmware_running(mvm)) 341 return -EIO; 342 343 mutex_lock(&mvm->mutex); 344 ret = iwl_mvm_get_temp(mvm, &temp); 345 mutex_unlock(&mvm->mutex); 346 347 if (ret) 348 return -EIO; 349 350 pos = scnprintf(buf , sizeof(buf), "%d\n", temp); 351 352 return simple_read_from_buffer(user_buf, count, ppos, buf, pos); 353 } 354 355 #ifdef CONFIG_ACPI 356 static ssize_t iwl_dbgfs_sar_geo_profile_read(struct file *file, 357 char __user *user_buf, 358 size_t count, loff_t *ppos) 359 { 360 struct iwl_mvm *mvm = file->private_data; 361 char buf[256]; 362 int pos = 0; 363 int bufsz = sizeof(buf); 364 int tbl_idx; 365 u8 *value; 366 367 if (!iwl_mvm_firmware_running(mvm)) 368 return -EIO; 369 370 mutex_lock(&mvm->mutex); 371 tbl_idx = iwl_mvm_get_sar_geo_profile(mvm); 372 if (tbl_idx < 0) { 373 mutex_unlock(&mvm->mutex); 374 return tbl_idx; 375 } 376 377 if (!tbl_idx) { 378 pos = scnprintf(buf, bufsz, 379 "SAR geographic profile disabled\n"); 380 } else { 381 value = &mvm->fwrt.geo_profiles[tbl_idx - 1].values[0]; 382 383 pos += scnprintf(buf + pos, bufsz - pos, 384 "Use geographic profile %d\n", tbl_idx); 385 pos += scnprintf(buf + pos, bufsz - pos, 386 "2.4GHz:\n\tChain A offset: %hhd dBm\n\tChain B offset: %hhd dBm\n\tmax tx power: %hhd dBm\n", 387 value[1], value[2], value[0]); 388 pos += scnprintf(buf + pos, bufsz - pos, 389 "5.2GHz:\n\tChain A offset: %hhd dBm\n\tChain B offset: %hhd dBm\n\tmax tx power: %hhd dBm\n", 390 value[4], value[5], value[3]); 391 } 392 mutex_unlock(&mvm->mutex); 393 394 return simple_read_from_buffer(user_buf, count, ppos, buf, pos); 395 } 396 #endif 397 398 static ssize_t iwl_dbgfs_stations_read(struct file *file, char __user *user_buf, 399 size_t count, loff_t *ppos) 400 { 401 struct iwl_mvm *mvm = file->private_data; 402 struct ieee80211_sta *sta; 403 char buf[400]; 404 int i, pos = 0, bufsz = sizeof(buf); 405 406 mutex_lock(&mvm->mutex); 407 408 for (i = 0; i < ARRAY_SIZE(mvm->fw_id_to_mac_id); i++) { 409 pos += scnprintf(buf + pos, bufsz - pos, "%.2d: ", i); 410 sta = rcu_dereference_protected(mvm->fw_id_to_mac_id[i], 411 lockdep_is_held(&mvm->mutex)); 412 if (!sta) 413 pos += scnprintf(buf + pos, bufsz - pos, "N/A\n"); 414 else if (IS_ERR(sta)) 415 pos += scnprintf(buf + pos, bufsz - pos, "%ld\n", 416 PTR_ERR(sta)); 417 else 418 pos += scnprintf(buf + pos, bufsz - pos, "%pM\n", 419 sta->addr); 420 } 421 422 mutex_unlock(&mvm->mutex); 423 424 return simple_read_from_buffer(user_buf, count, ppos, buf, pos); 425 } 426 427 static ssize_t iwl_dbgfs_rs_data_read(struct file *file, char __user *user_buf, 428 size_t count, loff_t *ppos) 429 { 430 struct ieee80211_sta *sta = file->private_data; 431 struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta); 432 struct iwl_lq_sta_rs_fw *lq_sta = &mvmsta->lq_sta.rs_fw; 433 struct iwl_mvm *mvm = lq_sta->pers.drv; 434 static const size_t bufsz = 2048; 435 char *buff; 436 int desc = 0; 437 ssize_t ret; 438 439 buff = kmalloc(bufsz, GFP_KERNEL); 440 if (!buff) 441 return -ENOMEM; 442 443 mutex_lock(&mvm->mutex); 444 445 desc += scnprintf(buff + desc, bufsz - desc, "sta_id %d\n", 446 lq_sta->pers.sta_id); 447 desc += scnprintf(buff + desc, bufsz - desc, 448 "fixed rate 0x%X\n", 449 lq_sta->pers.dbg_fixed_rate); 450 desc += scnprintf(buff + desc, bufsz - desc, 451 "A-MPDU size limit %d\n", 452 lq_sta->pers.dbg_agg_frame_count_lim); 453 desc += scnprintf(buff + desc, bufsz - desc, 454 "valid_tx_ant %s%s%s\n", 455 (iwl_mvm_get_valid_tx_ant(mvm) & ANT_A) ? "ANT_A," : "", 456 (iwl_mvm_get_valid_tx_ant(mvm) & ANT_B) ? "ANT_B," : "", 457 (iwl_mvm_get_valid_tx_ant(mvm) & ANT_C) ? "ANT_C" : ""); 458 desc += scnprintf(buff + desc, bufsz - desc, 459 "last tx rate=0x%X ", 460 lq_sta->last_rate_n_flags); 461 462 desc += rs_pretty_print_rate(buff + desc, bufsz - desc, 463 lq_sta->last_rate_n_flags); 464 mutex_unlock(&mvm->mutex); 465 466 ret = simple_read_from_buffer(user_buf, count, ppos, buff, desc); 467 kfree(buff); 468 return ret; 469 } 470 471 static ssize_t iwl_dbgfs_amsdu_len_write(struct ieee80211_sta *sta, 472 char *buf, size_t count, 473 loff_t *ppos) 474 { 475 struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta); 476 int i; 477 u16 amsdu_len; 478 479 if (kstrtou16(buf, 0, &amsdu_len)) 480 return -EINVAL; 481 482 if (amsdu_len) { 483 mvmsta->orig_amsdu_len = sta->max_amsdu_len; 484 sta->max_amsdu_len = amsdu_len; 485 for (i = 0; i < ARRAY_SIZE(sta->max_tid_amsdu_len); i++) 486 sta->max_tid_amsdu_len[i] = amsdu_len; 487 } else { 488 sta->max_amsdu_len = mvmsta->orig_amsdu_len; 489 mvmsta->orig_amsdu_len = 0; 490 } 491 return count; 492 } 493 494 static ssize_t iwl_dbgfs_amsdu_len_read(struct file *file, 495 char __user *user_buf, 496 size_t count, loff_t *ppos) 497 { 498 struct ieee80211_sta *sta = file->private_data; 499 struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta); 500 501 char buf[32]; 502 int pos; 503 504 pos = scnprintf(buf, sizeof(buf), "current %d ", sta->max_amsdu_len); 505 pos += scnprintf(buf + pos, sizeof(buf) - pos, "stored %d\n", 506 mvmsta->orig_amsdu_len); 507 508 return simple_read_from_buffer(user_buf, count, ppos, buf, pos); 509 } 510 511 static ssize_t iwl_dbgfs_disable_power_off_read(struct file *file, 512 char __user *user_buf, 513 size_t count, loff_t *ppos) 514 { 515 struct iwl_mvm *mvm = file->private_data; 516 char buf[64]; 517 int bufsz = sizeof(buf); 518 int pos = 0; 519 520 pos += scnprintf(buf+pos, bufsz-pos, "disable_power_off_d0=%d\n", 521 mvm->disable_power_off); 522 pos += scnprintf(buf+pos, bufsz-pos, "disable_power_off_d3=%d\n", 523 mvm->disable_power_off_d3); 524 525 return simple_read_from_buffer(user_buf, count, ppos, buf, pos); 526 } 527 528 static ssize_t iwl_dbgfs_disable_power_off_write(struct iwl_mvm *mvm, char *buf, 529 size_t count, loff_t *ppos) 530 { 531 int ret, val; 532 533 if (!iwl_mvm_firmware_running(mvm)) 534 return -EIO; 535 536 if (!strncmp("disable_power_off_d0=", buf, 21)) { 537 if (sscanf(buf + 21, "%d", &val) != 1) 538 return -EINVAL; 539 mvm->disable_power_off = val; 540 } else if (!strncmp("disable_power_off_d3=", buf, 21)) { 541 if (sscanf(buf + 21, "%d", &val) != 1) 542 return -EINVAL; 543 mvm->disable_power_off_d3 = val; 544 } else { 545 return -EINVAL; 546 } 547 548 mutex_lock(&mvm->mutex); 549 ret = iwl_mvm_power_update_device(mvm); 550 mutex_unlock(&mvm->mutex); 551 552 return ret ?: count; 553 } 554 555 static 556 int iwl_mvm_coex_dump_mbox(struct iwl_bt_coex_profile_notif *notif, char *buf, 557 int pos, int bufsz) 558 { 559 pos += scnprintf(buf+pos, bufsz-pos, "MBOX dw0:\n"); 560 561 BT_MBOX_PRINT(0, LE_SLAVE_LAT, false); 562 BT_MBOX_PRINT(0, LE_PROF1, false); 563 BT_MBOX_PRINT(0, LE_PROF2, false); 564 BT_MBOX_PRINT(0, LE_PROF_OTHER, false); 565 BT_MBOX_PRINT(0, CHL_SEQ_N, false); 566 BT_MBOX_PRINT(0, INBAND_S, false); 567 BT_MBOX_PRINT(0, LE_MIN_RSSI, false); 568 BT_MBOX_PRINT(0, LE_SCAN, false); 569 BT_MBOX_PRINT(0, LE_ADV, false); 570 BT_MBOX_PRINT(0, LE_MAX_TX_POWER, false); 571 BT_MBOX_PRINT(0, OPEN_CON_1, true); 572 573 pos += scnprintf(buf+pos, bufsz-pos, "MBOX dw1:\n"); 574 575 BT_MBOX_PRINT(1, BR_MAX_TX_POWER, false); 576 BT_MBOX_PRINT(1, IP_SR, false); 577 BT_MBOX_PRINT(1, LE_MSTR, false); 578 BT_MBOX_PRINT(1, AGGR_TRFC_LD, false); 579 BT_MBOX_PRINT(1, MSG_TYPE, false); 580 BT_MBOX_PRINT(1, SSN, true); 581 582 pos += scnprintf(buf+pos, bufsz-pos, "MBOX dw2:\n"); 583 584 BT_MBOX_PRINT(2, SNIFF_ACT, false); 585 BT_MBOX_PRINT(2, PAG, false); 586 BT_MBOX_PRINT(2, INQUIRY, false); 587 BT_MBOX_PRINT(2, CONN, false); 588 BT_MBOX_PRINT(2, SNIFF_INTERVAL, false); 589 BT_MBOX_PRINT(2, DISC, false); 590 BT_MBOX_PRINT(2, SCO_TX_ACT, false); 591 BT_MBOX_PRINT(2, SCO_RX_ACT, false); 592 BT_MBOX_PRINT(2, ESCO_RE_TX, false); 593 BT_MBOX_PRINT(2, SCO_DURATION, true); 594 595 pos += scnprintf(buf+pos, bufsz-pos, "MBOX dw3:\n"); 596 597 BT_MBOX_PRINT(3, SCO_STATE, false); 598 BT_MBOX_PRINT(3, SNIFF_STATE, false); 599 BT_MBOX_PRINT(3, A2DP_STATE, false); 600 BT_MBOX_PRINT(3, A2DP_SRC, false); 601 BT_MBOX_PRINT(3, ACL_STATE, false); 602 BT_MBOX_PRINT(3, MSTR_STATE, false); 603 BT_MBOX_PRINT(3, OBX_STATE, false); 604 BT_MBOX_PRINT(3, OPEN_CON_2, false); 605 BT_MBOX_PRINT(3, TRAFFIC_LOAD, false); 606 BT_MBOX_PRINT(3, CHL_SEQN_LSB, false); 607 BT_MBOX_PRINT(3, INBAND_P, false); 608 BT_MBOX_PRINT(3, MSG_TYPE_2, false); 609 BT_MBOX_PRINT(3, SSN_2, false); 610 BT_MBOX_PRINT(3, UPDATE_REQUEST, true); 611 612 return pos; 613 } 614 615 static ssize_t iwl_dbgfs_bt_notif_read(struct file *file, char __user *user_buf, 616 size_t count, loff_t *ppos) 617 { 618 struct iwl_mvm *mvm = file->private_data; 619 struct iwl_bt_coex_profile_notif *notif = &mvm->last_bt_notif; 620 char *buf; 621 int ret, pos = 0, bufsz = sizeof(char) * 1024; 622 623 buf = kmalloc(bufsz, GFP_KERNEL); 624 if (!buf) 625 return -ENOMEM; 626 627 mutex_lock(&mvm->mutex); 628 629 pos += iwl_mvm_coex_dump_mbox(notif, buf, pos, bufsz); 630 631 pos += scnprintf(buf + pos, bufsz - pos, "bt_ci_compliance = %d\n", 632 notif->bt_ci_compliance); 633 pos += scnprintf(buf + pos, bufsz - pos, "primary_ch_lut = %d\n", 634 le32_to_cpu(notif->primary_ch_lut)); 635 pos += scnprintf(buf + pos, bufsz - pos, "secondary_ch_lut = %d\n", 636 le32_to_cpu(notif->secondary_ch_lut)); 637 pos += scnprintf(buf + pos, 638 bufsz - pos, "bt_activity_grading = %d\n", 639 le32_to_cpu(notif->bt_activity_grading)); 640 pos += scnprintf(buf + pos, bufsz - pos, "bt_rrc = %d\n", 641 notif->rrc_status & 0xF); 642 pos += scnprintf(buf + pos, bufsz - pos, "bt_ttc = %d\n", 643 notif->ttc_status & 0xF); 644 645 pos += scnprintf(buf + pos, bufsz - pos, "sync_sco = %d\n", 646 IWL_MVM_BT_COEX_SYNC2SCO); 647 pos += scnprintf(buf + pos, bufsz - pos, "mplut = %d\n", 648 IWL_MVM_BT_COEX_MPLUT); 649 650 mutex_unlock(&mvm->mutex); 651 652 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); 653 kfree(buf); 654 655 return ret; 656 } 657 #undef BT_MBOX_PRINT 658 659 static ssize_t iwl_dbgfs_bt_cmd_read(struct file *file, char __user *user_buf, 660 size_t count, loff_t *ppos) 661 { 662 struct iwl_mvm *mvm = file->private_data; 663 struct iwl_bt_coex_ci_cmd *cmd = &mvm->last_bt_ci_cmd; 664 char buf[256]; 665 int bufsz = sizeof(buf); 666 int pos = 0; 667 668 mutex_lock(&mvm->mutex); 669 670 pos += scnprintf(buf + pos, bufsz - pos, "Channel inhibition CMD\n"); 671 pos += scnprintf(buf + pos, bufsz - pos, 672 "\tPrimary Channel Bitmap 0x%016llx\n", 673 le64_to_cpu(cmd->bt_primary_ci)); 674 pos += scnprintf(buf + pos, bufsz - pos, 675 "\tSecondary Channel Bitmap 0x%016llx\n", 676 le64_to_cpu(cmd->bt_secondary_ci)); 677 678 mutex_unlock(&mvm->mutex); 679 680 return simple_read_from_buffer(user_buf, count, ppos, buf, pos); 681 } 682 683 static ssize_t 684 iwl_dbgfs_bt_tx_prio_write(struct iwl_mvm *mvm, char *buf, 685 size_t count, loff_t *ppos) 686 { 687 u32 bt_tx_prio; 688 689 if (sscanf(buf, "%u", &bt_tx_prio) != 1) 690 return -EINVAL; 691 if (bt_tx_prio > 4) 692 return -EINVAL; 693 694 mvm->bt_tx_prio = bt_tx_prio; 695 696 return count; 697 } 698 699 static ssize_t 700 iwl_dbgfs_bt_force_ant_write(struct iwl_mvm *mvm, char *buf, 701 size_t count, loff_t *ppos) 702 { 703 static const char * const modes_str[BT_FORCE_ANT_MAX] = { 704 [BT_FORCE_ANT_DIS] = "dis", 705 [BT_FORCE_ANT_AUTO] = "auto", 706 [BT_FORCE_ANT_BT] = "bt", 707 [BT_FORCE_ANT_WIFI] = "wifi", 708 }; 709 int ret, bt_force_ant_mode; 710 711 ret = match_string(modes_str, ARRAY_SIZE(modes_str), buf); 712 if (ret < 0) 713 return ret; 714 715 bt_force_ant_mode = ret; 716 ret = 0; 717 mutex_lock(&mvm->mutex); 718 if (mvm->bt_force_ant_mode == bt_force_ant_mode) 719 goto out; 720 721 mvm->bt_force_ant_mode = bt_force_ant_mode; 722 IWL_DEBUG_COEX(mvm, "Force mode: %s\n", 723 modes_str[mvm->bt_force_ant_mode]); 724 725 if (iwl_mvm_firmware_running(mvm)) 726 ret = iwl_mvm_send_bt_init_conf(mvm); 727 else 728 ret = 0; 729 730 out: 731 mutex_unlock(&mvm->mutex); 732 return ret ?: count; 733 } 734 735 static ssize_t iwl_dbgfs_fw_ver_read(struct file *file, char __user *user_buf, 736 size_t count, loff_t *ppos) 737 { 738 struct iwl_mvm *mvm = file->private_data; 739 char *buff, *pos, *endpos; 740 static const size_t bufsz = 1024; 741 int ret; 742 743 buff = kmalloc(bufsz, GFP_KERNEL); 744 if (!buff) 745 return -ENOMEM; 746 747 pos = buff; 748 endpos = pos + bufsz; 749 750 pos += scnprintf(pos, endpos - pos, "FW prefix: %s\n", 751 mvm->trans->cfg->fw_name_pre); 752 pos += scnprintf(pos, endpos - pos, "FW: %s\n", 753 mvm->fwrt.fw->human_readable); 754 pos += scnprintf(pos, endpos - pos, "Device: %s\n", 755 mvm->fwrt.trans->cfg->name); 756 pos += scnprintf(pos, endpos - pos, "Bus: %s\n", 757 mvm->fwrt.dev->bus->name); 758 759 ret = simple_read_from_buffer(user_buf, count, ppos, buff, pos - buff); 760 kfree(buff); 761 762 return ret; 763 } 764 765 #define PRINT_STATS_LE32(_struct, _memb) \ 766 pos += scnprintf(buf + pos, bufsz - pos, \ 767 fmt_table, #_memb, \ 768 le32_to_cpu(_struct->_memb)) 769 770 static ssize_t iwl_dbgfs_fw_rx_stats_read(struct file *file, 771 char __user *user_buf, size_t count, 772 loff_t *ppos) 773 { 774 struct iwl_mvm *mvm = file->private_data; 775 static const char *fmt_table = "\t%-30s %10u\n"; 776 static const char *fmt_header = "%-32s\n"; 777 int pos = 0; 778 char *buf; 779 int ret; 780 size_t bufsz; 781 782 if (iwl_mvm_has_new_rx_stats_api(mvm)) 783 bufsz = ((sizeof(struct mvm_statistics_rx) / 784 sizeof(__le32)) * 43) + (4 * 33) + 1; 785 else 786 /* 43 = size of each data line; 33 = size of each header */ 787 bufsz = ((sizeof(struct mvm_statistics_rx_v3) / 788 sizeof(__le32)) * 43) + (4 * 33) + 1; 789 790 buf = kzalloc(bufsz, GFP_KERNEL); 791 if (!buf) 792 return -ENOMEM; 793 794 mutex_lock(&mvm->mutex); 795 796 if (iwl_mvm_firmware_running(mvm)) 797 iwl_mvm_request_statistics(mvm, false); 798 799 pos += scnprintf(buf + pos, bufsz - pos, fmt_header, 800 "Statistics_Rx - OFDM"); 801 if (!iwl_mvm_has_new_rx_stats_api(mvm)) { 802 struct mvm_statistics_rx_phy_v2 *ofdm = &mvm->rx_stats_v3.ofdm; 803 804 PRINT_STATS_LE32(ofdm, ina_cnt); 805 PRINT_STATS_LE32(ofdm, fina_cnt); 806 PRINT_STATS_LE32(ofdm, plcp_err); 807 PRINT_STATS_LE32(ofdm, crc32_err); 808 PRINT_STATS_LE32(ofdm, overrun_err); 809 PRINT_STATS_LE32(ofdm, early_overrun_err); 810 PRINT_STATS_LE32(ofdm, crc32_good); 811 PRINT_STATS_LE32(ofdm, false_alarm_cnt); 812 PRINT_STATS_LE32(ofdm, fina_sync_err_cnt); 813 PRINT_STATS_LE32(ofdm, sfd_timeout); 814 PRINT_STATS_LE32(ofdm, fina_timeout); 815 PRINT_STATS_LE32(ofdm, unresponded_rts); 816 PRINT_STATS_LE32(ofdm, rxe_frame_lmt_overrun); 817 PRINT_STATS_LE32(ofdm, sent_ack_cnt); 818 PRINT_STATS_LE32(ofdm, sent_cts_cnt); 819 PRINT_STATS_LE32(ofdm, sent_ba_rsp_cnt); 820 PRINT_STATS_LE32(ofdm, dsp_self_kill); 821 PRINT_STATS_LE32(ofdm, mh_format_err); 822 PRINT_STATS_LE32(ofdm, re_acq_main_rssi_sum); 823 PRINT_STATS_LE32(ofdm, reserved); 824 } else { 825 struct mvm_statistics_rx_phy *ofdm = &mvm->rx_stats.ofdm; 826 827 PRINT_STATS_LE32(ofdm, unresponded_rts); 828 PRINT_STATS_LE32(ofdm, rxe_frame_lmt_overrun); 829 PRINT_STATS_LE32(ofdm, sent_ba_rsp_cnt); 830 PRINT_STATS_LE32(ofdm, dsp_self_kill); 831 PRINT_STATS_LE32(ofdm, reserved); 832 } 833 834 pos += scnprintf(buf + pos, bufsz - pos, fmt_header, 835 "Statistics_Rx - CCK"); 836 if (!iwl_mvm_has_new_rx_stats_api(mvm)) { 837 struct mvm_statistics_rx_phy_v2 *cck = &mvm->rx_stats_v3.cck; 838 839 PRINT_STATS_LE32(cck, ina_cnt); 840 PRINT_STATS_LE32(cck, fina_cnt); 841 PRINT_STATS_LE32(cck, plcp_err); 842 PRINT_STATS_LE32(cck, crc32_err); 843 PRINT_STATS_LE32(cck, overrun_err); 844 PRINT_STATS_LE32(cck, early_overrun_err); 845 PRINT_STATS_LE32(cck, crc32_good); 846 PRINT_STATS_LE32(cck, false_alarm_cnt); 847 PRINT_STATS_LE32(cck, fina_sync_err_cnt); 848 PRINT_STATS_LE32(cck, sfd_timeout); 849 PRINT_STATS_LE32(cck, fina_timeout); 850 PRINT_STATS_LE32(cck, unresponded_rts); 851 PRINT_STATS_LE32(cck, rxe_frame_lmt_overrun); 852 PRINT_STATS_LE32(cck, sent_ack_cnt); 853 PRINT_STATS_LE32(cck, sent_cts_cnt); 854 PRINT_STATS_LE32(cck, sent_ba_rsp_cnt); 855 PRINT_STATS_LE32(cck, dsp_self_kill); 856 PRINT_STATS_LE32(cck, mh_format_err); 857 PRINT_STATS_LE32(cck, re_acq_main_rssi_sum); 858 PRINT_STATS_LE32(cck, reserved); 859 } else { 860 struct mvm_statistics_rx_phy *cck = &mvm->rx_stats.cck; 861 862 PRINT_STATS_LE32(cck, unresponded_rts); 863 PRINT_STATS_LE32(cck, rxe_frame_lmt_overrun); 864 PRINT_STATS_LE32(cck, sent_ba_rsp_cnt); 865 PRINT_STATS_LE32(cck, dsp_self_kill); 866 PRINT_STATS_LE32(cck, reserved); 867 } 868 869 pos += scnprintf(buf + pos, bufsz - pos, fmt_header, 870 "Statistics_Rx - GENERAL"); 871 if (!iwl_mvm_has_new_rx_stats_api(mvm)) { 872 struct mvm_statistics_rx_non_phy_v3 *general = 873 &mvm->rx_stats_v3.general; 874 875 PRINT_STATS_LE32(general, bogus_cts); 876 PRINT_STATS_LE32(general, bogus_ack); 877 PRINT_STATS_LE32(general, non_bssid_frames); 878 PRINT_STATS_LE32(general, filtered_frames); 879 PRINT_STATS_LE32(general, non_channel_beacons); 880 PRINT_STATS_LE32(general, channel_beacons); 881 PRINT_STATS_LE32(general, num_missed_bcon); 882 PRINT_STATS_LE32(general, adc_rx_saturation_time); 883 PRINT_STATS_LE32(general, ina_detection_search_time); 884 PRINT_STATS_LE32(general, beacon_silence_rssi_a); 885 PRINT_STATS_LE32(general, beacon_silence_rssi_b); 886 PRINT_STATS_LE32(general, beacon_silence_rssi_c); 887 PRINT_STATS_LE32(general, interference_data_flag); 888 PRINT_STATS_LE32(general, channel_load); 889 PRINT_STATS_LE32(general, dsp_false_alarms); 890 PRINT_STATS_LE32(general, beacon_rssi_a); 891 PRINT_STATS_LE32(general, beacon_rssi_b); 892 PRINT_STATS_LE32(general, beacon_rssi_c); 893 PRINT_STATS_LE32(general, beacon_energy_a); 894 PRINT_STATS_LE32(general, beacon_energy_b); 895 PRINT_STATS_LE32(general, beacon_energy_c); 896 PRINT_STATS_LE32(general, num_bt_kills); 897 PRINT_STATS_LE32(general, mac_id); 898 PRINT_STATS_LE32(general, directed_data_mpdu); 899 } else { 900 struct mvm_statistics_rx_non_phy *general = 901 &mvm->rx_stats.general; 902 903 PRINT_STATS_LE32(general, bogus_cts); 904 PRINT_STATS_LE32(general, bogus_ack); 905 PRINT_STATS_LE32(general, non_channel_beacons); 906 PRINT_STATS_LE32(general, channel_beacons); 907 PRINT_STATS_LE32(general, num_missed_bcon); 908 PRINT_STATS_LE32(general, adc_rx_saturation_time); 909 PRINT_STATS_LE32(general, ina_detection_search_time); 910 PRINT_STATS_LE32(general, beacon_silence_rssi_a); 911 PRINT_STATS_LE32(general, beacon_silence_rssi_b); 912 PRINT_STATS_LE32(general, beacon_silence_rssi_c); 913 PRINT_STATS_LE32(general, interference_data_flag); 914 PRINT_STATS_LE32(general, channel_load); 915 PRINT_STATS_LE32(general, beacon_rssi_a); 916 PRINT_STATS_LE32(general, beacon_rssi_b); 917 PRINT_STATS_LE32(general, beacon_rssi_c); 918 PRINT_STATS_LE32(general, beacon_energy_a); 919 PRINT_STATS_LE32(general, beacon_energy_b); 920 PRINT_STATS_LE32(general, beacon_energy_c); 921 PRINT_STATS_LE32(general, num_bt_kills); 922 PRINT_STATS_LE32(general, mac_id); 923 } 924 925 pos += scnprintf(buf + pos, bufsz - pos, fmt_header, 926 "Statistics_Rx - HT"); 927 if (!iwl_mvm_has_new_rx_stats_api(mvm)) { 928 struct mvm_statistics_rx_ht_phy_v1 *ht = 929 &mvm->rx_stats_v3.ofdm_ht; 930 931 PRINT_STATS_LE32(ht, plcp_err); 932 PRINT_STATS_LE32(ht, overrun_err); 933 PRINT_STATS_LE32(ht, early_overrun_err); 934 PRINT_STATS_LE32(ht, crc32_good); 935 PRINT_STATS_LE32(ht, crc32_err); 936 PRINT_STATS_LE32(ht, mh_format_err); 937 PRINT_STATS_LE32(ht, agg_crc32_good); 938 PRINT_STATS_LE32(ht, agg_mpdu_cnt); 939 PRINT_STATS_LE32(ht, agg_cnt); 940 PRINT_STATS_LE32(ht, unsupport_mcs); 941 } else { 942 struct mvm_statistics_rx_ht_phy *ht = 943 &mvm->rx_stats.ofdm_ht; 944 945 PRINT_STATS_LE32(ht, mh_format_err); 946 PRINT_STATS_LE32(ht, agg_mpdu_cnt); 947 PRINT_STATS_LE32(ht, agg_cnt); 948 PRINT_STATS_LE32(ht, unsupport_mcs); 949 } 950 951 mutex_unlock(&mvm->mutex); 952 953 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); 954 kfree(buf); 955 956 return ret; 957 } 958 #undef PRINT_STAT_LE32 959 960 static ssize_t iwl_dbgfs_frame_stats_read(struct iwl_mvm *mvm, 961 char __user *user_buf, size_t count, 962 loff_t *ppos, 963 struct iwl_mvm_frame_stats *stats) 964 { 965 char *buff, *pos, *endpos; 966 int idx, i; 967 int ret; 968 static const size_t bufsz = 1024; 969 970 buff = kmalloc(bufsz, GFP_KERNEL); 971 if (!buff) 972 return -ENOMEM; 973 974 spin_lock_bh(&mvm->drv_stats_lock); 975 976 pos = buff; 977 endpos = pos + bufsz; 978 979 pos += scnprintf(pos, endpos - pos, 980 "Legacy/HT/VHT\t:\t%d/%d/%d\n", 981 stats->legacy_frames, 982 stats->ht_frames, 983 stats->vht_frames); 984 pos += scnprintf(pos, endpos - pos, "20/40/80\t:\t%d/%d/%d\n", 985 stats->bw_20_frames, 986 stats->bw_40_frames, 987 stats->bw_80_frames); 988 pos += scnprintf(pos, endpos - pos, "NGI/SGI\t\t:\t%d/%d\n", 989 stats->ngi_frames, 990 stats->sgi_frames); 991 pos += scnprintf(pos, endpos - pos, "SISO/MIMO2\t:\t%d/%d\n", 992 stats->siso_frames, 993 stats->mimo2_frames); 994 pos += scnprintf(pos, endpos - pos, "FAIL/SCSS\t:\t%d/%d\n", 995 stats->fail_frames, 996 stats->success_frames); 997 pos += scnprintf(pos, endpos - pos, "MPDUs agg\t:\t%d\n", 998 stats->agg_frames); 999 pos += scnprintf(pos, endpos - pos, "A-MPDUs\t\t:\t%d\n", 1000 stats->ampdu_count); 1001 pos += scnprintf(pos, endpos - pos, "Avg MPDUs/A-MPDU:\t%d\n", 1002 stats->ampdu_count > 0 ? 1003 (stats->agg_frames / stats->ampdu_count) : 0); 1004 1005 pos += scnprintf(pos, endpos - pos, "Last Rates\n"); 1006 1007 idx = stats->last_frame_idx - 1; 1008 for (i = 0; i < ARRAY_SIZE(stats->last_rates); i++) { 1009 idx = (idx + 1) % ARRAY_SIZE(stats->last_rates); 1010 if (stats->last_rates[idx] == 0) 1011 continue; 1012 pos += scnprintf(pos, endpos - pos, "Rate[%d]: ", 1013 (int)(ARRAY_SIZE(stats->last_rates) - i)); 1014 pos += rs_pretty_print_rate(pos, endpos - pos, 1015 stats->last_rates[idx]); 1016 } 1017 spin_unlock_bh(&mvm->drv_stats_lock); 1018 1019 ret = simple_read_from_buffer(user_buf, count, ppos, buff, pos - buff); 1020 kfree(buff); 1021 1022 return ret; 1023 } 1024 1025 static ssize_t iwl_dbgfs_drv_rx_stats_read(struct file *file, 1026 char __user *user_buf, size_t count, 1027 loff_t *ppos) 1028 { 1029 struct iwl_mvm *mvm = file->private_data; 1030 1031 return iwl_dbgfs_frame_stats_read(mvm, user_buf, count, ppos, 1032 &mvm->drv_rx_stats); 1033 } 1034 1035 static ssize_t iwl_dbgfs_fw_restart_write(struct iwl_mvm *mvm, char *buf, 1036 size_t count, loff_t *ppos) 1037 { 1038 int __maybe_unused ret; 1039 1040 if (!iwl_mvm_firmware_running(mvm)) 1041 return -EIO; 1042 1043 mutex_lock(&mvm->mutex); 1044 1045 /* allow one more restart that we're provoking here */ 1046 if (mvm->fw_restart >= 0) 1047 mvm->fw_restart++; 1048 1049 /* take the return value to make compiler happy - it will fail anyway */ 1050 ret = iwl_mvm_send_cmd_pdu(mvm, REPLY_ERROR, 0, 0, NULL); 1051 1052 mutex_unlock(&mvm->mutex); 1053 1054 return count; 1055 } 1056 1057 static ssize_t iwl_dbgfs_fw_nmi_write(struct iwl_mvm *mvm, char *buf, 1058 size_t count, loff_t *ppos) 1059 { 1060 if (!iwl_mvm_firmware_running(mvm)) 1061 return -EIO; 1062 1063 iwl_force_nmi(mvm->trans); 1064 1065 return count; 1066 } 1067 1068 static ssize_t 1069 iwl_dbgfs_scan_ant_rxchain_read(struct file *file, 1070 char __user *user_buf, 1071 size_t count, loff_t *ppos) 1072 { 1073 struct iwl_mvm *mvm = file->private_data; 1074 int pos = 0; 1075 char buf[32]; 1076 const size_t bufsz = sizeof(buf); 1077 1078 /* print which antennas were set for the scan command by the user */ 1079 pos += scnprintf(buf + pos, bufsz - pos, "Antennas for scan: "); 1080 if (mvm->scan_rx_ant & ANT_A) 1081 pos += scnprintf(buf + pos, bufsz - pos, "A"); 1082 if (mvm->scan_rx_ant & ANT_B) 1083 pos += scnprintf(buf + pos, bufsz - pos, "B"); 1084 if (mvm->scan_rx_ant & ANT_C) 1085 pos += scnprintf(buf + pos, bufsz - pos, "C"); 1086 pos += scnprintf(buf + pos, bufsz - pos, " (%hhx)\n", mvm->scan_rx_ant); 1087 1088 return simple_read_from_buffer(user_buf, count, ppos, buf, pos); 1089 } 1090 1091 static ssize_t 1092 iwl_dbgfs_scan_ant_rxchain_write(struct iwl_mvm *mvm, char *buf, 1093 size_t count, loff_t *ppos) 1094 { 1095 u8 scan_rx_ant; 1096 1097 if (!iwl_mvm_firmware_running(mvm)) 1098 return -EIO; 1099 1100 if (sscanf(buf, "%hhx", &scan_rx_ant) != 1) 1101 return -EINVAL; 1102 if (scan_rx_ant > ANT_ABC) 1103 return -EINVAL; 1104 if (scan_rx_ant & ~(iwl_mvm_get_valid_rx_ant(mvm))) 1105 return -EINVAL; 1106 1107 if (mvm->scan_rx_ant != scan_rx_ant) { 1108 mvm->scan_rx_ant = scan_rx_ant; 1109 if (fw_has_capa(&mvm->fw->ucode_capa, 1110 IWL_UCODE_TLV_CAPA_UMAC_SCAN)) 1111 iwl_mvm_config_scan(mvm); 1112 } 1113 1114 return count; 1115 } 1116 1117 static ssize_t iwl_dbgfs_indirection_tbl_write(struct iwl_mvm *mvm, 1118 char *buf, size_t count, 1119 loff_t *ppos) 1120 { 1121 struct iwl_rss_config_cmd cmd = { 1122 .flags = cpu_to_le32(IWL_RSS_ENABLE), 1123 .hash_mask = IWL_RSS_HASH_TYPE_IPV4_TCP | 1124 IWL_RSS_HASH_TYPE_IPV4_UDP | 1125 IWL_RSS_HASH_TYPE_IPV4_PAYLOAD | 1126 IWL_RSS_HASH_TYPE_IPV6_TCP | 1127 IWL_RSS_HASH_TYPE_IPV6_UDP | 1128 IWL_RSS_HASH_TYPE_IPV6_PAYLOAD, 1129 }; 1130 int ret, i, num_repeats, nbytes = count / 2; 1131 1132 ret = hex2bin(cmd.indirection_table, buf, nbytes); 1133 if (ret) 1134 return ret; 1135 1136 /* 1137 * The input is the redirection table, partial or full. 1138 * Repeat the pattern if needed. 1139 * For example, input of 01020F will be repeated 42 times, 1140 * indirecting RSS hash results to queues 1, 2, 15 (skipping 1141 * queues 3 - 14). 1142 */ 1143 num_repeats = ARRAY_SIZE(cmd.indirection_table) / nbytes; 1144 for (i = 1; i < num_repeats; i++) 1145 memcpy(&cmd.indirection_table[i * nbytes], 1146 cmd.indirection_table, nbytes); 1147 /* handle cut in the middle pattern for the last places */ 1148 memcpy(&cmd.indirection_table[i * nbytes], cmd.indirection_table, 1149 ARRAY_SIZE(cmd.indirection_table) % nbytes); 1150 1151 netdev_rss_key_fill(cmd.secret_key, sizeof(cmd.secret_key)); 1152 1153 mutex_lock(&mvm->mutex); 1154 if (iwl_mvm_firmware_running(mvm)) 1155 ret = iwl_mvm_send_cmd_pdu(mvm, RSS_CONFIG_CMD, 0, 1156 sizeof(cmd), &cmd); 1157 else 1158 ret = 0; 1159 mutex_unlock(&mvm->mutex); 1160 1161 return ret ?: count; 1162 } 1163 1164 static ssize_t iwl_dbgfs_inject_packet_write(struct iwl_mvm *mvm, 1165 char *buf, size_t count, 1166 loff_t *ppos) 1167 { 1168 struct iwl_rx_cmd_buffer rxb = { 1169 ._rx_page_order = 0, 1170 .truesize = 0, /* not used */ 1171 ._offset = 0, 1172 }; 1173 struct iwl_rx_packet *pkt; 1174 struct iwl_rx_mpdu_desc *desc; 1175 int bin_len = count / 2; 1176 int ret = -EINVAL; 1177 size_t mpdu_cmd_hdr_size = (mvm->trans->trans_cfg->device_family >= 1178 IWL_DEVICE_FAMILY_AX210) ? 1179 sizeof(struct iwl_rx_mpdu_desc) : 1180 IWL_RX_DESC_SIZE_V1; 1181 1182 if (!iwl_mvm_firmware_running(mvm)) 1183 return -EIO; 1184 1185 /* supporting only 9000 descriptor */ 1186 if (!mvm->trans->trans_cfg->mq_rx_supported) 1187 return -ENOTSUPP; 1188 1189 rxb._page = alloc_pages(GFP_ATOMIC, 0); 1190 if (!rxb._page) 1191 return -ENOMEM; 1192 pkt = rxb_addr(&rxb); 1193 1194 ret = hex2bin(page_address(rxb._page), buf, bin_len); 1195 if (ret) 1196 goto out; 1197 1198 /* avoid invalid memory access */ 1199 if (bin_len < sizeof(*pkt) + mpdu_cmd_hdr_size) 1200 goto out; 1201 1202 /* check this is RX packet */ 1203 if (WIDE_ID(pkt->hdr.group_id, pkt->hdr.cmd) != 1204 WIDE_ID(LEGACY_GROUP, REPLY_RX_MPDU_CMD)) 1205 goto out; 1206 1207 /* check the length in metadata matches actual received length */ 1208 desc = (void *)pkt->data; 1209 if (le16_to_cpu(desc->mpdu_len) != 1210 (bin_len - mpdu_cmd_hdr_size - sizeof(*pkt))) 1211 goto out; 1212 1213 local_bh_disable(); 1214 iwl_mvm_rx_mpdu_mq(mvm, NULL, &rxb, 0); 1215 local_bh_enable(); 1216 ret = 0; 1217 1218 out: 1219 iwl_free_rxb(&rxb); 1220 1221 return ret ?: count; 1222 } 1223 1224 static int _iwl_dbgfs_inject_beacon_ie(struct iwl_mvm *mvm, char *bin, int len) 1225 { 1226 struct ieee80211_vif *vif; 1227 struct iwl_mvm_vif *mvmvif; 1228 struct sk_buff *beacon; 1229 struct ieee80211_tx_info *info; 1230 struct iwl_mac_beacon_cmd beacon_cmd = {}; 1231 u8 rate; 1232 u16 flags; 1233 int i; 1234 1235 len /= 2; 1236 1237 /* Element len should be represented by u8 */ 1238 if (len >= U8_MAX) 1239 return -EINVAL; 1240 1241 if (!iwl_mvm_firmware_running(mvm)) 1242 return -EIO; 1243 1244 if (!iwl_mvm_has_new_tx_api(mvm) && 1245 !fw_has_api(&mvm->fw->ucode_capa, 1246 IWL_UCODE_TLV_API_NEW_BEACON_TEMPLATE)) 1247 return -EINVAL; 1248 1249 rcu_read_lock(); 1250 1251 for (i = 0; i < NUM_MAC_INDEX_DRIVER; i++) { 1252 vif = iwl_mvm_rcu_dereference_vif_id(mvm, i, true); 1253 if (!vif) 1254 continue; 1255 1256 if (vif->type == NL80211_IFTYPE_AP) 1257 break; 1258 } 1259 1260 if (i == NUM_MAC_INDEX_DRIVER || !vif) 1261 goto out_err; 1262 1263 mvm->hw->extra_beacon_tailroom = len; 1264 1265 beacon = ieee80211_beacon_get_template(mvm->hw, vif, NULL); 1266 if (!beacon) 1267 goto out_err; 1268 1269 if (len && hex2bin(skb_put_zero(beacon, len), bin, len)) { 1270 dev_kfree_skb(beacon); 1271 goto out_err; 1272 } 1273 1274 mvm->beacon_inject_active = true; 1275 1276 mvmvif = iwl_mvm_vif_from_mac80211(vif); 1277 info = IEEE80211_SKB_CB(beacon); 1278 rate = iwl_mvm_mac_ctxt_get_lowest_rate(info, vif); 1279 flags = iwl_mvm_mac80211_idx_to_hwrate(rate); 1280 1281 if (rate == IWL_FIRST_CCK_RATE) 1282 flags |= IWL_MAC_BEACON_CCK; 1283 1284 beacon_cmd.flags = cpu_to_le16(flags); 1285 beacon_cmd.byte_cnt = cpu_to_le16((u16)beacon->len); 1286 beacon_cmd.template_id = cpu_to_le32((u32)mvmvif->id); 1287 1288 iwl_mvm_mac_ctxt_set_tim(mvm, &beacon_cmd.tim_idx, 1289 &beacon_cmd.tim_size, 1290 beacon->data, beacon->len); 1291 1292 mutex_lock(&mvm->mutex); 1293 iwl_mvm_mac_ctxt_send_beacon_cmd(mvm, beacon, &beacon_cmd, 1294 sizeof(beacon_cmd)); 1295 mutex_unlock(&mvm->mutex); 1296 1297 dev_kfree_skb(beacon); 1298 1299 rcu_read_unlock(); 1300 return 0; 1301 1302 out_err: 1303 rcu_read_unlock(); 1304 return -EINVAL; 1305 } 1306 1307 static ssize_t iwl_dbgfs_inject_beacon_ie_write(struct iwl_mvm *mvm, 1308 char *buf, size_t count, 1309 loff_t *ppos) 1310 { 1311 int ret = _iwl_dbgfs_inject_beacon_ie(mvm, buf, count); 1312 1313 mvm->hw->extra_beacon_tailroom = 0; 1314 return ret ?: count; 1315 } 1316 1317 static ssize_t iwl_dbgfs_inject_beacon_ie_restore_write(struct iwl_mvm *mvm, 1318 char *buf, 1319 size_t count, 1320 loff_t *ppos) 1321 { 1322 int ret = _iwl_dbgfs_inject_beacon_ie(mvm, NULL, 0); 1323 1324 mvm->hw->extra_beacon_tailroom = 0; 1325 mvm->beacon_inject_active = false; 1326 return ret ?: count; 1327 } 1328 1329 static ssize_t iwl_dbgfs_fw_dbg_conf_read(struct file *file, 1330 char __user *user_buf, 1331 size_t count, loff_t *ppos) 1332 { 1333 struct iwl_mvm *mvm = file->private_data; 1334 int conf; 1335 char buf[8]; 1336 const size_t bufsz = sizeof(buf); 1337 int pos = 0; 1338 1339 mutex_lock(&mvm->mutex); 1340 conf = mvm->fwrt.dump.conf; 1341 mutex_unlock(&mvm->mutex); 1342 1343 pos += scnprintf(buf + pos, bufsz - pos, "%d\n", conf); 1344 1345 return simple_read_from_buffer(user_buf, count, ppos, buf, pos); 1346 } 1347 1348 static ssize_t iwl_dbgfs_fw_dbg_conf_write(struct iwl_mvm *mvm, 1349 char *buf, size_t count, 1350 loff_t *ppos) 1351 { 1352 unsigned int conf_id; 1353 int ret; 1354 1355 if (!iwl_mvm_firmware_running(mvm)) 1356 return -EIO; 1357 1358 ret = kstrtouint(buf, 0, &conf_id); 1359 if (ret) 1360 return ret; 1361 1362 if (WARN_ON(conf_id >= FW_DBG_CONF_MAX)) 1363 return -EINVAL; 1364 1365 mutex_lock(&mvm->mutex); 1366 ret = iwl_fw_start_dbg_conf(&mvm->fwrt, conf_id); 1367 mutex_unlock(&mvm->mutex); 1368 1369 return ret ?: count; 1370 } 1371 1372 static ssize_t iwl_dbgfs_fw_dbg_collect_write(struct iwl_mvm *mvm, 1373 char *buf, size_t count, 1374 loff_t *ppos) 1375 { 1376 if (count == 0) 1377 return 0; 1378 1379 iwl_dbg_tlv_time_point(&mvm->fwrt, IWL_FW_INI_TIME_POINT_USER_TRIGGER, 1380 NULL); 1381 1382 iwl_fw_dbg_collect(&mvm->fwrt, FW_DBG_TRIGGER_USER, buf, 1383 (count - 1), NULL); 1384 1385 return count; 1386 } 1387 1388 #define ADD_TEXT(...) pos += scnprintf(buf + pos, bufsz - pos, __VA_ARGS__) 1389 #ifdef CONFIG_IWLWIFI_BCAST_FILTERING 1390 static ssize_t iwl_dbgfs_bcast_filters_read(struct file *file, 1391 char __user *user_buf, 1392 size_t count, loff_t *ppos) 1393 { 1394 struct iwl_mvm *mvm = file->private_data; 1395 struct iwl_bcast_filter_cmd cmd; 1396 const struct iwl_fw_bcast_filter *filter; 1397 char *buf; 1398 int bufsz = 1024; 1399 int i, j, pos = 0; 1400 ssize_t ret; 1401 1402 buf = kzalloc(bufsz, GFP_KERNEL); 1403 if (!buf) 1404 return -ENOMEM; 1405 1406 mutex_lock(&mvm->mutex); 1407 if (!iwl_mvm_bcast_filter_build_cmd(mvm, &cmd)) { 1408 ADD_TEXT("None\n"); 1409 mutex_unlock(&mvm->mutex); 1410 goto out; 1411 } 1412 mutex_unlock(&mvm->mutex); 1413 1414 for (i = 0; cmd.filters[i].attrs[0].mask; i++) { 1415 filter = &cmd.filters[i]; 1416 1417 ADD_TEXT("Filter [%d]:\n", i); 1418 ADD_TEXT("\tDiscard=%d\n", filter->discard); 1419 ADD_TEXT("\tFrame Type: %s\n", 1420 filter->frame_type ? "IPv4" : "Generic"); 1421 1422 for (j = 0; j < ARRAY_SIZE(filter->attrs); j++) { 1423 const struct iwl_fw_bcast_filter_attr *attr; 1424 1425 attr = &filter->attrs[j]; 1426 if (!attr->mask) 1427 break; 1428 1429 ADD_TEXT("\tAttr [%d]: offset=%d (from %s), mask=0x%x, value=0x%x reserved=0x%x\n", 1430 j, attr->offset, 1431 attr->offset_type ? "IP End" : 1432 "Payload Start", 1433 be32_to_cpu(attr->mask), 1434 be32_to_cpu(attr->val), 1435 le16_to_cpu(attr->reserved1)); 1436 } 1437 } 1438 out: 1439 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); 1440 kfree(buf); 1441 return ret; 1442 } 1443 1444 static ssize_t iwl_dbgfs_bcast_filters_write(struct iwl_mvm *mvm, char *buf, 1445 size_t count, loff_t *ppos) 1446 { 1447 int pos, next_pos; 1448 struct iwl_fw_bcast_filter filter = {}; 1449 struct iwl_bcast_filter_cmd cmd; 1450 u32 filter_id, attr_id, mask, value; 1451 int err = 0; 1452 1453 if (sscanf(buf, "%d %hhi %hhi %n", &filter_id, &filter.discard, 1454 &filter.frame_type, &pos) != 3) 1455 return -EINVAL; 1456 1457 if (filter_id >= ARRAY_SIZE(mvm->dbgfs_bcast_filtering.cmd.filters) || 1458 filter.frame_type > BCAST_FILTER_FRAME_TYPE_IPV4) 1459 return -EINVAL; 1460 1461 for (attr_id = 0; attr_id < ARRAY_SIZE(filter.attrs); 1462 attr_id++) { 1463 struct iwl_fw_bcast_filter_attr *attr = 1464 &filter.attrs[attr_id]; 1465 1466 if (pos >= count) 1467 break; 1468 1469 if (sscanf(&buf[pos], "%hhi %hhi %i %i %n", 1470 &attr->offset, &attr->offset_type, 1471 &mask, &value, &next_pos) != 4) 1472 return -EINVAL; 1473 1474 attr->mask = cpu_to_be32(mask); 1475 attr->val = cpu_to_be32(value); 1476 if (mask) 1477 filter.num_attrs++; 1478 1479 pos += next_pos; 1480 } 1481 1482 mutex_lock(&mvm->mutex); 1483 memcpy(&mvm->dbgfs_bcast_filtering.cmd.filters[filter_id], 1484 &filter, sizeof(filter)); 1485 1486 /* send updated bcast filtering configuration */ 1487 if (iwl_mvm_firmware_running(mvm) && 1488 mvm->dbgfs_bcast_filtering.override && 1489 iwl_mvm_bcast_filter_build_cmd(mvm, &cmd)) 1490 err = iwl_mvm_send_cmd_pdu(mvm, BCAST_FILTER_CMD, 0, 1491 sizeof(cmd), &cmd); 1492 mutex_unlock(&mvm->mutex); 1493 1494 return err ?: count; 1495 } 1496 1497 static ssize_t iwl_dbgfs_bcast_filters_macs_read(struct file *file, 1498 char __user *user_buf, 1499 size_t count, loff_t *ppos) 1500 { 1501 struct iwl_mvm *mvm = file->private_data; 1502 struct iwl_bcast_filter_cmd cmd; 1503 char *buf; 1504 int bufsz = 1024; 1505 int i, pos = 0; 1506 ssize_t ret; 1507 1508 buf = kzalloc(bufsz, GFP_KERNEL); 1509 if (!buf) 1510 return -ENOMEM; 1511 1512 mutex_lock(&mvm->mutex); 1513 if (!iwl_mvm_bcast_filter_build_cmd(mvm, &cmd)) { 1514 ADD_TEXT("None\n"); 1515 mutex_unlock(&mvm->mutex); 1516 goto out; 1517 } 1518 mutex_unlock(&mvm->mutex); 1519 1520 for (i = 0; i < ARRAY_SIZE(cmd.macs); i++) { 1521 const struct iwl_fw_bcast_mac *mac = &cmd.macs[i]; 1522 1523 ADD_TEXT("Mac [%d]: discard=%d attached_filters=0x%x\n", 1524 i, mac->default_discard, mac->attached_filters); 1525 } 1526 out: 1527 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); 1528 kfree(buf); 1529 return ret; 1530 } 1531 1532 static ssize_t iwl_dbgfs_bcast_filters_macs_write(struct iwl_mvm *mvm, 1533 char *buf, size_t count, 1534 loff_t *ppos) 1535 { 1536 struct iwl_bcast_filter_cmd cmd; 1537 struct iwl_fw_bcast_mac mac = {}; 1538 u32 mac_id, attached_filters; 1539 int err = 0; 1540 1541 if (!mvm->bcast_filters) 1542 return -ENOENT; 1543 1544 if (sscanf(buf, "%d %hhi %i", &mac_id, &mac.default_discard, 1545 &attached_filters) != 3) 1546 return -EINVAL; 1547 1548 if (mac_id >= ARRAY_SIZE(cmd.macs) || 1549 mac.default_discard > 1 || 1550 attached_filters >= BIT(ARRAY_SIZE(cmd.filters))) 1551 return -EINVAL; 1552 1553 mac.attached_filters = cpu_to_le16(attached_filters); 1554 1555 mutex_lock(&mvm->mutex); 1556 memcpy(&mvm->dbgfs_bcast_filtering.cmd.macs[mac_id], 1557 &mac, sizeof(mac)); 1558 1559 /* send updated bcast filtering configuration */ 1560 if (iwl_mvm_firmware_running(mvm) && 1561 mvm->dbgfs_bcast_filtering.override && 1562 iwl_mvm_bcast_filter_build_cmd(mvm, &cmd)) 1563 err = iwl_mvm_send_cmd_pdu(mvm, BCAST_FILTER_CMD, 0, 1564 sizeof(cmd), &cmd); 1565 mutex_unlock(&mvm->mutex); 1566 1567 return err ?: count; 1568 } 1569 #endif 1570 1571 #define MVM_DEBUGFS_WRITE_FILE_OPS(name, bufsz) \ 1572 _MVM_DEBUGFS_WRITE_FILE_OPS(name, bufsz, struct iwl_mvm) 1573 #define MVM_DEBUGFS_READ_WRITE_FILE_OPS(name, bufsz) \ 1574 _MVM_DEBUGFS_READ_WRITE_FILE_OPS(name, bufsz, struct iwl_mvm) 1575 #define MVM_DEBUGFS_ADD_FILE_ALIAS(alias, name, parent, mode) do { \ 1576 debugfs_create_file(alias, mode, parent, mvm, \ 1577 &iwl_dbgfs_##name##_ops); \ 1578 } while (0) 1579 #define MVM_DEBUGFS_ADD_FILE(name, parent, mode) \ 1580 MVM_DEBUGFS_ADD_FILE_ALIAS(#name, name, parent, mode) 1581 1582 #define MVM_DEBUGFS_WRITE_STA_FILE_OPS(name, bufsz) \ 1583 _MVM_DEBUGFS_WRITE_FILE_OPS(name, bufsz, struct ieee80211_sta) 1584 #define MVM_DEBUGFS_READ_WRITE_STA_FILE_OPS(name, bufsz) \ 1585 _MVM_DEBUGFS_READ_WRITE_FILE_OPS(name, bufsz, struct ieee80211_sta) 1586 1587 #define MVM_DEBUGFS_ADD_STA_FILE_ALIAS(alias, name, parent, mode) do { \ 1588 debugfs_create_file(alias, mode, parent, sta, \ 1589 &iwl_dbgfs_##name##_ops); \ 1590 } while (0) 1591 #define MVM_DEBUGFS_ADD_STA_FILE(name, parent, mode) \ 1592 MVM_DEBUGFS_ADD_STA_FILE_ALIAS(#name, name, parent, mode) 1593 1594 static ssize_t 1595 iwl_dbgfs_prph_reg_read(struct file *file, 1596 char __user *user_buf, 1597 size_t count, loff_t *ppos) 1598 { 1599 struct iwl_mvm *mvm = file->private_data; 1600 int pos = 0; 1601 char buf[32]; 1602 const size_t bufsz = sizeof(buf); 1603 1604 if (!mvm->dbgfs_prph_reg_addr) 1605 return -EINVAL; 1606 1607 pos += scnprintf(buf + pos, bufsz - pos, "Reg 0x%x: (0x%x)\n", 1608 mvm->dbgfs_prph_reg_addr, 1609 iwl_read_prph(mvm->trans, mvm->dbgfs_prph_reg_addr)); 1610 1611 return simple_read_from_buffer(user_buf, count, ppos, buf, pos); 1612 } 1613 1614 static ssize_t 1615 iwl_dbgfs_prph_reg_write(struct iwl_mvm *mvm, char *buf, 1616 size_t count, loff_t *ppos) 1617 { 1618 u8 args; 1619 u32 value; 1620 1621 args = sscanf(buf, "%i %i", &mvm->dbgfs_prph_reg_addr, &value); 1622 /* if we only want to set the reg address - nothing more to do */ 1623 if (args == 1) 1624 goto out; 1625 1626 /* otherwise, make sure we have both address and value */ 1627 if (args != 2) 1628 return -EINVAL; 1629 1630 iwl_write_prph(mvm->trans, mvm->dbgfs_prph_reg_addr, value); 1631 1632 out: 1633 return count; 1634 } 1635 1636 static ssize_t 1637 iwl_dbgfs_send_echo_cmd_write(struct iwl_mvm *mvm, char *buf, 1638 size_t count, loff_t *ppos) 1639 { 1640 int ret; 1641 1642 if (!iwl_mvm_firmware_running(mvm)) 1643 return -EIO; 1644 1645 mutex_lock(&mvm->mutex); 1646 ret = iwl_mvm_send_cmd_pdu(mvm, ECHO_CMD, 0, 0, NULL); 1647 mutex_unlock(&mvm->mutex); 1648 1649 return ret ?: count; 1650 } 1651 1652 struct iwl_mvm_sniffer_apply { 1653 struct iwl_mvm *mvm; 1654 u8 *bssid; 1655 u16 aid; 1656 }; 1657 1658 static bool iwl_mvm_sniffer_apply(struct iwl_notif_wait_data *notif_data, 1659 struct iwl_rx_packet *pkt, void *data) 1660 { 1661 struct iwl_mvm_sniffer_apply *apply = data; 1662 1663 apply->mvm->cur_aid = cpu_to_le16(apply->aid); 1664 memcpy(apply->mvm->cur_bssid, apply->bssid, 1665 sizeof(apply->mvm->cur_bssid)); 1666 1667 return true; 1668 } 1669 1670 static ssize_t 1671 iwl_dbgfs_he_sniffer_params_write(struct iwl_mvm *mvm, char *buf, 1672 size_t count, loff_t *ppos) 1673 { 1674 struct iwl_notification_wait wait; 1675 struct iwl_he_monitor_cmd he_mon_cmd = {}; 1676 struct iwl_mvm_sniffer_apply apply = { 1677 .mvm = mvm, 1678 }; 1679 u16 wait_cmds[] = { 1680 iwl_cmd_id(HE_AIR_SNIFFER_CONFIG_CMD, DATA_PATH_GROUP, 0), 1681 }; 1682 u32 aid; 1683 int ret; 1684 1685 if (!iwl_mvm_firmware_running(mvm)) 1686 return -EIO; 1687 1688 ret = sscanf(buf, "%x %2hhx:%2hhx:%2hhx:%2hhx:%2hhx:%2hhx", &aid, 1689 &he_mon_cmd.bssid[0], &he_mon_cmd.bssid[1], 1690 &he_mon_cmd.bssid[2], &he_mon_cmd.bssid[3], 1691 &he_mon_cmd.bssid[4], &he_mon_cmd.bssid[5]); 1692 if (ret != 7) 1693 return -EINVAL; 1694 1695 he_mon_cmd.aid = cpu_to_le16(aid); 1696 1697 apply.aid = aid; 1698 apply.bssid = (void *)he_mon_cmd.bssid; 1699 1700 mutex_lock(&mvm->mutex); 1701 1702 /* 1703 * Use the notification waiter to get our function triggered 1704 * in sequence with other RX. This ensures that frames we get 1705 * on the RX queue _before_ the new configuration is applied 1706 * still have mvm->cur_aid pointing to the old AID, and that 1707 * frames on the RX queue _after_ the firmware processed the 1708 * new configuration (and sent the response, synchronously) 1709 * get mvm->cur_aid correctly set to the new AID. 1710 */ 1711 iwl_init_notification_wait(&mvm->notif_wait, &wait, 1712 wait_cmds, ARRAY_SIZE(wait_cmds), 1713 iwl_mvm_sniffer_apply, &apply); 1714 1715 ret = iwl_mvm_send_cmd_pdu(mvm, iwl_cmd_id(HE_AIR_SNIFFER_CONFIG_CMD, 1716 DATA_PATH_GROUP, 0), 0, 1717 sizeof(he_mon_cmd), &he_mon_cmd); 1718 1719 /* no need to really wait, we already did anyway */ 1720 iwl_remove_notification(&mvm->notif_wait, &wait); 1721 1722 mutex_unlock(&mvm->mutex); 1723 1724 return ret ?: count; 1725 } 1726 1727 static ssize_t 1728 iwl_dbgfs_he_sniffer_params_read(struct file *file, char __user *user_buf, 1729 size_t count, loff_t *ppos) 1730 { 1731 struct iwl_mvm *mvm = file->private_data; 1732 u8 buf[32]; 1733 int len; 1734 1735 len = scnprintf(buf, sizeof(buf), 1736 "%d %02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx\n", 1737 le16_to_cpu(mvm->cur_aid), mvm->cur_bssid[0], 1738 mvm->cur_bssid[1], mvm->cur_bssid[2], mvm->cur_bssid[3], 1739 mvm->cur_bssid[4], mvm->cur_bssid[5]); 1740 1741 return simple_read_from_buffer(user_buf, count, ppos, buf, len); 1742 } 1743 1744 static ssize_t 1745 iwl_dbgfs_uapsd_noagg_bssids_read(struct file *file, char __user *user_buf, 1746 size_t count, loff_t *ppos) 1747 { 1748 struct iwl_mvm *mvm = file->private_data; 1749 u8 buf[IWL_MVM_UAPSD_NOAGG_BSSIDS_NUM * ETH_ALEN * 3 + 1]; 1750 unsigned int pos = 0; 1751 size_t bufsz = sizeof(buf); 1752 int i; 1753 1754 mutex_lock(&mvm->mutex); 1755 1756 for (i = 0; i < IWL_MVM_UAPSD_NOAGG_LIST_LEN; i++) 1757 pos += scnprintf(buf + pos, bufsz - pos, "%pM\n", 1758 mvm->uapsd_noagg_bssids[i].addr); 1759 1760 mutex_unlock(&mvm->mutex); 1761 1762 return simple_read_from_buffer(user_buf, count, ppos, buf, pos); 1763 } 1764 1765 static ssize_t 1766 iwl_dbgfs_ltr_config_write(struct iwl_mvm *mvm, 1767 char *buf, size_t count, loff_t *ppos) 1768 { 1769 int ret; 1770 struct iwl_ltr_config_cmd ltr_config = {0}; 1771 1772 if (!iwl_mvm_firmware_running(mvm)) 1773 return -EIO; 1774 1775 if (sscanf(buf, "%x,%x,%x,%x,%x,%x,%x", 1776 <r_config.flags, 1777 <r_config.static_long, 1778 <r_config.static_short, 1779 <r_config.ltr_cfg_values[0], 1780 <r_config.ltr_cfg_values[1], 1781 <r_config.ltr_cfg_values[2], 1782 <r_config.ltr_cfg_values[3]) != 7) { 1783 return -EINVAL; 1784 } 1785 1786 mutex_lock(&mvm->mutex); 1787 ret = iwl_mvm_send_cmd_pdu(mvm, LTR_CONFIG, 0, sizeof(ltr_config), 1788 <r_config); 1789 mutex_unlock(&mvm->mutex); 1790 1791 if (ret) 1792 IWL_ERR(mvm, "failed to send ltr configuration cmd\n"); 1793 1794 return ret ?: count; 1795 } 1796 1797 MVM_DEBUGFS_READ_WRITE_FILE_OPS(prph_reg, 64); 1798 1799 /* Device wide debugfs entries */ 1800 MVM_DEBUGFS_READ_FILE_OPS(ctdp_budget); 1801 MVM_DEBUGFS_WRITE_FILE_OPS(stop_ctdp, 8); 1802 MVM_DEBUGFS_WRITE_FILE_OPS(force_ctkill, 8); 1803 MVM_DEBUGFS_WRITE_FILE_OPS(tx_flush, 16); 1804 MVM_DEBUGFS_WRITE_FILE_OPS(sta_drain, 8); 1805 MVM_DEBUGFS_WRITE_FILE_OPS(send_echo_cmd, 8); 1806 MVM_DEBUGFS_READ_WRITE_FILE_OPS(sram, 64); 1807 MVM_DEBUGFS_READ_WRITE_FILE_OPS(set_nic_temperature, 64); 1808 MVM_DEBUGFS_READ_FILE_OPS(nic_temp); 1809 MVM_DEBUGFS_READ_FILE_OPS(stations); 1810 MVM_DEBUGFS_READ_FILE_OPS(rs_data); 1811 MVM_DEBUGFS_READ_FILE_OPS(bt_notif); 1812 MVM_DEBUGFS_READ_FILE_OPS(bt_cmd); 1813 MVM_DEBUGFS_READ_WRITE_FILE_OPS(disable_power_off, 64); 1814 MVM_DEBUGFS_READ_FILE_OPS(fw_rx_stats); 1815 MVM_DEBUGFS_READ_FILE_OPS(drv_rx_stats); 1816 MVM_DEBUGFS_READ_FILE_OPS(fw_ver); 1817 MVM_DEBUGFS_WRITE_FILE_OPS(fw_restart, 10); 1818 MVM_DEBUGFS_WRITE_FILE_OPS(fw_nmi, 10); 1819 MVM_DEBUGFS_WRITE_FILE_OPS(bt_tx_prio, 10); 1820 MVM_DEBUGFS_WRITE_FILE_OPS(bt_force_ant, 10); 1821 MVM_DEBUGFS_READ_WRITE_FILE_OPS(scan_ant_rxchain, 8); 1822 MVM_DEBUGFS_READ_WRITE_FILE_OPS(fw_dbg_conf, 8); 1823 MVM_DEBUGFS_WRITE_FILE_OPS(fw_dbg_collect, 64); 1824 MVM_DEBUGFS_WRITE_FILE_OPS(indirection_tbl, 1825 (IWL_RSS_INDIRECTION_TABLE_SIZE * 2)); 1826 MVM_DEBUGFS_WRITE_FILE_OPS(inject_packet, 512); 1827 MVM_DEBUGFS_WRITE_FILE_OPS(inject_beacon_ie, 512); 1828 MVM_DEBUGFS_WRITE_FILE_OPS(inject_beacon_ie_restore, 512); 1829 1830 MVM_DEBUGFS_READ_FILE_OPS(uapsd_noagg_bssids); 1831 1832 #ifdef CONFIG_IWLWIFI_BCAST_FILTERING 1833 MVM_DEBUGFS_READ_WRITE_FILE_OPS(bcast_filters, 256); 1834 MVM_DEBUGFS_READ_WRITE_FILE_OPS(bcast_filters_macs, 256); 1835 #endif 1836 1837 #ifdef CONFIG_ACPI 1838 MVM_DEBUGFS_READ_FILE_OPS(sar_geo_profile); 1839 #endif 1840 1841 MVM_DEBUGFS_READ_WRITE_STA_FILE_OPS(amsdu_len, 16); 1842 1843 MVM_DEBUGFS_READ_WRITE_FILE_OPS(he_sniffer_params, 32); 1844 1845 MVM_DEBUGFS_WRITE_FILE_OPS(ltr_config, 512); 1846 1847 static ssize_t iwl_dbgfs_mem_read(struct file *file, char __user *user_buf, 1848 size_t count, loff_t *ppos) 1849 { 1850 struct iwl_mvm *mvm = file->private_data; 1851 struct iwl_dbg_mem_access_cmd cmd = {}; 1852 struct iwl_dbg_mem_access_rsp *rsp; 1853 struct iwl_host_cmd hcmd = { 1854 .flags = CMD_WANT_SKB | CMD_SEND_IN_RFKILL, 1855 .data = { &cmd, }, 1856 .len = { sizeof(cmd) }, 1857 }; 1858 size_t delta; 1859 ssize_t ret, len; 1860 1861 if (!iwl_mvm_firmware_running(mvm)) 1862 return -EIO; 1863 1864 hcmd.id = iwl_cmd_id(*ppos >> 24 ? UMAC_RD_WR : LMAC_RD_WR, 1865 DEBUG_GROUP, 0); 1866 cmd.op = cpu_to_le32(DEBUG_MEM_OP_READ); 1867 1868 /* Take care of alignment of both the position and the length */ 1869 delta = *ppos & 0x3; 1870 cmd.addr = cpu_to_le32(*ppos - delta); 1871 cmd.len = cpu_to_le32(min(ALIGN(count + delta, 4) / 4, 1872 (size_t)DEBUG_MEM_MAX_SIZE_DWORDS)); 1873 1874 mutex_lock(&mvm->mutex); 1875 ret = iwl_mvm_send_cmd(mvm, &hcmd); 1876 mutex_unlock(&mvm->mutex); 1877 1878 if (ret < 0) 1879 return ret; 1880 1881 rsp = (void *)hcmd.resp_pkt->data; 1882 if (le32_to_cpu(rsp->status) != DEBUG_MEM_STATUS_SUCCESS) { 1883 ret = -ENXIO; 1884 goto out; 1885 } 1886 1887 len = min((size_t)le32_to_cpu(rsp->len) << 2, 1888 iwl_rx_packet_payload_len(hcmd.resp_pkt) - sizeof(*rsp)); 1889 len = min(len - delta, count); 1890 if (len < 0) { 1891 ret = -EFAULT; 1892 goto out; 1893 } 1894 1895 ret = len - copy_to_user(user_buf, (void *)rsp->data + delta, len); 1896 *ppos += ret; 1897 1898 out: 1899 iwl_free_resp(&hcmd); 1900 return ret; 1901 } 1902 1903 static ssize_t iwl_dbgfs_mem_write(struct file *file, 1904 const char __user *user_buf, size_t count, 1905 loff_t *ppos) 1906 { 1907 struct iwl_mvm *mvm = file->private_data; 1908 struct iwl_dbg_mem_access_cmd *cmd; 1909 struct iwl_dbg_mem_access_rsp *rsp; 1910 struct iwl_host_cmd hcmd = {}; 1911 size_t cmd_size; 1912 size_t data_size; 1913 u32 op, len; 1914 ssize_t ret; 1915 1916 if (!iwl_mvm_firmware_running(mvm)) 1917 return -EIO; 1918 1919 hcmd.id = iwl_cmd_id(*ppos >> 24 ? UMAC_RD_WR : LMAC_RD_WR, 1920 DEBUG_GROUP, 0); 1921 1922 if (*ppos & 0x3 || count < 4) { 1923 op = DEBUG_MEM_OP_WRITE_BYTES; 1924 len = min(count, (size_t)(4 - (*ppos & 0x3))); 1925 data_size = len; 1926 } else { 1927 op = DEBUG_MEM_OP_WRITE; 1928 len = min(count >> 2, (size_t)DEBUG_MEM_MAX_SIZE_DWORDS); 1929 data_size = len << 2; 1930 } 1931 1932 cmd_size = sizeof(*cmd) + ALIGN(data_size, 4); 1933 cmd = kzalloc(cmd_size, GFP_KERNEL); 1934 if (!cmd) 1935 return -ENOMEM; 1936 1937 cmd->op = cpu_to_le32(op); 1938 cmd->len = cpu_to_le32(len); 1939 cmd->addr = cpu_to_le32(*ppos); 1940 if (copy_from_user((void *)cmd->data, user_buf, data_size)) { 1941 kfree(cmd); 1942 return -EFAULT; 1943 } 1944 1945 hcmd.flags = CMD_WANT_SKB | CMD_SEND_IN_RFKILL, 1946 hcmd.data[0] = (void *)cmd; 1947 hcmd.len[0] = cmd_size; 1948 1949 mutex_lock(&mvm->mutex); 1950 ret = iwl_mvm_send_cmd(mvm, &hcmd); 1951 mutex_unlock(&mvm->mutex); 1952 1953 kfree(cmd); 1954 1955 if (ret < 0) 1956 return ret; 1957 1958 rsp = (void *)hcmd.resp_pkt->data; 1959 if (rsp->status != DEBUG_MEM_STATUS_SUCCESS) { 1960 ret = -ENXIO; 1961 goto out; 1962 } 1963 1964 ret = data_size; 1965 *ppos += ret; 1966 1967 out: 1968 iwl_free_resp(&hcmd); 1969 return ret; 1970 } 1971 1972 static const struct file_operations iwl_dbgfs_mem_ops = { 1973 .read = iwl_dbgfs_mem_read, 1974 .write = iwl_dbgfs_mem_write, 1975 .open = simple_open, 1976 .llseek = default_llseek, 1977 }; 1978 1979 void iwl_mvm_sta_add_debugfs(struct ieee80211_hw *hw, 1980 struct ieee80211_vif *vif, 1981 struct ieee80211_sta *sta, 1982 struct dentry *dir) 1983 { 1984 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); 1985 1986 if (iwl_mvm_has_tlc_offload(mvm)) { 1987 MVM_DEBUGFS_ADD_STA_FILE(rs_data, dir, 0400); 1988 } 1989 MVM_DEBUGFS_ADD_STA_FILE(amsdu_len, dir, 0600); 1990 } 1991 1992 void iwl_mvm_dbgfs_register(struct iwl_mvm *mvm, struct dentry *dbgfs_dir) 1993 { 1994 struct dentry *bcast_dir __maybe_unused; 1995 char buf[100]; 1996 1997 spin_lock_init(&mvm->drv_stats_lock); 1998 1999 mvm->debugfs_dir = dbgfs_dir; 2000 2001 MVM_DEBUGFS_ADD_FILE(tx_flush, mvm->debugfs_dir, 0200); 2002 MVM_DEBUGFS_ADD_FILE(sta_drain, mvm->debugfs_dir, 0200); 2003 MVM_DEBUGFS_ADD_FILE(sram, mvm->debugfs_dir, 0600); 2004 MVM_DEBUGFS_ADD_FILE(set_nic_temperature, mvm->debugfs_dir, 0600); 2005 MVM_DEBUGFS_ADD_FILE(nic_temp, dbgfs_dir, 0400); 2006 MVM_DEBUGFS_ADD_FILE(ctdp_budget, dbgfs_dir, 0400); 2007 MVM_DEBUGFS_ADD_FILE(stop_ctdp, dbgfs_dir, 0200); 2008 MVM_DEBUGFS_ADD_FILE(force_ctkill, dbgfs_dir, 0200); 2009 MVM_DEBUGFS_ADD_FILE(stations, dbgfs_dir, 0400); 2010 MVM_DEBUGFS_ADD_FILE(bt_notif, dbgfs_dir, 0400); 2011 MVM_DEBUGFS_ADD_FILE(bt_cmd, dbgfs_dir, 0400); 2012 MVM_DEBUGFS_ADD_FILE(disable_power_off, mvm->debugfs_dir, 0600); 2013 MVM_DEBUGFS_ADD_FILE(fw_ver, mvm->debugfs_dir, 0400); 2014 MVM_DEBUGFS_ADD_FILE(fw_rx_stats, mvm->debugfs_dir, 0400); 2015 MVM_DEBUGFS_ADD_FILE(drv_rx_stats, mvm->debugfs_dir, 0400); 2016 MVM_DEBUGFS_ADD_FILE(fw_restart, mvm->debugfs_dir, 0200); 2017 MVM_DEBUGFS_ADD_FILE(fw_nmi, mvm->debugfs_dir, 0200); 2018 MVM_DEBUGFS_ADD_FILE(bt_tx_prio, mvm->debugfs_dir, 0200); 2019 MVM_DEBUGFS_ADD_FILE(bt_force_ant, mvm->debugfs_dir, 0200); 2020 MVM_DEBUGFS_ADD_FILE(scan_ant_rxchain, mvm->debugfs_dir, 0600); 2021 MVM_DEBUGFS_ADD_FILE(prph_reg, mvm->debugfs_dir, 0600); 2022 MVM_DEBUGFS_ADD_FILE(fw_dbg_conf, mvm->debugfs_dir, 0600); 2023 MVM_DEBUGFS_ADD_FILE(fw_dbg_collect, mvm->debugfs_dir, 0200); 2024 MVM_DEBUGFS_ADD_FILE(send_echo_cmd, mvm->debugfs_dir, 0200); 2025 MVM_DEBUGFS_ADD_FILE(indirection_tbl, mvm->debugfs_dir, 0200); 2026 MVM_DEBUGFS_ADD_FILE(inject_packet, mvm->debugfs_dir, 0200); 2027 MVM_DEBUGFS_ADD_FILE(inject_beacon_ie, mvm->debugfs_dir, 0200); 2028 MVM_DEBUGFS_ADD_FILE(inject_beacon_ie_restore, mvm->debugfs_dir, 0200); 2029 #ifdef CONFIG_ACPI 2030 MVM_DEBUGFS_ADD_FILE(sar_geo_profile, dbgfs_dir, 0400); 2031 #endif 2032 MVM_DEBUGFS_ADD_FILE(he_sniffer_params, mvm->debugfs_dir, 0600); 2033 2034 if (fw_has_capa(&mvm->fw->ucode_capa, IWL_UCODE_TLV_CAPA_SET_LTR_GEN2)) 2035 MVM_DEBUGFS_ADD_FILE(ltr_config, mvm->debugfs_dir, 0200); 2036 2037 debugfs_create_bool("enable_scan_iteration_notif", 0600, 2038 mvm->debugfs_dir, &mvm->scan_iter_notif_enabled); 2039 debugfs_create_bool("drop_bcn_ap_mode", 0600, mvm->debugfs_dir, 2040 &mvm->drop_bcn_ap_mode); 2041 2042 MVM_DEBUGFS_ADD_FILE(uapsd_noagg_bssids, mvm->debugfs_dir, S_IRUSR); 2043 2044 #ifdef CONFIG_IWLWIFI_BCAST_FILTERING 2045 if (mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_BCAST_FILTERING) { 2046 bcast_dir = debugfs_create_dir("bcast_filtering", 2047 mvm->debugfs_dir); 2048 2049 debugfs_create_bool("override", 0600, bcast_dir, 2050 &mvm->dbgfs_bcast_filtering.override); 2051 2052 MVM_DEBUGFS_ADD_FILE_ALIAS("filters", bcast_filters, 2053 bcast_dir, 0600); 2054 MVM_DEBUGFS_ADD_FILE_ALIAS("macs", bcast_filters_macs, 2055 bcast_dir, 0600); 2056 } 2057 #endif 2058 2059 #ifdef CONFIG_PM_SLEEP 2060 MVM_DEBUGFS_ADD_FILE(d3_test, mvm->debugfs_dir, 0400); 2061 debugfs_create_bool("d3_wake_sysassert", 0600, mvm->debugfs_dir, 2062 &mvm->d3_wake_sysassert); 2063 debugfs_create_u32("last_netdetect_scans", 0400, mvm->debugfs_dir, 2064 &mvm->last_netdetect_scans); 2065 #endif 2066 2067 debugfs_create_u8("ps_disabled", 0400, mvm->debugfs_dir, 2068 &mvm->ps_disabled); 2069 debugfs_create_blob("nvm_hw", 0400, mvm->debugfs_dir, 2070 &mvm->nvm_hw_blob); 2071 debugfs_create_blob("nvm_sw", 0400, mvm->debugfs_dir, 2072 &mvm->nvm_sw_blob); 2073 debugfs_create_blob("nvm_calib", 0400, mvm->debugfs_dir, 2074 &mvm->nvm_calib_blob); 2075 debugfs_create_blob("nvm_prod", 0400, mvm->debugfs_dir, 2076 &mvm->nvm_prod_blob); 2077 debugfs_create_blob("nvm_phy_sku", 0400, mvm->debugfs_dir, 2078 &mvm->nvm_phy_sku_blob); 2079 debugfs_create_blob("nvm_reg", S_IRUSR, 2080 mvm->debugfs_dir, &mvm->nvm_reg_blob); 2081 2082 debugfs_create_file("mem", 0600, dbgfs_dir, mvm, &iwl_dbgfs_mem_ops); 2083 2084 /* 2085 * Create a symlink with mac80211. It will be removed when mac80211 2086 * exists (before the opmode exists which removes the target.) 2087 */ 2088 snprintf(buf, 100, "../../%pd2", dbgfs_dir->d_parent); 2089 debugfs_create_symlink("iwlwifi", mvm->hw->wiphy->debugfsdir, buf); 2090 } 2091