iwl-debugfs.c revision 6ab10ff8738dfb098fd32132b7ebcf5cdb43ebde
1/****************************************************************************** 2 * 3 * GPL LICENSE SUMMARY 4 * 5 * Copyright(c) 2008 - 2009 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/kernel.h> 30#include <linux/module.h> 31#include <linux/debugfs.h> 32 33#include <linux/ieee80211.h> 34#include <net/mac80211.h> 35 36 37#include "iwl-dev.h" 38#include "iwl-debug.h" 39#include "iwl-core.h" 40#include "iwl-io.h" 41#include "iwl-calib.h" 42 43/* create and remove of files */ 44#define DEBUGFS_ADD_DIR(name, parent) do { \ 45 dbgfs->dir_##name = debugfs_create_dir(#name, parent); \ 46 if (!(dbgfs->dir_##name)) \ 47 goto err; \ 48} while (0) 49 50#define DEBUGFS_ADD_FILE(name, parent) do { \ 51 dbgfs->dbgfs_##parent##_files.file_##name = \ 52 debugfs_create_file(#name, S_IWUSR | S_IRUSR, \ 53 dbgfs->dir_##parent, priv, \ 54 &iwl_dbgfs_##name##_ops); \ 55 if (!(dbgfs->dbgfs_##parent##_files.file_##name)) \ 56 goto err; \ 57} while (0) 58 59#define DEBUGFS_ADD_BOOL(name, parent, ptr) do { \ 60 dbgfs->dbgfs_##parent##_files.file_##name = \ 61 debugfs_create_bool(#name, S_IWUSR | S_IRUSR, \ 62 dbgfs->dir_##parent, ptr); \ 63 if (IS_ERR(dbgfs->dbgfs_##parent##_files.file_##name) \ 64 || !dbgfs->dbgfs_##parent##_files.file_##name) \ 65 goto err; \ 66} while (0) 67 68#define DEBUGFS_ADD_X32(name, parent, ptr) do { \ 69 dbgfs->dbgfs_##parent##_files.file_##name = \ 70 debugfs_create_x32(#name, S_IRUSR, dbgfs->dir_##parent, ptr); \ 71 if (IS_ERR(dbgfs->dbgfs_##parent##_files.file_##name) \ 72 || !dbgfs->dbgfs_##parent##_files.file_##name) \ 73 goto err; \ 74} while (0) 75 76#define DEBUGFS_REMOVE(name) do { \ 77 debugfs_remove(name); \ 78 name = NULL; \ 79} while (0); 80 81/* file operation */ 82#define DEBUGFS_READ_FUNC(name) \ 83static ssize_t iwl_dbgfs_##name##_read(struct file *file, \ 84 char __user *user_buf, \ 85 size_t count, loff_t *ppos); 86 87#define DEBUGFS_WRITE_FUNC(name) \ 88static ssize_t iwl_dbgfs_##name##_write(struct file *file, \ 89 const char __user *user_buf, \ 90 size_t count, loff_t *ppos); 91 92 93static int iwl_dbgfs_open_file_generic(struct inode *inode, struct file *file) 94{ 95 file->private_data = inode->i_private; 96 return 0; 97} 98 99#define DEBUGFS_READ_FILE_OPS(name) \ 100 DEBUGFS_READ_FUNC(name); \ 101static const struct file_operations iwl_dbgfs_##name##_ops = { \ 102 .read = iwl_dbgfs_##name##_read, \ 103 .open = iwl_dbgfs_open_file_generic, \ 104}; 105 106#define DEBUGFS_WRITE_FILE_OPS(name) \ 107 DEBUGFS_WRITE_FUNC(name); \ 108static const struct file_operations iwl_dbgfs_##name##_ops = { \ 109 .write = iwl_dbgfs_##name##_write, \ 110 .open = iwl_dbgfs_open_file_generic, \ 111}; 112 113 114#define DEBUGFS_READ_WRITE_FILE_OPS(name) \ 115 DEBUGFS_READ_FUNC(name); \ 116 DEBUGFS_WRITE_FUNC(name); \ 117static const struct file_operations iwl_dbgfs_##name##_ops = { \ 118 .write = iwl_dbgfs_##name##_write, \ 119 .read = iwl_dbgfs_##name##_read, \ 120 .open = iwl_dbgfs_open_file_generic, \ 121}; 122 123 124static ssize_t iwl_dbgfs_tx_statistics_read(struct file *file, 125 char __user *user_buf, 126 size_t count, loff_t *ppos) { 127 128 struct iwl_priv *priv = (struct iwl_priv *)file->private_data; 129 char *buf; 130 int pos = 0; 131 132 int cnt; 133 ssize_t ret; 134 const size_t bufsz = 100 + 135 sizeof(char) * 50 * (MANAGEMENT_MAX + CONTROL_MAX); 136 buf = kzalloc(bufsz, GFP_KERNEL); 137 if (!buf) 138 return -ENOMEM; 139 pos += scnprintf(buf + pos, bufsz - pos, "Management:\n"); 140 for (cnt = 0; cnt < MANAGEMENT_MAX; cnt++) { 141 pos += scnprintf(buf + pos, bufsz - pos, 142 "\t%25s\t\t: %u\n", 143 get_mgmt_string(cnt), 144 priv->tx_stats.mgmt[cnt]); 145 } 146 pos += scnprintf(buf + pos, bufsz - pos, "Control\n"); 147 for (cnt = 0; cnt < CONTROL_MAX; cnt++) { 148 pos += scnprintf(buf + pos, bufsz - pos, 149 "\t%25s\t\t: %u\n", 150 get_ctrl_string(cnt), 151 priv->tx_stats.ctrl[cnt]); 152 } 153 pos += scnprintf(buf + pos, bufsz - pos, "Data:\n"); 154 pos += scnprintf(buf + pos, bufsz - pos, "\tcnt: %u\n", 155 priv->tx_stats.data_cnt); 156 pos += scnprintf(buf + pos, bufsz - pos, "\tbytes: %llu\n", 157 priv->tx_stats.data_bytes); 158 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); 159 kfree(buf); 160 return ret; 161} 162 163static ssize_t iwl_dbgfs_tx_statistics_write(struct file *file, 164 const char __user *user_buf, 165 size_t count, loff_t *ppos) 166{ 167 struct iwl_priv *priv = file->private_data; 168 u32 clear_flag; 169 char buf[8]; 170 int buf_size; 171 172 memset(buf, 0, sizeof(buf)); 173 buf_size = min(count, sizeof(buf) - 1); 174 if (copy_from_user(buf, user_buf, buf_size)) 175 return -EFAULT; 176 if (sscanf(buf, "%x", &clear_flag) != 1) 177 return -EFAULT; 178 if (clear_flag == 1) 179 iwl_clear_tx_stats(priv); 180 181 return count; 182} 183 184static ssize_t iwl_dbgfs_rx_statistics_read(struct file *file, 185 char __user *user_buf, 186 size_t count, loff_t *ppos) { 187 188 struct iwl_priv *priv = (struct iwl_priv *)file->private_data; 189 char *buf; 190 int pos = 0; 191 int cnt; 192 ssize_t ret; 193 const size_t bufsz = 100 + 194 sizeof(char) * 50 * (MANAGEMENT_MAX + CONTROL_MAX); 195 buf = kzalloc(bufsz, GFP_KERNEL); 196 if (!buf) 197 return -ENOMEM; 198 199 pos += scnprintf(buf + pos, bufsz - pos, "Management:\n"); 200 for (cnt = 0; cnt < MANAGEMENT_MAX; cnt++) { 201 pos += scnprintf(buf + pos, bufsz - pos, 202 "\t%25s\t\t: %u\n", 203 get_mgmt_string(cnt), 204 priv->rx_stats.mgmt[cnt]); 205 } 206 pos += scnprintf(buf + pos, bufsz - pos, "Control:\n"); 207 for (cnt = 0; cnt < CONTROL_MAX; cnt++) { 208 pos += scnprintf(buf + pos, bufsz - pos, 209 "\t%25s\t\t: %u\n", 210 get_ctrl_string(cnt), 211 priv->rx_stats.ctrl[cnt]); 212 } 213 pos += scnprintf(buf + pos, bufsz - pos, "Data:\n"); 214 pos += scnprintf(buf + pos, bufsz - pos, "\tcnt: %u\n", 215 priv->rx_stats.data_cnt); 216 pos += scnprintf(buf + pos, bufsz - pos, "\tbytes: %llu\n", 217 priv->rx_stats.data_bytes); 218 219 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); 220 kfree(buf); 221 return ret; 222} 223 224static ssize_t iwl_dbgfs_rx_statistics_write(struct file *file, 225 const char __user *user_buf, 226 size_t count, loff_t *ppos) 227{ 228 struct iwl_priv *priv = file->private_data; 229 u32 clear_flag; 230 char buf[8]; 231 int buf_size; 232 233 memset(buf, 0, sizeof(buf)); 234 buf_size = min(count, sizeof(buf) - 1); 235 if (copy_from_user(buf, user_buf, buf_size)) 236 return -EFAULT; 237 if (sscanf(buf, "%x", &clear_flag) != 1) 238 return -EFAULT; 239 if (clear_flag == 1) 240 iwl_clear_rx_stats(priv); 241 return count; 242} 243 244#define BYTE1_MASK 0x000000ff; 245#define BYTE2_MASK 0x0000ffff; 246#define BYTE3_MASK 0x00ffffff; 247static ssize_t iwl_dbgfs_sram_read(struct file *file, 248 char __user *user_buf, 249 size_t count, loff_t *ppos) 250{ 251 u32 val; 252 char buf[1024]; 253 ssize_t ret; 254 int i; 255 int pos = 0; 256 struct iwl_priv *priv = (struct iwl_priv *)file->private_data; 257 const size_t bufsz = sizeof(buf); 258 259 for (i = priv->dbgfs->sram_len; i > 0; i -= 4) { 260 val = iwl_read_targ_mem(priv, priv->dbgfs->sram_offset + \ 261 priv->dbgfs->sram_len - i); 262 if (i < 4) { 263 switch (i) { 264 case 1: 265 val &= BYTE1_MASK; 266 break; 267 case 2: 268 val &= BYTE2_MASK; 269 break; 270 case 3: 271 val &= BYTE3_MASK; 272 break; 273 } 274 } 275 pos += scnprintf(buf + pos, bufsz - pos, "0x%08x ", val); 276 } 277 pos += scnprintf(buf + pos, bufsz - pos, "\n"); 278 279 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); 280 return ret; 281} 282 283static ssize_t iwl_dbgfs_sram_write(struct file *file, 284 const char __user *user_buf, 285 size_t count, loff_t *ppos) 286{ 287 struct iwl_priv *priv = file->private_data; 288 char buf[64]; 289 int buf_size; 290 u32 offset, len; 291 292 memset(buf, 0, sizeof(buf)); 293 buf_size = min(count, sizeof(buf) - 1); 294 if (copy_from_user(buf, user_buf, buf_size)) 295 return -EFAULT; 296 297 if (sscanf(buf, "%x,%x", &offset, &len) == 2) { 298 priv->dbgfs->sram_offset = offset; 299 priv->dbgfs->sram_len = len; 300 } else { 301 priv->dbgfs->sram_offset = 0; 302 priv->dbgfs->sram_len = 0; 303 } 304 305 return count; 306} 307 308static ssize_t iwl_dbgfs_stations_read(struct file *file, char __user *user_buf, 309 size_t count, loff_t *ppos) 310{ 311 struct iwl_priv *priv = (struct iwl_priv *)file->private_data; 312 struct iwl_station_entry *station; 313 int max_sta = priv->hw_params.max_stations; 314 char *buf; 315 int i, j, pos = 0; 316 ssize_t ret; 317 /* Add 30 for initial string */ 318 const size_t bufsz = 30 + sizeof(char) * 500 * (priv->num_stations); 319 320 buf = kmalloc(bufsz, GFP_KERNEL); 321 if (!buf) 322 return -ENOMEM; 323 324 pos += scnprintf(buf + pos, bufsz - pos, "num of stations: %d\n\n", 325 priv->num_stations); 326 327 for (i = 0; i < max_sta; i++) { 328 station = &priv->stations[i]; 329 if (station->used) { 330 pos += scnprintf(buf + pos, bufsz - pos, 331 "station %d:\ngeneral data:\n", i+1); 332 pos += scnprintf(buf + pos, bufsz - pos, "id: %u\n", 333 station->sta.sta.sta_id); 334 pos += scnprintf(buf + pos, bufsz - pos, "mode: %u\n", 335 station->sta.mode); 336 pos += scnprintf(buf + pos, bufsz - pos, 337 "flags: 0x%x\n", 338 station->sta.station_flags_msk); 339 pos += scnprintf(buf + pos, bufsz - pos, "tid data:\n"); 340 pos += scnprintf(buf + pos, bufsz - pos, 341 "seq_num\t\ttxq_id"); 342 pos += scnprintf(buf + pos, bufsz - pos, 343 "\tframe_count\twait_for_ba\t"); 344 pos += scnprintf(buf + pos, bufsz - pos, 345 "start_idx\tbitmap0\t"); 346 pos += scnprintf(buf + pos, bufsz - pos, 347 "bitmap1\trate_n_flags"); 348 pos += scnprintf(buf + pos, bufsz - pos, "\n"); 349 350 for (j = 0; j < MAX_TID_COUNT; j++) { 351 pos += scnprintf(buf + pos, bufsz - pos, 352 "[%d]:\t\t%u", j, 353 station->tid[j].seq_number); 354 pos += scnprintf(buf + pos, bufsz - pos, 355 "\t%u\t\t%u\t\t%u\t\t", 356 station->tid[j].agg.txq_id, 357 station->tid[j].agg.frame_count, 358 station->tid[j].agg.wait_for_ba); 359 pos += scnprintf(buf + pos, bufsz - pos, 360 "%u\t%llu\t%u", 361 station->tid[j].agg.start_idx, 362 (unsigned long long)station->tid[j].agg.bitmap, 363 station->tid[j].agg.rate_n_flags); 364 pos += scnprintf(buf + pos, bufsz - pos, "\n"); 365 } 366 pos += scnprintf(buf + pos, bufsz - pos, "\n"); 367 } 368 } 369 370 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); 371 kfree(buf); 372 return ret; 373} 374 375static ssize_t iwl_dbgfs_nvm_read(struct file *file, 376 char __user *user_buf, 377 size_t count, 378 loff_t *ppos) 379{ 380 ssize_t ret; 381 struct iwl_priv *priv = (struct iwl_priv *)file->private_data; 382 int pos = 0, ofs = 0, buf_size = 0; 383 const u8 *ptr; 384 char *buf; 385 u16 eeprom_ver; 386 size_t eeprom_len = priv->cfg->eeprom_size; 387 buf_size = 4 * eeprom_len + 256; 388 389 if (eeprom_len % 16) { 390 IWL_ERR(priv, "NVM size is not multiple of 16.\n"); 391 return -ENODATA; 392 } 393 394 ptr = priv->eeprom; 395 if (!ptr) { 396 IWL_ERR(priv, "Invalid EEPROM/OTP memory\n"); 397 return -ENOMEM; 398 } 399 400 /* 4 characters for byte 0xYY */ 401 buf = kzalloc(buf_size, GFP_KERNEL); 402 if (!buf) { 403 IWL_ERR(priv, "Can not allocate Buffer\n"); 404 return -ENOMEM; 405 } 406 eeprom_ver = iwl_eeprom_query16(priv, EEPROM_VERSION); 407 pos += scnprintf(buf + pos, buf_size - pos, "NVM Type: %s, " 408 "version: 0x%x\n", 409 (priv->nvm_device_type == NVM_DEVICE_TYPE_OTP) 410 ? "OTP" : "EEPROM", eeprom_ver); 411 for (ofs = 0 ; ofs < eeprom_len ; ofs += 16) { 412 pos += scnprintf(buf + pos, buf_size - pos, "0x%.4x ", ofs); 413 hex_dump_to_buffer(ptr + ofs, 16 , 16, 2, buf + pos, 414 buf_size - pos, 0); 415 pos += strlen(buf + pos); 416 if (buf_size - pos > 0) 417 buf[pos++] = '\n'; 418 } 419 420 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); 421 kfree(buf); 422 return ret; 423} 424 425static ssize_t iwl_dbgfs_log_event_write(struct file *file, 426 const char __user *user_buf, 427 size_t count, loff_t *ppos) 428{ 429 struct iwl_priv *priv = file->private_data; 430 u32 event_log_flag; 431 char buf[8]; 432 int buf_size; 433 434 memset(buf, 0, sizeof(buf)); 435 buf_size = min(count, sizeof(buf) - 1); 436 if (copy_from_user(buf, user_buf, buf_size)) 437 return -EFAULT; 438 if (sscanf(buf, "%d", &event_log_flag) != 1) 439 return -EFAULT; 440 if (event_log_flag == 1) 441 priv->cfg->ops->lib->dump_nic_event_log(priv); 442 443 return count; 444} 445 446 447 448static ssize_t iwl_dbgfs_channels_read(struct file *file, char __user *user_buf, 449 size_t count, loff_t *ppos) 450{ 451 struct iwl_priv *priv = (struct iwl_priv *)file->private_data; 452 struct ieee80211_channel *channels = NULL; 453 const struct ieee80211_supported_band *supp_band = NULL; 454 int pos = 0, i, bufsz = PAGE_SIZE; 455 char *buf; 456 ssize_t ret; 457 458 if (!test_bit(STATUS_GEO_CONFIGURED, &priv->status)) 459 return -EAGAIN; 460 461 buf = kzalloc(bufsz, GFP_KERNEL); 462 if (!buf) { 463 IWL_ERR(priv, "Can not allocate Buffer\n"); 464 return -ENOMEM; 465 } 466 467 supp_band = iwl_get_hw_mode(priv, IEEE80211_BAND_2GHZ); 468 if (supp_band) { 469 channels = supp_band->channels; 470 471 pos += scnprintf(buf + pos, bufsz - pos, 472 "Displaying %d channels in 2.4GHz band 802.11bg):\n", 473 supp_band->n_channels); 474 475 for (i = 0; i < supp_band->n_channels; i++) 476 pos += scnprintf(buf + pos, bufsz - pos, 477 "%d: %ddBm: BSS%s%s, %s.\n", 478 ieee80211_frequency_to_channel( 479 channels[i].center_freq), 480 channels[i].max_power, 481 channels[i].flags & IEEE80211_CHAN_RADAR ? 482 " (IEEE 802.11h required)" : "", 483 ((channels[i].flags & IEEE80211_CHAN_NO_IBSS) 484 || (channels[i].flags & 485 IEEE80211_CHAN_RADAR)) ? "" : 486 ", IBSS", 487 channels[i].flags & 488 IEEE80211_CHAN_PASSIVE_SCAN ? 489 "passive only" : "active/passive"); 490 } 491 supp_band = iwl_get_hw_mode(priv, IEEE80211_BAND_5GHZ); 492 if (supp_band) { 493 channels = supp_band->channels; 494 495 pos += scnprintf(buf + pos, bufsz - pos, 496 "Displaying %d channels in 5.2GHz band (802.11a)\n", 497 supp_band->n_channels); 498 499 for (i = 0; i < supp_band->n_channels; i++) 500 pos += scnprintf(buf + pos, bufsz - pos, 501 "%d: %ddBm: BSS%s%s, %s.\n", 502 ieee80211_frequency_to_channel( 503 channels[i].center_freq), 504 channels[i].max_power, 505 channels[i].flags & IEEE80211_CHAN_RADAR ? 506 " (IEEE 802.11h required)" : "", 507 ((channels[i].flags & IEEE80211_CHAN_NO_IBSS) 508 || (channels[i].flags & 509 IEEE80211_CHAN_RADAR)) ? "" : 510 ", IBSS", 511 channels[i].flags & 512 IEEE80211_CHAN_PASSIVE_SCAN ? 513 "passive only" : "active/passive"); 514 } 515 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); 516 kfree(buf); 517 return ret; 518} 519 520static ssize_t iwl_dbgfs_status_read(struct file *file, 521 char __user *user_buf, 522 size_t count, loff_t *ppos) { 523 524 struct iwl_priv *priv = (struct iwl_priv *)file->private_data; 525 char buf[512]; 526 int pos = 0; 527 const size_t bufsz = sizeof(buf); 528 529 pos += scnprintf(buf + pos, bufsz - pos, "STATUS_HCMD_ACTIVE:\t %d\n", 530 test_bit(STATUS_HCMD_ACTIVE, &priv->status)); 531 pos += scnprintf(buf + pos, bufsz - pos, "STATUS_HCMD_SYNC_ACTIVE: %d\n", 532 test_bit(STATUS_HCMD_SYNC_ACTIVE, &priv->status)); 533 pos += scnprintf(buf + pos, bufsz - pos, "STATUS_INT_ENABLED:\t %d\n", 534 test_bit(STATUS_INT_ENABLED, &priv->status)); 535 pos += scnprintf(buf + pos, bufsz - pos, "STATUS_RF_KILL_HW:\t %d\n", 536 test_bit(STATUS_RF_KILL_HW, &priv->status)); 537 pos += scnprintf(buf + pos, bufsz - pos, "STATUS_CT_KILL:\t\t %d\n", 538 test_bit(STATUS_CT_KILL, &priv->status)); 539 pos += scnprintf(buf + pos, bufsz - pos, "STATUS_INIT:\t\t %d\n", 540 test_bit(STATUS_INIT, &priv->status)); 541 pos += scnprintf(buf + pos, bufsz - pos, "STATUS_ALIVE:\t\t %d\n", 542 test_bit(STATUS_ALIVE, &priv->status)); 543 pos += scnprintf(buf + pos, bufsz - pos, "STATUS_READY:\t\t %d\n", 544 test_bit(STATUS_READY, &priv->status)); 545 pos += scnprintf(buf + pos, bufsz - pos, "STATUS_TEMPERATURE:\t %d\n", 546 test_bit(STATUS_TEMPERATURE, &priv->status)); 547 pos += scnprintf(buf + pos, bufsz - pos, "STATUS_GEO_CONFIGURED:\t %d\n", 548 test_bit(STATUS_GEO_CONFIGURED, &priv->status)); 549 pos += scnprintf(buf + pos, bufsz - pos, "STATUS_EXIT_PENDING:\t %d\n", 550 test_bit(STATUS_EXIT_PENDING, &priv->status)); 551 pos += scnprintf(buf + pos, bufsz - pos, "STATUS_STATISTICS:\t %d\n", 552 test_bit(STATUS_STATISTICS, &priv->status)); 553 pos += scnprintf(buf + pos, bufsz - pos, "STATUS_SCANNING:\t %d\n", 554 test_bit(STATUS_SCANNING, &priv->status)); 555 pos += scnprintf(buf + pos, bufsz - pos, "STATUS_SCAN_ABORTING:\t %d\n", 556 test_bit(STATUS_SCAN_ABORTING, &priv->status)); 557 pos += scnprintf(buf + pos, bufsz - pos, "STATUS_SCAN_HW:\t\t %d\n", 558 test_bit(STATUS_SCAN_HW, &priv->status)); 559 pos += scnprintf(buf + pos, bufsz - pos, "STATUS_POWER_PMI:\t %d\n", 560 test_bit(STATUS_POWER_PMI, &priv->status)); 561 pos += scnprintf(buf + pos, bufsz - pos, "STATUS_FW_ERROR:\t %d\n", 562 test_bit(STATUS_FW_ERROR, &priv->status)); 563 pos += scnprintf(buf + pos, bufsz - pos, "STATUS_MODE_PENDING:\t %d\n", 564 test_bit(STATUS_MODE_PENDING, &priv->status)); 565 return simple_read_from_buffer(user_buf, count, ppos, buf, pos); 566} 567 568static ssize_t iwl_dbgfs_interrupt_read(struct file *file, 569 char __user *user_buf, 570 size_t count, loff_t *ppos) { 571 572 struct iwl_priv *priv = (struct iwl_priv *)file->private_data; 573 int pos = 0; 574 int cnt = 0; 575 char *buf; 576 int bufsz = 24 * 64; /* 24 items * 64 char per item */ 577 ssize_t ret; 578 579 buf = kzalloc(bufsz, GFP_KERNEL); 580 if (!buf) { 581 IWL_ERR(priv, "Can not allocate Buffer\n"); 582 return -ENOMEM; 583 } 584 585 pos += scnprintf(buf + pos, bufsz - pos, 586 "Interrupt Statistics Report:\n"); 587 588 pos += scnprintf(buf + pos, bufsz - pos, "HW Error:\t\t\t %u\n", 589 priv->isr_stats.hw); 590 pos += scnprintf(buf + pos, bufsz - pos, "SW Error:\t\t\t %u\n", 591 priv->isr_stats.sw); 592 if (priv->isr_stats.sw > 0) { 593 pos += scnprintf(buf + pos, bufsz - pos, 594 "\tLast Restarting Code: 0x%X\n", 595 priv->isr_stats.sw_err); 596 } 597#ifdef CONFIG_IWLWIFI_DEBUG 598 pos += scnprintf(buf + pos, bufsz - pos, "Frame transmitted:\t\t %u\n", 599 priv->isr_stats.sch); 600 pos += scnprintf(buf + pos, bufsz - pos, "Alive interrupt:\t\t %u\n", 601 priv->isr_stats.alive); 602#endif 603 pos += scnprintf(buf + pos, bufsz - pos, 604 "HW RF KILL switch toggled:\t %u\n", 605 priv->isr_stats.rfkill); 606 607 pos += scnprintf(buf + pos, bufsz - pos, "CT KILL:\t\t\t %u\n", 608 priv->isr_stats.ctkill); 609 610 pos += scnprintf(buf + pos, bufsz - pos, "Wakeup Interrupt:\t\t %u\n", 611 priv->isr_stats.wakeup); 612 613 pos += scnprintf(buf + pos, bufsz - pos, 614 "Rx command responses:\t\t %u\n", 615 priv->isr_stats.rx); 616 for (cnt = 0; cnt < REPLY_MAX; cnt++) { 617 if (priv->isr_stats.rx_handlers[cnt] > 0) 618 pos += scnprintf(buf + pos, bufsz - pos, 619 "\tRx handler[%36s]:\t\t %u\n", 620 get_cmd_string(cnt), 621 priv->isr_stats.rx_handlers[cnt]); 622 } 623 624 pos += scnprintf(buf + pos, bufsz - pos, "Tx/FH interrupt:\t\t %u\n", 625 priv->isr_stats.tx); 626 627 pos += scnprintf(buf + pos, bufsz - pos, "Unexpected INTA:\t\t %u\n", 628 priv->isr_stats.unhandled); 629 630 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); 631 kfree(buf); 632 return ret; 633} 634 635static ssize_t iwl_dbgfs_interrupt_write(struct file *file, 636 const char __user *user_buf, 637 size_t count, loff_t *ppos) 638{ 639 struct iwl_priv *priv = file->private_data; 640 char buf[8]; 641 int buf_size; 642 u32 reset_flag; 643 644 memset(buf, 0, sizeof(buf)); 645 buf_size = min(count, sizeof(buf) - 1); 646 if (copy_from_user(buf, user_buf, buf_size)) 647 return -EFAULT; 648 if (sscanf(buf, "%x", &reset_flag) != 1) 649 return -EFAULT; 650 if (reset_flag == 0) 651 iwl_clear_isr_stats(priv); 652 653 return count; 654} 655 656static ssize_t iwl_dbgfs_qos_read(struct file *file, char __user *user_buf, 657 size_t count, loff_t *ppos) 658{ 659 struct iwl_priv *priv = (struct iwl_priv *)file->private_data; 660 int pos = 0, i; 661 char buf[256]; 662 const size_t bufsz = sizeof(buf); 663 ssize_t ret; 664 665 for (i = 0; i < AC_NUM; i++) { 666 pos += scnprintf(buf + pos, bufsz - pos, 667 "\tcw_min\tcw_max\taifsn\ttxop\n"); 668 pos += scnprintf(buf + pos, bufsz - pos, 669 "AC[%d]\t%u\t%u\t%u\t%u\n", i, 670 priv->qos_data.def_qos_parm.ac[i].cw_min, 671 priv->qos_data.def_qos_parm.ac[i].cw_max, 672 priv->qos_data.def_qos_parm.ac[i].aifsn, 673 priv->qos_data.def_qos_parm.ac[i].edca_txop); 674 } 675 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); 676 return ret; 677} 678 679static ssize_t iwl_dbgfs_led_read(struct file *file, char __user *user_buf, 680 size_t count, loff_t *ppos) 681{ 682 struct iwl_priv *priv = (struct iwl_priv *)file->private_data; 683 int pos = 0; 684 char buf[256]; 685 const size_t bufsz = sizeof(buf); 686 ssize_t ret; 687 688 pos += scnprintf(buf + pos, bufsz - pos, 689 "allow blinking: %s\n", 690 (priv->allow_blinking) ? "True" : "False"); 691 if (priv->allow_blinking) { 692 pos += scnprintf(buf + pos, bufsz - pos, 693 "Led blinking rate: %u\n", 694 priv->last_blink_rate); 695 pos += scnprintf(buf + pos, bufsz - pos, 696 "Last blink time: %lu\n", 697 priv->last_blink_time); 698 } 699 700 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); 701 return ret; 702} 703 704static ssize_t iwl_dbgfs_thermal_throttling_read(struct file *file, 705 char __user *user_buf, 706 size_t count, loff_t *ppos) 707{ 708 struct iwl_priv *priv = (struct iwl_priv *)file->private_data; 709 struct iwl_tt_mgmt *tt = &priv->thermal_throttle; 710 struct iwl_tt_restriction *restriction; 711 char buf[100]; 712 int pos = 0; 713 const size_t bufsz = sizeof(buf); 714 ssize_t ret; 715 716 pos += scnprintf(buf + pos, bufsz - pos, 717 "Thermal Throttling Mode: %s\n", 718 tt->advanced_tt ? "Advance" : "Legacy"); 719 pos += scnprintf(buf + pos, bufsz - pos, 720 "Thermal Throttling State: %d\n", 721 tt->state); 722 if (tt->advanced_tt) { 723 restriction = tt->restriction + tt->state; 724 pos += scnprintf(buf + pos, bufsz - pos, 725 "Tx mode: %d\n", 726 restriction->tx_stream); 727 pos += scnprintf(buf + pos, bufsz - pos, 728 "Rx mode: %d\n", 729 restriction->rx_stream); 730 pos += scnprintf(buf + pos, bufsz - pos, 731 "HT mode: %d\n", 732 restriction->is_ht); 733 } 734 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); 735 return ret; 736} 737 738static ssize_t iwl_dbgfs_disable_ht40_write(struct file *file, 739 const char __user *user_buf, 740 size_t count, loff_t *ppos) 741{ 742 struct iwl_priv *priv = file->private_data; 743 char buf[8]; 744 int buf_size; 745 int ht40; 746 747 memset(buf, 0, sizeof(buf)); 748 buf_size = min(count, sizeof(buf) - 1); 749 if (copy_from_user(buf, user_buf, buf_size)) 750 return -EFAULT; 751 if (sscanf(buf, "%d", &ht40) != 1) 752 return -EFAULT; 753 if (!iwl_is_associated(priv)) 754 priv->disable_ht40 = ht40 ? true : false; 755 else { 756 IWL_ERR(priv, "Sta associated with AP - " 757 "Change to 40MHz channel support is not allowed\n"); 758 return -EINVAL; 759 } 760 761 return count; 762} 763 764static ssize_t iwl_dbgfs_disable_ht40_read(struct file *file, 765 char __user *user_buf, 766 size_t count, loff_t *ppos) 767{ 768 struct iwl_priv *priv = (struct iwl_priv *)file->private_data; 769 char buf[100]; 770 int pos = 0; 771 const size_t bufsz = sizeof(buf); 772 ssize_t ret; 773 774 pos += scnprintf(buf + pos, bufsz - pos, 775 "11n 40MHz Mode: %s\n", 776 priv->disable_ht40 ? "Disabled" : "Enabled"); 777 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); 778 return ret; 779} 780 781static ssize_t iwl_dbgfs_sleep_level_override_write(struct file *file, 782 const char __user *user_buf, 783 size_t count, loff_t *ppos) 784{ 785 struct iwl_priv *priv = file->private_data; 786 char buf[8]; 787 int buf_size; 788 int value; 789 790 memset(buf, 0, sizeof(buf)); 791 buf_size = min(count, sizeof(buf) - 1); 792 if (copy_from_user(buf, user_buf, buf_size)) 793 return -EFAULT; 794 795 if (sscanf(buf, "%d", &value) != 1) 796 return -EINVAL; 797 798 /* 799 * Our users expect 0 to be "CAM", but 0 isn't actually 800 * valid here. However, let's not confuse them and present 801 * IWL_POWER_INDEX_1 as "1", not "0". 802 */ 803 if (value == 0) 804 return -EINVAL; 805 else if (value > 0) 806 value -= 1; 807 808 if (value != -1 && (value < 0 || value >= IWL_POWER_NUM)) 809 return -EINVAL; 810 811 if (!iwl_is_ready_rf(priv)) 812 return -EAGAIN; 813 814 priv->power_data.debug_sleep_level_override = value; 815 816 iwl_power_update_mode(priv, true); 817 818 return count; 819} 820 821static ssize_t iwl_dbgfs_sleep_level_override_read(struct file *file, 822 char __user *user_buf, 823 size_t count, loff_t *ppos) 824{ 825 struct iwl_priv *priv = (struct iwl_priv *)file->private_data; 826 char buf[10]; 827 int pos, value; 828 const size_t bufsz = sizeof(buf); 829 830 /* see the write function */ 831 value = priv->power_data.debug_sleep_level_override; 832 if (value >= 0) 833 value += 1; 834 835 pos = scnprintf(buf, bufsz, "%d\n", value); 836 return simple_read_from_buffer(user_buf, count, ppos, buf, pos); 837} 838 839static ssize_t iwl_dbgfs_current_sleep_command_read(struct file *file, 840 char __user *user_buf, 841 size_t count, loff_t *ppos) 842{ 843 struct iwl_priv *priv = (struct iwl_priv *)file->private_data; 844 char buf[200]; 845 int pos = 0, i; 846 const size_t bufsz = sizeof(buf); 847 struct iwl_powertable_cmd *cmd = &priv->power_data.sleep_cmd; 848 849 pos += scnprintf(buf + pos, bufsz - pos, 850 "flags: %#.2x\n", le16_to_cpu(cmd->flags)); 851 pos += scnprintf(buf + pos, bufsz - pos, 852 "RX/TX timeout: %d/%d usec\n", 853 le32_to_cpu(cmd->rx_data_timeout), 854 le32_to_cpu(cmd->tx_data_timeout)); 855 for (i = 0; i < IWL_POWER_VEC_SIZE; i++) 856 pos += scnprintf(buf + pos, bufsz - pos, 857 "sleep_interval[%d]: %d\n", i, 858 le32_to_cpu(cmd->sleep_interval[i])); 859 860 return simple_read_from_buffer(user_buf, count, ppos, buf, pos); 861} 862 863DEBUGFS_READ_WRITE_FILE_OPS(sram); 864DEBUGFS_WRITE_FILE_OPS(log_event); 865DEBUGFS_READ_FILE_OPS(nvm); 866DEBUGFS_READ_FILE_OPS(stations); 867DEBUGFS_READ_FILE_OPS(channels); 868DEBUGFS_READ_FILE_OPS(status); 869DEBUGFS_READ_WRITE_FILE_OPS(interrupt); 870DEBUGFS_READ_FILE_OPS(qos); 871DEBUGFS_READ_FILE_OPS(led); 872DEBUGFS_READ_FILE_OPS(thermal_throttling); 873DEBUGFS_READ_WRITE_FILE_OPS(disable_ht40); 874DEBUGFS_READ_WRITE_FILE_OPS(sleep_level_override); 875DEBUGFS_READ_FILE_OPS(current_sleep_command); 876 877static ssize_t iwl_dbgfs_traffic_log_read(struct file *file, 878 char __user *user_buf, 879 size_t count, loff_t *ppos) 880{ 881 struct iwl_priv *priv = file->private_data; 882 int pos = 0, ofs = 0; 883 int cnt = 0, entry; 884 struct iwl_tx_queue *txq; 885 struct iwl_queue *q; 886 struct iwl_rx_queue *rxq = &priv->rxq; 887 char *buf; 888 int bufsz = ((IWL_TRAFFIC_ENTRIES * IWL_TRAFFIC_ENTRY_SIZE * 64) * 2) + 889 (priv->cfg->num_of_queues * 32 * 8) + 400; 890 const u8 *ptr; 891 ssize_t ret; 892 893 if (!priv->txq) { 894 IWL_ERR(priv, "txq not ready\n"); 895 return -EAGAIN; 896 } 897 buf = kzalloc(bufsz, GFP_KERNEL); 898 if (!buf) { 899 IWL_ERR(priv, "Can not allocate buffer\n"); 900 return -ENOMEM; 901 } 902 pos += scnprintf(buf + pos, bufsz - pos, "Tx Queue\n"); 903 for (cnt = 0; cnt < priv->hw_params.max_txq_num; cnt++) { 904 txq = &priv->txq[cnt]; 905 q = &txq->q; 906 pos += scnprintf(buf + pos, bufsz - pos, 907 "q[%d]: read_ptr: %u, write_ptr: %u\n", 908 cnt, q->read_ptr, q->write_ptr); 909 } 910 if (priv->tx_traffic && (iwl_debug_level & IWL_DL_TX)) { 911 ptr = priv->tx_traffic; 912 pos += scnprintf(buf + pos, bufsz - pos, 913 "Tx Traffic idx: %u\n", priv->tx_traffic_idx); 914 for (cnt = 0, ofs = 0; cnt < IWL_TRAFFIC_ENTRIES; cnt++) { 915 for (entry = 0; entry < IWL_TRAFFIC_ENTRY_SIZE / 16; 916 entry++, ofs += 16) { 917 pos += scnprintf(buf + pos, bufsz - pos, 918 "0x%.4x ", ofs); 919 hex_dump_to_buffer(ptr + ofs, 16, 16, 2, 920 buf + pos, bufsz - pos, 0); 921 pos += strlen(buf + pos); 922 if (bufsz - pos > 0) 923 buf[pos++] = '\n'; 924 } 925 } 926 } 927 928 pos += scnprintf(buf + pos, bufsz - pos, "Rx Queue\n"); 929 pos += scnprintf(buf + pos, bufsz - pos, 930 "read: %u, write: %u\n", 931 rxq->read, rxq->write); 932 933 if (priv->rx_traffic && (iwl_debug_level & IWL_DL_RX)) { 934 ptr = priv->rx_traffic; 935 pos += scnprintf(buf + pos, bufsz - pos, 936 "Rx Traffic idx: %u\n", priv->rx_traffic_idx); 937 for (cnt = 0, ofs = 0; cnt < IWL_TRAFFIC_ENTRIES; cnt++) { 938 for (entry = 0; entry < IWL_TRAFFIC_ENTRY_SIZE / 16; 939 entry++, ofs += 16) { 940 pos += scnprintf(buf + pos, bufsz - pos, 941 "0x%.4x ", ofs); 942 hex_dump_to_buffer(ptr + ofs, 16, 16, 2, 943 buf + pos, bufsz - pos, 0); 944 pos += strlen(buf + pos); 945 if (bufsz - pos > 0) 946 buf[pos++] = '\n'; 947 } 948 } 949 } 950 951 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); 952 kfree(buf); 953 return ret; 954} 955 956static ssize_t iwl_dbgfs_traffic_log_write(struct file *file, 957 const char __user *user_buf, 958 size_t count, loff_t *ppos) 959{ 960 struct iwl_priv *priv = file->private_data; 961 char buf[8]; 962 int buf_size; 963 int traffic_log; 964 965 memset(buf, 0, sizeof(buf)); 966 buf_size = min(count, sizeof(buf) - 1); 967 if (copy_from_user(buf, user_buf, buf_size)) 968 return -EFAULT; 969 if (sscanf(buf, "%d", &traffic_log) != 1) 970 return -EFAULT; 971 if (traffic_log == 0) 972 iwl_reset_traffic_log(priv); 973 974 return count; 975} 976 977static ssize_t iwl_dbgfs_tx_queue_read(struct file *file, 978 char __user *user_buf, 979 size_t count, loff_t *ppos) { 980 981 struct iwl_priv *priv = (struct iwl_priv *)file->private_data; 982 struct iwl_tx_queue *txq; 983 struct iwl_queue *q; 984 char *buf; 985 int pos = 0; 986 int cnt; 987 int ret; 988 const size_t bufsz = sizeof(char) * 60 * priv->cfg->num_of_queues; 989 990 if (!priv->txq) { 991 IWL_ERR(priv, "txq not ready\n"); 992 return -EAGAIN; 993 } 994 buf = kzalloc(bufsz, GFP_KERNEL); 995 if (!buf) 996 return -ENOMEM; 997 998 for (cnt = 0; cnt < priv->hw_params.max_txq_num; cnt++) { 999 txq = &priv->txq[cnt]; 1000 q = &txq->q; 1001 pos += scnprintf(buf + pos, bufsz - pos, 1002 "hwq %.2d: read=%u write=%u stop=%d" 1003 " swq_id=%#.2x (ac %d/hwq %d)\n", 1004 cnt, q->read_ptr, q->write_ptr, 1005 !!test_bit(cnt, priv->queue_stopped), 1006 txq->swq_id, 1007 txq->swq_id & 0x80 ? txq->swq_id & 3 : 1008 txq->swq_id, 1009 txq->swq_id & 0x80 ? (txq->swq_id >> 2) & 1010 0x1f : txq->swq_id); 1011 if (cnt >= 4) 1012 continue; 1013 /* for the ACs, display the stop count too */ 1014 pos += scnprintf(buf + pos, bufsz - pos, 1015 " stop-count: %d\n", 1016 atomic_read(&priv->queue_stop_count[cnt])); 1017 } 1018 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); 1019 kfree(buf); 1020 return ret; 1021} 1022 1023static ssize_t iwl_dbgfs_rx_queue_read(struct file *file, 1024 char __user *user_buf, 1025 size_t count, loff_t *ppos) { 1026 1027 struct iwl_priv *priv = (struct iwl_priv *)file->private_data; 1028 struct iwl_rx_queue *rxq = &priv->rxq; 1029 char buf[256]; 1030 int pos = 0; 1031 const size_t bufsz = sizeof(buf); 1032 1033 pos += scnprintf(buf + pos, bufsz - pos, "read: %u\n", 1034 rxq->read); 1035 pos += scnprintf(buf + pos, bufsz - pos, "write: %u\n", 1036 rxq->write); 1037 pos += scnprintf(buf + pos, bufsz - pos, "free_count: %u\n", 1038 rxq->free_count); 1039 pos += scnprintf(buf + pos, bufsz - pos, "closed_rb_num: %u\n", 1040 le16_to_cpu(rxq->rb_stts->closed_rb_num) & 0x0FFF); 1041 return simple_read_from_buffer(user_buf, count, ppos, buf, pos); 1042} 1043 1044static int iwl_dbgfs_statistics_flag(struct iwl_priv *priv, char *buf, 1045 int bufsz) 1046{ 1047 int p = 0; 1048 1049 p += scnprintf(buf + p, bufsz - p, 1050 "Statistics Flag(0x%X):\n", 1051 le32_to_cpu(priv->statistics.flag)); 1052 if (le32_to_cpu(priv->statistics.flag) & UCODE_STATISTICS_CLEAR_MSK) 1053 p += scnprintf(buf + p, bufsz - p, 1054 "\tStatistics have been cleared\n"); 1055 p += scnprintf(buf + p, bufsz - p, 1056 "\tOperational Frequency: %s\n", 1057 (le32_to_cpu(priv->statistics.flag) & 1058 UCODE_STATISTICS_FREQUENCY_MSK) 1059 ? "2.4 GHz" : "5.2 GHz"); 1060 p += scnprintf(buf + p, bufsz - p, 1061 "\tTGj Narrow Band: %s\n", 1062 (le32_to_cpu(priv->statistics.flag) & 1063 UCODE_STATISTICS_NARROW_BAND_MSK) 1064 ? "enabled" : "disabled"); 1065 return p; 1066} 1067 1068 1069static ssize_t iwl_dbgfs_ucode_rx_stats_read(struct file *file, 1070 char __user *user_buf, 1071 size_t count, loff_t *ppos) 1072{ 1073 struct iwl_priv *priv = (struct iwl_priv *)file->private_data; 1074 int pos = 0; 1075 char *buf; 1076 int bufsz = sizeof(struct statistics_rx_phy) * 20 + 1077 sizeof(struct statistics_rx_non_phy) * 20 + 1078 sizeof(struct statistics_rx_ht_phy) * 20 + 400; 1079 ssize_t ret; 1080 struct statistics_rx_phy *ofdm, *accum_ofdm; 1081 struct statistics_rx_phy *cck, *accum_cck; 1082 struct statistics_rx_non_phy *general, *accum_general; 1083 struct statistics_rx_ht_phy *ht, *accum_ht; 1084 1085 if (!iwl_is_alive(priv)) 1086 return -EAGAIN; 1087 1088 /* make request to uCode to retrieve statistics information */ 1089 mutex_lock(&priv->mutex); 1090 ret = iwl_send_statistics_request(priv, CMD_SYNC, false); 1091 mutex_unlock(&priv->mutex); 1092 1093 if (ret) { 1094 IWL_ERR(priv, 1095 "Error sending statistics request: %zd\n", ret); 1096 return -EAGAIN; 1097 } 1098 buf = kzalloc(bufsz, GFP_KERNEL); 1099 if (!buf) { 1100 IWL_ERR(priv, "Can not allocate Buffer\n"); 1101 return -ENOMEM; 1102 } 1103 1104 /* the statistic information display here is based on 1105 * the last statistics notification from uCode 1106 * might not reflect the current uCode activity 1107 */ 1108 ofdm = &priv->statistics.rx.ofdm; 1109 cck = &priv->statistics.rx.cck; 1110 general = &priv->statistics.rx.general; 1111 ht = &priv->statistics.rx.ofdm_ht; 1112 accum_ofdm = &priv->accum_statistics.rx.ofdm; 1113 accum_cck = &priv->accum_statistics.rx.cck; 1114 accum_general = &priv->accum_statistics.rx.general; 1115 accum_ht = &priv->accum_statistics.rx.ofdm_ht; 1116 pos += iwl_dbgfs_statistics_flag(priv, buf, bufsz); 1117 pos += scnprintf(buf + pos, bufsz - pos, "Statistics_Rx - OFDM:\n"); 1118 pos += scnprintf(buf + pos, bufsz - pos, 1119 "\t\t\tcurrent\t\t\taccumulative\n"); 1120 pos += scnprintf(buf + pos, bufsz - pos, "ina_cnt:\t\t%u\t\t\t%u\n", 1121 le32_to_cpu(ofdm->ina_cnt), accum_ofdm->ina_cnt); 1122 pos += scnprintf(buf + pos, bufsz - pos, "fina_cnt:\t\t%u\t\t\t%u\n", 1123 le32_to_cpu(ofdm->fina_cnt), accum_ofdm->fina_cnt); 1124 pos += scnprintf(buf + pos, bufsz - pos, "plcp_err:\t\t%u\t\t\t%u\n", 1125 le32_to_cpu(ofdm->plcp_err), accum_ofdm->plcp_err); 1126 pos += scnprintf(buf + pos, bufsz - pos, "crc32_err:\t\t%u\t\t\t%u\n", 1127 le32_to_cpu(ofdm->crc32_err), accum_ofdm->crc32_err); 1128 pos += scnprintf(buf + pos, bufsz - pos, 1129 "overrun_err:\t\t%u\t\t\t%u\n", 1130 le32_to_cpu(ofdm->overrun_err), 1131 accum_ofdm->overrun_err); 1132 pos += scnprintf(buf + pos, bufsz - pos, 1133 "early_overrun_err:\t%u\t\t\t%u\n", 1134 le32_to_cpu(ofdm->early_overrun_err), 1135 accum_ofdm->early_overrun_err); 1136 pos += scnprintf(buf + pos, bufsz - pos, "crc32_good:\t\t%u\t\t\t%u\n", 1137 le32_to_cpu(ofdm->crc32_good), 1138 accum_ofdm->crc32_good); 1139 pos += scnprintf(buf + pos, bufsz - pos, 1140 "false_alarm_cnt:\t%u\t\t\t%u\n", 1141 le32_to_cpu(ofdm->false_alarm_cnt), 1142 accum_ofdm->false_alarm_cnt); 1143 pos += scnprintf(buf + pos, bufsz - pos, 1144 "fina_sync_err_cnt:\t%u\t\t\t%u\n", 1145 le32_to_cpu(ofdm->fina_sync_err_cnt), 1146 accum_ofdm->fina_sync_err_cnt); 1147 pos += scnprintf(buf + pos, bufsz - pos, 1148 "sfd_timeout:\t\t%u\t\t\t%u\n", 1149 le32_to_cpu(ofdm->sfd_timeout), 1150 accum_ofdm->sfd_timeout); 1151 pos += scnprintf(buf + pos, bufsz - pos, 1152 "fina_timeout:\t\t%u\t\t\t%u\n", 1153 le32_to_cpu(ofdm->fina_timeout), 1154 accum_ofdm->fina_timeout); 1155 pos += scnprintf(buf + pos, bufsz - pos, 1156 "unresponded_rts:\t%u\t\t\t%u\n", 1157 le32_to_cpu(ofdm->unresponded_rts), 1158 accum_ofdm->unresponded_rts); 1159 pos += scnprintf(buf + pos, bufsz - pos, 1160 "rxe_frame_lmt_ovrun:\t%u\t\t\t%u\n", 1161 le32_to_cpu(ofdm->rxe_frame_limit_overrun), 1162 accum_ofdm->rxe_frame_limit_overrun); 1163 pos += scnprintf(buf + pos, bufsz - pos, 1164 "sent_ack_cnt:\t\t%u\t\t\t%u\n", 1165 le32_to_cpu(ofdm->sent_ack_cnt), 1166 accum_ofdm->sent_ack_cnt); 1167 pos += scnprintf(buf + pos, bufsz - pos, 1168 "sent_cts_cnt:\t\t%u\t\t\t%u\n", 1169 le32_to_cpu(ofdm->sent_cts_cnt), 1170 accum_ofdm->sent_cts_cnt); 1171 pos += scnprintf(buf + pos, bufsz - pos, 1172 "sent_ba_rsp_cnt:\t%u\t\t\t%u\n", 1173 le32_to_cpu(ofdm->sent_ba_rsp_cnt), 1174 accum_ofdm->sent_ba_rsp_cnt); 1175 pos += scnprintf(buf + pos, bufsz - pos, 1176 "dsp_self_kill:\t\t%u\t\t\t%u\n", 1177 le32_to_cpu(ofdm->dsp_self_kill), 1178 accum_ofdm->dsp_self_kill); 1179 pos += scnprintf(buf + pos, bufsz - pos, 1180 "mh_format_err:\t\t%u\t\t\t%u\n", 1181 le32_to_cpu(ofdm->mh_format_err), 1182 accum_ofdm->mh_format_err); 1183 pos += scnprintf(buf + pos, bufsz - pos, 1184 "re_acq_main_rssi_sum:\t%u\t\t\t%u\n", 1185 le32_to_cpu(ofdm->re_acq_main_rssi_sum), 1186 accum_ofdm->re_acq_main_rssi_sum); 1187 1188 pos += scnprintf(buf + pos, bufsz - pos, "Statistics_Rx - CCK:\n"); 1189 pos += scnprintf(buf + pos, bufsz - pos, 1190 "\t\t\tcurrent\t\t\taccumulative\n"); 1191 pos += scnprintf(buf + pos, bufsz - pos, "ina_cnt:\t\t%u\t\t\t%u\n", 1192 le32_to_cpu(cck->ina_cnt), accum_cck->ina_cnt); 1193 pos += scnprintf(buf + pos, bufsz - pos, "fina_cnt:\t\t%u\t\t\t%u\n", 1194 le32_to_cpu(cck->fina_cnt), accum_cck->fina_cnt); 1195 pos += scnprintf(buf + pos, bufsz - pos, "plcp_err:\t\t%u\t\t\t%u\n", 1196 le32_to_cpu(cck->plcp_err), accum_cck->plcp_err); 1197 pos += scnprintf(buf + pos, bufsz - pos, "crc32_err:\t\t%u\t\t\t%u\n", 1198 le32_to_cpu(cck->crc32_err), accum_cck->crc32_err); 1199 pos += scnprintf(buf + pos, bufsz - pos, 1200 "overrun_err:\t\t%u\t\t\t%u\n", 1201 le32_to_cpu(cck->overrun_err), 1202 accum_cck->overrun_err); 1203 pos += scnprintf(buf + pos, bufsz - pos, 1204 "early_overrun_err:\t%u\t\t\t%u\n", 1205 le32_to_cpu(cck->early_overrun_err), 1206 accum_cck->early_overrun_err); 1207 pos += scnprintf(buf + pos, bufsz - pos, "crc32_good:\t\t%u\t\t\t%u\n", 1208 le32_to_cpu(cck->crc32_good), accum_cck->crc32_good); 1209 pos += scnprintf(buf + pos, bufsz - pos, 1210 "false_alarm_cnt:\t%u\t\t\t%u\n", 1211 le32_to_cpu(cck->false_alarm_cnt), 1212 accum_cck->false_alarm_cnt); 1213 pos += scnprintf(buf + pos, bufsz - pos, 1214 "fina_sync_err_cnt:\t%u\t\t\t%u\n", 1215 le32_to_cpu(cck->fina_sync_err_cnt), 1216 accum_cck->fina_sync_err_cnt); 1217 pos += scnprintf(buf + pos, bufsz - pos, 1218 "sfd_timeout:\t\t%u\t\t\t%u\n", 1219 le32_to_cpu(cck->sfd_timeout), 1220 accum_cck->sfd_timeout); 1221 pos += scnprintf(buf + pos, bufsz - pos, 1222 "fina_timeout:\t\t%u\t\t\t%u\n", 1223 le32_to_cpu(cck->fina_timeout), 1224 accum_cck->fina_timeout); 1225 pos += scnprintf(buf + pos, bufsz - pos, 1226 "unresponded_rts:\t%u\t\t\t%u\n", 1227 le32_to_cpu(cck->unresponded_rts), 1228 accum_cck->unresponded_rts); 1229 pos += scnprintf(buf + pos, bufsz - pos, 1230 "rxe_frame_lmt_ovrun:\t%u\t\t\t%u\n", 1231 le32_to_cpu(cck->rxe_frame_limit_overrun), 1232 accum_cck->rxe_frame_limit_overrun); 1233 pos += scnprintf(buf + pos, bufsz - pos, 1234 "sent_ack_cnt:\t\t%u\t\t\t%u\n", 1235 le32_to_cpu(cck->sent_ack_cnt), 1236 accum_cck->sent_ack_cnt); 1237 pos += scnprintf(buf + pos, bufsz - pos, 1238 "sent_cts_cnt:\t\t%u\t\t\t%u\n", 1239 le32_to_cpu(cck->sent_cts_cnt), 1240 accum_cck->sent_cts_cnt); 1241 pos += scnprintf(buf + pos, bufsz - pos, 1242 "sent_ba_rsp_cnt:\t%u\t\t\t%u\n", 1243 le32_to_cpu(cck->sent_ba_rsp_cnt), 1244 accum_cck->sent_ba_rsp_cnt); 1245 pos += scnprintf(buf + pos, bufsz - pos, 1246 "dsp_self_kill:\t\t%u\t\t\t%u\n", 1247 le32_to_cpu(cck->dsp_self_kill), 1248 accum_cck->dsp_self_kill); 1249 pos += scnprintf(buf + pos, bufsz - pos, 1250 "mh_format_err:\t\t%u\t\t\t%u\n", 1251 le32_to_cpu(cck->mh_format_err), 1252 accum_cck->mh_format_err); 1253 pos += scnprintf(buf + pos, bufsz - pos, 1254 "re_acq_main_rssi_sum:\t%u\t\t\t%u\n", 1255 le32_to_cpu(cck->re_acq_main_rssi_sum), 1256 accum_cck->re_acq_main_rssi_sum); 1257 1258 pos += scnprintf(buf + pos, bufsz - pos, "Statistics_Rx - GENERAL:\n"); 1259 pos += scnprintf(buf + pos, bufsz - pos, 1260 "\t\t\tcurrent\t\t\taccumulative\n"); 1261 pos += scnprintf(buf + pos, bufsz - pos, "bogus_cts:\t\t%u\t\t\t%u\n", 1262 le32_to_cpu(general->bogus_cts), 1263 accum_general->bogus_cts); 1264 pos += scnprintf(buf + pos, bufsz - pos, "bogus_ack:\t\t%u\t\t\t%u\n", 1265 le32_to_cpu(general->bogus_ack), 1266 accum_general->bogus_ack); 1267 pos += scnprintf(buf + pos, bufsz - pos, 1268 "non_bssid_frames:\t%u\t\t\t%u\n", 1269 le32_to_cpu(general->non_bssid_frames), 1270 accum_general->non_bssid_frames); 1271 pos += scnprintf(buf + pos, bufsz - pos, 1272 "filtered_frames:\t%u\t\t\t%u\n", 1273 le32_to_cpu(general->filtered_frames), 1274 accum_general->filtered_frames); 1275 pos += scnprintf(buf + pos, bufsz - pos, 1276 "non_channel_beacons:\t%u\t\t\t%u\n", 1277 le32_to_cpu(general->non_channel_beacons), 1278 accum_general->non_channel_beacons); 1279 pos += scnprintf(buf + pos, bufsz - pos, 1280 "channel_beacons:\t%u\t\t\t%u\n", 1281 le32_to_cpu(general->channel_beacons), 1282 accum_general->channel_beacons); 1283 pos += scnprintf(buf + pos, bufsz - pos, 1284 "num_missed_bcon:\t%u\t\t\t%u\n", 1285 le32_to_cpu(general->num_missed_bcon), 1286 accum_general->num_missed_bcon); 1287 pos += scnprintf(buf + pos, bufsz - pos, 1288 "adc_rx_saturation_time:\t%u\t\t\t%u\n", 1289 le32_to_cpu(general->adc_rx_saturation_time), 1290 accum_general->adc_rx_saturation_time); 1291 pos += scnprintf(buf + pos, bufsz - pos, 1292 "ina_detect_search_tm:\t%u\t\t\t%u\n", 1293 le32_to_cpu(general->ina_detection_search_time), 1294 accum_general->ina_detection_search_time); 1295 pos += scnprintf(buf + pos, bufsz - pos, 1296 "beacon_silence_rssi_a:\t%u\t\t\t%u\n", 1297 le32_to_cpu(general->beacon_silence_rssi_a), 1298 accum_general->beacon_silence_rssi_a); 1299 pos += scnprintf(buf + pos, bufsz - pos, 1300 "beacon_silence_rssi_b:\t%u\t\t\t%u\n", 1301 le32_to_cpu(general->beacon_silence_rssi_b), 1302 accum_general->beacon_silence_rssi_b); 1303 pos += scnprintf(buf + pos, bufsz - pos, 1304 "beacon_silence_rssi_c:\t%u\t\t\t%u\n", 1305 le32_to_cpu(general->beacon_silence_rssi_c), 1306 accum_general->beacon_silence_rssi_c); 1307 pos += scnprintf(buf + pos, bufsz - pos, 1308 "interference_data_flag:\t%u\t\t\t%u\n", 1309 le32_to_cpu(general->interference_data_flag), 1310 accum_general->interference_data_flag); 1311 pos += scnprintf(buf + pos, bufsz - pos, 1312 "channel_load:\t\t%u\t\t\t%u\n", 1313 le32_to_cpu(general->channel_load), 1314 accum_general->channel_load); 1315 pos += scnprintf(buf + pos, bufsz - pos, 1316 "dsp_false_alarms:\t%u\t\t\t%u\n", 1317 le32_to_cpu(general->dsp_false_alarms), 1318 accum_general->dsp_false_alarms); 1319 pos += scnprintf(buf + pos, bufsz - pos, 1320 "beacon_rssi_a:\t\t%u\t\t\t%u\n", 1321 le32_to_cpu(general->beacon_rssi_a), 1322 accum_general->beacon_rssi_a); 1323 pos += scnprintf(buf + pos, bufsz - pos, 1324 "beacon_rssi_b:\t\t%u\t\t\t%u\n", 1325 le32_to_cpu(general->beacon_rssi_b), 1326 accum_general->beacon_rssi_b); 1327 pos += scnprintf(buf + pos, bufsz - pos, 1328 "beacon_rssi_c:\t\t%u\t\t\t%u\n", 1329 le32_to_cpu(general->beacon_rssi_c), 1330 accum_general->beacon_rssi_c); 1331 pos += scnprintf(buf + pos, bufsz - pos, 1332 "beacon_energy_a:\t%u\t\t\t%u\n", 1333 le32_to_cpu(general->beacon_energy_a), 1334 accum_general->beacon_energy_a); 1335 pos += scnprintf(buf + pos, bufsz - pos, 1336 "beacon_energy_b:\t%u\t\t\t%u\n", 1337 le32_to_cpu(general->beacon_energy_b), 1338 accum_general->beacon_energy_b); 1339 pos += scnprintf(buf + pos, bufsz - pos, 1340 "beacon_energy_c:\t%u\t\t\t%u\n", 1341 le32_to_cpu(general->beacon_energy_c), 1342 accum_general->beacon_energy_c); 1343 1344 pos += scnprintf(buf + pos, bufsz - pos, "Statistics_Rx - OFDM_HT:\n"); 1345 pos += scnprintf(buf + pos, bufsz - pos, 1346 "\t\t\tcurrent\t\t\taccumulative\n"); 1347 pos += scnprintf(buf + pos, bufsz - pos, "plcp_err:\t\t%u\t\t\t%u\n", 1348 le32_to_cpu(ht->plcp_err), accum_ht->plcp_err); 1349 pos += scnprintf(buf + pos, bufsz - pos, 1350 "overrun_err:\t\t%u\t\t\t%u\n", 1351 le32_to_cpu(ht->overrun_err), accum_ht->overrun_err); 1352 pos += scnprintf(buf + pos, bufsz - pos, 1353 "early_overrun_err:\t%u\t\t\t%u\n", 1354 le32_to_cpu(ht->early_overrun_err), 1355 accum_ht->early_overrun_err); 1356 pos += scnprintf(buf + pos, bufsz - pos, "crc32_good:\t\t%u\t\t\t%u\n", 1357 le32_to_cpu(ht->crc32_good), accum_ht->crc32_good); 1358 pos += scnprintf(buf + pos, bufsz - pos, "crc32_err:\t\t%u\t\t\t%u\n", 1359 le32_to_cpu(ht->crc32_err), accum_ht->crc32_err); 1360 pos += scnprintf(buf + pos, bufsz - pos, 1361 "mh_format_err:\t\t%u\t\t\t%u\n", 1362 le32_to_cpu(ht->mh_format_err), 1363 accum_ht->mh_format_err); 1364 pos += scnprintf(buf + pos, bufsz - pos, 1365 "agg_crc32_good:\t\t%u\t\t\t%u\n", 1366 le32_to_cpu(ht->agg_crc32_good), 1367 accum_ht->agg_crc32_good); 1368 pos += scnprintf(buf + pos, bufsz - pos, 1369 "agg_mpdu_cnt:\t\t%u\t\t\t%u\n", 1370 le32_to_cpu(ht->agg_mpdu_cnt), 1371 accum_ht->agg_mpdu_cnt); 1372 pos += scnprintf(buf + pos, bufsz - pos, "agg_cnt:\t\t%u\t\t\t%u\n", 1373 le32_to_cpu(ht->agg_cnt), accum_ht->agg_cnt); 1374 1375 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); 1376 kfree(buf); 1377 return ret; 1378} 1379 1380static ssize_t iwl_dbgfs_ucode_tx_stats_read(struct file *file, 1381 char __user *user_buf, 1382 size_t count, loff_t *ppos) 1383{ 1384 struct iwl_priv *priv = (struct iwl_priv *)file->private_data; 1385 int pos = 0; 1386 char *buf; 1387 int bufsz = (sizeof(struct statistics_tx) * 24) + 250; 1388 ssize_t ret; 1389 struct statistics_tx *tx, *accum_tx; 1390 1391 if (!iwl_is_alive(priv)) 1392 return -EAGAIN; 1393 1394 /* make request to uCode to retrieve statistics information */ 1395 mutex_lock(&priv->mutex); 1396 ret = iwl_send_statistics_request(priv, CMD_SYNC, false); 1397 mutex_unlock(&priv->mutex); 1398 1399 if (ret) { 1400 IWL_ERR(priv, 1401 "Error sending statistics request: %zd\n", ret); 1402 return -EAGAIN; 1403 } 1404 buf = kzalloc(bufsz, GFP_KERNEL); 1405 if (!buf) { 1406 IWL_ERR(priv, "Can not allocate Buffer\n"); 1407 return -ENOMEM; 1408 } 1409 1410 /* the statistic information display here is based on 1411 * the last statistics notification from uCode 1412 * might not reflect the current uCode activity 1413 */ 1414 tx = &priv->statistics.tx; 1415 accum_tx = &priv->accum_statistics.tx; 1416 pos += iwl_dbgfs_statistics_flag(priv, buf, bufsz); 1417 pos += scnprintf(buf + pos, bufsz - pos, "Statistics_Tx:\n"); 1418 pos += scnprintf(buf + pos, bufsz - pos, 1419 "\t\t\tcurrent\t\t\taccumulative\n"); 1420 pos += scnprintf(buf + pos, bufsz - pos, "preamble:\t\t\t%u\t\t\t%u\n", 1421 le32_to_cpu(tx->preamble_cnt), 1422 accum_tx->preamble_cnt); 1423 pos += scnprintf(buf + pos, bufsz - pos, 1424 "rx_detected_cnt:\t\t%u\t\t\t%u\n", 1425 le32_to_cpu(tx->rx_detected_cnt), 1426 accum_tx->rx_detected_cnt); 1427 pos += scnprintf(buf + pos, bufsz - pos, 1428 "bt_prio_defer_cnt:\t\t%u\t\t\t%u\n", 1429 le32_to_cpu(tx->bt_prio_defer_cnt), 1430 accum_tx->bt_prio_defer_cnt); 1431 pos += scnprintf(buf + pos, bufsz - pos, 1432 "bt_prio_kill_cnt:\t\t%u\t\t\t%u\n", 1433 le32_to_cpu(tx->bt_prio_kill_cnt), 1434 accum_tx->bt_prio_kill_cnt); 1435 pos += scnprintf(buf + pos, bufsz - pos, 1436 "few_bytes_cnt:\t\t\t%u\t\t\t%u\n", 1437 le32_to_cpu(tx->few_bytes_cnt), 1438 accum_tx->few_bytes_cnt); 1439 pos += scnprintf(buf + pos, bufsz - pos, 1440 "cts_timeout:\t\t\t%u\t\t\t%u\n", 1441 le32_to_cpu(tx->cts_timeout), accum_tx->cts_timeout); 1442 pos += scnprintf(buf + pos, bufsz - pos, 1443 "ack_timeout:\t\t\t%u\t\t\t%u\n", 1444 le32_to_cpu(tx->ack_timeout), 1445 accum_tx->ack_timeout); 1446 pos += scnprintf(buf + pos, bufsz - pos, 1447 "expected_ack_cnt:\t\t%u\t\t\t%u\n", 1448 le32_to_cpu(tx->expected_ack_cnt), 1449 accum_tx->expected_ack_cnt); 1450 pos += scnprintf(buf + pos, bufsz - pos, 1451 "actual_ack_cnt:\t\t\t%u\t\t\t%u\n", 1452 le32_to_cpu(tx->actual_ack_cnt), 1453 accum_tx->actual_ack_cnt); 1454 pos += scnprintf(buf + pos, bufsz - pos, 1455 "dump_msdu_cnt:\t\t\t%u\t\t\t%u\n", 1456 le32_to_cpu(tx->dump_msdu_cnt), 1457 accum_tx->dump_msdu_cnt); 1458 pos += scnprintf(buf + pos, bufsz - pos, 1459 "abort_nxt_frame_mismatch:" 1460 "\t%u\t\t\t%u\n", 1461 le32_to_cpu(tx->burst_abort_next_frame_mismatch_cnt), 1462 accum_tx->burst_abort_next_frame_mismatch_cnt); 1463 pos += scnprintf(buf + pos, bufsz - pos, 1464 "abort_missing_nxt_frame:" 1465 "\t%u\t\t\t%u\n", 1466 le32_to_cpu(tx->burst_abort_missing_next_frame_cnt), 1467 accum_tx->burst_abort_missing_next_frame_cnt); 1468 pos += scnprintf(buf + pos, bufsz - pos, 1469 "cts_timeout_collision:\t\t%u\t\t\t%u\n", 1470 le32_to_cpu(tx->cts_timeout_collision), 1471 accum_tx->cts_timeout_collision); 1472 pos += scnprintf(buf + pos, bufsz - pos, 1473 "ack_ba_timeout_collision:\t%u\t\t\t%u\n", 1474 le32_to_cpu(tx->ack_or_ba_timeout_collision), 1475 accum_tx->ack_or_ba_timeout_collision); 1476 pos += scnprintf(buf + pos, bufsz - pos, 1477 "agg ba_timeout:\t\t\t%u\t\t\t%u\n", 1478 le32_to_cpu(tx->agg.ba_timeout), 1479 accum_tx->agg.ba_timeout); 1480 pos += scnprintf(buf + pos, bufsz - pos, 1481 "agg ba_resched_frames:\t\t%u\t\t\t%u\n", 1482 le32_to_cpu(tx->agg.ba_reschedule_frames), 1483 accum_tx->agg.ba_reschedule_frames); 1484 pos += scnprintf(buf + pos, bufsz - pos, 1485 "agg scd_query_agg_frame:\t%u\t\t\t%u\n", 1486 le32_to_cpu(tx->agg.scd_query_agg_frame_cnt), 1487 accum_tx->agg.scd_query_agg_frame_cnt); 1488 pos += scnprintf(buf + pos, bufsz - pos, 1489 "agg scd_query_no_agg:\t\t%u\t\t\t%u\n", 1490 le32_to_cpu(tx->agg.scd_query_no_agg), 1491 accum_tx->agg.scd_query_no_agg); 1492 pos += scnprintf(buf + pos, bufsz - pos, 1493 "agg scd_query_agg:\t\t%u\t\t\t%u\n", 1494 le32_to_cpu(tx->agg.scd_query_agg), 1495 accum_tx->agg.scd_query_agg); 1496 pos += scnprintf(buf + pos, bufsz - pos, 1497 "agg scd_query_mismatch:\t\t%u\t\t\t%u\n", 1498 le32_to_cpu(tx->agg.scd_query_mismatch), 1499 accum_tx->agg.scd_query_mismatch); 1500 pos += scnprintf(buf + pos, bufsz - pos, 1501 "agg frame_not_ready:\t\t%u\t\t\t%u\n", 1502 le32_to_cpu(tx->agg.frame_not_ready), 1503 accum_tx->agg.frame_not_ready); 1504 pos += scnprintf(buf + pos, bufsz - pos, 1505 "agg underrun:\t\t\t%u\t\t\t%u\n", 1506 le32_to_cpu(tx->agg.underrun), 1507 accum_tx->agg.underrun); 1508 pos += scnprintf(buf + pos, bufsz - pos, 1509 "agg bt_prio_kill:\t\t%u\t\t\t%u\n", 1510 le32_to_cpu(tx->agg.bt_prio_kill), 1511 accum_tx->agg.bt_prio_kill); 1512 pos += scnprintf(buf + pos, bufsz - pos, 1513 "agg rx_ba_rsp_cnt:\t\t%u\t\t\t%u\n", 1514 le32_to_cpu(tx->agg.rx_ba_rsp_cnt), 1515 accum_tx->agg.rx_ba_rsp_cnt); 1516 1517 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); 1518 kfree(buf); 1519 return ret; 1520} 1521 1522static ssize_t iwl_dbgfs_ucode_general_stats_read(struct file *file, 1523 char __user *user_buf, 1524 size_t count, loff_t *ppos) 1525{ 1526 struct iwl_priv *priv = (struct iwl_priv *)file->private_data; 1527 int pos = 0; 1528 char *buf; 1529 int bufsz = sizeof(struct statistics_general) * 4 + 250; 1530 ssize_t ret; 1531 struct statistics_general *general, *accum_general; 1532 struct statistics_dbg *dbg, *accum_dbg; 1533 struct statistics_div *div, *accum_div; 1534 1535 if (!iwl_is_alive(priv)) 1536 return -EAGAIN; 1537 1538 /* make request to uCode to retrieve statistics information */ 1539 mutex_lock(&priv->mutex); 1540 ret = iwl_send_statistics_request(priv, CMD_SYNC, false); 1541 mutex_unlock(&priv->mutex); 1542 1543 if (ret) { 1544 IWL_ERR(priv, 1545 "Error sending statistics request: %zd\n", ret); 1546 return -EAGAIN; 1547 } 1548 buf = kzalloc(bufsz, GFP_KERNEL); 1549 if (!buf) { 1550 IWL_ERR(priv, "Can not allocate Buffer\n"); 1551 return -ENOMEM; 1552 } 1553 1554 /* the statistic information display here is based on 1555 * the last statistics notification from uCode 1556 * might not reflect the current uCode activity 1557 */ 1558 general = &priv->statistics.general; 1559 dbg = &priv->statistics.general.dbg; 1560 div = &priv->statistics.general.div; 1561 accum_general = &priv->accum_statistics.general; 1562 accum_dbg = &priv->accum_statistics.general.dbg; 1563 accum_div = &priv->accum_statistics.general.div; 1564 pos += iwl_dbgfs_statistics_flag(priv, buf, bufsz); 1565 pos += scnprintf(buf + pos, bufsz - pos, "Statistics_General:\n"); 1566 pos += scnprintf(buf + pos, bufsz - pos, 1567 "\t\t\tcurrent\t\t\taccumulative\n"); 1568 pos += scnprintf(buf + pos, bufsz - pos, "temperature:\t\t\t%u\n", 1569 le32_to_cpu(general->temperature)); 1570 pos += scnprintf(buf + pos, bufsz - pos, "temperature_m:\t\t\t%u\n", 1571 le32_to_cpu(general->temperature_m)); 1572 pos += scnprintf(buf + pos, bufsz - pos, 1573 "burst_check:\t\t\t%u\t\t\t%u\n", 1574 le32_to_cpu(dbg->burst_check), 1575 accum_dbg->burst_check); 1576 pos += scnprintf(buf + pos, bufsz - pos, 1577 "burst_count:\t\t\t%u\t\t\t%u\n", 1578 le32_to_cpu(dbg->burst_count), 1579 accum_dbg->burst_count); 1580 pos += scnprintf(buf + pos, bufsz - pos, 1581 "sleep_time:\t\t\t%u\t\t\t%u\n", 1582 le32_to_cpu(general->sleep_time), 1583 accum_general->sleep_time); 1584 pos += scnprintf(buf + pos, bufsz - pos, 1585 "slots_out:\t\t\t%u\t\t\t%u\n", 1586 le32_to_cpu(general->slots_out), 1587 accum_general->slots_out); 1588 pos += scnprintf(buf + pos, bufsz - pos, 1589 "slots_idle:\t\t\t%u\t\t\t%u\n", 1590 le32_to_cpu(general->slots_idle), 1591 accum_general->slots_idle); 1592 pos += scnprintf(buf + pos, bufsz - pos, "ttl_timestamp:\t\t\t%u\n", 1593 le32_to_cpu(general->ttl_timestamp)); 1594 pos += scnprintf(buf + pos, bufsz - pos, "tx_on_a:\t\t\t%u\t\t\t%u\n", 1595 le32_to_cpu(div->tx_on_a), accum_div->tx_on_a); 1596 pos += scnprintf(buf + pos, bufsz - pos, "tx_on_b:\t\t\t%u\t\t\t%u\n", 1597 le32_to_cpu(div->tx_on_b), accum_div->tx_on_b); 1598 pos += scnprintf(buf + pos, bufsz - pos, 1599 "exec_time:\t\t\t%u\t\t\t%u\n", 1600 le32_to_cpu(div->exec_time), accum_div->exec_time); 1601 pos += scnprintf(buf + pos, bufsz - pos, 1602 "probe_time:\t\t\t%u\t\t\t%u\n", 1603 le32_to_cpu(div->probe_time), accum_div->probe_time); 1604 pos += scnprintf(buf + pos, bufsz - pos, 1605 "rx_enable_counter:\t\t%u\t\t\t%u\n", 1606 le32_to_cpu(general->rx_enable_counter), 1607 accum_general->rx_enable_counter); 1608 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); 1609 kfree(buf); 1610 return ret; 1611} 1612 1613static ssize_t iwl_dbgfs_sensitivity_read(struct file *file, 1614 char __user *user_buf, 1615 size_t count, loff_t *ppos) { 1616 1617 struct iwl_priv *priv = (struct iwl_priv *)file->private_data; 1618 int pos = 0; 1619 int cnt = 0; 1620 char *buf; 1621 int bufsz = sizeof(struct iwl_sensitivity_data) * 4 + 100; 1622 ssize_t ret; 1623 struct iwl_sensitivity_data *data; 1624 1625 data = &priv->sensitivity_data; 1626 buf = kzalloc(bufsz, GFP_KERNEL); 1627 if (!buf) { 1628 IWL_ERR(priv, "Can not allocate Buffer\n"); 1629 return -ENOMEM; 1630 } 1631 1632 pos += scnprintf(buf + pos, bufsz - pos, "auto_corr_ofdm:\t\t\t %u\n", 1633 data->auto_corr_ofdm); 1634 pos += scnprintf(buf + pos, bufsz - pos, 1635 "auto_corr_ofdm_mrc:\t\t %u\n", 1636 data->auto_corr_ofdm_mrc); 1637 pos += scnprintf(buf + pos, bufsz - pos, "auto_corr_ofdm_x1:\t\t %u\n", 1638 data->auto_corr_ofdm_x1); 1639 pos += scnprintf(buf + pos, bufsz - pos, 1640 "auto_corr_ofdm_mrc_x1:\t\t %u\n", 1641 data->auto_corr_ofdm_mrc_x1); 1642 pos += scnprintf(buf + pos, bufsz - pos, "auto_corr_cck:\t\t\t %u\n", 1643 data->auto_corr_cck); 1644 pos += scnprintf(buf + pos, bufsz - pos, "auto_corr_cck_mrc:\t\t %u\n", 1645 data->auto_corr_cck_mrc); 1646 pos += scnprintf(buf + pos, bufsz - pos, 1647 "last_bad_plcp_cnt_ofdm:\t\t %u\n", 1648 data->last_bad_plcp_cnt_ofdm); 1649 pos += scnprintf(buf + pos, bufsz - pos, "last_fa_cnt_ofdm:\t\t %u\n", 1650 data->last_fa_cnt_ofdm); 1651 pos += scnprintf(buf + pos, bufsz - pos, 1652 "last_bad_plcp_cnt_cck:\t\t %u\n", 1653 data->last_bad_plcp_cnt_cck); 1654 pos += scnprintf(buf + pos, bufsz - pos, "last_fa_cnt_cck:\t\t %u\n", 1655 data->last_fa_cnt_cck); 1656 pos += scnprintf(buf + pos, bufsz - pos, "nrg_curr_state:\t\t\t %u\n", 1657 data->nrg_curr_state); 1658 pos += scnprintf(buf + pos, bufsz - pos, "nrg_prev_state:\t\t\t %u\n", 1659 data->nrg_prev_state); 1660 pos += scnprintf(buf + pos, bufsz - pos, "nrg_value:\t\t\t"); 1661 for (cnt = 0; cnt < 10; cnt++) { 1662 pos += scnprintf(buf + pos, bufsz - pos, " %u", 1663 data->nrg_value[cnt]); 1664 } 1665 pos += scnprintf(buf + pos, bufsz - pos, "\n"); 1666 pos += scnprintf(buf + pos, bufsz - pos, "nrg_silence_rssi:\t\t"); 1667 for (cnt = 0; cnt < NRG_NUM_PREV_STAT_L; cnt++) { 1668 pos += scnprintf(buf + pos, bufsz - pos, " %u", 1669 data->nrg_silence_rssi[cnt]); 1670 } 1671 pos += scnprintf(buf + pos, bufsz - pos, "\n"); 1672 pos += scnprintf(buf + pos, bufsz - pos, "nrg_silence_ref:\t\t %u\n", 1673 data->nrg_silence_ref); 1674 pos += scnprintf(buf + pos, bufsz - pos, "nrg_energy_idx:\t\t\t %u\n", 1675 data->nrg_energy_idx); 1676 pos += scnprintf(buf + pos, bufsz - pos, "nrg_silence_idx:\t\t %u\n", 1677 data->nrg_silence_idx); 1678 pos += scnprintf(buf + pos, bufsz - pos, "nrg_th_cck:\t\t\t %u\n", 1679 data->nrg_th_cck); 1680 pos += scnprintf(buf + pos, bufsz - pos, 1681 "nrg_auto_corr_silence_diff:\t %u\n", 1682 data->nrg_auto_corr_silence_diff); 1683 pos += scnprintf(buf + pos, bufsz - pos, "num_in_cck_no_fa:\t\t %u\n", 1684 data->num_in_cck_no_fa); 1685 pos += scnprintf(buf + pos, bufsz - pos, "nrg_th_ofdm:\t\t\t %u\n", 1686 data->nrg_th_ofdm); 1687 1688 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); 1689 kfree(buf); 1690 return ret; 1691} 1692 1693 1694static ssize_t iwl_dbgfs_chain_noise_read(struct file *file, 1695 char __user *user_buf, 1696 size_t count, loff_t *ppos) { 1697 1698 struct iwl_priv *priv = (struct iwl_priv *)file->private_data; 1699 int pos = 0; 1700 int cnt = 0; 1701 char *buf; 1702 int bufsz = sizeof(struct iwl_chain_noise_data) * 4 + 100; 1703 ssize_t ret; 1704 struct iwl_chain_noise_data *data; 1705 1706 data = &priv->chain_noise_data; 1707 buf = kzalloc(bufsz, GFP_KERNEL); 1708 if (!buf) { 1709 IWL_ERR(priv, "Can not allocate Buffer\n"); 1710 return -ENOMEM; 1711 } 1712 1713 pos += scnprintf(buf + pos, bufsz - pos, "active_chains:\t\t\t %u\n", 1714 data->active_chains); 1715 pos += scnprintf(buf + pos, bufsz - pos, "chain_noise_a:\t\t\t %u\n", 1716 data->chain_noise_a); 1717 pos += scnprintf(buf + pos, bufsz - pos, "chain_noise_b:\t\t\t %u\n", 1718 data->chain_noise_b); 1719 pos += scnprintf(buf + pos, bufsz - pos, "chain_noise_c:\t\t\t %u\n", 1720 data->chain_noise_c); 1721 pos += scnprintf(buf + pos, bufsz - pos, "chain_signal_a:\t\t\t %u\n", 1722 data->chain_signal_a); 1723 pos += scnprintf(buf + pos, bufsz - pos, "chain_signal_b:\t\t\t %u\n", 1724 data->chain_signal_b); 1725 pos += scnprintf(buf + pos, bufsz - pos, "chain_signal_c:\t\t\t %u\n", 1726 data->chain_signal_c); 1727 pos += scnprintf(buf + pos, bufsz - pos, "beacon_count:\t\t\t %u\n", 1728 data->beacon_count); 1729 1730 pos += scnprintf(buf + pos, bufsz - pos, "disconn_array:\t\t\t"); 1731 for (cnt = 0; cnt < NUM_RX_CHAINS; cnt++) { 1732 pos += scnprintf(buf + pos, bufsz - pos, " %u", 1733 data->disconn_array[cnt]); 1734 } 1735 pos += scnprintf(buf + pos, bufsz - pos, "\n"); 1736 pos += scnprintf(buf + pos, bufsz - pos, "delta_gain_code:\t\t"); 1737 for (cnt = 0; cnt < NUM_RX_CHAINS; cnt++) { 1738 pos += scnprintf(buf + pos, bufsz - pos, " %u", 1739 data->delta_gain_code[cnt]); 1740 } 1741 pos += scnprintf(buf + pos, bufsz - pos, "\n"); 1742 pos += scnprintf(buf + pos, bufsz - pos, "radio_write:\t\t\t %u\n", 1743 data->radio_write); 1744 pos += scnprintf(buf + pos, bufsz - pos, "state:\t\t\t\t %u\n", 1745 data->state); 1746 1747 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); 1748 kfree(buf); 1749 return ret; 1750} 1751 1752static ssize_t iwl_dbgfs_tx_power_read(struct file *file, 1753 char __user *user_buf, 1754 size_t count, loff_t *ppos) { 1755 1756 struct iwl_priv *priv = (struct iwl_priv *)file->private_data; 1757 char buf[128]; 1758 int pos = 0; 1759 ssize_t ret; 1760 const size_t bufsz = sizeof(buf); 1761 struct statistics_tx *tx; 1762 1763 if (!iwl_is_alive(priv)) 1764 pos += scnprintf(buf + pos, bufsz - pos, "N/A\n"); 1765 else { 1766 /* make request to uCode to retrieve statistics information */ 1767 mutex_lock(&priv->mutex); 1768 ret = iwl_send_statistics_request(priv, CMD_SYNC, false); 1769 mutex_unlock(&priv->mutex); 1770 1771 if (ret) { 1772 IWL_ERR(priv, "Error sending statistics request: %zd\n", 1773 ret); 1774 return -EAGAIN; 1775 } 1776 tx = &priv->statistics.tx; 1777 if (tx->tx_power.ant_a || 1778 tx->tx_power.ant_b || 1779 tx->tx_power.ant_c) { 1780 pos += scnprintf(buf + pos, bufsz - pos, 1781 "tx power: (1/2 dB step)\n"); 1782 if ((priv->cfg->valid_tx_ant & ANT_A) && 1783 tx->tx_power.ant_a) 1784 pos += scnprintf(buf + pos, bufsz - pos, 1785 "\tantenna A: 0x%X\n", 1786 tx->tx_power.ant_a); 1787 if ((priv->cfg->valid_tx_ant & ANT_B) && 1788 tx->tx_power.ant_b) 1789 pos += scnprintf(buf + pos, bufsz - pos, 1790 "\tantenna B: 0x%X\n", 1791 tx->tx_power.ant_b); 1792 if ((priv->cfg->valid_tx_ant & ANT_C) && 1793 tx->tx_power.ant_c) 1794 pos += scnprintf(buf + pos, bufsz - pos, 1795 "\tantenna C: 0x%X\n", 1796 tx->tx_power.ant_c); 1797 } else 1798 pos += scnprintf(buf + pos, bufsz - pos, "N/A\n"); 1799 } 1800 return simple_read_from_buffer(user_buf, count, ppos, buf, pos); 1801} 1802 1803static ssize_t iwl_dbgfs_power_save_status_read(struct file *file, 1804 char __user *user_buf, 1805 size_t count, loff_t *ppos) 1806{ 1807 struct iwl_priv *priv = (struct iwl_priv *)file->private_data; 1808 char buf[60]; 1809 int pos = 0; 1810 const size_t bufsz = sizeof(buf); 1811 u32 pwrsave_status; 1812 1813 pwrsave_status = iwl_read32(priv, CSR_GP_CNTRL) & 1814 CSR_GP_REG_POWER_SAVE_STATUS_MSK; 1815 1816 pos += scnprintf(buf + pos, bufsz - pos, "Power Save Status: "); 1817 pos += scnprintf(buf + pos, bufsz - pos, "%s\n", 1818 (pwrsave_status == CSR_GP_REG_NO_POWER_SAVE) ? "none" : 1819 (pwrsave_status == CSR_GP_REG_MAC_POWER_SAVE) ? "MAC" : 1820 (pwrsave_status == CSR_GP_REG_PHY_POWER_SAVE) ? "PHY" : 1821 "error"); 1822 1823 return simple_read_from_buffer(user_buf, count, ppos, buf, pos); 1824} 1825 1826static ssize_t iwl_dbgfs_clear_statistics_write(struct file *file, 1827 const char __user *user_buf, 1828 size_t count, loff_t *ppos) 1829{ 1830 struct iwl_priv *priv = file->private_data; 1831 char buf[8]; 1832 int buf_size; 1833 int clear; 1834 1835 memset(buf, 0, sizeof(buf)); 1836 buf_size = min(count, sizeof(buf) - 1); 1837 if (copy_from_user(buf, user_buf, buf_size)) 1838 return -EFAULT; 1839 if (sscanf(buf, "%d", &clear) != 1) 1840 return -EFAULT; 1841 1842 /* make request to uCode to retrieve statistics information */ 1843 mutex_lock(&priv->mutex); 1844 iwl_send_statistics_request(priv, CMD_SYNC, true); 1845 mutex_unlock(&priv->mutex); 1846 1847 return count; 1848} 1849 1850DEBUGFS_READ_WRITE_FILE_OPS(rx_statistics); 1851DEBUGFS_READ_WRITE_FILE_OPS(tx_statistics); 1852DEBUGFS_READ_WRITE_FILE_OPS(traffic_log); 1853DEBUGFS_READ_FILE_OPS(rx_queue); 1854DEBUGFS_READ_FILE_OPS(tx_queue); 1855DEBUGFS_READ_FILE_OPS(ucode_rx_stats); 1856DEBUGFS_READ_FILE_OPS(ucode_tx_stats); 1857DEBUGFS_READ_FILE_OPS(ucode_general_stats); 1858DEBUGFS_READ_FILE_OPS(sensitivity); 1859DEBUGFS_READ_FILE_OPS(chain_noise); 1860DEBUGFS_READ_FILE_OPS(tx_power); 1861DEBUGFS_READ_FILE_OPS(power_save_status); 1862DEBUGFS_WRITE_FILE_OPS(clear_statistics); 1863 1864/* 1865 * Create the debugfs files and directories 1866 * 1867 */ 1868int iwl_dbgfs_register(struct iwl_priv *priv, const char *name) 1869{ 1870 struct iwl_debugfs *dbgfs; 1871 struct dentry *phyd = priv->hw->wiphy->debugfsdir; 1872 int ret = 0; 1873 1874 dbgfs = kzalloc(sizeof(struct iwl_debugfs), GFP_KERNEL); 1875 if (!dbgfs) { 1876 ret = -ENOMEM; 1877 goto err; 1878 } 1879 1880 priv->dbgfs = dbgfs; 1881 dbgfs->name = name; 1882 dbgfs->dir_drv = debugfs_create_dir(name, phyd); 1883 if (!dbgfs->dir_drv || IS_ERR(dbgfs->dir_drv)) { 1884 ret = -ENOENT; 1885 goto err; 1886 } 1887 1888 DEBUGFS_ADD_DIR(data, dbgfs->dir_drv); 1889 DEBUGFS_ADD_DIR(rf, dbgfs->dir_drv); 1890 DEBUGFS_ADD_DIR(debug, dbgfs->dir_drv); 1891 DEBUGFS_ADD_FILE(nvm, data); 1892 DEBUGFS_ADD_FILE(sram, data); 1893 DEBUGFS_ADD_FILE(log_event, data); 1894 DEBUGFS_ADD_FILE(stations, data); 1895 DEBUGFS_ADD_FILE(channels, data); 1896 DEBUGFS_ADD_FILE(status, data); 1897 DEBUGFS_ADD_FILE(interrupt, data); 1898 DEBUGFS_ADD_FILE(qos, data); 1899 DEBUGFS_ADD_FILE(led, data); 1900 DEBUGFS_ADD_FILE(sleep_level_override, data); 1901 DEBUGFS_ADD_FILE(current_sleep_command, data); 1902 DEBUGFS_ADD_FILE(thermal_throttling, data); 1903 DEBUGFS_ADD_FILE(disable_ht40, data); 1904 DEBUGFS_ADD_FILE(rx_statistics, debug); 1905 DEBUGFS_ADD_FILE(tx_statistics, debug); 1906 DEBUGFS_ADD_FILE(traffic_log, debug); 1907 DEBUGFS_ADD_FILE(rx_queue, debug); 1908 DEBUGFS_ADD_FILE(tx_queue, debug); 1909 DEBUGFS_ADD_FILE(tx_power, debug); 1910 DEBUGFS_ADD_FILE(power_save_status, debug); 1911 DEBUGFS_ADD_FILE(clear_statistics, debug); 1912 if ((priv->hw_rev & CSR_HW_REV_TYPE_MSK) != CSR_HW_REV_TYPE_3945) { 1913 DEBUGFS_ADD_FILE(ucode_rx_stats, debug); 1914 DEBUGFS_ADD_FILE(ucode_tx_stats, debug); 1915 DEBUGFS_ADD_FILE(ucode_general_stats, debug); 1916 DEBUGFS_ADD_FILE(sensitivity, debug); 1917 DEBUGFS_ADD_FILE(chain_noise, debug); 1918 } 1919 DEBUGFS_ADD_BOOL(disable_sensitivity, rf, &priv->disable_sens_cal); 1920 DEBUGFS_ADD_BOOL(disable_chain_noise, rf, 1921 &priv->disable_chain_noise_cal); 1922 if (((priv->hw_rev & CSR_HW_REV_TYPE_MSK) == CSR_HW_REV_TYPE_4965) || 1923 ((priv->hw_rev & CSR_HW_REV_TYPE_MSK) == CSR_HW_REV_TYPE_3945)) 1924 DEBUGFS_ADD_BOOL(disable_tx_power, rf, 1925 &priv->disable_tx_power_cal); 1926 return 0; 1927 1928err: 1929 IWL_ERR(priv, "Can't open the debugfs directory\n"); 1930 iwl_dbgfs_unregister(priv); 1931 return ret; 1932} 1933EXPORT_SYMBOL(iwl_dbgfs_register); 1934 1935/** 1936 * Remove the debugfs files and directories 1937 * 1938 */ 1939void iwl_dbgfs_unregister(struct iwl_priv *priv) 1940{ 1941 if (!priv->dbgfs) 1942 return; 1943 1944 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_sleep_level_override); 1945 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_current_sleep_command); 1946 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_nvm); 1947 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_sram); 1948 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_log_event); 1949 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_stations); 1950 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_channels); 1951 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_status); 1952 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_interrupt); 1953 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_qos); 1954 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_led); 1955 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_thermal_throttling); 1956 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_disable_ht40); 1957 DEBUGFS_REMOVE(priv->dbgfs->dir_data); 1958 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.file_rx_statistics); 1959 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.file_tx_statistics); 1960 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.file_traffic_log); 1961 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.file_rx_queue); 1962 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.file_tx_queue); 1963 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.file_tx_power); 1964 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.file_power_save_status); 1965 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files.file_clear_statistics); 1966 if ((priv->hw_rev & CSR_HW_REV_TYPE_MSK) != CSR_HW_REV_TYPE_3945) { 1967 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files. 1968 file_ucode_rx_stats); 1969 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files. 1970 file_ucode_tx_stats); 1971 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files. 1972 file_ucode_general_stats); 1973 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files. 1974 file_sensitivity); 1975 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_debug_files. 1976 file_chain_noise); 1977 } 1978 DEBUGFS_REMOVE(priv->dbgfs->dir_debug); 1979 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_rf_files.file_disable_sensitivity); 1980 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_rf_files.file_disable_chain_noise); 1981 if (((priv->hw_rev & CSR_HW_REV_TYPE_MSK) == CSR_HW_REV_TYPE_4965) || 1982 ((priv->hw_rev & CSR_HW_REV_TYPE_MSK) == CSR_HW_REV_TYPE_3945)) 1983 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_rf_files.file_disable_tx_power); 1984 DEBUGFS_REMOVE(priv->dbgfs->dir_rf); 1985 DEBUGFS_REMOVE(priv->dbgfs->dir_drv); 1986 kfree(priv->dbgfs); 1987 priv->dbgfs = NULL; 1988} 1989EXPORT_SYMBOL(iwl_dbgfs_unregister); 1990 1991 1992 1993