1 // SPDX-License-Identifier: GPL-2.0-only 2 /****************************************************************************** 3 * 4 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved. 5 * 6 * Contact Information: 7 * Intel Linux Wireless <ilw@linux.intel.com> 8 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 9 *****************************************************************************/ 10 #include <linux/ieee80211.h> 11 #include <linux/export.h> 12 #include <net/mac80211.h> 13 14 #include "common.h" 15 16 static void 17 il_clear_traffic_stats(struct il_priv *il) 18 { 19 memset(&il->tx_stats, 0, sizeof(struct traffic_stats)); 20 memset(&il->rx_stats, 0, sizeof(struct traffic_stats)); 21 } 22 23 /* 24 * il_update_stats function record all the MGMT, CTRL and DATA pkt for 25 * both TX and Rx . Use debugfs to display the rx/rx_stats 26 */ 27 void 28 il_update_stats(struct il_priv *il, bool is_tx, __le16 fc, u16 len) 29 { 30 struct traffic_stats *stats; 31 32 if (is_tx) 33 stats = &il->tx_stats; 34 else 35 stats = &il->rx_stats; 36 37 if (ieee80211_is_mgmt(fc)) { 38 switch (fc & cpu_to_le16(IEEE80211_FCTL_STYPE)) { 39 case cpu_to_le16(IEEE80211_STYPE_ASSOC_REQ): 40 stats->mgmt[MANAGEMENT_ASSOC_REQ]++; 41 break; 42 case cpu_to_le16(IEEE80211_STYPE_ASSOC_RESP): 43 stats->mgmt[MANAGEMENT_ASSOC_RESP]++; 44 break; 45 case cpu_to_le16(IEEE80211_STYPE_REASSOC_REQ): 46 stats->mgmt[MANAGEMENT_REASSOC_REQ]++; 47 break; 48 case cpu_to_le16(IEEE80211_STYPE_REASSOC_RESP): 49 stats->mgmt[MANAGEMENT_REASSOC_RESP]++; 50 break; 51 case cpu_to_le16(IEEE80211_STYPE_PROBE_REQ): 52 stats->mgmt[MANAGEMENT_PROBE_REQ]++; 53 break; 54 case cpu_to_le16(IEEE80211_STYPE_PROBE_RESP): 55 stats->mgmt[MANAGEMENT_PROBE_RESP]++; 56 break; 57 case cpu_to_le16(IEEE80211_STYPE_BEACON): 58 stats->mgmt[MANAGEMENT_BEACON]++; 59 break; 60 case cpu_to_le16(IEEE80211_STYPE_ATIM): 61 stats->mgmt[MANAGEMENT_ATIM]++; 62 break; 63 case cpu_to_le16(IEEE80211_STYPE_DISASSOC): 64 stats->mgmt[MANAGEMENT_DISASSOC]++; 65 break; 66 case cpu_to_le16(IEEE80211_STYPE_AUTH): 67 stats->mgmt[MANAGEMENT_AUTH]++; 68 break; 69 case cpu_to_le16(IEEE80211_STYPE_DEAUTH): 70 stats->mgmt[MANAGEMENT_DEAUTH]++; 71 break; 72 case cpu_to_le16(IEEE80211_STYPE_ACTION): 73 stats->mgmt[MANAGEMENT_ACTION]++; 74 break; 75 } 76 } else if (ieee80211_is_ctl(fc)) { 77 switch (fc & cpu_to_le16(IEEE80211_FCTL_STYPE)) { 78 case cpu_to_le16(IEEE80211_STYPE_BACK_REQ): 79 stats->ctrl[CONTROL_BACK_REQ]++; 80 break; 81 case cpu_to_le16(IEEE80211_STYPE_BACK): 82 stats->ctrl[CONTROL_BACK]++; 83 break; 84 case cpu_to_le16(IEEE80211_STYPE_PSPOLL): 85 stats->ctrl[CONTROL_PSPOLL]++; 86 break; 87 case cpu_to_le16(IEEE80211_STYPE_RTS): 88 stats->ctrl[CONTROL_RTS]++; 89 break; 90 case cpu_to_le16(IEEE80211_STYPE_CTS): 91 stats->ctrl[CONTROL_CTS]++; 92 break; 93 case cpu_to_le16(IEEE80211_STYPE_ACK): 94 stats->ctrl[CONTROL_ACK]++; 95 break; 96 case cpu_to_le16(IEEE80211_STYPE_CFEND): 97 stats->ctrl[CONTROL_CFEND]++; 98 break; 99 case cpu_to_le16(IEEE80211_STYPE_CFENDACK): 100 stats->ctrl[CONTROL_CFENDACK]++; 101 break; 102 } 103 } else { 104 /* data */ 105 stats->data_cnt++; 106 stats->data_bytes += len; 107 } 108 } 109 EXPORT_SYMBOL(il_update_stats); 110 111 /* create and remove of files */ 112 #define DEBUGFS_ADD_FILE(name, parent, mode) do { \ 113 debugfs_create_file(#name, mode, parent, il, \ 114 &il_dbgfs_##name##_ops); \ 115 } while (0) 116 117 #define DEBUGFS_ADD_BOOL(name, parent, ptr) do { \ 118 debugfs_create_bool(#name, 0600, parent, ptr); \ 119 } while (0) 120 121 /* file operation */ 122 #define DEBUGFS_READ_FUNC(name) \ 123 static ssize_t il_dbgfs_##name##_read(struct file *file, \ 124 char __user *user_buf, \ 125 size_t count, loff_t *ppos); 126 127 #define DEBUGFS_WRITE_FUNC(name) \ 128 static ssize_t il_dbgfs_##name##_write(struct file *file, \ 129 const char __user *user_buf, \ 130 size_t count, loff_t *ppos); 131 132 133 #define DEBUGFS_READ_FILE_OPS(name) \ 134 DEBUGFS_READ_FUNC(name); \ 135 static const struct file_operations il_dbgfs_##name##_ops = { \ 136 .read = il_dbgfs_##name##_read, \ 137 .open = simple_open, \ 138 .llseek = generic_file_llseek, \ 139 }; 140 141 #define DEBUGFS_WRITE_FILE_OPS(name) \ 142 DEBUGFS_WRITE_FUNC(name); \ 143 static const struct file_operations il_dbgfs_##name##_ops = { \ 144 .write = il_dbgfs_##name##_write, \ 145 .open = simple_open, \ 146 .llseek = generic_file_llseek, \ 147 }; 148 149 #define DEBUGFS_READ_WRITE_FILE_OPS(name) \ 150 DEBUGFS_READ_FUNC(name); \ 151 DEBUGFS_WRITE_FUNC(name); \ 152 static const struct file_operations il_dbgfs_##name##_ops = { \ 153 .write = il_dbgfs_##name##_write, \ 154 .read = il_dbgfs_##name##_read, \ 155 .open = simple_open, \ 156 .llseek = generic_file_llseek, \ 157 }; 158 159 static const char * 160 il_get_mgmt_string(int cmd) 161 { 162 switch (cmd) { 163 IL_CMD(MANAGEMENT_ASSOC_REQ); 164 IL_CMD(MANAGEMENT_ASSOC_RESP); 165 IL_CMD(MANAGEMENT_REASSOC_REQ); 166 IL_CMD(MANAGEMENT_REASSOC_RESP); 167 IL_CMD(MANAGEMENT_PROBE_REQ); 168 IL_CMD(MANAGEMENT_PROBE_RESP); 169 IL_CMD(MANAGEMENT_BEACON); 170 IL_CMD(MANAGEMENT_ATIM); 171 IL_CMD(MANAGEMENT_DISASSOC); 172 IL_CMD(MANAGEMENT_AUTH); 173 IL_CMD(MANAGEMENT_DEAUTH); 174 IL_CMD(MANAGEMENT_ACTION); 175 default: 176 return "UNKNOWN"; 177 178 } 179 } 180 181 static const char * 182 il_get_ctrl_string(int cmd) 183 { 184 switch (cmd) { 185 IL_CMD(CONTROL_BACK_REQ); 186 IL_CMD(CONTROL_BACK); 187 IL_CMD(CONTROL_PSPOLL); 188 IL_CMD(CONTROL_RTS); 189 IL_CMD(CONTROL_CTS); 190 IL_CMD(CONTROL_ACK); 191 IL_CMD(CONTROL_CFEND); 192 IL_CMD(CONTROL_CFENDACK); 193 default: 194 return "UNKNOWN"; 195 196 } 197 } 198 199 static ssize_t 200 il_dbgfs_tx_stats_read(struct file *file, char __user *user_buf, size_t count, 201 loff_t *ppos) 202 { 203 204 struct il_priv *il = file->private_data; 205 char *buf; 206 int pos = 0; 207 208 int cnt; 209 ssize_t ret; 210 const size_t bufsz = 211 100 + sizeof(char) * 50 * (MANAGEMENT_MAX + CONTROL_MAX); 212 buf = kzalloc(bufsz, GFP_KERNEL); 213 if (!buf) 214 return -ENOMEM; 215 pos += scnprintf(buf + pos, bufsz - pos, "Management:\n"); 216 for (cnt = 0; cnt < MANAGEMENT_MAX; cnt++) { 217 pos += 218 scnprintf(buf + pos, bufsz - pos, "\t%25s\t\t: %u\n", 219 il_get_mgmt_string(cnt), il->tx_stats.mgmt[cnt]); 220 } 221 pos += scnprintf(buf + pos, bufsz - pos, "Control\n"); 222 for (cnt = 0; cnt < CONTROL_MAX; cnt++) { 223 pos += 224 scnprintf(buf + pos, bufsz - pos, "\t%25s\t\t: %u\n", 225 il_get_ctrl_string(cnt), il->tx_stats.ctrl[cnt]); 226 } 227 pos += scnprintf(buf + pos, bufsz - pos, "Data:\n"); 228 pos += 229 scnprintf(buf + pos, bufsz - pos, "\tcnt: %u\n", 230 il->tx_stats.data_cnt); 231 pos += 232 scnprintf(buf + pos, bufsz - pos, "\tbytes: %llu\n", 233 il->tx_stats.data_bytes); 234 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); 235 kfree(buf); 236 return ret; 237 } 238 239 static ssize_t 240 il_dbgfs_clear_traffic_stats_write(struct file *file, 241 const char __user *user_buf, size_t count, 242 loff_t *ppos) 243 { 244 struct il_priv *il = file->private_data; 245 u32 clear_flag; 246 char buf[8]; 247 int buf_size; 248 249 memset(buf, 0, sizeof(buf)); 250 buf_size = min(count, sizeof(buf) - 1); 251 if (copy_from_user(buf, user_buf, buf_size)) 252 return -EFAULT; 253 if (sscanf(buf, "%x", &clear_flag) != 1) 254 return -EFAULT; 255 il_clear_traffic_stats(il); 256 257 return count; 258 } 259 260 static ssize_t 261 il_dbgfs_rx_stats_read(struct file *file, char __user *user_buf, size_t count, 262 loff_t *ppos) 263 { 264 265 struct il_priv *il = file->private_data; 266 char *buf; 267 int pos = 0; 268 int cnt; 269 ssize_t ret; 270 const size_t bufsz = 271 100 + sizeof(char) * 50 * (MANAGEMENT_MAX + CONTROL_MAX); 272 buf = kzalloc(bufsz, GFP_KERNEL); 273 if (!buf) 274 return -ENOMEM; 275 276 pos += scnprintf(buf + pos, bufsz - pos, "Management:\n"); 277 for (cnt = 0; cnt < MANAGEMENT_MAX; cnt++) { 278 pos += 279 scnprintf(buf + pos, bufsz - pos, "\t%25s\t\t: %u\n", 280 il_get_mgmt_string(cnt), il->rx_stats.mgmt[cnt]); 281 } 282 pos += scnprintf(buf + pos, bufsz - pos, "Control:\n"); 283 for (cnt = 0; cnt < CONTROL_MAX; cnt++) { 284 pos += 285 scnprintf(buf + pos, bufsz - pos, "\t%25s\t\t: %u\n", 286 il_get_ctrl_string(cnt), il->rx_stats.ctrl[cnt]); 287 } 288 pos += scnprintf(buf + pos, bufsz - pos, "Data:\n"); 289 pos += 290 scnprintf(buf + pos, bufsz - pos, "\tcnt: %u\n", 291 il->rx_stats.data_cnt); 292 pos += 293 scnprintf(buf + pos, bufsz - pos, "\tbytes: %llu\n", 294 il->rx_stats.data_bytes); 295 296 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); 297 kfree(buf); 298 return ret; 299 } 300 301 #define BYTE1_MASK 0x000000ff; 302 #define BYTE2_MASK 0x0000ffff; 303 #define BYTE3_MASK 0x00ffffff; 304 static ssize_t 305 il_dbgfs_sram_read(struct file *file, char __user *user_buf, size_t count, 306 loff_t *ppos) 307 { 308 u32 val; 309 char *buf; 310 ssize_t ret; 311 int i; 312 int pos = 0; 313 struct il_priv *il = file->private_data; 314 size_t bufsz; 315 316 /* default is to dump the entire data segment */ 317 if (!il->dbgfs_sram_offset && !il->dbgfs_sram_len) { 318 il->dbgfs_sram_offset = 0x800000; 319 if (il->ucode_type == UCODE_INIT) 320 il->dbgfs_sram_len = il->ucode_init_data.len; 321 else 322 il->dbgfs_sram_len = il->ucode_data.len; 323 } 324 bufsz = 30 + il->dbgfs_sram_len * sizeof(char) * 10; 325 buf = kmalloc(bufsz, GFP_KERNEL); 326 if (!buf) 327 return -ENOMEM; 328 pos += 329 scnprintf(buf + pos, bufsz - pos, "sram_len: 0x%x\n", 330 il->dbgfs_sram_len); 331 pos += 332 scnprintf(buf + pos, bufsz - pos, "sram_offset: 0x%x\n", 333 il->dbgfs_sram_offset); 334 for (i = il->dbgfs_sram_len; i > 0; i -= 4) { 335 val = 336 il_read_targ_mem(il, 337 il->dbgfs_sram_offset + 338 il->dbgfs_sram_len - i); 339 if (i < 4) { 340 switch (i) { 341 case 1: 342 val &= BYTE1_MASK; 343 break; 344 case 2: 345 val &= BYTE2_MASK; 346 break; 347 case 3: 348 val &= BYTE3_MASK; 349 break; 350 } 351 } 352 if (!(i % 16)) 353 pos += scnprintf(buf + pos, bufsz - pos, "\n"); 354 pos += scnprintf(buf + pos, bufsz - pos, "0x%08x ", val); 355 } 356 pos += scnprintf(buf + pos, bufsz - pos, "\n"); 357 358 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); 359 kfree(buf); 360 return ret; 361 } 362 363 static ssize_t 364 il_dbgfs_sram_write(struct file *file, const char __user *user_buf, 365 size_t count, loff_t *ppos) 366 { 367 struct il_priv *il = file->private_data; 368 char buf[64]; 369 int buf_size; 370 u32 offset, len; 371 372 memset(buf, 0, sizeof(buf)); 373 buf_size = min(count, sizeof(buf) - 1); 374 if (copy_from_user(buf, user_buf, buf_size)) 375 return -EFAULT; 376 377 if (sscanf(buf, "%x,%x", &offset, &len) == 2) { 378 il->dbgfs_sram_offset = offset; 379 il->dbgfs_sram_len = len; 380 } else { 381 il->dbgfs_sram_offset = 0; 382 il->dbgfs_sram_len = 0; 383 } 384 385 return count; 386 } 387 388 static ssize_t 389 il_dbgfs_stations_read(struct file *file, char __user *user_buf, size_t count, 390 loff_t *ppos) 391 { 392 struct il_priv *il = file->private_data; 393 struct il_station_entry *station; 394 int max_sta = il->hw_params.max_stations; 395 char *buf; 396 int i, j, pos = 0; 397 ssize_t ret; 398 /* Add 30 for initial string */ 399 const size_t bufsz = 30 + sizeof(char) * 500 * (il->num_stations); 400 401 buf = kmalloc(bufsz, GFP_KERNEL); 402 if (!buf) 403 return -ENOMEM; 404 405 pos += 406 scnprintf(buf + pos, bufsz - pos, "num of stations: %d\n\n", 407 il->num_stations); 408 409 for (i = 0; i < max_sta; i++) { 410 station = &il->stations[i]; 411 if (!station->used) 412 continue; 413 pos += 414 scnprintf(buf + pos, bufsz - pos, 415 "station %d - addr: %pM, flags: %#x\n", i, 416 station->sta.sta.addr, 417 station->sta.station_flags_msk); 418 pos += 419 scnprintf(buf + pos, bufsz - pos, 420 "TID\tseq_num\ttxq_id\tframes\ttfds\t"); 421 pos += 422 scnprintf(buf + pos, bufsz - pos, 423 "start_idx\tbitmap\t\t\trate_n_flags\n"); 424 425 for (j = 0; j < MAX_TID_COUNT; j++) { 426 pos += 427 scnprintf(buf + pos, bufsz - pos, 428 "%d:\t%#x\t%#x\t%u\t%u\t%u\t\t%#.16llx\t%#x", 429 j, station->tid[j].seq_number, 430 station->tid[j].agg.txq_id, 431 station->tid[j].agg.frame_count, 432 station->tid[j].tfds_in_queue, 433 station->tid[j].agg.start_idx, 434 station->tid[j].agg.bitmap, 435 station->tid[j].agg.rate_n_flags); 436 437 if (station->tid[j].agg.wait_for_ba) 438 pos += 439 scnprintf(buf + pos, bufsz - pos, 440 " - waitforba"); 441 pos += scnprintf(buf + pos, bufsz - pos, "\n"); 442 } 443 444 pos += scnprintf(buf + pos, bufsz - pos, "\n"); 445 } 446 447 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); 448 kfree(buf); 449 return ret; 450 } 451 452 static ssize_t 453 il_dbgfs_nvm_read(struct file *file, char __user *user_buf, size_t count, 454 loff_t *ppos) 455 { 456 ssize_t ret; 457 struct il_priv *il = file->private_data; 458 int pos = 0, ofs = 0, buf_size = 0; 459 const u8 *ptr; 460 char *buf; 461 u16 eeprom_ver; 462 size_t eeprom_len = il->cfg->eeprom_size; 463 buf_size = 4 * eeprom_len + 256; 464 465 if (eeprom_len % 16) { 466 IL_ERR("NVM size is not multiple of 16.\n"); 467 return -ENODATA; 468 } 469 470 ptr = il->eeprom; 471 if (!ptr) { 472 IL_ERR("Invalid EEPROM memory\n"); 473 return -ENOMEM; 474 } 475 476 /* 4 characters for byte 0xYY */ 477 buf = kzalloc(buf_size, GFP_KERNEL); 478 if (!buf) { 479 IL_ERR("Can not allocate Buffer\n"); 480 return -ENOMEM; 481 } 482 eeprom_ver = il_eeprom_query16(il, EEPROM_VERSION); 483 pos += 484 scnprintf(buf + pos, buf_size - pos, "EEPROM " "version: 0x%x\n", 485 eeprom_ver); 486 for (ofs = 0; ofs < eeprom_len; ofs += 16) { 487 pos += scnprintf(buf + pos, buf_size - pos, "0x%.4x %16ph\n", 488 ofs, ptr + ofs); 489 } 490 491 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); 492 kfree(buf); 493 return ret; 494 } 495 496 static ssize_t 497 il_dbgfs_channels_read(struct file *file, char __user *user_buf, size_t count, 498 loff_t *ppos) 499 { 500 struct il_priv *il = file->private_data; 501 struct ieee80211_channel *channels = NULL; 502 const struct ieee80211_supported_band *supp_band = NULL; 503 int pos = 0, i, bufsz = PAGE_SIZE; 504 char *buf; 505 ssize_t ret; 506 507 if (!test_bit(S_GEO_CONFIGURED, &il->status)) 508 return -EAGAIN; 509 510 buf = kzalloc(bufsz, GFP_KERNEL); 511 if (!buf) { 512 IL_ERR("Can not allocate Buffer\n"); 513 return -ENOMEM; 514 } 515 516 supp_band = il_get_hw_mode(il, NL80211_BAND_2GHZ); 517 if (supp_band) { 518 channels = supp_band->channels; 519 520 pos += 521 scnprintf(buf + pos, bufsz - pos, 522 "Displaying %d channels in 2.4GHz band 802.11bg):\n", 523 supp_band->n_channels); 524 525 for (i = 0; i < supp_band->n_channels; i++) 526 pos += 527 scnprintf(buf + pos, bufsz - pos, 528 "%d: %ddBm: BSS%s%s, %s.\n", 529 channels[i].hw_value, 530 channels[i].max_power, 531 channels[i]. 532 flags & IEEE80211_CHAN_RADAR ? 533 " (IEEE 802.11h required)" : "", 534 ((channels[i]. 535 flags & IEEE80211_CHAN_NO_IR) || 536 (channels[i]. 537 flags & IEEE80211_CHAN_RADAR)) ? "" : 538 ", IBSS", 539 channels[i]. 540 flags & IEEE80211_CHAN_NO_IR ? 541 "passive only" : "active/passive"); 542 } 543 supp_band = il_get_hw_mode(il, NL80211_BAND_5GHZ); 544 if (supp_band) { 545 channels = supp_band->channels; 546 547 pos += 548 scnprintf(buf + pos, bufsz - pos, 549 "Displaying %d channels in 5.2GHz band (802.11a)\n", 550 supp_band->n_channels); 551 552 for (i = 0; i < supp_band->n_channels; i++) 553 pos += 554 scnprintf(buf + pos, bufsz - pos, 555 "%d: %ddBm: BSS%s%s, %s.\n", 556 channels[i].hw_value, 557 channels[i].max_power, 558 channels[i]. 559 flags & IEEE80211_CHAN_RADAR ? 560 " (IEEE 802.11h required)" : "", 561 ((channels[i]. 562 flags & IEEE80211_CHAN_NO_IR) || 563 (channels[i]. 564 flags & IEEE80211_CHAN_RADAR)) ? "" : 565 ", IBSS", 566 channels[i]. 567 flags & IEEE80211_CHAN_NO_IR ? 568 "passive only" : "active/passive"); 569 } 570 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); 571 kfree(buf); 572 return ret; 573 } 574 575 static ssize_t 576 il_dbgfs_status_read(struct file *file, char __user *user_buf, size_t count, 577 loff_t *ppos) 578 { 579 580 struct il_priv *il = file->private_data; 581 char buf[512]; 582 int pos = 0; 583 const size_t bufsz = sizeof(buf); 584 585 pos += 586 scnprintf(buf + pos, bufsz - pos, "S_HCMD_ACTIVE:\t %d\n", 587 test_bit(S_HCMD_ACTIVE, &il->status)); 588 pos += 589 scnprintf(buf + pos, bufsz - pos, "S_INT_ENABLED:\t %d\n", 590 test_bit(S_INT_ENABLED, &il->status)); 591 pos += 592 scnprintf(buf + pos, bufsz - pos, "S_RFKILL:\t %d\n", 593 test_bit(S_RFKILL, &il->status)); 594 pos += 595 scnprintf(buf + pos, bufsz - pos, "S_CT_KILL:\t\t %d\n", 596 test_bit(S_CT_KILL, &il->status)); 597 pos += 598 scnprintf(buf + pos, bufsz - pos, "S_INIT:\t\t %d\n", 599 test_bit(S_INIT, &il->status)); 600 pos += 601 scnprintf(buf + pos, bufsz - pos, "S_ALIVE:\t\t %d\n", 602 test_bit(S_ALIVE, &il->status)); 603 pos += 604 scnprintf(buf + pos, bufsz - pos, "S_READY:\t\t %d\n", 605 test_bit(S_READY, &il->status)); 606 pos += 607 scnprintf(buf + pos, bufsz - pos, "S_TEMPERATURE:\t %d\n", 608 test_bit(S_TEMPERATURE, &il->status)); 609 pos += 610 scnprintf(buf + pos, bufsz - pos, "S_GEO_CONFIGURED:\t %d\n", 611 test_bit(S_GEO_CONFIGURED, &il->status)); 612 pos += 613 scnprintf(buf + pos, bufsz - pos, "S_EXIT_PENDING:\t %d\n", 614 test_bit(S_EXIT_PENDING, &il->status)); 615 pos += 616 scnprintf(buf + pos, bufsz - pos, "S_STATS:\t %d\n", 617 test_bit(S_STATS, &il->status)); 618 pos += 619 scnprintf(buf + pos, bufsz - pos, "S_SCANNING:\t %d\n", 620 test_bit(S_SCANNING, &il->status)); 621 pos += 622 scnprintf(buf + pos, bufsz - pos, "S_SCAN_ABORTING:\t %d\n", 623 test_bit(S_SCAN_ABORTING, &il->status)); 624 pos += 625 scnprintf(buf + pos, bufsz - pos, "S_SCAN_HW:\t\t %d\n", 626 test_bit(S_SCAN_HW, &il->status)); 627 pos += 628 scnprintf(buf + pos, bufsz - pos, "S_POWER_PMI:\t %d\n", 629 test_bit(S_POWER_PMI, &il->status)); 630 pos += 631 scnprintf(buf + pos, bufsz - pos, "S_FW_ERROR:\t %d\n", 632 test_bit(S_FW_ERROR, &il->status)); 633 return simple_read_from_buffer(user_buf, count, ppos, buf, pos); 634 } 635 636 static ssize_t 637 il_dbgfs_interrupt_read(struct file *file, char __user *user_buf, size_t count, 638 loff_t *ppos) 639 { 640 641 struct il_priv *il = file->private_data; 642 int pos = 0; 643 int cnt = 0; 644 char *buf; 645 int bufsz = 24 * 64; /* 24 items * 64 char per item */ 646 ssize_t ret; 647 648 buf = kzalloc(bufsz, GFP_KERNEL); 649 if (!buf) { 650 IL_ERR("Can not allocate Buffer\n"); 651 return -ENOMEM; 652 } 653 654 pos += 655 scnprintf(buf + pos, bufsz - pos, "Interrupt Statistics Report:\n"); 656 657 pos += 658 scnprintf(buf + pos, bufsz - pos, "HW Error:\t\t\t %u\n", 659 il->isr_stats.hw); 660 pos += 661 scnprintf(buf + pos, bufsz - pos, "SW Error:\t\t\t %u\n", 662 il->isr_stats.sw); 663 if (il->isr_stats.sw || il->isr_stats.hw) { 664 pos += 665 scnprintf(buf + pos, bufsz - pos, 666 "\tLast Restarting Code: 0x%X\n", 667 il->isr_stats.err_code); 668 } 669 #ifdef CONFIG_IWLEGACY_DEBUG 670 pos += 671 scnprintf(buf + pos, bufsz - pos, "Frame transmitted:\t\t %u\n", 672 il->isr_stats.sch); 673 pos += 674 scnprintf(buf + pos, bufsz - pos, "Alive interrupt:\t\t %u\n", 675 il->isr_stats.alive); 676 #endif 677 pos += 678 scnprintf(buf + pos, bufsz - pos, 679 "HW RF KILL switch toggled:\t %u\n", 680 il->isr_stats.rfkill); 681 682 pos += 683 scnprintf(buf + pos, bufsz - pos, "CT KILL:\t\t\t %u\n", 684 il->isr_stats.ctkill); 685 686 pos += 687 scnprintf(buf + pos, bufsz - pos, "Wakeup Interrupt:\t\t %u\n", 688 il->isr_stats.wakeup); 689 690 pos += 691 scnprintf(buf + pos, bufsz - pos, "Rx command responses:\t\t %u\n", 692 il->isr_stats.rx); 693 for (cnt = 0; cnt < IL_CN_MAX; cnt++) { 694 if (il->isr_stats.handlers[cnt] > 0) 695 pos += 696 scnprintf(buf + pos, bufsz - pos, 697 "\tRx handler[%36s]:\t\t %u\n", 698 il_get_cmd_string(cnt), 699 il->isr_stats.handlers[cnt]); 700 } 701 702 pos += 703 scnprintf(buf + pos, bufsz - pos, "Tx/FH interrupt:\t\t %u\n", 704 il->isr_stats.tx); 705 706 pos += 707 scnprintf(buf + pos, bufsz - pos, "Unexpected INTA:\t\t %u\n", 708 il->isr_stats.unhandled); 709 710 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); 711 kfree(buf); 712 return ret; 713 } 714 715 static ssize_t 716 il_dbgfs_interrupt_write(struct file *file, const char __user *user_buf, 717 size_t count, loff_t *ppos) 718 { 719 struct il_priv *il = file->private_data; 720 char buf[8]; 721 int buf_size; 722 u32 reset_flag; 723 724 memset(buf, 0, sizeof(buf)); 725 buf_size = min(count, sizeof(buf) - 1); 726 if (copy_from_user(buf, user_buf, buf_size)) 727 return -EFAULT; 728 if (sscanf(buf, "%x", &reset_flag) != 1) 729 return -EFAULT; 730 if (reset_flag == 0) 731 il_clear_isr_stats(il); 732 733 return count; 734 } 735 736 static ssize_t 737 il_dbgfs_qos_read(struct file *file, char __user *user_buf, size_t count, 738 loff_t *ppos) 739 { 740 struct il_priv *il = file->private_data; 741 int pos = 0, i; 742 char buf[256]; 743 const size_t bufsz = sizeof(buf); 744 745 for (i = 0; i < AC_NUM; i++) { 746 pos += 747 scnprintf(buf + pos, bufsz - pos, 748 "\tcw_min\tcw_max\taifsn\ttxop\n"); 749 pos += 750 scnprintf(buf + pos, bufsz - pos, 751 "AC[%d]\t%u\t%u\t%u\t%u\n", i, 752 il->qos_data.def_qos_parm.ac[i].cw_min, 753 il->qos_data.def_qos_parm.ac[i].cw_max, 754 il->qos_data.def_qos_parm.ac[i].aifsn, 755 il->qos_data.def_qos_parm.ac[i].edca_txop); 756 } 757 758 return simple_read_from_buffer(user_buf, count, ppos, buf, pos); 759 } 760 761 static ssize_t 762 il_dbgfs_disable_ht40_write(struct file *file, const char __user *user_buf, 763 size_t count, loff_t *ppos) 764 { 765 struct il_priv *il = file->private_data; 766 char buf[8]; 767 int buf_size; 768 int ht40; 769 770 memset(buf, 0, sizeof(buf)); 771 buf_size = min(count, sizeof(buf) - 1); 772 if (copy_from_user(buf, user_buf, buf_size)) 773 return -EFAULT; 774 if (sscanf(buf, "%d", &ht40) != 1) 775 return -EFAULT; 776 if (!il_is_any_associated(il)) 777 il->disable_ht40 = ht40 ? true : false; 778 else { 779 IL_ERR("Sta associated with AP - " 780 "Change to 40MHz channel support is not allowed\n"); 781 return -EINVAL; 782 } 783 784 return count; 785 } 786 787 static ssize_t 788 il_dbgfs_disable_ht40_read(struct file *file, char __user *user_buf, 789 size_t count, loff_t *ppos) 790 { 791 struct il_priv *il = file->private_data; 792 char buf[100]; 793 int pos = 0; 794 const size_t bufsz = sizeof(buf); 795 796 pos += 797 scnprintf(buf + pos, bufsz - pos, "11n 40MHz Mode: %s\n", 798 il->disable_ht40 ? "Disabled" : "Enabled"); 799 return simple_read_from_buffer(user_buf, count, ppos, buf, pos); 800 } 801 802 DEBUGFS_READ_WRITE_FILE_OPS(sram); 803 DEBUGFS_READ_FILE_OPS(nvm); 804 DEBUGFS_READ_FILE_OPS(stations); 805 DEBUGFS_READ_FILE_OPS(channels); 806 DEBUGFS_READ_FILE_OPS(status); 807 DEBUGFS_READ_WRITE_FILE_OPS(interrupt); 808 DEBUGFS_READ_FILE_OPS(qos); 809 DEBUGFS_READ_WRITE_FILE_OPS(disable_ht40); 810 811 static ssize_t 812 il_dbgfs_tx_queue_read(struct file *file, char __user *user_buf, size_t count, 813 loff_t *ppos) 814 { 815 816 struct il_priv *il = file->private_data; 817 struct il_tx_queue *txq; 818 struct il_queue *q; 819 char *buf; 820 int pos = 0; 821 int cnt; 822 int ret; 823 const size_t bufsz = 824 sizeof(char) * 64 * il->cfg->num_of_queues; 825 826 if (!il->txq) { 827 IL_ERR("txq not ready\n"); 828 return -EAGAIN; 829 } 830 buf = kzalloc(bufsz, GFP_KERNEL); 831 if (!buf) 832 return -ENOMEM; 833 834 for (cnt = 0; cnt < il->hw_params.max_txq_num; cnt++) { 835 txq = &il->txq[cnt]; 836 q = &txq->q; 837 pos += 838 scnprintf(buf + pos, bufsz - pos, 839 "hwq %.2d: read=%u write=%u stop=%d" 840 " swq_id=%#.2x (ac %d/hwq %d)\n", cnt, 841 q->read_ptr, q->write_ptr, 842 !!test_bit(cnt, il->queue_stopped), 843 txq->swq_id, txq->swq_id & 3, 844 (txq->swq_id >> 2) & 0x1f); 845 if (cnt >= 4) 846 continue; 847 /* for the ACs, display the stop count too */ 848 pos += 849 scnprintf(buf + pos, bufsz - pos, 850 " stop-count: %d\n", 851 atomic_read(&il->queue_stop_count[cnt])); 852 } 853 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); 854 kfree(buf); 855 return ret; 856 } 857 858 static ssize_t 859 il_dbgfs_rx_queue_read(struct file *file, char __user *user_buf, size_t count, 860 loff_t *ppos) 861 { 862 863 struct il_priv *il = file->private_data; 864 struct il_rx_queue *rxq = &il->rxq; 865 char buf[256]; 866 int pos = 0; 867 const size_t bufsz = sizeof(buf); 868 869 pos += scnprintf(buf + pos, bufsz - pos, "read: %u\n", rxq->read); 870 pos += scnprintf(buf + pos, bufsz - pos, "write: %u\n", rxq->write); 871 pos += 872 scnprintf(buf + pos, bufsz - pos, "free_count: %u\n", 873 rxq->free_count); 874 if (rxq->rb_stts) { 875 pos += 876 scnprintf(buf + pos, bufsz - pos, "closed_rb_num: %u\n", 877 le16_to_cpu(rxq->rb_stts-> 878 closed_rb_num) & 0x0FFF); 879 } else { 880 pos += 881 scnprintf(buf + pos, bufsz - pos, 882 "closed_rb_num: Not Allocated\n"); 883 } 884 return simple_read_from_buffer(user_buf, count, ppos, buf, pos); 885 } 886 887 static ssize_t 888 il_dbgfs_ucode_rx_stats_read(struct file *file, char __user *user_buf, 889 size_t count, loff_t *ppos) 890 { 891 struct il_priv *il = file->private_data; 892 893 return il->debugfs_ops->rx_stats_read(file, user_buf, count, ppos); 894 } 895 896 static ssize_t 897 il_dbgfs_ucode_tx_stats_read(struct file *file, char __user *user_buf, 898 size_t count, loff_t *ppos) 899 { 900 struct il_priv *il = file->private_data; 901 902 return il->debugfs_ops->tx_stats_read(file, user_buf, count, ppos); 903 } 904 905 static ssize_t 906 il_dbgfs_ucode_general_stats_read(struct file *file, char __user *user_buf, 907 size_t count, loff_t *ppos) 908 { 909 struct il_priv *il = file->private_data; 910 911 return il->debugfs_ops->general_stats_read(file, user_buf, count, ppos); 912 } 913 914 static ssize_t 915 il_dbgfs_sensitivity_read(struct file *file, char __user *user_buf, 916 size_t count, loff_t *ppos) 917 { 918 919 struct il_priv *il = file->private_data; 920 int pos = 0; 921 int cnt = 0; 922 char *buf; 923 int bufsz = sizeof(struct il_sensitivity_data) * 4 + 100; 924 ssize_t ret; 925 struct il_sensitivity_data *data; 926 927 data = &il->sensitivity_data; 928 buf = kzalloc(bufsz, GFP_KERNEL); 929 if (!buf) { 930 IL_ERR("Can not allocate Buffer\n"); 931 return -ENOMEM; 932 } 933 934 pos += 935 scnprintf(buf + pos, bufsz - pos, "auto_corr_ofdm:\t\t\t %u\n", 936 data->auto_corr_ofdm); 937 pos += 938 scnprintf(buf + pos, bufsz - pos, "auto_corr_ofdm_mrc:\t\t %u\n", 939 data->auto_corr_ofdm_mrc); 940 pos += 941 scnprintf(buf + pos, bufsz - pos, "auto_corr_ofdm_x1:\t\t %u\n", 942 data->auto_corr_ofdm_x1); 943 pos += 944 scnprintf(buf + pos, bufsz - pos, "auto_corr_ofdm_mrc_x1:\t\t %u\n", 945 data->auto_corr_ofdm_mrc_x1); 946 pos += 947 scnprintf(buf + pos, bufsz - pos, "auto_corr_cck:\t\t\t %u\n", 948 data->auto_corr_cck); 949 pos += 950 scnprintf(buf + pos, bufsz - pos, "auto_corr_cck_mrc:\t\t %u\n", 951 data->auto_corr_cck_mrc); 952 pos += 953 scnprintf(buf + pos, bufsz - pos, 954 "last_bad_plcp_cnt_ofdm:\t\t %u\n", 955 data->last_bad_plcp_cnt_ofdm); 956 pos += 957 scnprintf(buf + pos, bufsz - pos, "last_fa_cnt_ofdm:\t\t %u\n", 958 data->last_fa_cnt_ofdm); 959 pos += 960 scnprintf(buf + pos, bufsz - pos, "last_bad_plcp_cnt_cck:\t\t %u\n", 961 data->last_bad_plcp_cnt_cck); 962 pos += 963 scnprintf(buf + pos, bufsz - pos, "last_fa_cnt_cck:\t\t %u\n", 964 data->last_fa_cnt_cck); 965 pos += 966 scnprintf(buf + pos, bufsz - pos, "nrg_curr_state:\t\t\t %u\n", 967 data->nrg_curr_state); 968 pos += 969 scnprintf(buf + pos, bufsz - pos, "nrg_prev_state:\t\t\t %u\n", 970 data->nrg_prev_state); 971 pos += scnprintf(buf + pos, bufsz - pos, "nrg_value:\t\t\t"); 972 for (cnt = 0; cnt < 10; cnt++) { 973 pos += 974 scnprintf(buf + pos, bufsz - pos, " %u", 975 data->nrg_value[cnt]); 976 } 977 pos += scnprintf(buf + pos, bufsz - pos, "\n"); 978 pos += scnprintf(buf + pos, bufsz - pos, "nrg_silence_rssi:\t\t"); 979 for (cnt = 0; cnt < NRG_NUM_PREV_STAT_L; cnt++) { 980 pos += 981 scnprintf(buf + pos, bufsz - pos, " %u", 982 data->nrg_silence_rssi[cnt]); 983 } 984 pos += scnprintf(buf + pos, bufsz - pos, "\n"); 985 pos += 986 scnprintf(buf + pos, bufsz - pos, "nrg_silence_ref:\t\t %u\n", 987 data->nrg_silence_ref); 988 pos += 989 scnprintf(buf + pos, bufsz - pos, "nrg_energy_idx:\t\t\t %u\n", 990 data->nrg_energy_idx); 991 pos += 992 scnprintf(buf + pos, bufsz - pos, "nrg_silence_idx:\t\t %u\n", 993 data->nrg_silence_idx); 994 pos += 995 scnprintf(buf + pos, bufsz - pos, "nrg_th_cck:\t\t\t %u\n", 996 data->nrg_th_cck); 997 pos += 998 scnprintf(buf + pos, bufsz - pos, 999 "nrg_auto_corr_silence_diff:\t %u\n", 1000 data->nrg_auto_corr_silence_diff); 1001 pos += 1002 scnprintf(buf + pos, bufsz - pos, "num_in_cck_no_fa:\t\t %u\n", 1003 data->num_in_cck_no_fa); 1004 pos += 1005 scnprintf(buf + pos, bufsz - pos, "nrg_th_ofdm:\t\t\t %u\n", 1006 data->nrg_th_ofdm); 1007 1008 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); 1009 kfree(buf); 1010 return ret; 1011 } 1012 1013 static ssize_t 1014 il_dbgfs_chain_noise_read(struct file *file, char __user *user_buf, 1015 size_t count, loff_t *ppos) 1016 { 1017 1018 struct il_priv *il = file->private_data; 1019 int pos = 0; 1020 int cnt = 0; 1021 char *buf; 1022 int bufsz = sizeof(struct il_chain_noise_data) * 4 + 100; 1023 ssize_t ret; 1024 struct il_chain_noise_data *data; 1025 1026 data = &il->chain_noise_data; 1027 buf = kzalloc(bufsz, GFP_KERNEL); 1028 if (!buf) { 1029 IL_ERR("Can not allocate Buffer\n"); 1030 return -ENOMEM; 1031 } 1032 1033 pos += 1034 scnprintf(buf + pos, bufsz - pos, "active_chains:\t\t\t %u\n", 1035 data->active_chains); 1036 pos += 1037 scnprintf(buf + pos, bufsz - pos, "chain_noise_a:\t\t\t %u\n", 1038 data->chain_noise_a); 1039 pos += 1040 scnprintf(buf + pos, bufsz - pos, "chain_noise_b:\t\t\t %u\n", 1041 data->chain_noise_b); 1042 pos += 1043 scnprintf(buf + pos, bufsz - pos, "chain_noise_c:\t\t\t %u\n", 1044 data->chain_noise_c); 1045 pos += 1046 scnprintf(buf + pos, bufsz - pos, "chain_signal_a:\t\t\t %u\n", 1047 data->chain_signal_a); 1048 pos += 1049 scnprintf(buf + pos, bufsz - pos, "chain_signal_b:\t\t\t %u\n", 1050 data->chain_signal_b); 1051 pos += 1052 scnprintf(buf + pos, bufsz - pos, "chain_signal_c:\t\t\t %u\n", 1053 data->chain_signal_c); 1054 pos += 1055 scnprintf(buf + pos, bufsz - pos, "beacon_count:\t\t\t %u\n", 1056 data->beacon_count); 1057 1058 pos += scnprintf(buf + pos, bufsz - pos, "disconn_array:\t\t\t"); 1059 for (cnt = 0; cnt < NUM_RX_CHAINS; cnt++) { 1060 pos += 1061 scnprintf(buf + pos, bufsz - pos, " %u", 1062 data->disconn_array[cnt]); 1063 } 1064 pos += scnprintf(buf + pos, bufsz - pos, "\n"); 1065 pos += scnprintf(buf + pos, bufsz - pos, "delta_gain_code:\t\t"); 1066 for (cnt = 0; cnt < NUM_RX_CHAINS; cnt++) { 1067 pos += 1068 scnprintf(buf + pos, bufsz - pos, " %u", 1069 data->delta_gain_code[cnt]); 1070 } 1071 pos += scnprintf(buf + pos, bufsz - pos, "\n"); 1072 pos += 1073 scnprintf(buf + pos, bufsz - pos, "radio_write:\t\t\t %u\n", 1074 data->radio_write); 1075 pos += 1076 scnprintf(buf + pos, bufsz - pos, "state:\t\t\t\t %u\n", 1077 data->state); 1078 1079 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); 1080 kfree(buf); 1081 return ret; 1082 } 1083 1084 static ssize_t 1085 il_dbgfs_power_save_status_read(struct file *file, char __user *user_buf, 1086 size_t count, loff_t *ppos) 1087 { 1088 struct il_priv *il = file->private_data; 1089 char buf[60]; 1090 int pos = 0; 1091 const size_t bufsz = sizeof(buf); 1092 u32 pwrsave_status; 1093 1094 pwrsave_status = 1095 _il_rd(il, CSR_GP_CNTRL) & CSR_GP_REG_POWER_SAVE_STATUS_MSK; 1096 1097 pos += scnprintf(buf + pos, bufsz - pos, "Power Save Status: "); 1098 pos += 1099 scnprintf(buf + pos, bufsz - pos, "%s\n", 1100 (pwrsave_status == CSR_GP_REG_NO_POWER_SAVE) ? "none" : 1101 (pwrsave_status == CSR_GP_REG_MAC_POWER_SAVE) ? "MAC" : 1102 (pwrsave_status == CSR_GP_REG_PHY_POWER_SAVE) ? "PHY" : 1103 "error"); 1104 1105 return simple_read_from_buffer(user_buf, count, ppos, buf, pos); 1106 } 1107 1108 static ssize_t 1109 il_dbgfs_clear_ucode_stats_write(struct file *file, 1110 const char __user *user_buf, size_t count, 1111 loff_t *ppos) 1112 { 1113 struct il_priv *il = file->private_data; 1114 char buf[8]; 1115 int buf_size; 1116 int clear; 1117 1118 memset(buf, 0, sizeof(buf)); 1119 buf_size = min(count, sizeof(buf) - 1); 1120 if (copy_from_user(buf, user_buf, buf_size)) 1121 return -EFAULT; 1122 if (sscanf(buf, "%d", &clear) != 1) 1123 return -EFAULT; 1124 1125 /* make request to uCode to retrieve stats information */ 1126 mutex_lock(&il->mutex); 1127 il_send_stats_request(il, CMD_SYNC, true); 1128 mutex_unlock(&il->mutex); 1129 1130 return count; 1131 } 1132 1133 static ssize_t 1134 il_dbgfs_rxon_flags_read(struct file *file, char __user *user_buf, 1135 size_t count, loff_t *ppos) 1136 { 1137 1138 struct il_priv *il = file->private_data; 1139 int len = 0; 1140 char buf[20]; 1141 1142 len = sprintf(buf, "0x%04X\n", le32_to_cpu(il->active.flags)); 1143 return simple_read_from_buffer(user_buf, count, ppos, buf, len); 1144 } 1145 1146 static ssize_t 1147 il_dbgfs_rxon_filter_flags_read(struct file *file, char __user *user_buf, 1148 size_t count, loff_t *ppos) 1149 { 1150 1151 struct il_priv *il = file->private_data; 1152 int len = 0; 1153 char buf[20]; 1154 1155 len = 1156 sprintf(buf, "0x%04X\n", le32_to_cpu(il->active.filter_flags)); 1157 return simple_read_from_buffer(user_buf, count, ppos, buf, len); 1158 } 1159 1160 static ssize_t 1161 il_dbgfs_fh_reg_read(struct file *file, char __user *user_buf, size_t count, 1162 loff_t *ppos) 1163 { 1164 struct il_priv *il = file->private_data; 1165 char *buf; 1166 int pos = 0; 1167 ssize_t ret = -EFAULT; 1168 1169 if (il->ops->dump_fh) { 1170 ret = pos = il->ops->dump_fh(il, &buf, true); 1171 if (buf) { 1172 ret = 1173 simple_read_from_buffer(user_buf, count, ppos, buf, 1174 pos); 1175 kfree(buf); 1176 } 1177 } 1178 1179 return ret; 1180 } 1181 1182 static ssize_t 1183 il_dbgfs_missed_beacon_read(struct file *file, char __user *user_buf, 1184 size_t count, loff_t *ppos) 1185 { 1186 1187 struct il_priv *il = file->private_data; 1188 int pos = 0; 1189 char buf[12]; 1190 const size_t bufsz = sizeof(buf); 1191 1192 pos += 1193 scnprintf(buf + pos, bufsz - pos, "%d\n", 1194 il->missed_beacon_threshold); 1195 1196 return simple_read_from_buffer(user_buf, count, ppos, buf, pos); 1197 } 1198 1199 static ssize_t 1200 il_dbgfs_missed_beacon_write(struct file *file, const char __user *user_buf, 1201 size_t count, loff_t *ppos) 1202 { 1203 struct il_priv *il = file->private_data; 1204 char buf[8]; 1205 int buf_size; 1206 int missed; 1207 1208 memset(buf, 0, sizeof(buf)); 1209 buf_size = min(count, sizeof(buf) - 1); 1210 if (copy_from_user(buf, user_buf, buf_size)) 1211 return -EFAULT; 1212 if (sscanf(buf, "%d", &missed) != 1) 1213 return -EINVAL; 1214 1215 if (missed < IL_MISSED_BEACON_THRESHOLD_MIN || 1216 missed > IL_MISSED_BEACON_THRESHOLD_MAX) 1217 il->missed_beacon_threshold = IL_MISSED_BEACON_THRESHOLD_DEF; 1218 else 1219 il->missed_beacon_threshold = missed; 1220 1221 return count; 1222 } 1223 1224 static ssize_t 1225 il_dbgfs_force_reset_read(struct file *file, char __user *user_buf, 1226 size_t count, loff_t *ppos) 1227 { 1228 1229 struct il_priv *il = file->private_data; 1230 int pos = 0; 1231 char buf[300]; 1232 const size_t bufsz = sizeof(buf); 1233 struct il_force_reset *force_reset; 1234 1235 force_reset = &il->force_reset; 1236 1237 pos += 1238 scnprintf(buf + pos, bufsz - pos, "\tnumber of reset request: %d\n", 1239 force_reset->reset_request_count); 1240 pos += 1241 scnprintf(buf + pos, bufsz - pos, 1242 "\tnumber of reset request success: %d\n", 1243 force_reset->reset_success_count); 1244 pos += 1245 scnprintf(buf + pos, bufsz - pos, 1246 "\tnumber of reset request reject: %d\n", 1247 force_reset->reset_reject_count); 1248 pos += 1249 scnprintf(buf + pos, bufsz - pos, "\treset duration: %lu\n", 1250 force_reset->reset_duration); 1251 1252 return simple_read_from_buffer(user_buf, count, ppos, buf, pos); 1253 } 1254 1255 static ssize_t 1256 il_dbgfs_force_reset_write(struct file *file, const char __user *user_buf, 1257 size_t count, loff_t *ppos) 1258 { 1259 1260 int ret; 1261 struct il_priv *il = file->private_data; 1262 1263 ret = il_force_reset(il, true); 1264 1265 return ret ? ret : count; 1266 } 1267 1268 static ssize_t 1269 il_dbgfs_wd_timeout_write(struct file *file, const char __user *user_buf, 1270 size_t count, loff_t *ppos) 1271 { 1272 1273 struct il_priv *il = file->private_data; 1274 char buf[8]; 1275 int buf_size; 1276 int timeout; 1277 1278 memset(buf, 0, sizeof(buf)); 1279 buf_size = min(count, sizeof(buf) - 1); 1280 if (copy_from_user(buf, user_buf, buf_size)) 1281 return -EFAULT; 1282 if (sscanf(buf, "%d", &timeout) != 1) 1283 return -EINVAL; 1284 if (timeout < 0 || timeout > IL_MAX_WD_TIMEOUT) 1285 timeout = IL_DEF_WD_TIMEOUT; 1286 1287 il->cfg->wd_timeout = timeout; 1288 il_setup_watchdog(il); 1289 return count; 1290 } 1291 1292 DEBUGFS_READ_FILE_OPS(rx_stats); 1293 DEBUGFS_READ_FILE_OPS(tx_stats); 1294 DEBUGFS_READ_FILE_OPS(rx_queue); 1295 DEBUGFS_READ_FILE_OPS(tx_queue); 1296 DEBUGFS_READ_FILE_OPS(ucode_rx_stats); 1297 DEBUGFS_READ_FILE_OPS(ucode_tx_stats); 1298 DEBUGFS_READ_FILE_OPS(ucode_general_stats); 1299 DEBUGFS_READ_FILE_OPS(sensitivity); 1300 DEBUGFS_READ_FILE_OPS(chain_noise); 1301 DEBUGFS_READ_FILE_OPS(power_save_status); 1302 DEBUGFS_WRITE_FILE_OPS(clear_ucode_stats); 1303 DEBUGFS_WRITE_FILE_OPS(clear_traffic_stats); 1304 DEBUGFS_READ_FILE_OPS(fh_reg); 1305 DEBUGFS_READ_WRITE_FILE_OPS(missed_beacon); 1306 DEBUGFS_READ_WRITE_FILE_OPS(force_reset); 1307 DEBUGFS_READ_FILE_OPS(rxon_flags); 1308 DEBUGFS_READ_FILE_OPS(rxon_filter_flags); 1309 DEBUGFS_WRITE_FILE_OPS(wd_timeout); 1310 1311 /* 1312 * Create the debugfs files and directories 1313 * 1314 */ 1315 void 1316 il_dbgfs_register(struct il_priv *il, const char *name) 1317 { 1318 struct dentry *phyd = il->hw->wiphy->debugfsdir; 1319 struct dentry *dir_drv, *dir_data, *dir_rf, *dir_debug; 1320 1321 dir_drv = debugfs_create_dir(name, phyd); 1322 il->debugfs_dir = dir_drv; 1323 1324 dir_data = debugfs_create_dir("data", dir_drv); 1325 dir_rf = debugfs_create_dir("rf", dir_drv); 1326 dir_debug = debugfs_create_dir("debug", dir_drv); 1327 1328 DEBUGFS_ADD_FILE(nvm, dir_data, 0400); 1329 DEBUGFS_ADD_FILE(sram, dir_data, 0600); 1330 DEBUGFS_ADD_FILE(stations, dir_data, 0400); 1331 DEBUGFS_ADD_FILE(channels, dir_data, 0400); 1332 DEBUGFS_ADD_FILE(status, dir_data, 0400); 1333 DEBUGFS_ADD_FILE(interrupt, dir_data, 0600); 1334 DEBUGFS_ADD_FILE(qos, dir_data, 0400); 1335 DEBUGFS_ADD_FILE(disable_ht40, dir_data, 0600); 1336 DEBUGFS_ADD_FILE(rx_stats, dir_debug, 0400); 1337 DEBUGFS_ADD_FILE(tx_stats, dir_debug, 0400); 1338 DEBUGFS_ADD_FILE(rx_queue, dir_debug, 0400); 1339 DEBUGFS_ADD_FILE(tx_queue, dir_debug, 0400); 1340 DEBUGFS_ADD_FILE(power_save_status, dir_debug, 0400); 1341 DEBUGFS_ADD_FILE(clear_ucode_stats, dir_debug, 0200); 1342 DEBUGFS_ADD_FILE(clear_traffic_stats, dir_debug, 0200); 1343 DEBUGFS_ADD_FILE(fh_reg, dir_debug, 0400); 1344 DEBUGFS_ADD_FILE(missed_beacon, dir_debug, 0200); 1345 DEBUGFS_ADD_FILE(force_reset, dir_debug, 0600); 1346 DEBUGFS_ADD_FILE(ucode_rx_stats, dir_debug, 0400); 1347 DEBUGFS_ADD_FILE(ucode_tx_stats, dir_debug, 0400); 1348 DEBUGFS_ADD_FILE(ucode_general_stats, dir_debug, 0400); 1349 1350 if (il->cfg->sensitivity_calib_by_driver) 1351 DEBUGFS_ADD_FILE(sensitivity, dir_debug, 0400); 1352 if (il->cfg->chain_noise_calib_by_driver) 1353 DEBUGFS_ADD_FILE(chain_noise, dir_debug, 0400); 1354 DEBUGFS_ADD_FILE(rxon_flags, dir_debug, 0200); 1355 DEBUGFS_ADD_FILE(rxon_filter_flags, dir_debug, 0200); 1356 DEBUGFS_ADD_FILE(wd_timeout, dir_debug, 0200); 1357 if (il->cfg->sensitivity_calib_by_driver) 1358 DEBUGFS_ADD_BOOL(disable_sensitivity, dir_rf, 1359 &il->disable_sens_cal); 1360 if (il->cfg->chain_noise_calib_by_driver) 1361 DEBUGFS_ADD_BOOL(disable_chain_noise, dir_rf, 1362 &il->disable_chain_noise_cal); 1363 DEBUGFS_ADD_BOOL(disable_tx_power, dir_rf, &il->disable_tx_power_cal); 1364 } 1365 EXPORT_SYMBOL(il_dbgfs_register); 1366 1367 /* 1368 * Remove the debugfs files and directories 1369 */ 1370 void 1371 il_dbgfs_unregister(struct il_priv *il) 1372 { 1373 if (!il->debugfs_dir) 1374 return; 1375 1376 debugfs_remove_recursive(il->debugfs_dir); 1377 il->debugfs_dir = NULL; 1378 } 1379 EXPORT_SYMBOL(il_dbgfs_unregister); 1380