iwl-debugfs.c revision 898ed67be047d0762cc7592f67bf1313dff53ca9
1/****************************************************************************** 2 * 3 * GPL LICENSE SUMMARY 4 * 5 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved. 6 * 7 * This program is free software; you can redistribute it and/or modify 8 * it under the terms of version 2 of the GNU General Public License as 9 * published by the Free Software Foundation. 10 * 11 * This program is distributed in the hope that it will be useful, but 12 * WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 * General Public License for more details. 15 * 16 * You should have received a copy of the GNU General Public License 17 * along with this program; if not, write to the Free Software 18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, 19 * USA 20 * 21 * The full GNU General Public License is included in this distribution 22 * in the file called LICENSE.GPL. 23 * 24 * Contact Information: 25 * Intel Linux Wireless <ilw@linux.intel.com> 26 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 27 *****************************************************************************/ 28 29#include <linux/slab.h> 30#include <linux/kernel.h> 31#include <linux/module.h> 32#include <linux/debugfs.h> 33 34#include <linux/ieee80211.h> 35#include <net/mac80211.h> 36 37 38#include "iwl-dev.h" 39#include "iwl-debug.h" 40#include "iwl-core.h" 41#include "iwl-io.h" 42#include "iwl-agn.h" 43 44/* create and remove of files */ 45#define DEBUGFS_ADD_FILE(name, parent, mode) do { \ 46 if (!debugfs_create_file(#name, mode, parent, priv, \ 47 &iwl_dbgfs_##name##_ops)) \ 48 goto err; \ 49} while (0) 50 51#define DEBUGFS_ADD_BOOL(name, parent, ptr) do { \ 52 struct dentry *__tmp; \ 53 __tmp = debugfs_create_bool(#name, S_IWUSR | S_IRUSR, \ 54 parent, ptr); \ 55 if (IS_ERR(__tmp) || !__tmp) \ 56 goto err; \ 57} while (0) 58 59#define DEBUGFS_ADD_X32(name, parent, ptr) do { \ 60 struct dentry *__tmp; \ 61 __tmp = debugfs_create_x32(#name, S_IWUSR | S_IRUSR, \ 62 parent, ptr); \ 63 if (IS_ERR(__tmp) || !__tmp) \ 64 goto err; \ 65} while (0) 66 67/* file operation */ 68#define DEBUGFS_READ_FUNC(name) \ 69static ssize_t iwl_dbgfs_##name##_read(struct file *file, \ 70 char __user *user_buf, \ 71 size_t count, loff_t *ppos); 72 73#define DEBUGFS_WRITE_FUNC(name) \ 74static ssize_t iwl_dbgfs_##name##_write(struct file *file, \ 75 const char __user *user_buf, \ 76 size_t count, loff_t *ppos); 77 78 79static int iwl_dbgfs_open_file_generic(struct inode *inode, struct file *file) 80{ 81 file->private_data = inode->i_private; 82 return 0; 83} 84 85#define DEBUGFS_READ_FILE_OPS(name) \ 86 DEBUGFS_READ_FUNC(name); \ 87static const struct file_operations iwl_dbgfs_##name##_ops = { \ 88 .read = iwl_dbgfs_##name##_read, \ 89 .open = iwl_dbgfs_open_file_generic, \ 90 .llseek = generic_file_llseek, \ 91}; 92 93#define DEBUGFS_WRITE_FILE_OPS(name) \ 94 DEBUGFS_WRITE_FUNC(name); \ 95static const struct file_operations iwl_dbgfs_##name##_ops = { \ 96 .write = iwl_dbgfs_##name##_write, \ 97 .open = iwl_dbgfs_open_file_generic, \ 98 .llseek = generic_file_llseek, \ 99}; 100 101 102#define DEBUGFS_READ_WRITE_FILE_OPS(name) \ 103 DEBUGFS_READ_FUNC(name); \ 104 DEBUGFS_WRITE_FUNC(name); \ 105static const struct file_operations iwl_dbgfs_##name##_ops = { \ 106 .write = iwl_dbgfs_##name##_write, \ 107 .read = iwl_dbgfs_##name##_read, \ 108 .open = iwl_dbgfs_open_file_generic, \ 109 .llseek = generic_file_llseek, \ 110}; 111 112static ssize_t iwl_dbgfs_tx_statistics_read(struct file *file, 113 char __user *user_buf, 114 size_t count, loff_t *ppos) { 115 116 struct iwl_priv *priv = file->private_data; 117 char *buf; 118 int pos = 0; 119 120 int cnt; 121 ssize_t ret; 122 const size_t bufsz = 100 + 123 sizeof(char) * 50 * (MANAGEMENT_MAX + CONTROL_MAX); 124 buf = kzalloc(bufsz, GFP_KERNEL); 125 if (!buf) 126 return -ENOMEM; 127 pos += scnprintf(buf + pos, bufsz - pos, "Management:\n"); 128 for (cnt = 0; cnt < MANAGEMENT_MAX; cnt++) { 129 pos += scnprintf(buf + pos, bufsz - pos, 130 "\t%25s\t\t: %u\n", 131 get_mgmt_string(cnt), 132 priv->tx_stats.mgmt[cnt]); 133 } 134 pos += scnprintf(buf + pos, bufsz - pos, "Control\n"); 135 for (cnt = 0; cnt < CONTROL_MAX; cnt++) { 136 pos += scnprintf(buf + pos, bufsz - pos, 137 "\t%25s\t\t: %u\n", 138 get_ctrl_string(cnt), 139 priv->tx_stats.ctrl[cnt]); 140 } 141 pos += scnprintf(buf + pos, bufsz - pos, "Data:\n"); 142 pos += scnprintf(buf + pos, bufsz - pos, "\tcnt: %u\n", 143 priv->tx_stats.data_cnt); 144 pos += scnprintf(buf + pos, bufsz - pos, "\tbytes: %llu\n", 145 priv->tx_stats.data_bytes); 146 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); 147 kfree(buf); 148 return ret; 149} 150 151static ssize_t iwl_dbgfs_clear_traffic_statistics_write(struct file *file, 152 const char __user *user_buf, 153 size_t count, loff_t *ppos) 154{ 155 struct iwl_priv *priv = file->private_data; 156 u32 clear_flag; 157 char buf[8]; 158 int buf_size; 159 160 memset(buf, 0, sizeof(buf)); 161 buf_size = min(count, sizeof(buf) - 1); 162 if (copy_from_user(buf, user_buf, buf_size)) 163 return -EFAULT; 164 if (sscanf(buf, "%x", &clear_flag) != 1) 165 return -EFAULT; 166 iwl_clear_traffic_stats(priv); 167 168 return count; 169} 170 171static ssize_t iwl_dbgfs_rx_statistics_read(struct file *file, 172 char __user *user_buf, 173 size_t count, loff_t *ppos) { 174 175 struct iwl_priv *priv = file->private_data; 176 char *buf; 177 int pos = 0; 178 int cnt; 179 ssize_t ret; 180 const size_t bufsz = 100 + 181 sizeof(char) * 50 * (MANAGEMENT_MAX + CONTROL_MAX); 182 buf = kzalloc(bufsz, GFP_KERNEL); 183 if (!buf) 184 return -ENOMEM; 185 186 pos += scnprintf(buf + pos, bufsz - pos, "Management:\n"); 187 for (cnt = 0; cnt < MANAGEMENT_MAX; cnt++) { 188 pos += scnprintf(buf + pos, bufsz - pos, 189 "\t%25s\t\t: %u\n", 190 get_mgmt_string(cnt), 191 priv->rx_stats.mgmt[cnt]); 192 } 193 pos += scnprintf(buf + pos, bufsz - pos, "Control:\n"); 194 for (cnt = 0; cnt < CONTROL_MAX; cnt++) { 195 pos += scnprintf(buf + pos, bufsz - pos, 196 "\t%25s\t\t: %u\n", 197 get_ctrl_string(cnt), 198 priv->rx_stats.ctrl[cnt]); 199 } 200 pos += scnprintf(buf + pos, bufsz - pos, "Data:\n"); 201 pos += scnprintf(buf + pos, bufsz - pos, "\tcnt: %u\n", 202 priv->rx_stats.data_cnt); 203 pos += scnprintf(buf + pos, bufsz - pos, "\tbytes: %llu\n", 204 priv->rx_stats.data_bytes); 205 206 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); 207 kfree(buf); 208 return ret; 209} 210 211static ssize_t iwl_dbgfs_sram_read(struct file *file, 212 char __user *user_buf, 213 size_t count, loff_t *ppos) 214{ 215 u32 val = 0; 216 char *buf; 217 ssize_t ret; 218 int i = 0; 219 bool device_format = false; 220 int offset = 0; 221 int len = 0; 222 int pos = 0; 223 int sram; 224 struct iwl_priv *priv = file->private_data; 225 size_t bufsz; 226 227 /* default is to dump the entire data segment */ 228 if (!priv->dbgfs_sram_offset && !priv->dbgfs_sram_len) { 229 priv->dbgfs_sram_offset = 0x800000; 230 if (priv->ucode_type == IWL_UCODE_INIT) 231 priv->dbgfs_sram_len = priv->ucode_init.data.len; 232 else 233 priv->dbgfs_sram_len = priv->ucode_rt.data.len; 234 } 235 len = priv->dbgfs_sram_len; 236 237 if (len == -4) { 238 device_format = true; 239 len = 4; 240 } 241 242 bufsz = 50 + len * 4; 243 buf = kmalloc(bufsz, GFP_KERNEL); 244 if (!buf) 245 return -ENOMEM; 246 247 pos += scnprintf(buf + pos, bufsz - pos, "sram_len: 0x%x\n", 248 len); 249 pos += scnprintf(buf + pos, bufsz - pos, "sram_offset: 0x%x\n", 250 priv->dbgfs_sram_offset); 251 252 /* adjust sram address since reads are only on even u32 boundaries */ 253 offset = priv->dbgfs_sram_offset & 0x3; 254 sram = priv->dbgfs_sram_offset & ~0x3; 255 256 /* read the first u32 from sram */ 257 val = iwl_read_targ_mem(priv, sram); 258 259 for (; len; len--) { 260 /* put the address at the start of every line */ 261 if (i == 0) 262 pos += scnprintf(buf + pos, bufsz - pos, 263 "%08X: ", sram + offset); 264 265 if (device_format) 266 pos += scnprintf(buf + pos, bufsz - pos, 267 "%02x", (val >> (8 * (3 - offset))) & 0xff); 268 else 269 pos += scnprintf(buf + pos, bufsz - pos, 270 "%02x ", (val >> (8 * offset)) & 0xff); 271 272 /* if all bytes processed, read the next u32 from sram */ 273 if (++offset == 4) { 274 sram += 4; 275 offset = 0; 276 val = iwl_read_targ_mem(priv, sram); 277 } 278 279 /* put in extra spaces and split lines for human readability */ 280 if (++i == 16) { 281 i = 0; 282 pos += scnprintf(buf + pos, bufsz - pos, "\n"); 283 } else if (!(i & 7)) { 284 pos += scnprintf(buf + pos, bufsz - pos, " "); 285 } else if (!(i & 3)) { 286 pos += scnprintf(buf + pos, bufsz - pos, " "); 287 } 288 } 289 if (i) 290 pos += scnprintf(buf + pos, bufsz - pos, "\n"); 291 292 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); 293 kfree(buf); 294 return ret; 295} 296 297static ssize_t iwl_dbgfs_sram_write(struct file *file, 298 const char __user *user_buf, 299 size_t count, loff_t *ppos) 300{ 301 struct iwl_priv *priv = file->private_data; 302 char buf[64]; 303 int buf_size; 304 u32 offset, len; 305 306 memset(buf, 0, sizeof(buf)); 307 buf_size = min(count, sizeof(buf) - 1); 308 if (copy_from_user(buf, user_buf, buf_size)) 309 return -EFAULT; 310 311 if (sscanf(buf, "%x,%x", &offset, &len) == 2) { 312 priv->dbgfs_sram_offset = offset; 313 priv->dbgfs_sram_len = len; 314 } else if (sscanf(buf, "%x", &offset) == 1) { 315 priv->dbgfs_sram_offset = offset; 316 priv->dbgfs_sram_len = -4; 317 } else { 318 priv->dbgfs_sram_offset = 0; 319 priv->dbgfs_sram_len = 0; 320 } 321 322 return count; 323} 324 325static ssize_t iwl_dbgfs_stations_read(struct file *file, char __user *user_buf, 326 size_t count, loff_t *ppos) 327{ 328 struct iwl_priv *priv = file->private_data; 329 struct iwl_station_entry *station; 330 int max_sta = priv->hw_params.max_stations; 331 char *buf; 332 int i, j, pos = 0; 333 ssize_t ret; 334 /* Add 30 for initial string */ 335 const size_t bufsz = 30 + sizeof(char) * 500 * (priv->num_stations); 336 337 buf = kmalloc(bufsz, GFP_KERNEL); 338 if (!buf) 339 return -ENOMEM; 340 341 pos += scnprintf(buf + pos, bufsz - pos, "num of stations: %d\n\n", 342 priv->num_stations); 343 344 for (i = 0; i < max_sta; i++) { 345 station = &priv->stations[i]; 346 if (!station->used) 347 continue; 348 pos += scnprintf(buf + pos, bufsz - pos, 349 "station %d - addr: %pM, flags: %#x\n", 350 i, station->sta.sta.addr, 351 station->sta.station_flags_msk); 352 pos += scnprintf(buf + pos, bufsz - pos, 353 "TID\tseq_num\ttxq_id\tframes\ttfds\t"); 354 pos += scnprintf(buf + pos, bufsz - pos, 355 "start_idx\tbitmap\t\t\trate_n_flags\n"); 356 357 for (j = 0; j < MAX_TID_COUNT; j++) { 358 pos += scnprintf(buf + pos, bufsz - pos, 359 "%d:\t%#x\t%#x\t%u\t%u\t%u\t\t%#.16llx\t%#x", 360 j, station->tid[j].seq_number, 361 station->tid[j].agg.txq_id, 362 station->tid[j].agg.frame_count, 363 station->tid[j].tfds_in_queue, 364 station->tid[j].agg.start_idx, 365 station->tid[j].agg.bitmap, 366 station->tid[j].agg.rate_n_flags); 367 368 if (station->tid[j].agg.wait_for_ba) 369 pos += scnprintf(buf + pos, bufsz - pos, 370 " - waitforba"); 371 pos += scnprintf(buf + pos, bufsz - pos, "\n"); 372 } 373 374 pos += scnprintf(buf + pos, bufsz - pos, "\n"); 375 } 376 377 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); 378 kfree(buf); 379 return ret; 380} 381 382static ssize_t iwl_dbgfs_nvm_read(struct file *file, 383 char __user *user_buf, 384 size_t count, 385 loff_t *ppos) 386{ 387 ssize_t ret; 388 struct iwl_priv *priv = file->private_data; 389 int pos = 0, ofs = 0, buf_size = 0; 390 const u8 *ptr; 391 char *buf; 392 u16 eeprom_ver; 393 size_t eeprom_len = priv->cfg->base_params->eeprom_size; 394 buf_size = 4 * eeprom_len + 256; 395 396 if (eeprom_len % 16) { 397 IWL_ERR(priv, "NVM size is not multiple of 16.\n"); 398 return -ENODATA; 399 } 400 401 ptr = priv->eeprom; 402 if (!ptr) { 403 IWL_ERR(priv, "Invalid EEPROM/OTP memory\n"); 404 return -ENOMEM; 405 } 406 407 /* 4 characters for byte 0xYY */ 408 buf = kzalloc(buf_size, GFP_KERNEL); 409 if (!buf) { 410 IWL_ERR(priv, "Can not allocate Buffer\n"); 411 return -ENOMEM; 412 } 413 eeprom_ver = iwl_eeprom_query16(priv, EEPROM_VERSION); 414 pos += scnprintf(buf + pos, buf_size - pos, "NVM Type: %s, " 415 "version: 0x%x\n", 416 (priv->nvm_device_type == NVM_DEVICE_TYPE_OTP) 417 ? "OTP" : "EEPROM", eeprom_ver); 418 for (ofs = 0 ; ofs < eeprom_len ; ofs += 16) { 419 pos += scnprintf(buf + pos, buf_size - pos, "0x%.4x ", ofs); 420 hex_dump_to_buffer(ptr + ofs, 16 , 16, 2, buf + pos, 421 buf_size - pos, 0); 422 pos += strlen(buf + pos); 423 if (buf_size - pos > 0) 424 buf[pos++] = '\n'; 425 } 426 427 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); 428 kfree(buf); 429 return ret; 430} 431 432static ssize_t iwl_dbgfs_log_event_read(struct file *file, 433 char __user *user_buf, 434 size_t count, loff_t *ppos) 435{ 436 struct iwl_priv *priv = file->private_data; 437 char *buf; 438 int pos = 0; 439 ssize_t ret = -ENOMEM; 440 441 ret = pos = iwl_dump_nic_event_log(priv, true, &buf, true); 442 if (buf) { 443 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); 444 kfree(buf); 445 } 446 return ret; 447} 448 449static ssize_t iwl_dbgfs_log_event_write(struct file *file, 450 const char __user *user_buf, 451 size_t count, loff_t *ppos) 452{ 453 struct iwl_priv *priv = file->private_data; 454 u32 event_log_flag; 455 char buf[8]; 456 int buf_size; 457 458 memset(buf, 0, sizeof(buf)); 459 buf_size = min(count, sizeof(buf) - 1); 460 if (copy_from_user(buf, user_buf, buf_size)) 461 return -EFAULT; 462 if (sscanf(buf, "%d", &event_log_flag) != 1) 463 return -EFAULT; 464 if (event_log_flag == 1) 465 iwl_dump_nic_event_log(priv, true, NULL, false); 466 467 return count; 468} 469 470 471 472static ssize_t iwl_dbgfs_channels_read(struct file *file, char __user *user_buf, 473 size_t count, loff_t *ppos) 474{ 475 struct iwl_priv *priv = file->private_data; 476 struct ieee80211_channel *channels = NULL; 477 const struct ieee80211_supported_band *supp_band = NULL; 478 int pos = 0, i, bufsz = PAGE_SIZE; 479 char *buf; 480 ssize_t ret; 481 482 if (!test_bit(STATUS_GEO_CONFIGURED, &priv->status)) 483 return -EAGAIN; 484 485 buf = kzalloc(bufsz, GFP_KERNEL); 486 if (!buf) { 487 IWL_ERR(priv, "Can not allocate Buffer\n"); 488 return -ENOMEM; 489 } 490 491 supp_band = iwl_get_hw_mode(priv, IEEE80211_BAND_2GHZ); 492 if (supp_band) { 493 channels = supp_band->channels; 494 495 pos += scnprintf(buf + pos, bufsz - pos, 496 "Displaying %d channels in 2.4GHz band 802.11bg):\n", 497 supp_band->n_channels); 498 499 for (i = 0; i < supp_band->n_channels; i++) 500 pos += scnprintf(buf + pos, bufsz - pos, 501 "%d: %ddBm: BSS%s%s, %s.\n", 502 channels[i].hw_value, 503 channels[i].max_power, 504 channels[i].flags & IEEE80211_CHAN_RADAR ? 505 " (IEEE 802.11h required)" : "", 506 ((channels[i].flags & IEEE80211_CHAN_NO_IBSS) 507 || (channels[i].flags & 508 IEEE80211_CHAN_RADAR)) ? "" : 509 ", IBSS", 510 channels[i].flags & 511 IEEE80211_CHAN_PASSIVE_SCAN ? 512 "passive only" : "active/passive"); 513 } 514 supp_band = iwl_get_hw_mode(priv, IEEE80211_BAND_5GHZ); 515 if (supp_band) { 516 channels = supp_band->channels; 517 518 pos += scnprintf(buf + pos, bufsz - pos, 519 "Displaying %d channels in 5.2GHz band (802.11a)\n", 520 supp_band->n_channels); 521 522 for (i = 0; i < supp_band->n_channels; i++) 523 pos += scnprintf(buf + pos, bufsz - pos, 524 "%d: %ddBm: BSS%s%s, %s.\n", 525 channels[i].hw_value, 526 channels[i].max_power, 527 channels[i].flags & IEEE80211_CHAN_RADAR ? 528 " (IEEE 802.11h required)" : "", 529 ((channels[i].flags & IEEE80211_CHAN_NO_IBSS) 530 || (channels[i].flags & 531 IEEE80211_CHAN_RADAR)) ? "" : 532 ", IBSS", 533 channels[i].flags & 534 IEEE80211_CHAN_PASSIVE_SCAN ? 535 "passive only" : "active/passive"); 536 } 537 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); 538 kfree(buf); 539 return ret; 540} 541 542static ssize_t iwl_dbgfs_status_read(struct file *file, 543 char __user *user_buf, 544 size_t count, loff_t *ppos) { 545 546 struct iwl_priv *priv = file->private_data; 547 char buf[512]; 548 int pos = 0; 549 const size_t bufsz = sizeof(buf); 550 551 pos += scnprintf(buf + pos, bufsz - pos, "STATUS_HCMD_ACTIVE:\t %d\n", 552 test_bit(STATUS_HCMD_ACTIVE, &priv->status)); 553 pos += scnprintf(buf + pos, bufsz - pos, "STATUS_INT_ENABLED:\t %d\n", 554 test_bit(STATUS_INT_ENABLED, &priv->status)); 555 pos += scnprintf(buf + pos, bufsz - pos, "STATUS_RF_KILL_HW:\t %d\n", 556 test_bit(STATUS_RF_KILL_HW, &priv->status)); 557 pos += scnprintf(buf + pos, bufsz - pos, "STATUS_CT_KILL:\t\t %d\n", 558 test_bit(STATUS_CT_KILL, &priv->status)); 559 pos += scnprintf(buf + pos, bufsz - pos, "STATUS_INIT:\t\t %d\n", 560 test_bit(STATUS_INIT, &priv->status)); 561 pos += scnprintf(buf + pos, bufsz - pos, "STATUS_ALIVE:\t\t %d\n", 562 test_bit(STATUS_ALIVE, &priv->status)); 563 pos += scnprintf(buf + pos, bufsz - pos, "STATUS_READY:\t\t %d\n", 564 test_bit(STATUS_READY, &priv->status)); 565 pos += scnprintf(buf + pos, bufsz - pos, "STATUS_TEMPERATURE:\t %d\n", 566 test_bit(STATUS_TEMPERATURE, &priv->status)); 567 pos += scnprintf(buf + pos, bufsz - pos, "STATUS_GEO_CONFIGURED:\t %d\n", 568 test_bit(STATUS_GEO_CONFIGURED, &priv->status)); 569 pos += scnprintf(buf + pos, bufsz - pos, "STATUS_EXIT_PENDING:\t %d\n", 570 test_bit(STATUS_EXIT_PENDING, &priv->status)); 571 pos += scnprintf(buf + pos, bufsz - pos, "STATUS_STATISTICS:\t %d\n", 572 test_bit(STATUS_STATISTICS, &priv->status)); 573 pos += scnprintf(buf + pos, bufsz - pos, "STATUS_SCANNING:\t %d\n", 574 test_bit(STATUS_SCANNING, &priv->status)); 575 pos += scnprintf(buf + pos, bufsz - pos, "STATUS_SCAN_ABORTING:\t %d\n", 576 test_bit(STATUS_SCAN_ABORTING, &priv->status)); 577 pos += scnprintf(buf + pos, bufsz - pos, "STATUS_SCAN_HW:\t\t %d\n", 578 test_bit(STATUS_SCAN_HW, &priv->status)); 579 pos += scnprintf(buf + pos, bufsz - pos, "STATUS_POWER_PMI:\t %d\n", 580 test_bit(STATUS_POWER_PMI, &priv->status)); 581 pos += scnprintf(buf + pos, bufsz - pos, "STATUS_FW_ERROR:\t %d\n", 582 test_bit(STATUS_FW_ERROR, &priv->status)); 583 return simple_read_from_buffer(user_buf, count, ppos, buf, pos); 584} 585 586static ssize_t iwl_dbgfs_interrupt_read(struct file *file, 587 char __user *user_buf, 588 size_t count, loff_t *ppos) { 589 590 struct iwl_priv *priv = file->private_data; 591 int pos = 0; 592 int cnt = 0; 593 char *buf; 594 int bufsz = 24 * 64; /* 24 items * 64 char per item */ 595 ssize_t ret; 596 597 buf = kzalloc(bufsz, GFP_KERNEL); 598 if (!buf) { 599 IWL_ERR(priv, "Can not allocate Buffer\n"); 600 return -ENOMEM; 601 } 602 603 pos += scnprintf(buf + pos, bufsz - pos, 604 "Interrupt Statistics Report:\n"); 605 606 pos += scnprintf(buf + pos, bufsz - pos, "HW Error:\t\t\t %u\n", 607 priv->isr_stats.hw); 608 pos += scnprintf(buf + pos, bufsz - pos, "SW Error:\t\t\t %u\n", 609 priv->isr_stats.sw); 610 if (priv->isr_stats.sw || priv->isr_stats.hw) { 611 pos += scnprintf(buf + pos, bufsz - pos, 612 "\tLast Restarting Code: 0x%X\n", 613 priv->isr_stats.err_code); 614 } 615#ifdef CONFIG_IWLWIFI_DEBUG 616 pos += scnprintf(buf + pos, bufsz - pos, "Frame transmitted:\t\t %u\n", 617 priv->isr_stats.sch); 618 pos += scnprintf(buf + pos, bufsz - pos, "Alive interrupt:\t\t %u\n", 619 priv->isr_stats.alive); 620#endif 621 pos += scnprintf(buf + pos, bufsz - pos, 622 "HW RF KILL switch toggled:\t %u\n", 623 priv->isr_stats.rfkill); 624 625 pos += scnprintf(buf + pos, bufsz - pos, "CT KILL:\t\t\t %u\n", 626 priv->isr_stats.ctkill); 627 628 pos += scnprintf(buf + pos, bufsz - pos, "Wakeup Interrupt:\t\t %u\n", 629 priv->isr_stats.wakeup); 630 631 pos += scnprintf(buf + pos, bufsz - pos, 632 "Rx command responses:\t\t %u\n", 633 priv->isr_stats.rx); 634 for (cnt = 0; cnt < REPLY_MAX; cnt++) { 635 if (priv->isr_stats.rx_handlers[cnt] > 0) 636 pos += scnprintf(buf + pos, bufsz - pos, 637 "\tRx handler[%36s]:\t\t %u\n", 638 get_cmd_string(cnt), 639 priv->isr_stats.rx_handlers[cnt]); 640 } 641 642 pos += scnprintf(buf + pos, bufsz - pos, "Tx/FH interrupt:\t\t %u\n", 643 priv->isr_stats.tx); 644 645 pos += scnprintf(buf + pos, bufsz - pos, "Unexpected INTA:\t\t %u\n", 646 priv->isr_stats.unhandled); 647 648 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); 649 kfree(buf); 650 return ret; 651} 652 653static ssize_t iwl_dbgfs_interrupt_write(struct file *file, 654 const char __user *user_buf, 655 size_t count, loff_t *ppos) 656{ 657 struct iwl_priv *priv = file->private_data; 658 char buf[8]; 659 int buf_size; 660 u32 reset_flag; 661 662 memset(buf, 0, sizeof(buf)); 663 buf_size = min(count, sizeof(buf) - 1); 664 if (copy_from_user(buf, user_buf, buf_size)) 665 return -EFAULT; 666 if (sscanf(buf, "%x", &reset_flag) != 1) 667 return -EFAULT; 668 if (reset_flag == 0) 669 iwl_clear_isr_stats(priv); 670 671 return count; 672} 673 674static ssize_t iwl_dbgfs_qos_read(struct file *file, char __user *user_buf, 675 size_t count, loff_t *ppos) 676{ 677 struct iwl_priv *priv = file->private_data; 678 struct iwl_rxon_context *ctx; 679 int pos = 0, i; 680 char buf[256 * NUM_IWL_RXON_CTX]; 681 const size_t bufsz = sizeof(buf); 682 683 for_each_context(priv, ctx) { 684 pos += scnprintf(buf + pos, bufsz - pos, "context %d:\n", 685 ctx->ctxid); 686 for (i = 0; i < AC_NUM; i++) { 687 pos += scnprintf(buf + pos, bufsz - pos, 688 "\tcw_min\tcw_max\taifsn\ttxop\n"); 689 pos += scnprintf(buf + pos, bufsz - pos, 690 "AC[%d]\t%u\t%u\t%u\t%u\n", i, 691 ctx->qos_data.def_qos_parm.ac[i].cw_min, 692 ctx->qos_data.def_qos_parm.ac[i].cw_max, 693 ctx->qos_data.def_qos_parm.ac[i].aifsn, 694 ctx->qos_data.def_qos_parm.ac[i].edca_txop); 695 } 696 pos += scnprintf(buf + pos, bufsz - pos, "\n"); 697 } 698 return simple_read_from_buffer(user_buf, count, ppos, buf, pos); 699} 700 701static ssize_t iwl_dbgfs_thermal_throttling_read(struct file *file, 702 char __user *user_buf, 703 size_t count, loff_t *ppos) 704{ 705 struct iwl_priv *priv = file->private_data; 706 struct iwl_tt_mgmt *tt = &priv->thermal_throttle; 707 struct iwl_tt_restriction *restriction; 708 char buf[100]; 709 int pos = 0; 710 const size_t bufsz = sizeof(buf); 711 712 pos += scnprintf(buf + pos, bufsz - pos, 713 "Thermal Throttling Mode: %s\n", 714 tt->advanced_tt ? "Advance" : "Legacy"); 715 pos += scnprintf(buf + pos, bufsz - pos, 716 "Thermal Throttling State: %d\n", 717 tt->state); 718 if (tt->advanced_tt) { 719 restriction = tt->restriction + tt->state; 720 pos += scnprintf(buf + pos, bufsz - pos, 721 "Tx mode: %d\n", 722 restriction->tx_stream); 723 pos += scnprintf(buf + pos, bufsz - pos, 724 "Rx mode: %d\n", 725 restriction->rx_stream); 726 pos += scnprintf(buf + pos, bufsz - pos, 727 "HT mode: %d\n", 728 restriction->is_ht); 729 } 730 return simple_read_from_buffer(user_buf, count, ppos, buf, pos); 731} 732 733static ssize_t iwl_dbgfs_disable_ht40_write(struct file *file, 734 const char __user *user_buf, 735 size_t count, loff_t *ppos) 736{ 737 struct iwl_priv *priv = file->private_data; 738 char buf[8]; 739 int buf_size; 740 int ht40; 741 742 memset(buf, 0, sizeof(buf)); 743 buf_size = min(count, sizeof(buf) - 1); 744 if (copy_from_user(buf, user_buf, buf_size)) 745 return -EFAULT; 746 if (sscanf(buf, "%d", &ht40) != 1) 747 return -EFAULT; 748 if (!iwl_is_any_associated(priv)) 749 priv->disable_ht40 = ht40 ? true : false; 750 else { 751 IWL_ERR(priv, "Sta associated with AP - " 752 "Change to 40MHz channel support is not allowed\n"); 753 return -EINVAL; 754 } 755 756 return count; 757} 758 759static ssize_t iwl_dbgfs_disable_ht40_read(struct file *file, 760 char __user *user_buf, 761 size_t count, loff_t *ppos) 762{ 763 struct iwl_priv *priv = file->private_data; 764 char buf[100]; 765 int pos = 0; 766 const size_t bufsz = sizeof(buf); 767 768 pos += scnprintf(buf + pos, bufsz - pos, 769 "11n 40MHz Mode: %s\n", 770 priv->disable_ht40 ? "Disabled" : "Enabled"); 771 return simple_read_from_buffer(user_buf, count, ppos, buf, pos); 772} 773 774static ssize_t iwl_dbgfs_sleep_level_override_write(struct file *file, 775 const char __user *user_buf, 776 size_t count, loff_t *ppos) 777{ 778 struct iwl_priv *priv = file->private_data; 779 char buf[8]; 780 int buf_size; 781 int value; 782 783 memset(buf, 0, sizeof(buf)); 784 buf_size = min(count, sizeof(buf) - 1); 785 if (copy_from_user(buf, user_buf, buf_size)) 786 return -EFAULT; 787 788 if (sscanf(buf, "%d", &value) != 1) 789 return -EINVAL; 790 791 /* 792 * Our users expect 0 to be "CAM", but 0 isn't actually 793 * valid here. However, let's not confuse them and present 794 * IWL_POWER_INDEX_1 as "1", not "0". 795 */ 796 if (value == 0) 797 return -EINVAL; 798 else if (value > 0) 799 value -= 1; 800 801 if (value != -1 && (value < 0 || value >= IWL_POWER_NUM)) 802 return -EINVAL; 803 804 if (!iwl_is_ready_rf(priv)) 805 return -EAGAIN; 806 807 priv->power_data.debug_sleep_level_override = value; 808 809 mutex_lock(&priv->mutex); 810 iwl_power_update_mode(priv, true); 811 mutex_unlock(&priv->mutex); 812 813 return count; 814} 815 816static ssize_t iwl_dbgfs_sleep_level_override_read(struct file *file, 817 char __user *user_buf, 818 size_t count, loff_t *ppos) 819{ 820 struct iwl_priv *priv = file->private_data; 821 char buf[10]; 822 int pos, value; 823 const size_t bufsz = sizeof(buf); 824 825 /* see the write function */ 826 value = priv->power_data.debug_sleep_level_override; 827 if (value >= 0) 828 value += 1; 829 830 pos = scnprintf(buf, bufsz, "%d\n", value); 831 return simple_read_from_buffer(user_buf, count, ppos, buf, pos); 832} 833 834static ssize_t iwl_dbgfs_current_sleep_command_read(struct file *file, 835 char __user *user_buf, 836 size_t count, loff_t *ppos) 837{ 838 struct iwl_priv *priv = file->private_data; 839 char buf[200]; 840 int pos = 0, i; 841 const size_t bufsz = sizeof(buf); 842 struct iwl_powertable_cmd *cmd = &priv->power_data.sleep_cmd; 843 844 pos += scnprintf(buf + pos, bufsz - pos, 845 "flags: %#.2x\n", le16_to_cpu(cmd->flags)); 846 pos += scnprintf(buf + pos, bufsz - pos, 847 "RX/TX timeout: %d/%d usec\n", 848 le32_to_cpu(cmd->rx_data_timeout), 849 le32_to_cpu(cmd->tx_data_timeout)); 850 for (i = 0; i < IWL_POWER_VEC_SIZE; i++) 851 pos += scnprintf(buf + pos, bufsz - pos, 852 "sleep_interval[%d]: %d\n", i, 853 le32_to_cpu(cmd->sleep_interval[i])); 854 855 return simple_read_from_buffer(user_buf, count, ppos, buf, pos); 856} 857 858DEBUGFS_READ_WRITE_FILE_OPS(sram); 859DEBUGFS_READ_WRITE_FILE_OPS(log_event); 860DEBUGFS_READ_FILE_OPS(nvm); 861DEBUGFS_READ_FILE_OPS(stations); 862DEBUGFS_READ_FILE_OPS(channels); 863DEBUGFS_READ_FILE_OPS(status); 864DEBUGFS_READ_WRITE_FILE_OPS(interrupt); 865DEBUGFS_READ_FILE_OPS(qos); 866DEBUGFS_READ_FILE_OPS(thermal_throttling); 867DEBUGFS_READ_WRITE_FILE_OPS(disable_ht40); 868DEBUGFS_READ_WRITE_FILE_OPS(sleep_level_override); 869DEBUGFS_READ_FILE_OPS(current_sleep_command); 870 871static ssize_t iwl_dbgfs_traffic_log_read(struct file *file, 872 char __user *user_buf, 873 size_t count, loff_t *ppos) 874{ 875 struct iwl_priv *priv = file->private_data; 876 int pos = 0, ofs = 0; 877 int cnt = 0, entry; 878 struct iwl_tx_queue *txq; 879 struct iwl_queue *q; 880 struct iwl_rx_queue *rxq = &priv->rxq; 881 char *buf; 882 int bufsz = ((IWL_TRAFFIC_ENTRIES * IWL_TRAFFIC_ENTRY_SIZE * 64) * 2) + 883 (priv->cfg->base_params->num_of_queues * 32 * 8) + 400; 884 const u8 *ptr; 885 ssize_t ret; 886 887 if (!priv->txq) { 888 IWL_ERR(priv, "txq not ready\n"); 889 return -EAGAIN; 890 } 891 buf = kzalloc(bufsz, GFP_KERNEL); 892 if (!buf) { 893 IWL_ERR(priv, "Can not allocate buffer\n"); 894 return -ENOMEM; 895 } 896 pos += scnprintf(buf + pos, bufsz - pos, "Tx Queue\n"); 897 for (cnt = 0; cnt < priv->hw_params.max_txq_num; cnt++) { 898 txq = &priv->txq[cnt]; 899 q = &txq->q; 900 pos += scnprintf(buf + pos, bufsz - pos, 901 "q[%d]: read_ptr: %u, write_ptr: %u\n", 902 cnt, q->read_ptr, q->write_ptr); 903 } 904 if (priv->tx_traffic && (iwl_debug_level & IWL_DL_TX)) { 905 ptr = priv->tx_traffic; 906 pos += scnprintf(buf + pos, bufsz - pos, 907 "Tx Traffic idx: %u\n", priv->tx_traffic_idx); 908 for (cnt = 0, ofs = 0; cnt < IWL_TRAFFIC_ENTRIES; cnt++) { 909 for (entry = 0; entry < IWL_TRAFFIC_ENTRY_SIZE / 16; 910 entry++, ofs += 16) { 911 pos += scnprintf(buf + pos, bufsz - pos, 912 "0x%.4x ", ofs); 913 hex_dump_to_buffer(ptr + ofs, 16, 16, 2, 914 buf + pos, bufsz - pos, 0); 915 pos += strlen(buf + pos); 916 if (bufsz - pos > 0) 917 buf[pos++] = '\n'; 918 } 919 } 920 } 921 922 pos += scnprintf(buf + pos, bufsz - pos, "Rx Queue\n"); 923 pos += scnprintf(buf + pos, bufsz - pos, 924 "read: %u, write: %u\n", 925 rxq->read, rxq->write); 926 927 if (priv->rx_traffic && (iwl_debug_level & IWL_DL_RX)) { 928 ptr = priv->rx_traffic; 929 pos += scnprintf(buf + pos, bufsz - pos, 930 "Rx Traffic idx: %u\n", priv->rx_traffic_idx); 931 for (cnt = 0, ofs = 0; cnt < IWL_TRAFFIC_ENTRIES; cnt++) { 932 for (entry = 0; entry < IWL_TRAFFIC_ENTRY_SIZE / 16; 933 entry++, ofs += 16) { 934 pos += scnprintf(buf + pos, bufsz - pos, 935 "0x%.4x ", ofs); 936 hex_dump_to_buffer(ptr + ofs, 16, 16, 2, 937 buf + pos, bufsz - pos, 0); 938 pos += strlen(buf + pos); 939 if (bufsz - pos > 0) 940 buf[pos++] = '\n'; 941 } 942 } 943 } 944 945 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); 946 kfree(buf); 947 return ret; 948} 949 950static ssize_t iwl_dbgfs_traffic_log_write(struct file *file, 951 const char __user *user_buf, 952 size_t count, loff_t *ppos) 953{ 954 struct iwl_priv *priv = file->private_data; 955 char buf[8]; 956 int buf_size; 957 int traffic_log; 958 959 memset(buf, 0, sizeof(buf)); 960 buf_size = min(count, sizeof(buf) - 1); 961 if (copy_from_user(buf, user_buf, buf_size)) 962 return -EFAULT; 963 if (sscanf(buf, "%d", &traffic_log) != 1) 964 return -EFAULT; 965 if (traffic_log == 0) 966 iwl_reset_traffic_log(priv); 967 968 return count; 969} 970 971static ssize_t iwl_dbgfs_tx_queue_read(struct file *file, 972 char __user *user_buf, 973 size_t count, loff_t *ppos) { 974 975 struct iwl_priv *priv = file->private_data; 976 struct iwl_tx_queue *txq; 977 struct iwl_queue *q; 978 char *buf; 979 int pos = 0; 980 int cnt; 981 int ret; 982 const size_t bufsz = sizeof(char) * 64 * 983 priv->cfg->base_params->num_of_queues; 984 985 if (!priv->txq) { 986 IWL_ERR(priv, "txq not ready\n"); 987 return -EAGAIN; 988 } 989 buf = kzalloc(bufsz, GFP_KERNEL); 990 if (!buf) 991 return -ENOMEM; 992 993 for (cnt = 0; cnt < priv->hw_params.max_txq_num; cnt++) { 994 txq = &priv->txq[cnt]; 995 q = &txq->q; 996 pos += scnprintf(buf + pos, bufsz - pos, 997 "hwq %.2d: read=%u write=%u stop=%d" 998 " swq_id=%#.2x (ac %d/hwq %d)\n", 999 cnt, q->read_ptr, q->write_ptr, 1000 !!test_bit(cnt, priv->queue_stopped), 1001 txq->swq_id, txq->swq_id & 3, 1002 (txq->swq_id >> 2) & 0x1f); 1003 if (cnt >= 4) 1004 continue; 1005 /* for the ACs, display the stop count too */ 1006 pos += scnprintf(buf + pos, bufsz - pos, 1007 " stop-count: %d\n", 1008 atomic_read(&priv->queue_stop_count[cnt])); 1009 } 1010 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); 1011 kfree(buf); 1012 return ret; 1013} 1014 1015static ssize_t iwl_dbgfs_rx_queue_read(struct file *file, 1016 char __user *user_buf, 1017 size_t count, loff_t *ppos) { 1018 1019 struct iwl_priv *priv = file->private_data; 1020 struct iwl_rx_queue *rxq = &priv->rxq; 1021 char buf[256]; 1022 int pos = 0; 1023 const size_t bufsz = sizeof(buf); 1024 1025 pos += scnprintf(buf + pos, bufsz - pos, "read: %u\n", 1026 rxq->read); 1027 pos += scnprintf(buf + pos, bufsz - pos, "write: %u\n", 1028 rxq->write); 1029 pos += scnprintf(buf + pos, bufsz - pos, "free_count: %u\n", 1030 rxq->free_count); 1031 if (rxq->rb_stts) { 1032 pos += scnprintf(buf + pos, bufsz - pos, "closed_rb_num: %u\n", 1033 le16_to_cpu(rxq->rb_stts->closed_rb_num) & 0x0FFF); 1034 } else { 1035 pos += scnprintf(buf + pos, bufsz - pos, 1036 "closed_rb_num: Not Allocated\n"); 1037 } 1038 return simple_read_from_buffer(user_buf, count, ppos, buf, pos); 1039} 1040 1041static const char *fmt_value = " %-30s %10u\n"; 1042static const char *fmt_hex = " %-30s 0x%02X\n"; 1043static const char *fmt_table = " %-30s %10u %10u %10u %10u\n"; 1044static const char *fmt_header = 1045 "%-32s current cumulative delta max\n"; 1046 1047static int iwl_statistics_flag(struct iwl_priv *priv, char *buf, int bufsz) 1048{ 1049 int p = 0; 1050 u32 flag; 1051 1052 flag = le32_to_cpu(priv->statistics.flag); 1053 1054 p += scnprintf(buf + p, bufsz - p, "Statistics Flag(0x%X):\n", flag); 1055 if (flag & UCODE_STATISTICS_CLEAR_MSK) 1056 p += scnprintf(buf + p, bufsz - p, 1057 "\tStatistics have been cleared\n"); 1058 p += scnprintf(buf + p, bufsz - p, "\tOperational Frequency: %s\n", 1059 (flag & UCODE_STATISTICS_FREQUENCY_MSK) 1060 ? "2.4 GHz" : "5.2 GHz"); 1061 p += scnprintf(buf + p, bufsz - p, "\tTGj Narrow Band: %s\n", 1062 (flag & UCODE_STATISTICS_NARROW_BAND_MSK) 1063 ? "enabled" : "disabled"); 1064 1065 return p; 1066} 1067 1068static ssize_t iwl_dbgfs_ucode_rx_stats_read(struct file *file, 1069 char __user *user_buf, 1070 size_t count, loff_t *ppos) 1071{ 1072 struct iwl_priv *priv = file->private_data; 1073 int pos = 0; 1074 char *buf; 1075 int bufsz = sizeof(struct statistics_rx_phy) * 40 + 1076 sizeof(struct statistics_rx_non_phy) * 40 + 1077 sizeof(struct statistics_rx_ht_phy) * 40 + 400; 1078 ssize_t ret; 1079 struct statistics_rx_phy *ofdm, *accum_ofdm, *delta_ofdm, *max_ofdm; 1080 struct statistics_rx_phy *cck, *accum_cck, *delta_cck, *max_cck; 1081 struct statistics_rx_non_phy *general, *accum_general; 1082 struct statistics_rx_non_phy *delta_general, *max_general; 1083 struct statistics_rx_ht_phy *ht, *accum_ht, *delta_ht, *max_ht; 1084 1085 if (!iwl_is_alive(priv)) 1086 return -EAGAIN; 1087 1088 buf = kzalloc(bufsz, GFP_KERNEL); 1089 if (!buf) { 1090 IWL_ERR(priv, "Can not allocate Buffer\n"); 1091 return -ENOMEM; 1092 } 1093 1094 /* 1095 * the statistic information display here is based on 1096 * the last statistics notification from uCode 1097 * might not reflect the current uCode activity 1098 */ 1099 ofdm = &priv->statistics.rx_ofdm; 1100 cck = &priv->statistics.rx_cck; 1101 general = &priv->statistics.rx_non_phy; 1102 ht = &priv->statistics.rx_ofdm_ht; 1103 accum_ofdm = &priv->accum_stats.rx_ofdm; 1104 accum_cck = &priv->accum_stats.rx_cck; 1105 accum_general = &priv->accum_stats.rx_non_phy; 1106 accum_ht = &priv->accum_stats.rx_ofdm_ht; 1107 delta_ofdm = &priv->delta_stats.rx_ofdm; 1108 delta_cck = &priv->delta_stats.rx_cck; 1109 delta_general = &priv->delta_stats.rx_non_phy; 1110 delta_ht = &priv->delta_stats.rx_ofdm_ht; 1111 max_ofdm = &priv->max_delta_stats.rx_ofdm; 1112 max_cck = &priv->max_delta_stats.rx_cck; 1113 max_general = &priv->max_delta_stats.rx_non_phy; 1114 max_ht = &priv->max_delta_stats.rx_ofdm_ht; 1115 1116 pos += iwl_statistics_flag(priv, buf, bufsz); 1117 pos += scnprintf(buf + pos, bufsz - pos, 1118 fmt_header, "Statistics_Rx - OFDM:"); 1119 pos += scnprintf(buf + pos, bufsz - pos, 1120 fmt_table, "ina_cnt:", 1121 le32_to_cpu(ofdm->ina_cnt), 1122 accum_ofdm->ina_cnt, 1123 delta_ofdm->ina_cnt, max_ofdm->ina_cnt); 1124 pos += scnprintf(buf + pos, bufsz - pos, 1125 fmt_table, "fina_cnt:", 1126 le32_to_cpu(ofdm->fina_cnt), accum_ofdm->fina_cnt, 1127 delta_ofdm->fina_cnt, max_ofdm->fina_cnt); 1128 pos += scnprintf(buf + pos, bufsz - pos, 1129 fmt_table, "plcp_err:", 1130 le32_to_cpu(ofdm->plcp_err), accum_ofdm->plcp_err, 1131 delta_ofdm->plcp_err, max_ofdm->plcp_err); 1132 pos += scnprintf(buf + pos, bufsz - pos, 1133 fmt_table, "crc32_err:", 1134 le32_to_cpu(ofdm->crc32_err), accum_ofdm->crc32_err, 1135 delta_ofdm->crc32_err, max_ofdm->crc32_err); 1136 pos += scnprintf(buf + pos, bufsz - pos, 1137 fmt_table, "overrun_err:", 1138 le32_to_cpu(ofdm->overrun_err), 1139 accum_ofdm->overrun_err, delta_ofdm->overrun_err, 1140 max_ofdm->overrun_err); 1141 pos += scnprintf(buf + pos, bufsz - pos, 1142 fmt_table, "early_overrun_err:", 1143 le32_to_cpu(ofdm->early_overrun_err), 1144 accum_ofdm->early_overrun_err, 1145 delta_ofdm->early_overrun_err, 1146 max_ofdm->early_overrun_err); 1147 pos += scnprintf(buf + pos, bufsz - pos, 1148 fmt_table, "crc32_good:", 1149 le32_to_cpu(ofdm->crc32_good), 1150 accum_ofdm->crc32_good, delta_ofdm->crc32_good, 1151 max_ofdm->crc32_good); 1152 pos += scnprintf(buf + pos, bufsz - pos, 1153 fmt_table, "false_alarm_cnt:", 1154 le32_to_cpu(ofdm->false_alarm_cnt), 1155 accum_ofdm->false_alarm_cnt, 1156 delta_ofdm->false_alarm_cnt, 1157 max_ofdm->false_alarm_cnt); 1158 pos += scnprintf(buf + pos, bufsz - pos, 1159 fmt_table, "fina_sync_err_cnt:", 1160 le32_to_cpu(ofdm->fina_sync_err_cnt), 1161 accum_ofdm->fina_sync_err_cnt, 1162 delta_ofdm->fina_sync_err_cnt, 1163 max_ofdm->fina_sync_err_cnt); 1164 pos += scnprintf(buf + pos, bufsz - pos, 1165 fmt_table, "sfd_timeout:", 1166 le32_to_cpu(ofdm->sfd_timeout), 1167 accum_ofdm->sfd_timeout, delta_ofdm->sfd_timeout, 1168 max_ofdm->sfd_timeout); 1169 pos += scnprintf(buf + pos, bufsz - pos, 1170 fmt_table, "fina_timeout:", 1171 le32_to_cpu(ofdm->fina_timeout), 1172 accum_ofdm->fina_timeout, delta_ofdm->fina_timeout, 1173 max_ofdm->fina_timeout); 1174 pos += scnprintf(buf + pos, bufsz - pos, 1175 fmt_table, "unresponded_rts:", 1176 le32_to_cpu(ofdm->unresponded_rts), 1177 accum_ofdm->unresponded_rts, 1178 delta_ofdm->unresponded_rts, 1179 max_ofdm->unresponded_rts); 1180 pos += scnprintf(buf + pos, bufsz - pos, 1181 fmt_table, "rxe_frame_lmt_ovrun:", 1182 le32_to_cpu(ofdm->rxe_frame_limit_overrun), 1183 accum_ofdm->rxe_frame_limit_overrun, 1184 delta_ofdm->rxe_frame_limit_overrun, 1185 max_ofdm->rxe_frame_limit_overrun); 1186 pos += scnprintf(buf + pos, bufsz - pos, 1187 fmt_table, "sent_ack_cnt:", 1188 le32_to_cpu(ofdm->sent_ack_cnt), 1189 accum_ofdm->sent_ack_cnt, delta_ofdm->sent_ack_cnt, 1190 max_ofdm->sent_ack_cnt); 1191 pos += scnprintf(buf + pos, bufsz - pos, 1192 fmt_table, "sent_cts_cnt:", 1193 le32_to_cpu(ofdm->sent_cts_cnt), 1194 accum_ofdm->sent_cts_cnt, delta_ofdm->sent_cts_cnt, 1195 max_ofdm->sent_cts_cnt); 1196 pos += scnprintf(buf + pos, bufsz - pos, 1197 fmt_table, "sent_ba_rsp_cnt:", 1198 le32_to_cpu(ofdm->sent_ba_rsp_cnt), 1199 accum_ofdm->sent_ba_rsp_cnt, 1200 delta_ofdm->sent_ba_rsp_cnt, 1201 max_ofdm->sent_ba_rsp_cnt); 1202 pos += scnprintf(buf + pos, bufsz - pos, 1203 fmt_table, "dsp_self_kill:", 1204 le32_to_cpu(ofdm->dsp_self_kill), 1205 accum_ofdm->dsp_self_kill, 1206 delta_ofdm->dsp_self_kill, 1207 max_ofdm->dsp_self_kill); 1208 pos += scnprintf(buf + pos, bufsz - pos, 1209 fmt_table, "mh_format_err:", 1210 le32_to_cpu(ofdm->mh_format_err), 1211 accum_ofdm->mh_format_err, 1212 delta_ofdm->mh_format_err, 1213 max_ofdm->mh_format_err); 1214 pos += scnprintf(buf + pos, bufsz - pos, 1215 fmt_table, "re_acq_main_rssi_sum:", 1216 le32_to_cpu(ofdm->re_acq_main_rssi_sum), 1217 accum_ofdm->re_acq_main_rssi_sum, 1218 delta_ofdm->re_acq_main_rssi_sum, 1219 max_ofdm->re_acq_main_rssi_sum); 1220 1221 pos += scnprintf(buf + pos, bufsz - pos, 1222 fmt_header, "Statistics_Rx - CCK:"); 1223 pos += scnprintf(buf + pos, bufsz - pos, 1224 fmt_table, "ina_cnt:", 1225 le32_to_cpu(cck->ina_cnt), accum_cck->ina_cnt, 1226 delta_cck->ina_cnt, max_cck->ina_cnt); 1227 pos += scnprintf(buf + pos, bufsz - pos, 1228 fmt_table, "fina_cnt:", 1229 le32_to_cpu(cck->fina_cnt), accum_cck->fina_cnt, 1230 delta_cck->fina_cnt, max_cck->fina_cnt); 1231 pos += scnprintf(buf + pos, bufsz - pos, 1232 fmt_table, "plcp_err:", 1233 le32_to_cpu(cck->plcp_err), accum_cck->plcp_err, 1234 delta_cck->plcp_err, max_cck->plcp_err); 1235 pos += scnprintf(buf + pos, bufsz - pos, 1236 fmt_table, "crc32_err:", 1237 le32_to_cpu(cck->crc32_err), accum_cck->crc32_err, 1238 delta_cck->crc32_err, max_cck->crc32_err); 1239 pos += scnprintf(buf + pos, bufsz - pos, 1240 fmt_table, "overrun_err:", 1241 le32_to_cpu(cck->overrun_err), 1242 accum_cck->overrun_err, delta_cck->overrun_err, 1243 max_cck->overrun_err); 1244 pos += scnprintf(buf + pos, bufsz - pos, 1245 fmt_table, "early_overrun_err:", 1246 le32_to_cpu(cck->early_overrun_err), 1247 accum_cck->early_overrun_err, 1248 delta_cck->early_overrun_err, 1249 max_cck->early_overrun_err); 1250 pos += scnprintf(buf + pos, bufsz - pos, 1251 fmt_table, "crc32_good:", 1252 le32_to_cpu(cck->crc32_good), accum_cck->crc32_good, 1253 delta_cck->crc32_good, max_cck->crc32_good); 1254 pos += scnprintf(buf + pos, bufsz - pos, 1255 fmt_table, "false_alarm_cnt:", 1256 le32_to_cpu(cck->false_alarm_cnt), 1257 accum_cck->false_alarm_cnt, 1258 delta_cck->false_alarm_cnt, max_cck->false_alarm_cnt); 1259 pos += scnprintf(buf + pos, bufsz - pos, 1260 fmt_table, "fina_sync_err_cnt:", 1261 le32_to_cpu(cck->fina_sync_err_cnt), 1262 accum_cck->fina_sync_err_cnt, 1263 delta_cck->fina_sync_err_cnt, 1264 max_cck->fina_sync_err_cnt); 1265 pos += scnprintf(buf + pos, bufsz - pos, 1266 fmt_table, "sfd_timeout:", 1267 le32_to_cpu(cck->sfd_timeout), 1268 accum_cck->sfd_timeout, delta_cck->sfd_timeout, 1269 max_cck->sfd_timeout); 1270 pos += scnprintf(buf + pos, bufsz - pos, 1271 fmt_table, "fina_timeout:", 1272 le32_to_cpu(cck->fina_timeout), 1273 accum_cck->fina_timeout, delta_cck->fina_timeout, 1274 max_cck->fina_timeout); 1275 pos += scnprintf(buf + pos, bufsz - pos, 1276 fmt_table, "unresponded_rts:", 1277 le32_to_cpu(cck->unresponded_rts), 1278 accum_cck->unresponded_rts, delta_cck->unresponded_rts, 1279 max_cck->unresponded_rts); 1280 pos += scnprintf(buf + pos, bufsz - pos, 1281 fmt_table, "rxe_frame_lmt_ovrun:", 1282 le32_to_cpu(cck->rxe_frame_limit_overrun), 1283 accum_cck->rxe_frame_limit_overrun, 1284 delta_cck->rxe_frame_limit_overrun, 1285 max_cck->rxe_frame_limit_overrun); 1286 pos += scnprintf(buf + pos, bufsz - pos, 1287 fmt_table, "sent_ack_cnt:", 1288 le32_to_cpu(cck->sent_ack_cnt), 1289 accum_cck->sent_ack_cnt, delta_cck->sent_ack_cnt, 1290 max_cck->sent_ack_cnt); 1291 pos += scnprintf(buf + pos, bufsz - pos, 1292 fmt_table, "sent_cts_cnt:", 1293 le32_to_cpu(cck->sent_cts_cnt), 1294 accum_cck->sent_cts_cnt, delta_cck->sent_cts_cnt, 1295 max_cck->sent_cts_cnt); 1296 pos += scnprintf(buf + pos, bufsz - pos, 1297 fmt_table, "sent_ba_rsp_cnt:", 1298 le32_to_cpu(cck->sent_ba_rsp_cnt), 1299 accum_cck->sent_ba_rsp_cnt, 1300 delta_cck->sent_ba_rsp_cnt, 1301 max_cck->sent_ba_rsp_cnt); 1302 pos += scnprintf(buf + pos, bufsz - pos, 1303 fmt_table, "dsp_self_kill:", 1304 le32_to_cpu(cck->dsp_self_kill), 1305 accum_cck->dsp_self_kill, delta_cck->dsp_self_kill, 1306 max_cck->dsp_self_kill); 1307 pos += scnprintf(buf + pos, bufsz - pos, 1308 fmt_table, "mh_format_err:", 1309 le32_to_cpu(cck->mh_format_err), 1310 accum_cck->mh_format_err, delta_cck->mh_format_err, 1311 max_cck->mh_format_err); 1312 pos += scnprintf(buf + pos, bufsz - pos, 1313 fmt_table, "re_acq_main_rssi_sum:", 1314 le32_to_cpu(cck->re_acq_main_rssi_sum), 1315 accum_cck->re_acq_main_rssi_sum, 1316 delta_cck->re_acq_main_rssi_sum, 1317 max_cck->re_acq_main_rssi_sum); 1318 1319 pos += scnprintf(buf + pos, bufsz - pos, 1320 fmt_header, "Statistics_Rx - GENERAL:"); 1321 pos += scnprintf(buf + pos, bufsz - pos, 1322 fmt_table, "bogus_cts:", 1323 le32_to_cpu(general->bogus_cts), 1324 accum_general->bogus_cts, delta_general->bogus_cts, 1325 max_general->bogus_cts); 1326 pos += scnprintf(buf + pos, bufsz - pos, 1327 fmt_table, "bogus_ack:", 1328 le32_to_cpu(general->bogus_ack), 1329 accum_general->bogus_ack, delta_general->bogus_ack, 1330 max_general->bogus_ack); 1331 pos += scnprintf(buf + pos, bufsz - pos, 1332 fmt_table, "non_bssid_frames:", 1333 le32_to_cpu(general->non_bssid_frames), 1334 accum_general->non_bssid_frames, 1335 delta_general->non_bssid_frames, 1336 max_general->non_bssid_frames); 1337 pos += scnprintf(buf + pos, bufsz - pos, 1338 fmt_table, "filtered_frames:", 1339 le32_to_cpu(general->filtered_frames), 1340 accum_general->filtered_frames, 1341 delta_general->filtered_frames, 1342 max_general->filtered_frames); 1343 pos += scnprintf(buf + pos, bufsz - pos, 1344 fmt_table, "non_channel_beacons:", 1345 le32_to_cpu(general->non_channel_beacons), 1346 accum_general->non_channel_beacons, 1347 delta_general->non_channel_beacons, 1348 max_general->non_channel_beacons); 1349 pos += scnprintf(buf + pos, bufsz - pos, 1350 fmt_table, "channel_beacons:", 1351 le32_to_cpu(general->channel_beacons), 1352 accum_general->channel_beacons, 1353 delta_general->channel_beacons, 1354 max_general->channel_beacons); 1355 pos += scnprintf(buf + pos, bufsz - pos, 1356 fmt_table, "num_missed_bcon:", 1357 le32_to_cpu(general->num_missed_bcon), 1358 accum_general->num_missed_bcon, 1359 delta_general->num_missed_bcon, 1360 max_general->num_missed_bcon); 1361 pos += scnprintf(buf + pos, bufsz - pos, 1362 fmt_table, "adc_rx_saturation_time:", 1363 le32_to_cpu(general->adc_rx_saturation_time), 1364 accum_general->adc_rx_saturation_time, 1365 delta_general->adc_rx_saturation_time, 1366 max_general->adc_rx_saturation_time); 1367 pos += scnprintf(buf + pos, bufsz - pos, 1368 fmt_table, "ina_detect_search_tm:", 1369 le32_to_cpu(general->ina_detection_search_time), 1370 accum_general->ina_detection_search_time, 1371 delta_general->ina_detection_search_time, 1372 max_general->ina_detection_search_time); 1373 pos += scnprintf(buf + pos, bufsz - pos, 1374 fmt_table, "beacon_silence_rssi_a:", 1375 le32_to_cpu(general->beacon_silence_rssi_a), 1376 accum_general->beacon_silence_rssi_a, 1377 delta_general->beacon_silence_rssi_a, 1378 max_general->beacon_silence_rssi_a); 1379 pos += scnprintf(buf + pos, bufsz - pos, 1380 fmt_table, "beacon_silence_rssi_b:", 1381 le32_to_cpu(general->beacon_silence_rssi_b), 1382 accum_general->beacon_silence_rssi_b, 1383 delta_general->beacon_silence_rssi_b, 1384 max_general->beacon_silence_rssi_b); 1385 pos += scnprintf(buf + pos, bufsz - pos, 1386 fmt_table, "beacon_silence_rssi_c:", 1387 le32_to_cpu(general->beacon_silence_rssi_c), 1388 accum_general->beacon_silence_rssi_c, 1389 delta_general->beacon_silence_rssi_c, 1390 max_general->beacon_silence_rssi_c); 1391 pos += scnprintf(buf + pos, bufsz - pos, 1392 fmt_table, "interference_data_flag:", 1393 le32_to_cpu(general->interference_data_flag), 1394 accum_general->interference_data_flag, 1395 delta_general->interference_data_flag, 1396 max_general->interference_data_flag); 1397 pos += scnprintf(buf + pos, bufsz - pos, 1398 fmt_table, "channel_load:", 1399 le32_to_cpu(general->channel_load), 1400 accum_general->channel_load, 1401 delta_general->channel_load, 1402 max_general->channel_load); 1403 pos += scnprintf(buf + pos, bufsz - pos, 1404 fmt_table, "dsp_false_alarms:", 1405 le32_to_cpu(general->dsp_false_alarms), 1406 accum_general->dsp_false_alarms, 1407 delta_general->dsp_false_alarms, 1408 max_general->dsp_false_alarms); 1409 pos += scnprintf(buf + pos, bufsz - pos, 1410 fmt_table, "beacon_rssi_a:", 1411 le32_to_cpu(general->beacon_rssi_a), 1412 accum_general->beacon_rssi_a, 1413 delta_general->beacon_rssi_a, 1414 max_general->beacon_rssi_a); 1415 pos += scnprintf(buf + pos, bufsz - pos, 1416 fmt_table, "beacon_rssi_b:", 1417 le32_to_cpu(general->beacon_rssi_b), 1418 accum_general->beacon_rssi_b, 1419 delta_general->beacon_rssi_b, 1420 max_general->beacon_rssi_b); 1421 pos += scnprintf(buf + pos, bufsz - pos, 1422 fmt_table, "beacon_rssi_c:", 1423 le32_to_cpu(general->beacon_rssi_c), 1424 accum_general->beacon_rssi_c, 1425 delta_general->beacon_rssi_c, 1426 max_general->beacon_rssi_c); 1427 pos += scnprintf(buf + pos, bufsz - pos, 1428 fmt_table, "beacon_energy_a:", 1429 le32_to_cpu(general->beacon_energy_a), 1430 accum_general->beacon_energy_a, 1431 delta_general->beacon_energy_a, 1432 max_general->beacon_energy_a); 1433 pos += scnprintf(buf + pos, bufsz - pos, 1434 fmt_table, "beacon_energy_b:", 1435 le32_to_cpu(general->beacon_energy_b), 1436 accum_general->beacon_energy_b, 1437 delta_general->beacon_energy_b, 1438 max_general->beacon_energy_b); 1439 pos += scnprintf(buf + pos, bufsz - pos, 1440 fmt_table, "beacon_energy_c:", 1441 le32_to_cpu(general->beacon_energy_c), 1442 accum_general->beacon_energy_c, 1443 delta_general->beacon_energy_c, 1444 max_general->beacon_energy_c); 1445 1446 pos += scnprintf(buf + pos, bufsz - pos, 1447 fmt_header, "Statistics_Rx - OFDM_HT:"); 1448 pos += scnprintf(buf + pos, bufsz - pos, 1449 fmt_table, "plcp_err:", 1450 le32_to_cpu(ht->plcp_err), accum_ht->plcp_err, 1451 delta_ht->plcp_err, max_ht->plcp_err); 1452 pos += scnprintf(buf + pos, bufsz - pos, 1453 fmt_table, "overrun_err:", 1454 le32_to_cpu(ht->overrun_err), accum_ht->overrun_err, 1455 delta_ht->overrun_err, max_ht->overrun_err); 1456 pos += scnprintf(buf + pos, bufsz - pos, 1457 fmt_table, "early_overrun_err:", 1458 le32_to_cpu(ht->early_overrun_err), 1459 accum_ht->early_overrun_err, 1460 delta_ht->early_overrun_err, 1461 max_ht->early_overrun_err); 1462 pos += scnprintf(buf + pos, bufsz - pos, 1463 fmt_table, "crc32_good:", 1464 le32_to_cpu(ht->crc32_good), accum_ht->crc32_good, 1465 delta_ht->crc32_good, max_ht->crc32_good); 1466 pos += scnprintf(buf + pos, bufsz - pos, 1467 fmt_table, "crc32_err:", 1468 le32_to_cpu(ht->crc32_err), accum_ht->crc32_err, 1469 delta_ht->crc32_err, max_ht->crc32_err); 1470 pos += scnprintf(buf + pos, bufsz - pos, 1471 fmt_table, "mh_format_err:", 1472 le32_to_cpu(ht->mh_format_err), 1473 accum_ht->mh_format_err, 1474 delta_ht->mh_format_err, max_ht->mh_format_err); 1475 pos += scnprintf(buf + pos, bufsz - pos, 1476 fmt_table, "agg_crc32_good:", 1477 le32_to_cpu(ht->agg_crc32_good), 1478 accum_ht->agg_crc32_good, 1479 delta_ht->agg_crc32_good, max_ht->agg_crc32_good); 1480 pos += scnprintf(buf + pos, bufsz - pos, 1481 fmt_table, "agg_mpdu_cnt:", 1482 le32_to_cpu(ht->agg_mpdu_cnt), 1483 accum_ht->agg_mpdu_cnt, 1484 delta_ht->agg_mpdu_cnt, max_ht->agg_mpdu_cnt); 1485 pos += scnprintf(buf + pos, bufsz - pos, 1486 fmt_table, "agg_cnt:", 1487 le32_to_cpu(ht->agg_cnt), accum_ht->agg_cnt, 1488 delta_ht->agg_cnt, max_ht->agg_cnt); 1489 pos += scnprintf(buf + pos, bufsz - pos, 1490 fmt_table, "unsupport_mcs:", 1491 le32_to_cpu(ht->unsupport_mcs), 1492 accum_ht->unsupport_mcs, 1493 delta_ht->unsupport_mcs, max_ht->unsupport_mcs); 1494 1495 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); 1496 kfree(buf); 1497 return ret; 1498} 1499 1500static ssize_t iwl_dbgfs_ucode_tx_stats_read(struct file *file, 1501 char __user *user_buf, 1502 size_t count, loff_t *ppos) 1503{ 1504 struct iwl_priv *priv = file->private_data; 1505 int pos = 0; 1506 char *buf; 1507 int bufsz = (sizeof(struct statistics_tx) * 48) + 250; 1508 ssize_t ret; 1509 struct statistics_tx *tx, *accum_tx, *delta_tx, *max_tx; 1510 1511 if (!iwl_is_alive(priv)) 1512 return -EAGAIN; 1513 1514 buf = kzalloc(bufsz, GFP_KERNEL); 1515 if (!buf) { 1516 IWL_ERR(priv, "Can not allocate Buffer\n"); 1517 return -ENOMEM; 1518 } 1519 1520 /* the statistic information display here is based on 1521 * the last statistics notification from uCode 1522 * might not reflect the current uCode activity 1523 */ 1524 tx = &priv->statistics.tx; 1525 accum_tx = &priv->accum_stats.tx; 1526 delta_tx = &priv->delta_stats.tx; 1527 max_tx = &priv->max_delta_stats.tx; 1528 1529 pos += iwl_statistics_flag(priv, buf, bufsz); 1530 pos += scnprintf(buf + pos, bufsz - pos, 1531 fmt_header, "Statistics_Tx:"); 1532 pos += scnprintf(buf + pos, bufsz - pos, 1533 fmt_table, "preamble:", 1534 le32_to_cpu(tx->preamble_cnt), 1535 accum_tx->preamble_cnt, 1536 delta_tx->preamble_cnt, max_tx->preamble_cnt); 1537 pos += scnprintf(buf + pos, bufsz - pos, 1538 fmt_table, "rx_detected_cnt:", 1539 le32_to_cpu(tx->rx_detected_cnt), 1540 accum_tx->rx_detected_cnt, 1541 delta_tx->rx_detected_cnt, max_tx->rx_detected_cnt); 1542 pos += scnprintf(buf + pos, bufsz - pos, 1543 fmt_table, "bt_prio_defer_cnt:", 1544 le32_to_cpu(tx->bt_prio_defer_cnt), 1545 accum_tx->bt_prio_defer_cnt, 1546 delta_tx->bt_prio_defer_cnt, 1547 max_tx->bt_prio_defer_cnt); 1548 pos += scnprintf(buf + pos, bufsz - pos, 1549 fmt_table, "bt_prio_kill_cnt:", 1550 le32_to_cpu(tx->bt_prio_kill_cnt), 1551 accum_tx->bt_prio_kill_cnt, 1552 delta_tx->bt_prio_kill_cnt, 1553 max_tx->bt_prio_kill_cnt); 1554 pos += scnprintf(buf + pos, bufsz - pos, 1555 fmt_table, "few_bytes_cnt:", 1556 le32_to_cpu(tx->few_bytes_cnt), 1557 accum_tx->few_bytes_cnt, 1558 delta_tx->few_bytes_cnt, max_tx->few_bytes_cnt); 1559 pos += scnprintf(buf + pos, bufsz - pos, 1560 fmt_table, "cts_timeout:", 1561 le32_to_cpu(tx->cts_timeout), accum_tx->cts_timeout, 1562 delta_tx->cts_timeout, max_tx->cts_timeout); 1563 pos += scnprintf(buf + pos, bufsz - pos, 1564 fmt_table, "ack_timeout:", 1565 le32_to_cpu(tx->ack_timeout), 1566 accum_tx->ack_timeout, 1567 delta_tx->ack_timeout, max_tx->ack_timeout); 1568 pos += scnprintf(buf + pos, bufsz - pos, 1569 fmt_table, "expected_ack_cnt:", 1570 le32_to_cpu(tx->expected_ack_cnt), 1571 accum_tx->expected_ack_cnt, 1572 delta_tx->expected_ack_cnt, 1573 max_tx->expected_ack_cnt); 1574 pos += scnprintf(buf + pos, bufsz - pos, 1575 fmt_table, "actual_ack_cnt:", 1576 le32_to_cpu(tx->actual_ack_cnt), 1577 accum_tx->actual_ack_cnt, 1578 delta_tx->actual_ack_cnt, 1579 max_tx->actual_ack_cnt); 1580 pos += scnprintf(buf + pos, bufsz - pos, 1581 fmt_table, "dump_msdu_cnt:", 1582 le32_to_cpu(tx->dump_msdu_cnt), 1583 accum_tx->dump_msdu_cnt, 1584 delta_tx->dump_msdu_cnt, 1585 max_tx->dump_msdu_cnt); 1586 pos += scnprintf(buf + pos, bufsz - pos, 1587 fmt_table, "abort_nxt_frame_mismatch:", 1588 le32_to_cpu(tx->burst_abort_next_frame_mismatch_cnt), 1589 accum_tx->burst_abort_next_frame_mismatch_cnt, 1590 delta_tx->burst_abort_next_frame_mismatch_cnt, 1591 max_tx->burst_abort_next_frame_mismatch_cnt); 1592 pos += scnprintf(buf + pos, bufsz - pos, 1593 fmt_table, "abort_missing_nxt_frame:", 1594 le32_to_cpu(tx->burst_abort_missing_next_frame_cnt), 1595 accum_tx->burst_abort_missing_next_frame_cnt, 1596 delta_tx->burst_abort_missing_next_frame_cnt, 1597 max_tx->burst_abort_missing_next_frame_cnt); 1598 pos += scnprintf(buf + pos, bufsz - pos, 1599 fmt_table, "cts_timeout_collision:", 1600 le32_to_cpu(tx->cts_timeout_collision), 1601 accum_tx->cts_timeout_collision, 1602 delta_tx->cts_timeout_collision, 1603 max_tx->cts_timeout_collision); 1604 pos += scnprintf(buf + pos, bufsz - pos, 1605 fmt_table, "ack_ba_timeout_collision:", 1606 le32_to_cpu(tx->ack_or_ba_timeout_collision), 1607 accum_tx->ack_or_ba_timeout_collision, 1608 delta_tx->ack_or_ba_timeout_collision, 1609 max_tx->ack_or_ba_timeout_collision); 1610 pos += scnprintf(buf + pos, bufsz - pos, 1611 fmt_table, "agg ba_timeout:", 1612 le32_to_cpu(tx->agg.ba_timeout), 1613 accum_tx->agg.ba_timeout, 1614 delta_tx->agg.ba_timeout, 1615 max_tx->agg.ba_timeout); 1616 pos += scnprintf(buf + pos, bufsz - pos, 1617 fmt_table, "agg ba_resched_frames:", 1618 le32_to_cpu(tx->agg.ba_reschedule_frames), 1619 accum_tx->agg.ba_reschedule_frames, 1620 delta_tx->agg.ba_reschedule_frames, 1621 max_tx->agg.ba_reschedule_frames); 1622 pos += scnprintf(buf + pos, bufsz - pos, 1623 fmt_table, "agg scd_query_agg_frame:", 1624 le32_to_cpu(tx->agg.scd_query_agg_frame_cnt), 1625 accum_tx->agg.scd_query_agg_frame_cnt, 1626 delta_tx->agg.scd_query_agg_frame_cnt, 1627 max_tx->agg.scd_query_agg_frame_cnt); 1628 pos += scnprintf(buf + pos, bufsz - pos, 1629 fmt_table, "agg scd_query_no_agg:", 1630 le32_to_cpu(tx->agg.scd_query_no_agg), 1631 accum_tx->agg.scd_query_no_agg, 1632 delta_tx->agg.scd_query_no_agg, 1633 max_tx->agg.scd_query_no_agg); 1634 pos += scnprintf(buf + pos, bufsz - pos, 1635 fmt_table, "agg scd_query_agg:", 1636 le32_to_cpu(tx->agg.scd_query_agg), 1637 accum_tx->agg.scd_query_agg, 1638 delta_tx->agg.scd_query_agg, 1639 max_tx->agg.scd_query_agg); 1640 pos += scnprintf(buf + pos, bufsz - pos, 1641 fmt_table, "agg scd_query_mismatch:", 1642 le32_to_cpu(tx->agg.scd_query_mismatch), 1643 accum_tx->agg.scd_query_mismatch, 1644 delta_tx->agg.scd_query_mismatch, 1645 max_tx->agg.scd_query_mismatch); 1646 pos += scnprintf(buf + pos, bufsz - pos, 1647 fmt_table, "agg frame_not_ready:", 1648 le32_to_cpu(tx->agg.frame_not_ready), 1649 accum_tx->agg.frame_not_ready, 1650 delta_tx->agg.frame_not_ready, 1651 max_tx->agg.frame_not_ready); 1652 pos += scnprintf(buf + pos, bufsz - pos, 1653 fmt_table, "agg underrun:", 1654 le32_to_cpu(tx->agg.underrun), 1655 accum_tx->agg.underrun, 1656 delta_tx->agg.underrun, max_tx->agg.underrun); 1657 pos += scnprintf(buf + pos, bufsz - pos, 1658 fmt_table, "agg bt_prio_kill:", 1659 le32_to_cpu(tx->agg.bt_prio_kill), 1660 accum_tx->agg.bt_prio_kill, 1661 delta_tx->agg.bt_prio_kill, 1662 max_tx->agg.bt_prio_kill); 1663 pos += scnprintf(buf + pos, bufsz - pos, 1664 fmt_table, "agg rx_ba_rsp_cnt:", 1665 le32_to_cpu(tx->agg.rx_ba_rsp_cnt), 1666 accum_tx->agg.rx_ba_rsp_cnt, 1667 delta_tx->agg.rx_ba_rsp_cnt, 1668 max_tx->agg.rx_ba_rsp_cnt); 1669 1670 if (tx->tx_power.ant_a || tx->tx_power.ant_b || tx->tx_power.ant_c) { 1671 pos += scnprintf(buf + pos, bufsz - pos, 1672 "tx power: (1/2 dB step)\n"); 1673 if ((priv->cfg->valid_tx_ant & ANT_A) && tx->tx_power.ant_a) 1674 pos += scnprintf(buf + pos, bufsz - pos, 1675 fmt_hex, "antenna A:", 1676 tx->tx_power.ant_a); 1677 if ((priv->cfg->valid_tx_ant & ANT_B) && tx->tx_power.ant_b) 1678 pos += scnprintf(buf + pos, bufsz - pos, 1679 fmt_hex, "antenna B:", 1680 tx->tx_power.ant_b); 1681 if ((priv->cfg->valid_tx_ant & ANT_C) && tx->tx_power.ant_c) 1682 pos += scnprintf(buf + pos, bufsz - pos, 1683 fmt_hex, "antenna C:", 1684 tx->tx_power.ant_c); 1685 } 1686 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); 1687 kfree(buf); 1688 return ret; 1689} 1690 1691static ssize_t iwl_dbgfs_ucode_general_stats_read(struct file *file, 1692 char __user *user_buf, 1693 size_t count, loff_t *ppos) 1694{ 1695 struct iwl_priv *priv = file->private_data; 1696 int pos = 0; 1697 char *buf; 1698 int bufsz = sizeof(struct statistics_general) * 10 + 300; 1699 ssize_t ret; 1700 struct statistics_general_common *general, *accum_general; 1701 struct statistics_general_common *delta_general, *max_general; 1702 struct statistics_dbg *dbg, *accum_dbg, *delta_dbg, *max_dbg; 1703 struct statistics_div *div, *accum_div, *delta_div, *max_div; 1704 1705 if (!iwl_is_alive(priv)) 1706 return -EAGAIN; 1707 1708 buf = kzalloc(bufsz, GFP_KERNEL); 1709 if (!buf) { 1710 IWL_ERR(priv, "Can not allocate Buffer\n"); 1711 return -ENOMEM; 1712 } 1713 1714 /* the statistic information display here is based on 1715 * the last statistics notification from uCode 1716 * might not reflect the current uCode activity 1717 */ 1718 general = &priv->statistics.common; 1719 dbg = &priv->statistics.common.dbg; 1720 div = &priv->statistics.common.div; 1721 accum_general = &priv->accum_stats.common; 1722 accum_dbg = &priv->accum_stats.common.dbg; 1723 accum_div = &priv->accum_stats.common.div; 1724 delta_general = &priv->delta_stats.common; 1725 max_general = &priv->max_delta_stats.common; 1726 delta_dbg = &priv->delta_stats.common.dbg; 1727 max_dbg = &priv->max_delta_stats.common.dbg; 1728 delta_div = &priv->delta_stats.common.div; 1729 max_div = &priv->max_delta_stats.common.div; 1730 1731 pos += iwl_statistics_flag(priv, buf, bufsz); 1732 pos += scnprintf(buf + pos, bufsz - pos, 1733 fmt_header, "Statistics_General:"); 1734 pos += scnprintf(buf + pos, bufsz - pos, 1735 fmt_value, "temperature:", 1736 le32_to_cpu(general->temperature)); 1737 pos += scnprintf(buf + pos, bufsz - pos, 1738 fmt_value, "temperature_m:", 1739 le32_to_cpu(general->temperature_m)); 1740 pos += scnprintf(buf + pos, bufsz - pos, 1741 fmt_value, "ttl_timestamp:", 1742 le32_to_cpu(general->ttl_timestamp)); 1743 pos += scnprintf(buf + pos, bufsz - pos, 1744 fmt_table, "burst_check:", 1745 le32_to_cpu(dbg->burst_check), 1746 accum_dbg->burst_check, 1747 delta_dbg->burst_check, max_dbg->burst_check); 1748 pos += scnprintf(buf + pos, bufsz - pos, 1749 fmt_table, "burst_count:", 1750 le32_to_cpu(dbg->burst_count), 1751 accum_dbg->burst_count, 1752 delta_dbg->burst_count, max_dbg->burst_count); 1753 pos += scnprintf(buf + pos, bufsz - pos, 1754 fmt_table, "wait_for_silence_timeout_count:", 1755 le32_to_cpu(dbg->wait_for_silence_timeout_cnt), 1756 accum_dbg->wait_for_silence_timeout_cnt, 1757 delta_dbg->wait_for_silence_timeout_cnt, 1758 max_dbg->wait_for_silence_timeout_cnt); 1759 pos += scnprintf(buf + pos, bufsz - pos, 1760 fmt_table, "sleep_time:", 1761 le32_to_cpu(general->sleep_time), 1762 accum_general->sleep_time, 1763 delta_general->sleep_time, max_general->sleep_time); 1764 pos += scnprintf(buf + pos, bufsz - pos, 1765 fmt_table, "slots_out:", 1766 le32_to_cpu(general->slots_out), 1767 accum_general->slots_out, 1768 delta_general->slots_out, max_general->slots_out); 1769 pos += scnprintf(buf + pos, bufsz - pos, 1770 fmt_table, "slots_idle:", 1771 le32_to_cpu(general->slots_idle), 1772 accum_general->slots_idle, 1773 delta_general->slots_idle, max_general->slots_idle); 1774 pos += scnprintf(buf + pos, bufsz - pos, 1775 fmt_table, "tx_on_a:", 1776 le32_to_cpu(div->tx_on_a), accum_div->tx_on_a, 1777 delta_div->tx_on_a, max_div->tx_on_a); 1778 pos += scnprintf(buf + pos, bufsz - pos, 1779 fmt_table, "tx_on_b:", 1780 le32_to_cpu(div->tx_on_b), accum_div->tx_on_b, 1781 delta_div->tx_on_b, max_div->tx_on_b); 1782 pos += scnprintf(buf + pos, bufsz - pos, 1783 fmt_table, "exec_time:", 1784 le32_to_cpu(div->exec_time), accum_div->exec_time, 1785 delta_div->exec_time, max_div->exec_time); 1786 pos += scnprintf(buf + pos, bufsz - pos, 1787 fmt_table, "probe_time:", 1788 le32_to_cpu(div->probe_time), accum_div->probe_time, 1789 delta_div->probe_time, max_div->probe_time); 1790 pos += scnprintf(buf + pos, bufsz - pos, 1791 fmt_table, "rx_enable_counter:", 1792 le32_to_cpu(general->rx_enable_counter), 1793 accum_general->rx_enable_counter, 1794 delta_general->rx_enable_counter, 1795 max_general->rx_enable_counter); 1796 pos += scnprintf(buf + pos, bufsz - pos, 1797 fmt_table, "num_of_sos_states:", 1798 le32_to_cpu(general->num_of_sos_states), 1799 accum_general->num_of_sos_states, 1800 delta_general->num_of_sos_states, 1801 max_general->num_of_sos_states); 1802 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); 1803 kfree(buf); 1804 return ret; 1805} 1806 1807static ssize_t iwl_dbgfs_ucode_bt_stats_read(struct file *file, 1808 char __user *user_buf, 1809 size_t count, loff_t *ppos) 1810{ 1811 struct iwl_priv *priv = (struct iwl_priv *)file->private_data; 1812 int pos = 0; 1813 char *buf; 1814 int bufsz = (sizeof(struct statistics_bt_activity) * 24) + 200; 1815 ssize_t ret; 1816 struct statistics_bt_activity *bt, *accum_bt; 1817 1818 if (!iwl_is_alive(priv)) 1819 return -EAGAIN; 1820 1821 if (!priv->bt_enable_flag) 1822 return -EINVAL; 1823 1824 /* make request to uCode to retrieve statistics information */ 1825 mutex_lock(&priv->mutex); 1826 ret = iwl_send_statistics_request(priv, CMD_SYNC, false); 1827 mutex_unlock(&priv->mutex); 1828 1829 if (ret) { 1830 IWL_ERR(priv, 1831 "Error sending statistics request: %zd\n", ret); 1832 return -EAGAIN; 1833 } 1834 buf = kzalloc(bufsz, GFP_KERNEL); 1835 if (!buf) { 1836 IWL_ERR(priv, "Can not allocate Buffer\n"); 1837 return -ENOMEM; 1838 } 1839 1840 /* 1841 * the statistic information display here is based on 1842 * the last statistics notification from uCode 1843 * might not reflect the current uCode activity 1844 */ 1845 bt = &priv->statistics.bt_activity; 1846 accum_bt = &priv->accum_stats.bt_activity; 1847 1848 pos += iwl_statistics_flag(priv, buf, bufsz); 1849 pos += scnprintf(buf + pos, bufsz - pos, "Statistics_BT:\n"); 1850 pos += scnprintf(buf + pos, bufsz - pos, 1851 "\t\t\tcurrent\t\t\taccumulative\n"); 1852 pos += scnprintf(buf + pos, bufsz - pos, 1853 "hi_priority_tx_req_cnt:\t\t%u\t\t\t%u\n", 1854 le32_to_cpu(bt->hi_priority_tx_req_cnt), 1855 accum_bt->hi_priority_tx_req_cnt); 1856 pos += scnprintf(buf + pos, bufsz - pos, 1857 "hi_priority_tx_denied_cnt:\t%u\t\t\t%u\n", 1858 le32_to_cpu(bt->hi_priority_tx_denied_cnt), 1859 accum_bt->hi_priority_tx_denied_cnt); 1860 pos += scnprintf(buf + pos, bufsz - pos, 1861 "lo_priority_tx_req_cnt:\t\t%u\t\t\t%u\n", 1862 le32_to_cpu(bt->lo_priority_tx_req_cnt), 1863 accum_bt->lo_priority_tx_req_cnt); 1864 pos += scnprintf(buf + pos, bufsz - pos, 1865 "lo_priority_tx_denied_cnt:\t%u\t\t\t%u\n", 1866 le32_to_cpu(bt->lo_priority_tx_denied_cnt), 1867 accum_bt->lo_priority_tx_denied_cnt); 1868 pos += scnprintf(buf + pos, bufsz - pos, 1869 "hi_priority_rx_req_cnt:\t\t%u\t\t\t%u\n", 1870 le32_to_cpu(bt->hi_priority_rx_req_cnt), 1871 accum_bt->hi_priority_rx_req_cnt); 1872 pos += scnprintf(buf + pos, bufsz - pos, 1873 "hi_priority_rx_denied_cnt:\t%u\t\t\t%u\n", 1874 le32_to_cpu(bt->hi_priority_rx_denied_cnt), 1875 accum_bt->hi_priority_rx_denied_cnt); 1876 pos += scnprintf(buf + pos, bufsz - pos, 1877 "lo_priority_rx_req_cnt:\t\t%u\t\t\t%u\n", 1878 le32_to_cpu(bt->lo_priority_rx_req_cnt), 1879 accum_bt->lo_priority_rx_req_cnt); 1880 pos += scnprintf(buf + pos, bufsz - pos, 1881 "lo_priority_rx_denied_cnt:\t%u\t\t\t%u\n", 1882 le32_to_cpu(bt->lo_priority_rx_denied_cnt), 1883 accum_bt->lo_priority_rx_denied_cnt); 1884 1885 pos += scnprintf(buf + pos, bufsz - pos, 1886 "(rx)num_bt_kills:\t\t%u\t\t\t%u\n", 1887 le32_to_cpu(priv->statistics.num_bt_kills), 1888 priv->statistics.accum_num_bt_kills); 1889 1890 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); 1891 kfree(buf); 1892 return ret; 1893} 1894 1895static ssize_t iwl_dbgfs_reply_tx_error_read(struct file *file, 1896 char __user *user_buf, 1897 size_t count, loff_t *ppos) 1898{ 1899 struct iwl_priv *priv = (struct iwl_priv *)file->private_data; 1900 int pos = 0; 1901 char *buf; 1902 int bufsz = (sizeof(struct reply_tx_error_statistics) * 24) + 1903 (sizeof(struct reply_agg_tx_error_statistics) * 24) + 200; 1904 ssize_t ret; 1905 1906 if (!iwl_is_alive(priv)) 1907 return -EAGAIN; 1908 1909 buf = kzalloc(bufsz, GFP_KERNEL); 1910 if (!buf) { 1911 IWL_ERR(priv, "Can not allocate Buffer\n"); 1912 return -ENOMEM; 1913 } 1914 1915 pos += scnprintf(buf + pos, bufsz - pos, "Statistics_TX_Error:\n"); 1916 pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t\t%u\n", 1917 iwl_get_tx_fail_reason(TX_STATUS_POSTPONE_DELAY), 1918 priv->reply_tx_stats.pp_delay); 1919 pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n", 1920 iwl_get_tx_fail_reason(TX_STATUS_POSTPONE_FEW_BYTES), 1921 priv->reply_tx_stats.pp_few_bytes); 1922 pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n", 1923 iwl_get_tx_fail_reason(TX_STATUS_POSTPONE_BT_PRIO), 1924 priv->reply_tx_stats.pp_bt_prio); 1925 pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n", 1926 iwl_get_tx_fail_reason(TX_STATUS_POSTPONE_QUIET_PERIOD), 1927 priv->reply_tx_stats.pp_quiet_period); 1928 pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n", 1929 iwl_get_tx_fail_reason(TX_STATUS_POSTPONE_CALC_TTAK), 1930 priv->reply_tx_stats.pp_calc_ttak); 1931 pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t%u\n", 1932 iwl_get_tx_fail_reason( 1933 TX_STATUS_FAIL_INTERNAL_CROSSED_RETRY), 1934 priv->reply_tx_stats.int_crossed_retry); 1935 pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n", 1936 iwl_get_tx_fail_reason(TX_STATUS_FAIL_SHORT_LIMIT), 1937 priv->reply_tx_stats.short_limit); 1938 pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n", 1939 iwl_get_tx_fail_reason(TX_STATUS_FAIL_LONG_LIMIT), 1940 priv->reply_tx_stats.long_limit); 1941 pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n", 1942 iwl_get_tx_fail_reason(TX_STATUS_FAIL_FIFO_UNDERRUN), 1943 priv->reply_tx_stats.fifo_underrun); 1944 pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n", 1945 iwl_get_tx_fail_reason(TX_STATUS_FAIL_DRAIN_FLOW), 1946 priv->reply_tx_stats.drain_flow); 1947 pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n", 1948 iwl_get_tx_fail_reason(TX_STATUS_FAIL_RFKILL_FLUSH), 1949 priv->reply_tx_stats.rfkill_flush); 1950 pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n", 1951 iwl_get_tx_fail_reason(TX_STATUS_FAIL_LIFE_EXPIRE), 1952 priv->reply_tx_stats.life_expire); 1953 pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n", 1954 iwl_get_tx_fail_reason(TX_STATUS_FAIL_DEST_PS), 1955 priv->reply_tx_stats.dest_ps); 1956 pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n", 1957 iwl_get_tx_fail_reason(TX_STATUS_FAIL_HOST_ABORTED), 1958 priv->reply_tx_stats.host_abort); 1959 pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n", 1960 iwl_get_tx_fail_reason(TX_STATUS_FAIL_BT_RETRY), 1961 priv->reply_tx_stats.pp_delay); 1962 pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n", 1963 iwl_get_tx_fail_reason(TX_STATUS_FAIL_STA_INVALID), 1964 priv->reply_tx_stats.sta_invalid); 1965 pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n", 1966 iwl_get_tx_fail_reason(TX_STATUS_FAIL_FRAG_DROPPED), 1967 priv->reply_tx_stats.frag_drop); 1968 pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n", 1969 iwl_get_tx_fail_reason(TX_STATUS_FAIL_TID_DISABLE), 1970 priv->reply_tx_stats.tid_disable); 1971 pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n", 1972 iwl_get_tx_fail_reason(TX_STATUS_FAIL_FIFO_FLUSHED), 1973 priv->reply_tx_stats.fifo_flush); 1974 pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t%u\n", 1975 iwl_get_tx_fail_reason( 1976 TX_STATUS_FAIL_INSUFFICIENT_CF_POLL), 1977 priv->reply_tx_stats.insuff_cf_poll); 1978 pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n", 1979 iwl_get_tx_fail_reason(TX_STATUS_FAIL_PASSIVE_NO_RX), 1980 priv->reply_tx_stats.fail_hw_drop); 1981 pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t%u\n", 1982 iwl_get_tx_fail_reason( 1983 TX_STATUS_FAIL_NO_BEACON_ON_RADAR), 1984 priv->reply_tx_stats.sta_color_mismatch); 1985 pos += scnprintf(buf + pos, bufsz - pos, "UNKNOWN:\t\t\t%u\n", 1986 priv->reply_tx_stats.unknown); 1987 1988 pos += scnprintf(buf + pos, bufsz - pos, 1989 "\nStatistics_Agg_TX_Error:\n"); 1990 1991 pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n", 1992 iwl_get_agg_tx_fail_reason(AGG_TX_STATE_UNDERRUN_MSK), 1993 priv->reply_agg_tx_stats.underrun); 1994 pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n", 1995 iwl_get_agg_tx_fail_reason(AGG_TX_STATE_BT_PRIO_MSK), 1996 priv->reply_agg_tx_stats.bt_prio); 1997 pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n", 1998 iwl_get_agg_tx_fail_reason(AGG_TX_STATE_FEW_BYTES_MSK), 1999 priv->reply_agg_tx_stats.few_bytes); 2000 pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n", 2001 iwl_get_agg_tx_fail_reason(AGG_TX_STATE_ABORT_MSK), 2002 priv->reply_agg_tx_stats.abort); 2003 pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t%u\n", 2004 iwl_get_agg_tx_fail_reason( 2005 AGG_TX_STATE_LAST_SENT_TTL_MSK), 2006 priv->reply_agg_tx_stats.last_sent_ttl); 2007 pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t%u\n", 2008 iwl_get_agg_tx_fail_reason( 2009 AGG_TX_STATE_LAST_SENT_TRY_CNT_MSK), 2010 priv->reply_agg_tx_stats.last_sent_try); 2011 pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t%u\n", 2012 iwl_get_agg_tx_fail_reason( 2013 AGG_TX_STATE_LAST_SENT_BT_KILL_MSK), 2014 priv->reply_agg_tx_stats.last_sent_bt_kill); 2015 pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n", 2016 iwl_get_agg_tx_fail_reason(AGG_TX_STATE_SCD_QUERY_MSK), 2017 priv->reply_agg_tx_stats.scd_query); 2018 pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t%u\n", 2019 iwl_get_agg_tx_fail_reason( 2020 AGG_TX_STATE_TEST_BAD_CRC32_MSK), 2021 priv->reply_agg_tx_stats.bad_crc32); 2022 pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n", 2023 iwl_get_agg_tx_fail_reason(AGG_TX_STATE_RESPONSE_MSK), 2024 priv->reply_agg_tx_stats.response); 2025 pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n", 2026 iwl_get_agg_tx_fail_reason(AGG_TX_STATE_DUMP_TX_MSK), 2027 priv->reply_agg_tx_stats.dump_tx); 2028 pos += scnprintf(buf + pos, bufsz - pos, "%s:\t\t\t%u\n", 2029 iwl_get_agg_tx_fail_reason(AGG_TX_STATE_DELAY_TX_MSK), 2030 priv->reply_agg_tx_stats.delay_tx); 2031 pos += scnprintf(buf + pos, bufsz - pos, "UNKNOWN:\t\t\t%u\n", 2032 priv->reply_agg_tx_stats.unknown); 2033 2034 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); 2035 kfree(buf); 2036 return ret; 2037} 2038 2039static ssize_t iwl_dbgfs_sensitivity_read(struct file *file, 2040 char __user *user_buf, 2041 size_t count, loff_t *ppos) { 2042 2043 struct iwl_priv *priv = file->private_data; 2044 int pos = 0; 2045 int cnt = 0; 2046 char *buf; 2047 int bufsz = sizeof(struct iwl_sensitivity_data) * 4 + 100; 2048 ssize_t ret; 2049 struct iwl_sensitivity_data *data; 2050 2051 data = &priv->sensitivity_data; 2052 buf = kzalloc(bufsz, GFP_KERNEL); 2053 if (!buf) { 2054 IWL_ERR(priv, "Can not allocate Buffer\n"); 2055 return -ENOMEM; 2056 } 2057 2058 pos += scnprintf(buf + pos, bufsz - pos, "auto_corr_ofdm:\t\t\t %u\n", 2059 data->auto_corr_ofdm); 2060 pos += scnprintf(buf + pos, bufsz - pos, 2061 "auto_corr_ofdm_mrc:\t\t %u\n", 2062 data->auto_corr_ofdm_mrc); 2063 pos += scnprintf(buf + pos, bufsz - pos, "auto_corr_ofdm_x1:\t\t %u\n", 2064 data->auto_corr_ofdm_x1); 2065 pos += scnprintf(buf + pos, bufsz - pos, 2066 "auto_corr_ofdm_mrc_x1:\t\t %u\n", 2067 data->auto_corr_ofdm_mrc_x1); 2068 pos += scnprintf(buf + pos, bufsz - pos, "auto_corr_cck:\t\t\t %u\n", 2069 data->auto_corr_cck); 2070 pos += scnprintf(buf + pos, bufsz - pos, "auto_corr_cck_mrc:\t\t %u\n", 2071 data->auto_corr_cck_mrc); 2072 pos += scnprintf(buf + pos, bufsz - pos, 2073 "last_bad_plcp_cnt_ofdm:\t\t %u\n", 2074 data->last_bad_plcp_cnt_ofdm); 2075 pos += scnprintf(buf + pos, bufsz - pos, "last_fa_cnt_ofdm:\t\t %u\n", 2076 data->last_fa_cnt_ofdm); 2077 pos += scnprintf(buf + pos, bufsz - pos, 2078 "last_bad_plcp_cnt_cck:\t\t %u\n", 2079 data->last_bad_plcp_cnt_cck); 2080 pos += scnprintf(buf + pos, bufsz - pos, "last_fa_cnt_cck:\t\t %u\n", 2081 data->last_fa_cnt_cck); 2082 pos += scnprintf(buf + pos, bufsz - pos, "nrg_curr_state:\t\t\t %u\n", 2083 data->nrg_curr_state); 2084 pos += scnprintf(buf + pos, bufsz - pos, "nrg_prev_state:\t\t\t %u\n", 2085 data->nrg_prev_state); 2086 pos += scnprintf(buf + pos, bufsz - pos, "nrg_value:\t\t\t"); 2087 for (cnt = 0; cnt < 10; cnt++) { 2088 pos += scnprintf(buf + pos, bufsz - pos, " %u", 2089 data->nrg_value[cnt]); 2090 } 2091 pos += scnprintf(buf + pos, bufsz - pos, "\n"); 2092 pos += scnprintf(buf + pos, bufsz - pos, "nrg_silence_rssi:\t\t"); 2093 for (cnt = 0; cnt < NRG_NUM_PREV_STAT_L; cnt++) { 2094 pos += scnprintf(buf + pos, bufsz - pos, " %u", 2095 data->nrg_silence_rssi[cnt]); 2096 } 2097 pos += scnprintf(buf + pos, bufsz - pos, "\n"); 2098 pos += scnprintf(buf + pos, bufsz - pos, "nrg_silence_ref:\t\t %u\n", 2099 data->nrg_silence_ref); 2100 pos += scnprintf(buf + pos, bufsz - pos, "nrg_energy_idx:\t\t\t %u\n", 2101 data->nrg_energy_idx); 2102 pos += scnprintf(buf + pos, bufsz - pos, "nrg_silence_idx:\t\t %u\n", 2103 data->nrg_silence_idx); 2104 pos += scnprintf(buf + pos, bufsz - pos, "nrg_th_cck:\t\t\t %u\n", 2105 data->nrg_th_cck); 2106 pos += scnprintf(buf + pos, bufsz - pos, 2107 "nrg_auto_corr_silence_diff:\t %u\n", 2108 data->nrg_auto_corr_silence_diff); 2109 pos += scnprintf(buf + pos, bufsz - pos, "num_in_cck_no_fa:\t\t %u\n", 2110 data->num_in_cck_no_fa); 2111 pos += scnprintf(buf + pos, bufsz - pos, "nrg_th_ofdm:\t\t\t %u\n", 2112 data->nrg_th_ofdm); 2113 2114 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); 2115 kfree(buf); 2116 return ret; 2117} 2118 2119 2120static ssize_t iwl_dbgfs_chain_noise_read(struct file *file, 2121 char __user *user_buf, 2122 size_t count, loff_t *ppos) { 2123 2124 struct iwl_priv *priv = file->private_data; 2125 int pos = 0; 2126 int cnt = 0; 2127 char *buf; 2128 int bufsz = sizeof(struct iwl_chain_noise_data) * 4 + 100; 2129 ssize_t ret; 2130 struct iwl_chain_noise_data *data; 2131 2132 data = &priv->chain_noise_data; 2133 buf = kzalloc(bufsz, GFP_KERNEL); 2134 if (!buf) { 2135 IWL_ERR(priv, "Can not allocate Buffer\n"); 2136 return -ENOMEM; 2137 } 2138 2139 pos += scnprintf(buf + pos, bufsz - pos, "active_chains:\t\t\t %u\n", 2140 data->active_chains); 2141 pos += scnprintf(buf + pos, bufsz - pos, "chain_noise_a:\t\t\t %u\n", 2142 data->chain_noise_a); 2143 pos += scnprintf(buf + pos, bufsz - pos, "chain_noise_b:\t\t\t %u\n", 2144 data->chain_noise_b); 2145 pos += scnprintf(buf + pos, bufsz - pos, "chain_noise_c:\t\t\t %u\n", 2146 data->chain_noise_c); 2147 pos += scnprintf(buf + pos, bufsz - pos, "chain_signal_a:\t\t\t %u\n", 2148 data->chain_signal_a); 2149 pos += scnprintf(buf + pos, bufsz - pos, "chain_signal_b:\t\t\t %u\n", 2150 data->chain_signal_b); 2151 pos += scnprintf(buf + pos, bufsz - pos, "chain_signal_c:\t\t\t %u\n", 2152 data->chain_signal_c); 2153 pos += scnprintf(buf + pos, bufsz - pos, "beacon_count:\t\t\t %u\n", 2154 data->beacon_count); 2155 2156 pos += scnprintf(buf + pos, bufsz - pos, "disconn_array:\t\t\t"); 2157 for (cnt = 0; cnt < NUM_RX_CHAINS; cnt++) { 2158 pos += scnprintf(buf + pos, bufsz - pos, " %u", 2159 data->disconn_array[cnt]); 2160 } 2161 pos += scnprintf(buf + pos, bufsz - pos, "\n"); 2162 pos += scnprintf(buf + pos, bufsz - pos, "delta_gain_code:\t\t"); 2163 for (cnt = 0; cnt < NUM_RX_CHAINS; cnt++) { 2164 pos += scnprintf(buf + pos, bufsz - pos, " %u", 2165 data->delta_gain_code[cnt]); 2166 } 2167 pos += scnprintf(buf + pos, bufsz - pos, "\n"); 2168 pos += scnprintf(buf + pos, bufsz - pos, "radio_write:\t\t\t %u\n", 2169 data->radio_write); 2170 pos += scnprintf(buf + pos, bufsz - pos, "state:\t\t\t\t %u\n", 2171 data->state); 2172 2173 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); 2174 kfree(buf); 2175 return ret; 2176} 2177 2178static ssize_t iwl_dbgfs_power_save_status_read(struct file *file, 2179 char __user *user_buf, 2180 size_t count, loff_t *ppos) 2181{ 2182 struct iwl_priv *priv = file->private_data; 2183 char buf[60]; 2184 int pos = 0; 2185 const size_t bufsz = sizeof(buf); 2186 u32 pwrsave_status; 2187 2188 pwrsave_status = iwl_read32(priv, CSR_GP_CNTRL) & 2189 CSR_GP_REG_POWER_SAVE_STATUS_MSK; 2190 2191 pos += scnprintf(buf + pos, bufsz - pos, "Power Save Status: "); 2192 pos += scnprintf(buf + pos, bufsz - pos, "%s\n", 2193 (pwrsave_status == CSR_GP_REG_NO_POWER_SAVE) ? "none" : 2194 (pwrsave_status == CSR_GP_REG_MAC_POWER_SAVE) ? "MAC" : 2195 (pwrsave_status == CSR_GP_REG_PHY_POWER_SAVE) ? "PHY" : 2196 "error"); 2197 2198 return simple_read_from_buffer(user_buf, count, ppos, buf, pos); 2199} 2200 2201static ssize_t iwl_dbgfs_clear_ucode_statistics_write(struct file *file, 2202 const char __user *user_buf, 2203 size_t count, loff_t *ppos) 2204{ 2205 struct iwl_priv *priv = file->private_data; 2206 char buf[8]; 2207 int buf_size; 2208 int clear; 2209 2210 memset(buf, 0, sizeof(buf)); 2211 buf_size = min(count, sizeof(buf) - 1); 2212 if (copy_from_user(buf, user_buf, buf_size)) 2213 return -EFAULT; 2214 if (sscanf(buf, "%d", &clear) != 1) 2215 return -EFAULT; 2216 2217 /* make request to uCode to retrieve statistics information */ 2218 mutex_lock(&priv->mutex); 2219 iwl_send_statistics_request(priv, CMD_SYNC, true); 2220 mutex_unlock(&priv->mutex); 2221 2222 return count; 2223} 2224 2225static ssize_t iwl_dbgfs_csr_write(struct file *file, 2226 const char __user *user_buf, 2227 size_t count, loff_t *ppos) 2228{ 2229 struct iwl_priv *priv = file->private_data; 2230 char buf[8]; 2231 int buf_size; 2232 int csr; 2233 2234 memset(buf, 0, sizeof(buf)); 2235 buf_size = min(count, sizeof(buf) - 1); 2236 if (copy_from_user(buf, user_buf, buf_size)) 2237 return -EFAULT; 2238 if (sscanf(buf, "%d", &csr) != 1) 2239 return -EFAULT; 2240 2241 iwl_dump_csr(priv); 2242 2243 return count; 2244} 2245 2246static ssize_t iwl_dbgfs_ucode_tracing_read(struct file *file, 2247 char __user *user_buf, 2248 size_t count, loff_t *ppos) { 2249 2250 struct iwl_priv *priv = file->private_data; 2251 int pos = 0; 2252 char buf[128]; 2253 const size_t bufsz = sizeof(buf); 2254 2255 pos += scnprintf(buf + pos, bufsz - pos, "ucode trace timer is %s\n", 2256 priv->event_log.ucode_trace ? "On" : "Off"); 2257 pos += scnprintf(buf + pos, bufsz - pos, "non_wraps_count:\t\t %u\n", 2258 priv->event_log.non_wraps_count); 2259 pos += scnprintf(buf + pos, bufsz - pos, "wraps_once_count:\t\t %u\n", 2260 priv->event_log.wraps_once_count); 2261 pos += scnprintf(buf + pos, bufsz - pos, "wraps_more_count:\t\t %u\n", 2262 priv->event_log.wraps_more_count); 2263 2264 return simple_read_from_buffer(user_buf, count, ppos, buf, pos); 2265} 2266 2267static ssize_t iwl_dbgfs_ucode_tracing_write(struct file *file, 2268 const char __user *user_buf, 2269 size_t count, loff_t *ppos) 2270{ 2271 struct iwl_priv *priv = file->private_data; 2272 char buf[8]; 2273 int buf_size; 2274 int trace; 2275 2276 memset(buf, 0, sizeof(buf)); 2277 buf_size = min(count, sizeof(buf) - 1); 2278 if (copy_from_user(buf, user_buf, buf_size)) 2279 return -EFAULT; 2280 if (sscanf(buf, "%d", &trace) != 1) 2281 return -EFAULT; 2282 2283 if (trace) { 2284 priv->event_log.ucode_trace = true; 2285 /* schedule the ucode timer to occur in UCODE_TRACE_PERIOD */ 2286 mod_timer(&priv->ucode_trace, 2287 jiffies + msecs_to_jiffies(UCODE_TRACE_PERIOD)); 2288 } else { 2289 priv->event_log.ucode_trace = false; 2290 del_timer_sync(&priv->ucode_trace); 2291 } 2292 2293 return count; 2294} 2295 2296static ssize_t iwl_dbgfs_rxon_flags_read(struct file *file, 2297 char __user *user_buf, 2298 size_t count, loff_t *ppos) { 2299 2300 struct iwl_priv *priv = file->private_data; 2301 int len = 0; 2302 char buf[20]; 2303 2304 len = sprintf(buf, "0x%04X\n", 2305 le32_to_cpu(priv->contexts[IWL_RXON_CTX_BSS].active.flags)); 2306 return simple_read_from_buffer(user_buf, count, ppos, buf, len); 2307} 2308 2309static ssize_t iwl_dbgfs_rxon_filter_flags_read(struct file *file, 2310 char __user *user_buf, 2311 size_t count, loff_t *ppos) { 2312 2313 struct iwl_priv *priv = file->private_data; 2314 int len = 0; 2315 char buf[20]; 2316 2317 len = sprintf(buf, "0x%04X\n", 2318 le32_to_cpu(priv->contexts[IWL_RXON_CTX_BSS].active.filter_flags)); 2319 return simple_read_from_buffer(user_buf, count, ppos, buf, len); 2320} 2321 2322static ssize_t iwl_dbgfs_fh_reg_read(struct file *file, 2323 char __user *user_buf, 2324 size_t count, loff_t *ppos) 2325{ 2326 struct iwl_priv *priv = file->private_data; 2327 char *buf; 2328 int pos = 0; 2329 ssize_t ret = -EFAULT; 2330 2331 ret = pos = iwl_dump_fh(priv, &buf, true); 2332 if (buf) { 2333 ret = simple_read_from_buffer(user_buf, 2334 count, ppos, buf, pos); 2335 kfree(buf); 2336 } 2337 2338 return ret; 2339} 2340 2341static ssize_t iwl_dbgfs_missed_beacon_read(struct file *file, 2342 char __user *user_buf, 2343 size_t count, loff_t *ppos) { 2344 2345 struct iwl_priv *priv = file->private_data; 2346 int pos = 0; 2347 char buf[12]; 2348 const size_t bufsz = sizeof(buf); 2349 2350 pos += scnprintf(buf + pos, bufsz - pos, "%d\n", 2351 priv->missed_beacon_threshold); 2352 2353 return simple_read_from_buffer(user_buf, count, ppos, buf, pos); 2354} 2355 2356static ssize_t iwl_dbgfs_missed_beacon_write(struct file *file, 2357 const char __user *user_buf, 2358 size_t count, loff_t *ppos) 2359{ 2360 struct iwl_priv *priv = file->private_data; 2361 char buf[8]; 2362 int buf_size; 2363 int missed; 2364 2365 memset(buf, 0, sizeof(buf)); 2366 buf_size = min(count, sizeof(buf) - 1); 2367 if (copy_from_user(buf, user_buf, buf_size)) 2368 return -EFAULT; 2369 if (sscanf(buf, "%d", &missed) != 1) 2370 return -EINVAL; 2371 2372 if (missed < IWL_MISSED_BEACON_THRESHOLD_MIN || 2373 missed > IWL_MISSED_BEACON_THRESHOLD_MAX) 2374 priv->missed_beacon_threshold = 2375 IWL_MISSED_BEACON_THRESHOLD_DEF; 2376 else 2377 priv->missed_beacon_threshold = missed; 2378 2379 return count; 2380} 2381 2382static ssize_t iwl_dbgfs_plcp_delta_read(struct file *file, 2383 char __user *user_buf, 2384 size_t count, loff_t *ppos) { 2385 2386 struct iwl_priv *priv = file->private_data; 2387 int pos = 0; 2388 char buf[12]; 2389 const size_t bufsz = sizeof(buf); 2390 2391 pos += scnprintf(buf + pos, bufsz - pos, "%u\n", 2392 priv->cfg->base_params->plcp_delta_threshold); 2393 2394 return simple_read_from_buffer(user_buf, count, ppos, buf, pos); 2395} 2396 2397static ssize_t iwl_dbgfs_plcp_delta_write(struct file *file, 2398 const char __user *user_buf, 2399 size_t count, loff_t *ppos) { 2400 2401 struct iwl_priv *priv = file->private_data; 2402 char buf[8]; 2403 int buf_size; 2404 int plcp; 2405 2406 memset(buf, 0, sizeof(buf)); 2407 buf_size = min(count, sizeof(buf) - 1); 2408 if (copy_from_user(buf, user_buf, buf_size)) 2409 return -EFAULT; 2410 if (sscanf(buf, "%d", &plcp) != 1) 2411 return -EINVAL; 2412 if ((plcp < IWL_MAX_PLCP_ERR_THRESHOLD_MIN) || 2413 (plcp > IWL_MAX_PLCP_ERR_THRESHOLD_MAX)) 2414 priv->cfg->base_params->plcp_delta_threshold = 2415 IWL_MAX_PLCP_ERR_THRESHOLD_DISABLE; 2416 else 2417 priv->cfg->base_params->plcp_delta_threshold = plcp; 2418 return count; 2419} 2420 2421static ssize_t iwl_dbgfs_force_reset_read(struct file *file, 2422 char __user *user_buf, 2423 size_t count, loff_t *ppos) { 2424 2425 struct iwl_priv *priv = file->private_data; 2426 int i, pos = 0; 2427 char buf[300]; 2428 const size_t bufsz = sizeof(buf); 2429 struct iwl_force_reset *force_reset; 2430 2431 for (i = 0; i < IWL_MAX_FORCE_RESET; i++) { 2432 force_reset = &priv->force_reset[i]; 2433 pos += scnprintf(buf + pos, bufsz - pos, 2434 "Force reset method %d\n", i); 2435 pos += scnprintf(buf + pos, bufsz - pos, 2436 "\tnumber of reset request: %d\n", 2437 force_reset->reset_request_count); 2438 pos += scnprintf(buf + pos, bufsz - pos, 2439 "\tnumber of reset request success: %d\n", 2440 force_reset->reset_success_count); 2441 pos += scnprintf(buf + pos, bufsz - pos, 2442 "\tnumber of reset request reject: %d\n", 2443 force_reset->reset_reject_count); 2444 pos += scnprintf(buf + pos, bufsz - pos, 2445 "\treset duration: %lu\n", 2446 force_reset->reset_duration); 2447 } 2448 return simple_read_from_buffer(user_buf, count, ppos, buf, pos); 2449} 2450 2451static ssize_t iwl_dbgfs_force_reset_write(struct file *file, 2452 const char __user *user_buf, 2453 size_t count, loff_t *ppos) { 2454 2455 struct iwl_priv *priv = file->private_data; 2456 char buf[8]; 2457 int buf_size; 2458 int reset, ret; 2459 2460 memset(buf, 0, sizeof(buf)); 2461 buf_size = min(count, sizeof(buf) - 1); 2462 if (copy_from_user(buf, user_buf, buf_size)) 2463 return -EFAULT; 2464 if (sscanf(buf, "%d", &reset) != 1) 2465 return -EINVAL; 2466 switch (reset) { 2467 case IWL_RF_RESET: 2468 case IWL_FW_RESET: 2469 ret = iwl_force_reset(priv, reset, true); 2470 break; 2471 default: 2472 return -EINVAL; 2473 } 2474 return ret ? ret : count; 2475} 2476 2477static ssize_t iwl_dbgfs_txfifo_flush_write(struct file *file, 2478 const char __user *user_buf, 2479 size_t count, loff_t *ppos) { 2480 2481 struct iwl_priv *priv = file->private_data; 2482 char buf[8]; 2483 int buf_size; 2484 int flush; 2485 2486 memset(buf, 0, sizeof(buf)); 2487 buf_size = min(count, sizeof(buf) - 1); 2488 if (copy_from_user(buf, user_buf, buf_size)) 2489 return -EFAULT; 2490 if (sscanf(buf, "%d", &flush) != 1) 2491 return -EINVAL; 2492 2493 if (iwl_is_rfkill(priv)) 2494 return -EFAULT; 2495 2496 iwlagn_dev_txfifo_flush(priv, IWL_DROP_ALL); 2497 2498 return count; 2499} 2500 2501static ssize_t iwl_dbgfs_wd_timeout_write(struct file *file, 2502 const char __user *user_buf, 2503 size_t count, loff_t *ppos) { 2504 2505 struct iwl_priv *priv = file->private_data; 2506 char buf[8]; 2507 int buf_size; 2508 int timeout; 2509 2510 memset(buf, 0, sizeof(buf)); 2511 buf_size = min(count, sizeof(buf) - 1); 2512 if (copy_from_user(buf, user_buf, buf_size)) 2513 return -EFAULT; 2514 if (sscanf(buf, "%d", &timeout) != 1) 2515 return -EINVAL; 2516 if (timeout < 0 || timeout > IWL_MAX_WD_TIMEOUT) 2517 timeout = IWL_DEF_WD_TIMEOUT; 2518 2519 priv->cfg->base_params->wd_timeout = timeout; 2520 iwl_setup_watchdog(priv); 2521 return count; 2522} 2523 2524static ssize_t iwl_dbgfs_bt_traffic_read(struct file *file, 2525 char __user *user_buf, 2526 size_t count, loff_t *ppos) { 2527 2528 struct iwl_priv *priv = (struct iwl_priv *)file->private_data; 2529 int pos = 0; 2530 char buf[200]; 2531 const size_t bufsz = sizeof(buf); 2532 2533 if (!priv->bt_enable_flag) { 2534 pos += scnprintf(buf + pos, bufsz - pos, "BT coex disabled\n"); 2535 return simple_read_from_buffer(user_buf, count, ppos, buf, pos); 2536 } 2537 pos += scnprintf(buf + pos, bufsz - pos, "BT enable flag: 0x%x\n", 2538 priv->bt_enable_flag); 2539 pos += scnprintf(buf + pos, bufsz - pos, "BT in %s mode\n", 2540 priv->bt_full_concurrent ? "full concurrency" : "3-wire"); 2541 pos += scnprintf(buf + pos, bufsz - pos, "BT status: %s, " 2542 "last traffic notif: %d\n", 2543 priv->bt_status ? "On" : "Off", priv->last_bt_traffic_load); 2544 pos += scnprintf(buf + pos, bufsz - pos, "ch_announcement: %d, " 2545 "kill_ack_mask: %x, kill_cts_mask: %x\n", 2546 priv->bt_ch_announce, priv->kill_ack_mask, 2547 priv->kill_cts_mask); 2548 2549 pos += scnprintf(buf + pos, bufsz - pos, "bluetooth traffic load: "); 2550 switch (priv->bt_traffic_load) { 2551 case IWL_BT_COEX_TRAFFIC_LOAD_CONTINUOUS: 2552 pos += scnprintf(buf + pos, bufsz - pos, "Continuous\n"); 2553 break; 2554 case IWL_BT_COEX_TRAFFIC_LOAD_HIGH: 2555 pos += scnprintf(buf + pos, bufsz - pos, "High\n"); 2556 break; 2557 case IWL_BT_COEX_TRAFFIC_LOAD_LOW: 2558 pos += scnprintf(buf + pos, bufsz - pos, "Low\n"); 2559 break; 2560 case IWL_BT_COEX_TRAFFIC_LOAD_NONE: 2561 default: 2562 pos += scnprintf(buf + pos, bufsz - pos, "None\n"); 2563 break; 2564 } 2565 2566 return simple_read_from_buffer(user_buf, count, ppos, buf, pos); 2567} 2568 2569static ssize_t iwl_dbgfs_protection_mode_read(struct file *file, 2570 char __user *user_buf, 2571 size_t count, loff_t *ppos) 2572{ 2573 struct iwl_priv *priv = (struct iwl_priv *)file->private_data; 2574 2575 int pos = 0; 2576 char buf[40]; 2577 const size_t bufsz = sizeof(buf); 2578 2579 if (priv->cfg->ht_params) 2580 pos += scnprintf(buf + pos, bufsz - pos, 2581 "use %s for aggregation\n", 2582 (priv->cfg->ht_params->use_rts_for_aggregation) ? 2583 "rts/cts" : "cts-to-self"); 2584 else 2585 pos += scnprintf(buf + pos, bufsz - pos, "N/A"); 2586 2587 return simple_read_from_buffer(user_buf, count, ppos, buf, pos); 2588} 2589 2590static ssize_t iwl_dbgfs_protection_mode_write(struct file *file, 2591 const char __user *user_buf, 2592 size_t count, loff_t *ppos) { 2593 2594 struct iwl_priv *priv = file->private_data; 2595 char buf[8]; 2596 int buf_size; 2597 int rts; 2598 2599 if (!priv->cfg->ht_params) 2600 return -EINVAL; 2601 2602 memset(buf, 0, sizeof(buf)); 2603 buf_size = min(count, sizeof(buf) - 1); 2604 if (copy_from_user(buf, user_buf, buf_size)) 2605 return -EFAULT; 2606 if (sscanf(buf, "%d", &rts) != 1) 2607 return -EINVAL; 2608 if (rts) 2609 priv->cfg->ht_params->use_rts_for_aggregation = true; 2610 else 2611 priv->cfg->ht_params->use_rts_for_aggregation = false; 2612 return count; 2613} 2614 2615DEBUGFS_READ_FILE_OPS(rx_statistics); 2616DEBUGFS_READ_FILE_OPS(tx_statistics); 2617DEBUGFS_READ_WRITE_FILE_OPS(traffic_log); 2618DEBUGFS_READ_FILE_OPS(rx_queue); 2619DEBUGFS_READ_FILE_OPS(tx_queue); 2620DEBUGFS_READ_FILE_OPS(ucode_rx_stats); 2621DEBUGFS_READ_FILE_OPS(ucode_tx_stats); 2622DEBUGFS_READ_FILE_OPS(ucode_general_stats); 2623DEBUGFS_READ_FILE_OPS(sensitivity); 2624DEBUGFS_READ_FILE_OPS(chain_noise); 2625DEBUGFS_READ_FILE_OPS(power_save_status); 2626DEBUGFS_WRITE_FILE_OPS(clear_ucode_statistics); 2627DEBUGFS_WRITE_FILE_OPS(clear_traffic_statistics); 2628DEBUGFS_WRITE_FILE_OPS(csr); 2629DEBUGFS_READ_WRITE_FILE_OPS(ucode_tracing); 2630DEBUGFS_READ_FILE_OPS(fh_reg); 2631DEBUGFS_READ_WRITE_FILE_OPS(missed_beacon); 2632DEBUGFS_READ_WRITE_FILE_OPS(plcp_delta); 2633DEBUGFS_READ_WRITE_FILE_OPS(force_reset); 2634DEBUGFS_READ_FILE_OPS(rxon_flags); 2635DEBUGFS_READ_FILE_OPS(rxon_filter_flags); 2636DEBUGFS_WRITE_FILE_OPS(txfifo_flush); 2637DEBUGFS_READ_FILE_OPS(ucode_bt_stats); 2638DEBUGFS_WRITE_FILE_OPS(wd_timeout); 2639DEBUGFS_READ_FILE_OPS(bt_traffic); 2640DEBUGFS_READ_WRITE_FILE_OPS(protection_mode); 2641DEBUGFS_READ_FILE_OPS(reply_tx_error); 2642 2643/* 2644 * Create the debugfs files and directories 2645 * 2646 */ 2647int iwl_dbgfs_register(struct iwl_priv *priv, const char *name) 2648{ 2649 struct dentry *phyd = priv->hw->wiphy->debugfsdir; 2650 struct dentry *dir_drv, *dir_data, *dir_rf, *dir_debug; 2651 2652 dir_drv = debugfs_create_dir(name, phyd); 2653 if (!dir_drv) 2654 return -ENOMEM; 2655 2656 priv->debugfs_dir = dir_drv; 2657 2658 dir_data = debugfs_create_dir("data", dir_drv); 2659 if (!dir_data) 2660 goto err; 2661 dir_rf = debugfs_create_dir("rf", dir_drv); 2662 if (!dir_rf) 2663 goto err; 2664 dir_debug = debugfs_create_dir("debug", dir_drv); 2665 if (!dir_debug) 2666 goto err; 2667 2668 DEBUGFS_ADD_FILE(nvm, dir_data, S_IRUSR); 2669 DEBUGFS_ADD_FILE(sram, dir_data, S_IWUSR | S_IRUSR); 2670 DEBUGFS_ADD_FILE(log_event, dir_data, S_IWUSR | S_IRUSR); 2671 DEBUGFS_ADD_FILE(stations, dir_data, S_IRUSR); 2672 DEBUGFS_ADD_FILE(channels, dir_data, S_IRUSR); 2673 DEBUGFS_ADD_FILE(status, dir_data, S_IRUSR); 2674 DEBUGFS_ADD_FILE(interrupt, dir_data, S_IWUSR | S_IRUSR); 2675 DEBUGFS_ADD_FILE(qos, dir_data, S_IRUSR); 2676 DEBUGFS_ADD_FILE(sleep_level_override, dir_data, S_IWUSR | S_IRUSR); 2677 DEBUGFS_ADD_FILE(current_sleep_command, dir_data, S_IRUSR); 2678 DEBUGFS_ADD_FILE(thermal_throttling, dir_data, S_IRUSR); 2679 DEBUGFS_ADD_FILE(disable_ht40, dir_data, S_IWUSR | S_IRUSR); 2680 DEBUGFS_ADD_FILE(rx_statistics, dir_debug, S_IRUSR); 2681 DEBUGFS_ADD_FILE(tx_statistics, dir_debug, S_IRUSR); 2682 DEBUGFS_ADD_FILE(traffic_log, dir_debug, S_IWUSR | S_IRUSR); 2683 DEBUGFS_ADD_FILE(rx_queue, dir_debug, S_IRUSR); 2684 DEBUGFS_ADD_FILE(tx_queue, dir_debug, S_IRUSR); 2685 DEBUGFS_ADD_FILE(power_save_status, dir_debug, S_IRUSR); 2686 DEBUGFS_ADD_FILE(clear_ucode_statistics, dir_debug, S_IWUSR); 2687 DEBUGFS_ADD_FILE(clear_traffic_statistics, dir_debug, S_IWUSR); 2688 DEBUGFS_ADD_FILE(csr, dir_debug, S_IWUSR); 2689 DEBUGFS_ADD_FILE(fh_reg, dir_debug, S_IRUSR); 2690 DEBUGFS_ADD_FILE(missed_beacon, dir_debug, S_IWUSR); 2691 DEBUGFS_ADD_FILE(plcp_delta, dir_debug, S_IWUSR | S_IRUSR); 2692 DEBUGFS_ADD_FILE(force_reset, dir_debug, S_IWUSR | S_IRUSR); 2693 DEBUGFS_ADD_FILE(ucode_rx_stats, dir_debug, S_IRUSR); 2694 DEBUGFS_ADD_FILE(ucode_tx_stats, dir_debug, S_IRUSR); 2695 DEBUGFS_ADD_FILE(ucode_general_stats, dir_debug, S_IRUSR); 2696 DEBUGFS_ADD_FILE(txfifo_flush, dir_debug, S_IWUSR); 2697 DEBUGFS_ADD_FILE(protection_mode, dir_debug, S_IWUSR | S_IRUSR); 2698 2699 DEBUGFS_ADD_FILE(sensitivity, dir_debug, S_IRUSR); 2700 DEBUGFS_ADD_FILE(chain_noise, dir_debug, S_IRUSR); 2701 DEBUGFS_ADD_FILE(ucode_tracing, dir_debug, S_IWUSR | S_IRUSR); 2702 DEBUGFS_ADD_FILE(ucode_bt_stats, dir_debug, S_IRUSR); 2703 DEBUGFS_ADD_FILE(reply_tx_error, dir_debug, S_IRUSR); 2704 DEBUGFS_ADD_FILE(rxon_flags, dir_debug, S_IWUSR); 2705 DEBUGFS_ADD_FILE(rxon_filter_flags, dir_debug, S_IWUSR); 2706 DEBUGFS_ADD_FILE(wd_timeout, dir_debug, S_IWUSR); 2707 if (iwl_advanced_bt_coexist(priv)) 2708 DEBUGFS_ADD_FILE(bt_traffic, dir_debug, S_IRUSR); 2709 DEBUGFS_ADD_BOOL(disable_sensitivity, dir_rf, 2710 &priv->disable_sens_cal); 2711 DEBUGFS_ADD_BOOL(disable_chain_noise, dir_rf, 2712 &priv->disable_chain_noise_cal); 2713 return 0; 2714 2715err: 2716 IWL_ERR(priv, "Can't create the debugfs directory\n"); 2717 iwl_dbgfs_unregister(priv); 2718 return -ENOMEM; 2719} 2720 2721/** 2722 * Remove the debugfs files and directories 2723 * 2724 */ 2725void iwl_dbgfs_unregister(struct iwl_priv *priv) 2726{ 2727 if (!priv->debugfs_dir) 2728 return; 2729 2730 debugfs_remove_recursive(priv->debugfs_dir); 2731 priv->debugfs_dir = NULL; 2732} 2733 2734 2735 2736