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