iwl-debugfs.c revision 6da3a13e4fcab0ff58592087d28bd283caf23d88
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 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, 0644, dbgfs->dir_##parent, priv, \ 53 &iwl_dbgfs_##name##_ops); \ 54 if (!(dbgfs->dbgfs_##parent##_files.file_##name)) \ 55 goto err; \ 56} while (0) 57 58#define DEBUGFS_ADD_BOOL(name, parent, ptr) do { \ 59 dbgfs->dbgfs_##parent##_files.file_##name = \ 60 debugfs_create_bool(#name, 0644, dbgfs->dir_##parent, ptr); \ 61 if (IS_ERR(dbgfs->dbgfs_##parent##_files.file_##name) \ 62 || !dbgfs->dbgfs_##parent##_files.file_##name) \ 63 goto err; \ 64} while (0) 65 66#define DEBUGFS_ADD_X32(name, parent, ptr) do { \ 67 dbgfs->dbgfs_##parent##_files.file_##name = \ 68 debugfs_create_x32(#name, 0444, dbgfs->dir_##parent, ptr); \ 69 if (IS_ERR(dbgfs->dbgfs_##parent##_files.file_##name) \ 70 || !dbgfs->dbgfs_##parent##_files.file_##name) \ 71 goto err; \ 72} while (0) 73 74#define DEBUGFS_REMOVE(name) do { \ 75 debugfs_remove(name); \ 76 name = NULL; \ 77} while (0); 78 79/* file operation */ 80#define DEBUGFS_READ_FUNC(name) \ 81static ssize_t iwl_dbgfs_##name##_read(struct file *file, \ 82 char __user *user_buf, \ 83 size_t count, loff_t *ppos); 84 85#define DEBUGFS_WRITE_FUNC(name) \ 86static ssize_t iwl_dbgfs_##name##_write(struct file *file, \ 87 const char __user *user_buf, \ 88 size_t count, loff_t *ppos); 89 90 91static int iwl_dbgfs_open_file_generic(struct inode *inode, struct file *file) 92{ 93 file->private_data = inode->i_private; 94 return 0; 95} 96 97#define DEBUGFS_READ_FILE_OPS(name) \ 98 DEBUGFS_READ_FUNC(name); \ 99static const struct file_operations iwl_dbgfs_##name##_ops = { \ 100 .read = iwl_dbgfs_##name##_read, \ 101 .open = iwl_dbgfs_open_file_generic, \ 102}; 103 104#define DEBUGFS_WRITE_FILE_OPS(name) \ 105 DEBUGFS_WRITE_FUNC(name); \ 106static const struct file_operations iwl_dbgfs_##name##_ops = { \ 107 .write = iwl_dbgfs_##name##_write, \ 108 .open = iwl_dbgfs_open_file_generic, \ 109}; 110 111 112#define DEBUGFS_READ_WRITE_FILE_OPS(name) \ 113 DEBUGFS_READ_FUNC(name); \ 114 DEBUGFS_WRITE_FUNC(name); \ 115static const struct file_operations iwl_dbgfs_##name##_ops = { \ 116 .write = iwl_dbgfs_##name##_write, \ 117 .read = iwl_dbgfs_##name##_read, \ 118 .open = iwl_dbgfs_open_file_generic, \ 119}; 120 121 122static ssize_t iwl_dbgfs_tx_statistics_read(struct file *file, 123 char __user *user_buf, 124 size_t count, loff_t *ppos) { 125 126 struct iwl_priv *priv = (struct iwl_priv *)file->private_data; 127 char buf[256]; 128 int pos = 0; 129 const size_t bufsz = sizeof(buf); 130 131 pos += scnprintf(buf + pos, bufsz - pos, "mgmt: %u\n", 132 priv->tx_stats[0].cnt); 133 pos += scnprintf(buf + pos, bufsz - pos, "ctrl: %u\n", 134 priv->tx_stats[1].cnt); 135 pos += scnprintf(buf + pos, bufsz - pos, "data: %u\n", 136 priv->tx_stats[2].cnt); 137 138 return simple_read_from_buffer(user_buf, count, ppos, buf, pos); 139} 140 141static ssize_t iwl_dbgfs_rx_statistics_read(struct file *file, 142 char __user *user_buf, 143 size_t count, loff_t *ppos) { 144 145 struct iwl_priv *priv = (struct iwl_priv *)file->private_data; 146 char buf[256]; 147 int pos = 0; 148 const size_t bufsz = sizeof(buf); 149 150 pos += scnprintf(buf + pos, bufsz - pos, "mgmt: %u\n", 151 priv->rx_stats[0].cnt); 152 pos += scnprintf(buf + pos, bufsz - pos, "ctrl: %u\n", 153 priv->rx_stats[1].cnt); 154 pos += scnprintf(buf + pos, bufsz - pos, "data: %u\n", 155 priv->rx_stats[2].cnt); 156 157 return simple_read_from_buffer(user_buf, count, ppos, buf, pos); 158} 159 160#define BYTE1_MASK 0x000000ff; 161#define BYTE2_MASK 0x0000ffff; 162#define BYTE3_MASK 0x00ffffff; 163static ssize_t iwl_dbgfs_sram_read(struct file *file, 164 char __user *user_buf, 165 size_t count, loff_t *ppos) 166{ 167 u32 val; 168 char buf[1024]; 169 ssize_t ret; 170 int i; 171 int pos = 0; 172 struct iwl_priv *priv = (struct iwl_priv *)file->private_data; 173 const size_t bufsz = sizeof(buf); 174 175 iwl_grab_nic_access(priv); 176 for (i = priv->dbgfs->sram_len; i > 0; i -= 4) { 177 val = iwl_read_targ_mem(priv, priv->dbgfs->sram_offset + \ 178 priv->dbgfs->sram_len - i); 179 if (i < 4) { 180 switch (i) { 181 case 1: 182 val &= BYTE1_MASK; 183 break; 184 case 2: 185 val &= BYTE2_MASK; 186 break; 187 case 3: 188 val &= BYTE3_MASK; 189 break; 190 } 191 } 192 pos += scnprintf(buf + pos, bufsz - pos, "0x%08x ", val); 193 } 194 pos += scnprintf(buf + pos, bufsz - pos, "\n"); 195 iwl_release_nic_access(priv); 196 197 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); 198 return ret; 199} 200 201static ssize_t iwl_dbgfs_sram_write(struct file *file, 202 const char __user *user_buf, 203 size_t count, loff_t *ppos) 204{ 205 struct iwl_priv *priv = file->private_data; 206 char buf[64]; 207 int buf_size; 208 u32 offset, len; 209 210 memset(buf, 0, sizeof(buf)); 211 buf_size = min(count, sizeof(buf) - 1); 212 if (copy_from_user(buf, user_buf, buf_size)) 213 return -EFAULT; 214 215 if (sscanf(buf, "%x,%x", &offset, &len) == 2) { 216 priv->dbgfs->sram_offset = offset; 217 priv->dbgfs->sram_len = len; 218 } else { 219 priv->dbgfs->sram_offset = 0; 220 priv->dbgfs->sram_len = 0; 221 } 222 223 return count; 224} 225 226static ssize_t iwl_dbgfs_stations_read(struct file *file, char __user *user_buf, 227 size_t count, loff_t *ppos) 228{ 229 struct iwl_priv *priv = (struct iwl_priv *)file->private_data; 230 struct iwl_station_entry *station; 231 int max_sta = priv->hw_params.max_stations; 232 char *buf; 233 int i, j, pos = 0; 234 ssize_t ret; 235 /* Add 30 for initial string */ 236 const size_t bufsz = 30 + sizeof(char) * 500 * (priv->num_stations); 237 238 buf = kmalloc(bufsz, GFP_KERNEL); 239 if (!buf) 240 return -ENOMEM; 241 242 pos += scnprintf(buf + pos, bufsz - pos, "num of stations: %d\n\n", 243 priv->num_stations); 244 245 for (i = 0; i < max_sta; i++) { 246 station = &priv->stations[i]; 247 if (station->used) { 248 pos += scnprintf(buf + pos, bufsz - pos, 249 "station %d:\ngeneral data:\n", i+1); 250 pos += scnprintf(buf + pos, bufsz - pos, "id: %u\n", 251 station->sta.sta.sta_id); 252 pos += scnprintf(buf + pos, bufsz - pos, "mode: %u\n", 253 station->sta.mode); 254 pos += scnprintf(buf + pos, bufsz - pos, 255 "flags: 0x%x\n", 256 station->sta.station_flags_msk); 257 pos += scnprintf(buf + pos, bufsz - pos, 258 "ps_status: %u\n", station->ps_status); 259 pos += scnprintf(buf + pos, bufsz - pos, "tid data:\n"); 260 pos += scnprintf(buf + pos, bufsz - pos, 261 "seq_num\t\ttxq_id"); 262 pos += scnprintf(buf + pos, bufsz - pos, 263 "\tframe_count\twait_for_ba\t"); 264 pos += scnprintf(buf + pos, bufsz - pos, 265 "start_idx\tbitmap0\t"); 266 pos += scnprintf(buf + pos, bufsz - pos, 267 "bitmap1\trate_n_flags"); 268 pos += scnprintf(buf + pos, bufsz - pos, "\n"); 269 270 for (j = 0; j < MAX_TID_COUNT; j++) { 271 pos += scnprintf(buf + pos, bufsz - pos, 272 "[%d]:\t\t%u", j, 273 station->tid[j].seq_number); 274 pos += scnprintf(buf + pos, bufsz - pos, 275 "\t%u\t\t%u\t\t%u\t\t", 276 station->tid[j].agg.txq_id, 277 station->tid[j].agg.frame_count, 278 station->tid[j].agg.wait_for_ba); 279 pos += scnprintf(buf + pos, bufsz - pos, 280 "%u\t%llu\t%u", 281 station->tid[j].agg.start_idx, 282 (unsigned long long)station->tid[j].agg.bitmap, 283 station->tid[j].agg.rate_n_flags); 284 pos += scnprintf(buf + pos, bufsz - pos, "\n"); 285 } 286 pos += scnprintf(buf + pos, bufsz - pos, "\n"); 287 } 288 } 289 290 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); 291 kfree(buf); 292 return ret; 293} 294 295static ssize_t iwl_dbgfs_eeprom_read(struct file *file, 296 char __user *user_buf, 297 size_t count, 298 loff_t *ppos) 299{ 300 ssize_t ret; 301 struct iwl_priv *priv = (struct iwl_priv *)file->private_data; 302 int pos = 0, ofs = 0, buf_size = 0; 303 const u8 *ptr; 304 char *buf; 305 size_t eeprom_len = priv->cfg->eeprom_size; 306 buf_size = 4 * eeprom_len + 256; 307 308 if (eeprom_len % 16) { 309 IWL_ERR(priv, "EEPROM size is not multiple of 16.\n"); 310 return -ENODATA; 311 } 312 313 /* 4 characters for byte 0xYY */ 314 buf = kzalloc(buf_size, GFP_KERNEL); 315 if (!buf) { 316 IWL_ERR(priv, "Can not allocate Buffer\n"); 317 return -ENOMEM; 318 } 319 320 ptr = priv->eeprom; 321 for (ofs = 0 ; ofs < eeprom_len ; ofs += 16) { 322 pos += scnprintf(buf + pos, buf_size - pos, "0x%.4x ", ofs); 323 hex_dump_to_buffer(ptr + ofs, 16 , 16, 2, buf + pos, 324 buf_size - pos, 0); 325 pos += strlen(buf); 326 if (buf_size - pos > 0) 327 buf[pos++] = '\n'; 328 } 329 330 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); 331 kfree(buf); 332 return ret; 333} 334 335static ssize_t iwl_dbgfs_log_event_write(struct file *file, 336 const char __user *user_buf, 337 size_t count, loff_t *ppos) 338{ 339 struct iwl_priv *priv = file->private_data; 340 u32 event_log_flag; 341 char buf[8]; 342 int buf_size; 343 344 memset(buf, 0, sizeof(buf)); 345 buf_size = min(count, sizeof(buf) - 1); 346 if (copy_from_user(buf, user_buf, buf_size)) 347 return -EFAULT; 348 if (sscanf(buf, "%d", &event_log_flag) != 1) 349 return -EFAULT; 350 if (event_log_flag == 1) 351 iwl_dump_nic_event_log(priv); 352 353 return count; 354} 355 356 357 358static ssize_t iwl_dbgfs_channels_read(struct file *file, char __user *user_buf, 359 size_t count, loff_t *ppos) 360{ 361 struct iwl_priv *priv = (struct iwl_priv *)file->private_data; 362 struct ieee80211_channel *channels = NULL; 363 const struct ieee80211_supported_band *supp_band = NULL; 364 int pos = 0, i, bufsz = PAGE_SIZE; 365 char *buf; 366 ssize_t ret; 367 368 if (!test_bit(STATUS_GEO_CONFIGURED, &priv->status)) 369 return -EAGAIN; 370 371 buf = kzalloc(bufsz, GFP_KERNEL); 372 if (!buf) { 373 IWL_ERR(priv, "Can not allocate Buffer\n"); 374 return -ENOMEM; 375 } 376 377 supp_band = iwl_get_hw_mode(priv, IEEE80211_BAND_2GHZ); 378 channels = supp_band->channels; 379 380 pos += scnprintf(buf + pos, bufsz - pos, 381 "Displaying %d channels in 2.4GHz band 802.11bg):\n", 382 supp_band->n_channels); 383 384 for (i = 0; i < supp_band->n_channels; i++) 385 pos += scnprintf(buf + pos, bufsz - pos, 386 "%d: %ddBm: BSS%s%s, %s.\n", 387 ieee80211_frequency_to_channel( 388 channels[i].center_freq), 389 channels[i].max_power, 390 channels[i].flags & IEEE80211_CHAN_RADAR ? 391 " (IEEE 802.11h required)" : "", 392 (!(channels[i].flags & IEEE80211_CHAN_NO_IBSS) 393 || (channels[i].flags & 394 IEEE80211_CHAN_RADAR)) ? "" : 395 ", IBSS", 396 channels[i].flags & 397 IEEE80211_CHAN_PASSIVE_SCAN ? 398 "passive only" : "active/passive"); 399 400 supp_band = iwl_get_hw_mode(priv, IEEE80211_BAND_5GHZ); 401 channels = supp_band->channels; 402 403 pos += scnprintf(buf + pos, bufsz - pos, 404 "Displaying %d channels in 5.2GHz band (802.11a)\n", 405 supp_band->n_channels); 406 407 for (i = 0; i < supp_band->n_channels; i++) 408 pos += scnprintf(buf + pos, bufsz - pos, 409 "%d: %ddBm: BSS%s%s, %s.\n", 410 ieee80211_frequency_to_channel( 411 channels[i].center_freq), 412 channels[i].max_power, 413 channels[i].flags & IEEE80211_CHAN_RADAR ? 414 " (IEEE 802.11h required)" : "", 415 ((channels[i].flags & IEEE80211_CHAN_NO_IBSS) 416 || (channels[i].flags & 417 IEEE80211_CHAN_RADAR)) ? "" : 418 ", IBSS", 419 channels[i].flags & 420 IEEE80211_CHAN_PASSIVE_SCAN ? 421 "passive only" : "active/passive"); 422 423 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); 424 kfree(buf); 425 return ret; 426} 427 428static ssize_t iwl_dbgfs_status_read(struct file *file, 429 char __user *user_buf, 430 size_t count, loff_t *ppos) { 431 432 struct iwl_priv *priv = (struct iwl_priv *)file->private_data; 433 char buf[512]; 434 int pos = 0; 435 const size_t bufsz = sizeof(buf); 436 437 pos += scnprintf(buf + pos, bufsz - pos, "STATUS_HCMD_ACTIVE:\t %d\n", 438 test_bit(STATUS_HCMD_ACTIVE, &priv->status)); 439 pos += scnprintf(buf + pos, bufsz - pos, "STATUS_HCMD_SYNC_ACTIVE: %d\n", 440 test_bit(STATUS_HCMD_SYNC_ACTIVE, &priv->status)); 441 pos += scnprintf(buf + pos, bufsz - pos, "STATUS_INT_ENABLED:\t %d\n", 442 test_bit(STATUS_INT_ENABLED, &priv->status)); 443 pos += scnprintf(buf + pos, bufsz - pos, "STATUS_RF_KILL_HW:\t %d\n", 444 test_bit(STATUS_RF_KILL_HW, &priv->status)); 445 pos += scnprintf(buf + pos, bufsz - pos, "STATUS_RF_KILL_SW:\t %d\n", 446 test_bit(STATUS_RF_KILL_SW, &priv->status)); 447 pos += scnprintf(buf + pos, bufsz - pos, "STATUS_INIT:\t\t %d\n", 448 test_bit(STATUS_INIT, &priv->status)); 449 pos += scnprintf(buf + pos, bufsz - pos, "STATUS_ALIVE:\t\t %d\n", 450 test_bit(STATUS_ALIVE, &priv->status)); 451 pos += scnprintf(buf + pos, bufsz - pos, "STATUS_READY:\t\t %d\n", 452 test_bit(STATUS_READY, &priv->status)); 453 pos += scnprintf(buf + pos, bufsz - pos, "STATUS_TEMPERATURE:\t %d\n", 454 test_bit(STATUS_TEMPERATURE, &priv->status)); 455 pos += scnprintf(buf + pos, bufsz - pos, "STATUS_GEO_CONFIGURED:\t %d\n", 456 test_bit(STATUS_GEO_CONFIGURED, &priv->status)); 457 pos += scnprintf(buf + pos, bufsz - pos, "STATUS_EXIT_PENDING:\t %d\n", 458 test_bit(STATUS_EXIT_PENDING, &priv->status)); 459 pos += scnprintf(buf + pos, bufsz - pos, "STATUS_STATISTICS:\t %d\n", 460 test_bit(STATUS_STATISTICS, &priv->status)); 461 pos += scnprintf(buf + pos, bufsz - pos, "STATUS_SCANNING:\t %d\n", 462 test_bit(STATUS_SCANNING, &priv->status)); 463 pos += scnprintf(buf + pos, bufsz - pos, "STATUS_SCAN_ABORTING:\t %d\n", 464 test_bit(STATUS_SCAN_ABORTING, &priv->status)); 465 pos += scnprintf(buf + pos, bufsz - pos, "STATUS_SCAN_HW:\t\t %d\n", 466 test_bit(STATUS_SCAN_HW, &priv->status)); 467 pos += scnprintf(buf + pos, bufsz - pos, "STATUS_POWER_PMI:\t %d\n", 468 test_bit(STATUS_POWER_PMI, &priv->status)); 469 pos += scnprintf(buf + pos, bufsz - pos, "STATUS_FW_ERROR:\t %d\n", 470 test_bit(STATUS_FW_ERROR, &priv->status)); 471 pos += scnprintf(buf + pos, bufsz - pos, "STATUS_MODE_PENDING:\t %d\n", 472 test_bit(STATUS_MODE_PENDING, &priv->status)); 473 return simple_read_from_buffer(user_buf, count, ppos, buf, pos); 474} 475 476DEBUGFS_READ_WRITE_FILE_OPS(sram); 477DEBUGFS_WRITE_FILE_OPS(log_event); 478DEBUGFS_READ_FILE_OPS(eeprom); 479DEBUGFS_READ_FILE_OPS(stations); 480DEBUGFS_READ_FILE_OPS(rx_statistics); 481DEBUGFS_READ_FILE_OPS(tx_statistics); 482DEBUGFS_READ_FILE_OPS(channels); 483DEBUGFS_READ_FILE_OPS(status); 484 485/* 486 * Create the debugfs files and directories 487 * 488 */ 489int iwl_dbgfs_register(struct iwl_priv *priv, const char *name) 490{ 491 struct iwl_debugfs *dbgfs; 492 struct dentry *phyd = priv->hw->wiphy->debugfsdir; 493 int ret = 0; 494 495 dbgfs = kzalloc(sizeof(struct iwl_debugfs), GFP_KERNEL); 496 if (!dbgfs) { 497 ret = -ENOMEM; 498 goto err; 499 } 500 501 priv->dbgfs = dbgfs; 502 dbgfs->name = name; 503 dbgfs->dir_drv = debugfs_create_dir(name, phyd); 504 if (!dbgfs->dir_drv || IS_ERR(dbgfs->dir_drv)) { 505 ret = -ENOENT; 506 goto err; 507 } 508 509 DEBUGFS_ADD_DIR(data, dbgfs->dir_drv); 510 DEBUGFS_ADD_DIR(rf, dbgfs->dir_drv); 511 DEBUGFS_ADD_FILE(eeprom, data); 512 DEBUGFS_ADD_FILE(sram, data); 513 DEBUGFS_ADD_FILE(log_event, data); 514 DEBUGFS_ADD_FILE(stations, data); 515 DEBUGFS_ADD_FILE(rx_statistics, data); 516 DEBUGFS_ADD_FILE(tx_statistics, data); 517 DEBUGFS_ADD_FILE(channels, data); 518 DEBUGFS_ADD_FILE(status, data); 519 DEBUGFS_ADD_BOOL(disable_sensitivity, rf, &priv->disable_sens_cal); 520 DEBUGFS_ADD_BOOL(disable_chain_noise, rf, 521 &priv->disable_chain_noise_cal); 522 DEBUGFS_ADD_BOOL(disable_tx_power, rf, &priv->disable_tx_power_cal); 523 return 0; 524 525err: 526 IWL_ERR(priv, "Can't open the debugfs directory\n"); 527 iwl_dbgfs_unregister(priv); 528 return ret; 529} 530EXPORT_SYMBOL(iwl_dbgfs_register); 531 532/** 533 * Remove the debugfs files and directories 534 * 535 */ 536void iwl_dbgfs_unregister(struct iwl_priv *priv) 537{ 538 if (!priv->dbgfs) 539 return; 540 541 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_eeprom); 542 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_rx_statistics); 543 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_tx_statistics); 544 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_sram); 545 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_log_event); 546 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_stations); 547 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_channels); 548 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_status); 549 DEBUGFS_REMOVE(priv->dbgfs->dir_data); 550 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_rf_files.file_disable_sensitivity); 551 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_rf_files.file_disable_chain_noise); 552 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_rf_files.file_disable_tx_power); 553 DEBUGFS_REMOVE(priv->dbgfs->dir_rf); 554 DEBUGFS_REMOVE(priv->dbgfs->dir_drv); 555 kfree(priv->dbgfs); 556 priv->dbgfs = NULL; 557} 558EXPORT_SYMBOL(iwl_dbgfs_unregister); 559 560 561 562