debugfs.c revision fa5e13756ad5112842bd5e765d66b6c6074b74b7
1/* 2 * This file is part of wl1271 3 * 4 * Copyright (C) 2009 Nokia Corporation 5 * 6 * Contact: Luciano Coelho <luciano.coelho@nokia.com> 7 * 8 * This program is free software; you can redistribute it and/or 9 * modify it under the terms of the GNU General Public License 10 * version 2 as published by the Free Software Foundation. 11 * 12 * This program is distributed in the hope that it will be useful, but 13 * WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 * General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 20 * 02110-1301 USA 21 * 22 */ 23 24#include "debugfs.h" 25 26#include <linux/skbuff.h> 27#include <linux/slab.h> 28 29#include "wl12xx.h" 30#include "debug.h" 31#include "acx.h" 32#include "ps.h" 33#include "io.h" 34#include "tx.h" 35 36/* ms */ 37#define WL1271_DEBUGFS_STATS_LIFETIME 1000 38 39/* debugfs macros idea from mac80211 */ 40#define DEBUGFS_FORMAT_BUFFER_SIZE 100 41static int wl1271_format_buffer(char __user *userbuf, size_t count, 42 loff_t *ppos, char *fmt, ...) 43{ 44 va_list args; 45 char buf[DEBUGFS_FORMAT_BUFFER_SIZE]; 46 int res; 47 48 va_start(args, fmt); 49 res = vscnprintf(buf, sizeof(buf), fmt, args); 50 va_end(args); 51 52 return simple_read_from_buffer(userbuf, count, ppos, buf, res); 53} 54 55#define DEBUGFS_READONLY_FILE(name, fmt, value...) \ 56static ssize_t name## _read(struct file *file, char __user *userbuf, \ 57 size_t count, loff_t *ppos) \ 58{ \ 59 struct wl1271 *wl = file->private_data; \ 60 return wl1271_format_buffer(userbuf, count, ppos, \ 61 fmt "\n", ##value); \ 62} \ 63 \ 64static const struct file_operations name## _ops = { \ 65 .read = name## _read, \ 66 .open = wl1271_open_file_generic, \ 67 .llseek = generic_file_llseek, \ 68}; 69 70#define DEBUGFS_ADD(name, parent) \ 71 entry = debugfs_create_file(#name, 0400, parent, \ 72 wl, &name## _ops); \ 73 if (!entry || IS_ERR(entry)) \ 74 goto err; \ 75 76#define DEBUGFS_ADD_PREFIX(prefix, name, parent) \ 77 do { \ 78 entry = debugfs_create_file(#name, 0400, parent, \ 79 wl, &prefix## _## name## _ops); \ 80 if (!entry || IS_ERR(entry)) \ 81 goto err; \ 82 } while (0); 83 84#define DEBUGFS_FWSTATS_FILE(sub, name, fmt) \ 85static ssize_t sub## _ ##name## _read(struct file *file, \ 86 char __user *userbuf, \ 87 size_t count, loff_t *ppos) \ 88{ \ 89 struct wl1271 *wl = file->private_data; \ 90 \ 91 wl1271_debugfs_update_stats(wl); \ 92 \ 93 return wl1271_format_buffer(userbuf, count, ppos, fmt "\n", \ 94 wl->stats.fw_stats->sub.name); \ 95} \ 96 \ 97static const struct file_operations sub## _ ##name## _ops = { \ 98 .read = sub## _ ##name## _read, \ 99 .open = wl1271_open_file_generic, \ 100 .llseek = generic_file_llseek, \ 101}; 102 103#define DEBUGFS_FWSTATS_ADD(sub, name) \ 104 DEBUGFS_ADD(sub## _ ##name, stats) 105 106static void wl1271_debugfs_update_stats(struct wl1271 *wl) 107{ 108 int ret; 109 110 mutex_lock(&wl->mutex); 111 112 ret = wl1271_ps_elp_wakeup(wl); 113 if (ret < 0) 114 goto out; 115 116 if (wl->state == WL1271_STATE_ON && 117 time_after(jiffies, wl->stats.fw_stats_update + 118 msecs_to_jiffies(WL1271_DEBUGFS_STATS_LIFETIME))) { 119 wl1271_acx_statistics(wl, wl->stats.fw_stats); 120 wl->stats.fw_stats_update = jiffies; 121 } 122 123 wl1271_ps_elp_sleep(wl); 124 125out: 126 mutex_unlock(&wl->mutex); 127} 128 129static int wl1271_open_file_generic(struct inode *inode, struct file *file) 130{ 131 file->private_data = inode->i_private; 132 return 0; 133} 134 135DEBUGFS_FWSTATS_FILE(tx, internal_desc_overflow, "%u"); 136 137DEBUGFS_FWSTATS_FILE(rx, out_of_mem, "%u"); 138DEBUGFS_FWSTATS_FILE(rx, hdr_overflow, "%u"); 139DEBUGFS_FWSTATS_FILE(rx, hw_stuck, "%u"); 140DEBUGFS_FWSTATS_FILE(rx, dropped, "%u"); 141DEBUGFS_FWSTATS_FILE(rx, fcs_err, "%u"); 142DEBUGFS_FWSTATS_FILE(rx, xfr_hint_trig, "%u"); 143DEBUGFS_FWSTATS_FILE(rx, path_reset, "%u"); 144DEBUGFS_FWSTATS_FILE(rx, reset_counter, "%u"); 145 146DEBUGFS_FWSTATS_FILE(dma, rx_requested, "%u"); 147DEBUGFS_FWSTATS_FILE(dma, rx_errors, "%u"); 148DEBUGFS_FWSTATS_FILE(dma, tx_requested, "%u"); 149DEBUGFS_FWSTATS_FILE(dma, tx_errors, "%u"); 150 151DEBUGFS_FWSTATS_FILE(isr, cmd_cmplt, "%u"); 152DEBUGFS_FWSTATS_FILE(isr, fiqs, "%u"); 153DEBUGFS_FWSTATS_FILE(isr, rx_headers, "%u"); 154DEBUGFS_FWSTATS_FILE(isr, rx_mem_overflow, "%u"); 155DEBUGFS_FWSTATS_FILE(isr, rx_rdys, "%u"); 156DEBUGFS_FWSTATS_FILE(isr, irqs, "%u"); 157DEBUGFS_FWSTATS_FILE(isr, tx_procs, "%u"); 158DEBUGFS_FWSTATS_FILE(isr, decrypt_done, "%u"); 159DEBUGFS_FWSTATS_FILE(isr, dma0_done, "%u"); 160DEBUGFS_FWSTATS_FILE(isr, dma1_done, "%u"); 161DEBUGFS_FWSTATS_FILE(isr, tx_exch_complete, "%u"); 162DEBUGFS_FWSTATS_FILE(isr, commands, "%u"); 163DEBUGFS_FWSTATS_FILE(isr, rx_procs, "%u"); 164DEBUGFS_FWSTATS_FILE(isr, hw_pm_mode_changes, "%u"); 165DEBUGFS_FWSTATS_FILE(isr, host_acknowledges, "%u"); 166DEBUGFS_FWSTATS_FILE(isr, pci_pm, "%u"); 167DEBUGFS_FWSTATS_FILE(isr, wakeups, "%u"); 168DEBUGFS_FWSTATS_FILE(isr, low_rssi, "%u"); 169 170DEBUGFS_FWSTATS_FILE(wep, addr_key_count, "%u"); 171DEBUGFS_FWSTATS_FILE(wep, default_key_count, "%u"); 172/* skipping wep.reserved */ 173DEBUGFS_FWSTATS_FILE(wep, key_not_found, "%u"); 174DEBUGFS_FWSTATS_FILE(wep, decrypt_fail, "%u"); 175DEBUGFS_FWSTATS_FILE(wep, packets, "%u"); 176DEBUGFS_FWSTATS_FILE(wep, interrupt, "%u"); 177 178DEBUGFS_FWSTATS_FILE(pwr, ps_enter, "%u"); 179DEBUGFS_FWSTATS_FILE(pwr, elp_enter, "%u"); 180DEBUGFS_FWSTATS_FILE(pwr, missing_bcns, "%u"); 181DEBUGFS_FWSTATS_FILE(pwr, wake_on_host, "%u"); 182DEBUGFS_FWSTATS_FILE(pwr, wake_on_timer_exp, "%u"); 183DEBUGFS_FWSTATS_FILE(pwr, tx_with_ps, "%u"); 184DEBUGFS_FWSTATS_FILE(pwr, tx_without_ps, "%u"); 185DEBUGFS_FWSTATS_FILE(pwr, rcvd_beacons, "%u"); 186DEBUGFS_FWSTATS_FILE(pwr, power_save_off, "%u"); 187DEBUGFS_FWSTATS_FILE(pwr, enable_ps, "%u"); 188DEBUGFS_FWSTATS_FILE(pwr, disable_ps, "%u"); 189DEBUGFS_FWSTATS_FILE(pwr, fix_tsf_ps, "%u"); 190/* skipping cont_miss_bcns_spread for now */ 191DEBUGFS_FWSTATS_FILE(pwr, rcvd_awake_beacons, "%u"); 192 193DEBUGFS_FWSTATS_FILE(mic, rx_pkts, "%u"); 194DEBUGFS_FWSTATS_FILE(mic, calc_failure, "%u"); 195 196DEBUGFS_FWSTATS_FILE(aes, encrypt_fail, "%u"); 197DEBUGFS_FWSTATS_FILE(aes, decrypt_fail, "%u"); 198DEBUGFS_FWSTATS_FILE(aes, encrypt_packets, "%u"); 199DEBUGFS_FWSTATS_FILE(aes, decrypt_packets, "%u"); 200DEBUGFS_FWSTATS_FILE(aes, encrypt_interrupt, "%u"); 201DEBUGFS_FWSTATS_FILE(aes, decrypt_interrupt, "%u"); 202 203DEBUGFS_FWSTATS_FILE(event, heart_beat, "%u"); 204DEBUGFS_FWSTATS_FILE(event, calibration, "%u"); 205DEBUGFS_FWSTATS_FILE(event, rx_mismatch, "%u"); 206DEBUGFS_FWSTATS_FILE(event, rx_mem_empty, "%u"); 207DEBUGFS_FWSTATS_FILE(event, rx_pool, "%u"); 208DEBUGFS_FWSTATS_FILE(event, oom_late, "%u"); 209DEBUGFS_FWSTATS_FILE(event, phy_transmit_error, "%u"); 210DEBUGFS_FWSTATS_FILE(event, tx_stuck, "%u"); 211 212DEBUGFS_FWSTATS_FILE(ps, pspoll_timeouts, "%u"); 213DEBUGFS_FWSTATS_FILE(ps, upsd_timeouts, "%u"); 214DEBUGFS_FWSTATS_FILE(ps, upsd_max_sptime, "%u"); 215DEBUGFS_FWSTATS_FILE(ps, upsd_max_apturn, "%u"); 216DEBUGFS_FWSTATS_FILE(ps, pspoll_max_apturn, "%u"); 217DEBUGFS_FWSTATS_FILE(ps, pspoll_utilization, "%u"); 218DEBUGFS_FWSTATS_FILE(ps, upsd_utilization, "%u"); 219 220DEBUGFS_FWSTATS_FILE(rxpipe, rx_prep_beacon_drop, "%u"); 221DEBUGFS_FWSTATS_FILE(rxpipe, descr_host_int_trig_rx_data, "%u"); 222DEBUGFS_FWSTATS_FILE(rxpipe, beacon_buffer_thres_host_int_trig_rx_data, "%u"); 223DEBUGFS_FWSTATS_FILE(rxpipe, missed_beacon_host_int_trig_rx_data, "%u"); 224DEBUGFS_FWSTATS_FILE(rxpipe, tx_xfr_host_int_trig_rx_data, "%u"); 225 226DEBUGFS_READONLY_FILE(retry_count, "%u", wl->stats.retry_count); 227DEBUGFS_READONLY_FILE(excessive_retries, "%u", 228 wl->stats.excessive_retries); 229 230static ssize_t tx_queue_len_read(struct file *file, char __user *userbuf, 231 size_t count, loff_t *ppos) 232{ 233 struct wl1271 *wl = file->private_data; 234 u32 queue_len; 235 char buf[20]; 236 int res; 237 238 queue_len = wl1271_tx_total_queue_count(wl); 239 240 res = scnprintf(buf, sizeof(buf), "%u\n", queue_len); 241 return simple_read_from_buffer(userbuf, count, ppos, buf, res); 242} 243 244static const struct file_operations tx_queue_len_ops = { 245 .read = tx_queue_len_read, 246 .open = wl1271_open_file_generic, 247 .llseek = default_llseek, 248}; 249 250static ssize_t gpio_power_read(struct file *file, char __user *user_buf, 251 size_t count, loff_t *ppos) 252{ 253 struct wl1271 *wl = file->private_data; 254 bool state = test_bit(WL1271_FLAG_GPIO_POWER, &wl->flags); 255 256 int res; 257 char buf[10]; 258 259 res = scnprintf(buf, sizeof(buf), "%d\n", state); 260 261 return simple_read_from_buffer(user_buf, count, ppos, buf, res); 262} 263 264static ssize_t gpio_power_write(struct file *file, 265 const char __user *user_buf, 266 size_t count, loff_t *ppos) 267{ 268 struct wl1271 *wl = file->private_data; 269 unsigned long value; 270 int ret; 271 272 ret = kstrtoul_from_user(user_buf, count, 10, &value); 273 if (ret < 0) { 274 wl1271_warning("illegal value in gpio_power"); 275 return -EINVAL; 276 } 277 278 mutex_lock(&wl->mutex); 279 280 if (value) 281 wl1271_power_on(wl); 282 else 283 wl1271_power_off(wl); 284 285 mutex_unlock(&wl->mutex); 286 return count; 287} 288 289static const struct file_operations gpio_power_ops = { 290 .read = gpio_power_read, 291 .write = gpio_power_write, 292 .open = wl1271_open_file_generic, 293 .llseek = default_llseek, 294}; 295 296static ssize_t start_recovery_write(struct file *file, 297 const char __user *user_buf, 298 size_t count, loff_t *ppos) 299{ 300 struct wl1271 *wl = file->private_data; 301 302 mutex_lock(&wl->mutex); 303 wl12xx_queue_recovery_work(wl); 304 mutex_unlock(&wl->mutex); 305 306 return count; 307} 308 309static const struct file_operations start_recovery_ops = { 310 .write = start_recovery_write, 311 .open = wl1271_open_file_generic, 312 .llseek = default_llseek, 313}; 314 315static ssize_t driver_state_read(struct file *file, char __user *user_buf, 316 size_t count, loff_t *ppos) 317{ 318 struct wl1271 *wl = file->private_data; 319 int res = 0; 320 char buf[1024]; 321 322 mutex_lock(&wl->mutex); 323 324#define DRIVER_STATE_PRINT(x, fmt) \ 325 (res += scnprintf(buf + res, sizeof(buf) - res,\ 326 #x " = " fmt "\n", wl->x)) 327 328#define DRIVER_STATE_PRINT_LONG(x) DRIVER_STATE_PRINT(x, "%ld") 329#define DRIVER_STATE_PRINT_INT(x) DRIVER_STATE_PRINT(x, "%d") 330#define DRIVER_STATE_PRINT_STR(x) DRIVER_STATE_PRINT(x, "%s") 331#define DRIVER_STATE_PRINT_LHEX(x) DRIVER_STATE_PRINT(x, "0x%lx") 332#define DRIVER_STATE_PRINT_HEX(x) DRIVER_STATE_PRINT(x, "0x%x") 333 334 DRIVER_STATE_PRINT_INT(tx_blocks_available); 335 DRIVER_STATE_PRINT_INT(tx_allocated_blocks); 336 DRIVER_STATE_PRINT_INT(tx_allocated_pkts[0]); 337 DRIVER_STATE_PRINT_INT(tx_allocated_pkts[1]); 338 DRIVER_STATE_PRINT_INT(tx_allocated_pkts[2]); 339 DRIVER_STATE_PRINT_INT(tx_allocated_pkts[3]); 340 DRIVER_STATE_PRINT_INT(tx_frames_cnt); 341 DRIVER_STATE_PRINT_LHEX(tx_frames_map[0]); 342 DRIVER_STATE_PRINT_INT(tx_queue_count[0]); 343 DRIVER_STATE_PRINT_INT(tx_queue_count[1]); 344 DRIVER_STATE_PRINT_INT(tx_queue_count[2]); 345 DRIVER_STATE_PRINT_INT(tx_queue_count[3]); 346 DRIVER_STATE_PRINT_INT(tx_packets_count); 347 DRIVER_STATE_PRINT_INT(tx_results_count); 348 DRIVER_STATE_PRINT_LHEX(flags); 349 DRIVER_STATE_PRINT_INT(tx_blocks_freed); 350 DRIVER_STATE_PRINT_INT(rx_counter); 351 DRIVER_STATE_PRINT_INT(state); 352 DRIVER_STATE_PRINT_INT(channel); 353 DRIVER_STATE_PRINT_INT(band); 354 DRIVER_STATE_PRINT_INT(power_level); 355 DRIVER_STATE_PRINT_INT(sg_enabled); 356 DRIVER_STATE_PRINT_INT(enable_11a); 357 DRIVER_STATE_PRINT_INT(noise); 358 DRIVER_STATE_PRINT_HEX(ap_fw_ps_map); 359 DRIVER_STATE_PRINT_LHEX(ap_ps_map); 360 DRIVER_STATE_PRINT_HEX(quirks); 361 DRIVER_STATE_PRINT_HEX(irq); 362 DRIVER_STATE_PRINT_HEX(ref_clock); 363 DRIVER_STATE_PRINT_HEX(tcxo_clock); 364 DRIVER_STATE_PRINT_HEX(hw_pg_ver); 365 DRIVER_STATE_PRINT_HEX(platform_quirks); 366 DRIVER_STATE_PRINT_HEX(chip.id); 367 DRIVER_STATE_PRINT_STR(chip.fw_ver_str); 368 DRIVER_STATE_PRINT_INT(sched_scanning); 369 370#undef DRIVER_STATE_PRINT_INT 371#undef DRIVER_STATE_PRINT_LONG 372#undef DRIVER_STATE_PRINT_HEX 373#undef DRIVER_STATE_PRINT_LHEX 374#undef DRIVER_STATE_PRINT_STR 375#undef DRIVER_STATE_PRINT 376 377 mutex_unlock(&wl->mutex); 378 379 return simple_read_from_buffer(user_buf, count, ppos, buf, res); 380} 381 382static const struct file_operations driver_state_ops = { 383 .read = driver_state_read, 384 .open = wl1271_open_file_generic, 385 .llseek = default_llseek, 386}; 387 388static ssize_t vifs_state_read(struct file *file, char __user *user_buf, 389 size_t count, loff_t *ppos) 390{ 391 struct wl1271 *wl = file->private_data; 392 struct wl12xx_vif *wlvif; 393 int ret, res = 0; 394 const int buf_size = 4096; 395 char *buf; 396 char tmp_buf[64]; 397 398 buf = kzalloc(buf_size, GFP_KERNEL); 399 if (!buf) 400 return -ENOMEM; 401 402 mutex_lock(&wl->mutex); 403 404#define VIF_STATE_PRINT(x, fmt) \ 405 (res += scnprintf(buf + res, buf_size - res, \ 406 #x " = " fmt "\n", wlvif->x)) 407 408#define VIF_STATE_PRINT_LONG(x) VIF_STATE_PRINT(x, "%ld") 409#define VIF_STATE_PRINT_INT(x) VIF_STATE_PRINT(x, "%d") 410#define VIF_STATE_PRINT_STR(x) VIF_STATE_PRINT(x, "%s") 411#define VIF_STATE_PRINT_LHEX(x) VIF_STATE_PRINT(x, "0x%lx") 412#define VIF_STATE_PRINT_LLHEX(x) VIF_STATE_PRINT(x, "0x%llx") 413#define VIF_STATE_PRINT_HEX(x) VIF_STATE_PRINT(x, "0x%x") 414 415#define VIF_STATE_PRINT_NSTR(x, len) \ 416 do { \ 417 memset(tmp_buf, 0, sizeof(tmp_buf)); \ 418 memcpy(tmp_buf, wlvif->x, \ 419 min_t(u8, len, sizeof(tmp_buf) - 1)); \ 420 res += scnprintf(buf + res, buf_size - res, \ 421 #x " = %s\n", tmp_buf); \ 422 } while (0) 423 424 wl12xx_for_each_wlvif(wl, wlvif) { 425 VIF_STATE_PRINT_INT(role_id); 426 VIF_STATE_PRINT_INT(bss_type); 427 VIF_STATE_PRINT_LHEX(flags); 428 VIF_STATE_PRINT_INT(p2p); 429 VIF_STATE_PRINT_INT(dev_role_id); 430 VIF_STATE_PRINT_INT(dev_hlid); 431 432 if (wlvif->bss_type == BSS_TYPE_STA_BSS || 433 wlvif->bss_type == BSS_TYPE_IBSS) { 434 VIF_STATE_PRINT_INT(sta.hlid); 435 VIF_STATE_PRINT_INT(sta.ba_rx_bitmap); 436 VIF_STATE_PRINT_INT(sta.basic_rate_idx); 437 VIF_STATE_PRINT_INT(sta.ap_rate_idx); 438 VIF_STATE_PRINT_INT(sta.p2p_rate_idx); 439 } else { 440 VIF_STATE_PRINT_INT(ap.global_hlid); 441 VIF_STATE_PRINT_INT(ap.bcast_hlid); 442 VIF_STATE_PRINT_LHEX(ap.sta_hlid_map[0]); 443 VIF_STATE_PRINT_INT(ap.mgmt_rate_idx); 444 VIF_STATE_PRINT_INT(ap.bcast_rate_idx); 445 VIF_STATE_PRINT_INT(ap.ucast_rate_idx[0]); 446 VIF_STATE_PRINT_INT(ap.ucast_rate_idx[1]); 447 VIF_STATE_PRINT_INT(ap.ucast_rate_idx[2]); 448 VIF_STATE_PRINT_INT(ap.ucast_rate_idx[3]); 449 } 450 VIF_STATE_PRINT_INT(last_tx_hlid); 451 VIF_STATE_PRINT_LHEX(links_map[0]); 452 VIF_STATE_PRINT_NSTR(ssid, wlvif->ssid_len); 453 VIF_STATE_PRINT_INT(band); 454 VIF_STATE_PRINT_INT(channel); 455 VIF_STATE_PRINT_HEX(bitrate_masks[0]); 456 VIF_STATE_PRINT_HEX(bitrate_masks[1]); 457 VIF_STATE_PRINT_HEX(basic_rate_set); 458 VIF_STATE_PRINT_HEX(basic_rate); 459 VIF_STATE_PRINT_HEX(rate_set); 460 VIF_STATE_PRINT_INT(beacon_int); 461 VIF_STATE_PRINT_INT(default_key); 462 VIF_STATE_PRINT_INT(aid); 463 VIF_STATE_PRINT_INT(session_counter); 464 VIF_STATE_PRINT_INT(ps_poll_failures); 465 VIF_STATE_PRINT_INT(psm_entry_retry); 466 VIF_STATE_PRINT_INT(power_level); 467 VIF_STATE_PRINT_INT(rssi_thold); 468 VIF_STATE_PRINT_INT(last_rssi_event); 469 VIF_STATE_PRINT_INT(ba_support); 470 VIF_STATE_PRINT_INT(ba_allowed); 471 VIF_STATE_PRINT_LLHEX(tx_security_seq); 472 VIF_STATE_PRINT_INT(tx_security_last_seq_lsb); 473 } 474 475#undef VIF_STATE_PRINT_INT 476#undef VIF_STATE_PRINT_LONG 477#undef VIF_STATE_PRINT_HEX 478#undef VIF_STATE_PRINT_LHEX 479#undef VIF_STATE_PRINT_LLHEX 480#undef VIF_STATE_PRINT_STR 481#undef VIF_STATE_PRINT_NSTR 482#undef VIF_STATE_PRINT 483 484 mutex_unlock(&wl->mutex); 485 486 ret = simple_read_from_buffer(user_buf, count, ppos, buf, res); 487 kfree(buf); 488 return ret; 489} 490 491static const struct file_operations vifs_state_ops = { 492 .read = vifs_state_read, 493 .open = wl1271_open_file_generic, 494 .llseek = default_llseek, 495}; 496 497static ssize_t dtim_interval_read(struct file *file, char __user *user_buf, 498 size_t count, loff_t *ppos) 499{ 500 struct wl1271 *wl = file->private_data; 501 u8 value; 502 503 if (wl->conf.conn.wake_up_event == CONF_WAKE_UP_EVENT_DTIM || 504 wl->conf.conn.wake_up_event == CONF_WAKE_UP_EVENT_N_DTIM) 505 value = wl->conf.conn.listen_interval; 506 else 507 value = 0; 508 509 return wl1271_format_buffer(user_buf, count, ppos, "%d\n", value); 510} 511 512static ssize_t dtim_interval_write(struct file *file, 513 const char __user *user_buf, 514 size_t count, loff_t *ppos) 515{ 516 struct wl1271 *wl = file->private_data; 517 unsigned long value; 518 int ret; 519 520 ret = kstrtoul_from_user(user_buf, count, 10, &value); 521 if (ret < 0) { 522 wl1271_warning("illegal value for dtim_interval"); 523 return -EINVAL; 524 } 525 526 if (value < 1 || value > 10) { 527 wl1271_warning("dtim value is not in valid range"); 528 return -ERANGE; 529 } 530 531 mutex_lock(&wl->mutex); 532 533 wl->conf.conn.listen_interval = value; 534 /* for some reason there are different event types for 1 and >1 */ 535 if (value == 1) 536 wl->conf.conn.wake_up_event = CONF_WAKE_UP_EVENT_DTIM; 537 else 538 wl->conf.conn.wake_up_event = CONF_WAKE_UP_EVENT_N_DTIM; 539 540 /* 541 * we don't reconfigure ACX_WAKE_UP_CONDITIONS now, so it will only 542 * take effect on the next time we enter psm. 543 */ 544 mutex_unlock(&wl->mutex); 545 return count; 546} 547 548static const struct file_operations dtim_interval_ops = { 549 .read = dtim_interval_read, 550 .write = dtim_interval_write, 551 .open = wl1271_open_file_generic, 552 .llseek = default_llseek, 553}; 554 555static ssize_t beacon_interval_read(struct file *file, char __user *user_buf, 556 size_t count, loff_t *ppos) 557{ 558 struct wl1271 *wl = file->private_data; 559 u8 value; 560 561 if (wl->conf.conn.wake_up_event == CONF_WAKE_UP_EVENT_BEACON || 562 wl->conf.conn.wake_up_event == CONF_WAKE_UP_EVENT_N_BEACONS) 563 value = wl->conf.conn.listen_interval; 564 else 565 value = 0; 566 567 return wl1271_format_buffer(user_buf, count, ppos, "%d\n", value); 568} 569 570static ssize_t beacon_interval_write(struct file *file, 571 const char __user *user_buf, 572 size_t count, loff_t *ppos) 573{ 574 struct wl1271 *wl = file->private_data; 575 unsigned long value; 576 int ret; 577 578 ret = kstrtoul_from_user(user_buf, count, 10, &value); 579 if (ret < 0) { 580 wl1271_warning("illegal value for beacon_interval"); 581 return -EINVAL; 582 } 583 584 if (value < 1 || value > 255) { 585 wl1271_warning("beacon interval value is not in valid range"); 586 return -ERANGE; 587 } 588 589 mutex_lock(&wl->mutex); 590 591 wl->conf.conn.listen_interval = value; 592 /* for some reason there are different event types for 1 and >1 */ 593 if (value == 1) 594 wl->conf.conn.wake_up_event = CONF_WAKE_UP_EVENT_BEACON; 595 else 596 wl->conf.conn.wake_up_event = CONF_WAKE_UP_EVENT_N_BEACONS; 597 598 /* 599 * we don't reconfigure ACX_WAKE_UP_CONDITIONS now, so it will only 600 * take effect on the next time we enter psm. 601 */ 602 mutex_unlock(&wl->mutex); 603 return count; 604} 605 606static const struct file_operations beacon_interval_ops = { 607 .read = beacon_interval_read, 608 .write = beacon_interval_write, 609 .open = wl1271_open_file_generic, 610 .llseek = default_llseek, 611}; 612 613static ssize_t rx_streaming_interval_write(struct file *file, 614 const char __user *user_buf, 615 size_t count, loff_t *ppos) 616{ 617 struct wl1271 *wl = file->private_data; 618 struct wl12xx_vif *wlvif; 619 unsigned long value; 620 int ret; 621 622 ret = kstrtoul_from_user(user_buf, count, 10, &value); 623 if (ret < 0) { 624 wl1271_warning("illegal value in rx_streaming_interval!"); 625 return -EINVAL; 626 } 627 628 /* valid values: 0, 10-100 */ 629 if (value && (value < 10 || value > 100)) { 630 wl1271_warning("value is not in range!"); 631 return -ERANGE; 632 } 633 634 mutex_lock(&wl->mutex); 635 636 wl->conf.rx_streaming.interval = value; 637 638 ret = wl1271_ps_elp_wakeup(wl); 639 if (ret < 0) 640 goto out; 641 642 wl12xx_for_each_wlvif_sta(wl, wlvif) { 643 wl1271_recalc_rx_streaming(wl, wlvif); 644 } 645 646 wl1271_ps_elp_sleep(wl); 647out: 648 mutex_unlock(&wl->mutex); 649 return count; 650} 651 652static ssize_t rx_streaming_interval_read(struct file *file, 653 char __user *userbuf, 654 size_t count, loff_t *ppos) 655{ 656 struct wl1271 *wl = file->private_data; 657 return wl1271_format_buffer(userbuf, count, ppos, 658 "%d\n", wl->conf.rx_streaming.interval); 659} 660 661static const struct file_operations rx_streaming_interval_ops = { 662 .read = rx_streaming_interval_read, 663 .write = rx_streaming_interval_write, 664 .open = wl1271_open_file_generic, 665 .llseek = default_llseek, 666}; 667 668static ssize_t rx_streaming_always_write(struct file *file, 669 const char __user *user_buf, 670 size_t count, loff_t *ppos) 671{ 672 struct wl1271 *wl = file->private_data; 673 struct wl12xx_vif *wlvif; 674 unsigned long value; 675 int ret; 676 677 ret = kstrtoul_from_user(user_buf, count, 10, &value); 678 if (ret < 0) { 679 wl1271_warning("illegal value in rx_streaming_write!"); 680 return -EINVAL; 681 } 682 683 /* valid values: 0, 10-100 */ 684 if (!(value == 0 || value == 1)) { 685 wl1271_warning("value is not in valid!"); 686 return -EINVAL; 687 } 688 689 mutex_lock(&wl->mutex); 690 691 wl->conf.rx_streaming.always = value; 692 693 ret = wl1271_ps_elp_wakeup(wl); 694 if (ret < 0) 695 goto out; 696 697 wl12xx_for_each_wlvif_sta(wl, wlvif) { 698 wl1271_recalc_rx_streaming(wl, wlvif); 699 } 700 701 wl1271_ps_elp_sleep(wl); 702out: 703 mutex_unlock(&wl->mutex); 704 return count; 705} 706 707static ssize_t rx_streaming_always_read(struct file *file, 708 char __user *userbuf, 709 size_t count, loff_t *ppos) 710{ 711 struct wl1271 *wl = file->private_data; 712 return wl1271_format_buffer(userbuf, count, ppos, 713 "%d\n", wl->conf.rx_streaming.always); 714} 715 716static const struct file_operations rx_streaming_always_ops = { 717 .read = rx_streaming_always_read, 718 .write = rx_streaming_always_write, 719 .open = wl1271_open_file_generic, 720 .llseek = default_llseek, 721}; 722 723static ssize_t beacon_filtering_write(struct file *file, 724 const char __user *user_buf, 725 size_t count, loff_t *ppos) 726{ 727 struct wl1271 *wl = file->private_data; 728 struct wl12xx_vif *wlvif; 729 char buf[10]; 730 size_t len; 731 unsigned long value; 732 int ret; 733 734 len = min(count, sizeof(buf) - 1); 735 if (copy_from_user(buf, user_buf, len)) 736 return -EFAULT; 737 buf[len] = '\0'; 738 739 ret = kstrtoul(buf, 0, &value); 740 if (ret < 0) { 741 wl1271_warning("illegal value for beacon_filtering!"); 742 return -EINVAL; 743 } 744 745 mutex_lock(&wl->mutex); 746 747 ret = wl1271_ps_elp_wakeup(wl); 748 if (ret < 0) 749 goto out; 750 751 wl12xx_for_each_wlvif(wl, wlvif) { 752 ret = wl1271_acx_beacon_filter_opt(wl, wlvif, !!value); 753 } 754 755 wl1271_ps_elp_sleep(wl); 756out: 757 mutex_unlock(&wl->mutex); 758 return count; 759} 760 761static const struct file_operations beacon_filtering_ops = { 762 .write = beacon_filtering_write, 763 .open = wl1271_open_file_generic, 764 .llseek = default_llseek, 765}; 766 767static int wl1271_debugfs_add_files(struct wl1271 *wl, 768 struct dentry *rootdir) 769{ 770 int ret = 0; 771 struct dentry *entry, *stats, *streaming; 772 773 stats = debugfs_create_dir("fw-statistics", rootdir); 774 if (!stats || IS_ERR(stats)) { 775 entry = stats; 776 goto err; 777 } 778 779 DEBUGFS_FWSTATS_ADD(tx, internal_desc_overflow); 780 781 DEBUGFS_FWSTATS_ADD(rx, out_of_mem); 782 DEBUGFS_FWSTATS_ADD(rx, hdr_overflow); 783 DEBUGFS_FWSTATS_ADD(rx, hw_stuck); 784 DEBUGFS_FWSTATS_ADD(rx, dropped); 785 DEBUGFS_FWSTATS_ADD(rx, fcs_err); 786 DEBUGFS_FWSTATS_ADD(rx, xfr_hint_trig); 787 DEBUGFS_FWSTATS_ADD(rx, path_reset); 788 DEBUGFS_FWSTATS_ADD(rx, reset_counter); 789 790 DEBUGFS_FWSTATS_ADD(dma, rx_requested); 791 DEBUGFS_FWSTATS_ADD(dma, rx_errors); 792 DEBUGFS_FWSTATS_ADD(dma, tx_requested); 793 DEBUGFS_FWSTATS_ADD(dma, tx_errors); 794 795 DEBUGFS_FWSTATS_ADD(isr, cmd_cmplt); 796 DEBUGFS_FWSTATS_ADD(isr, fiqs); 797 DEBUGFS_FWSTATS_ADD(isr, rx_headers); 798 DEBUGFS_FWSTATS_ADD(isr, rx_mem_overflow); 799 DEBUGFS_FWSTATS_ADD(isr, rx_rdys); 800 DEBUGFS_FWSTATS_ADD(isr, irqs); 801 DEBUGFS_FWSTATS_ADD(isr, tx_procs); 802 DEBUGFS_FWSTATS_ADD(isr, decrypt_done); 803 DEBUGFS_FWSTATS_ADD(isr, dma0_done); 804 DEBUGFS_FWSTATS_ADD(isr, dma1_done); 805 DEBUGFS_FWSTATS_ADD(isr, tx_exch_complete); 806 DEBUGFS_FWSTATS_ADD(isr, commands); 807 DEBUGFS_FWSTATS_ADD(isr, rx_procs); 808 DEBUGFS_FWSTATS_ADD(isr, hw_pm_mode_changes); 809 DEBUGFS_FWSTATS_ADD(isr, host_acknowledges); 810 DEBUGFS_FWSTATS_ADD(isr, pci_pm); 811 DEBUGFS_FWSTATS_ADD(isr, wakeups); 812 DEBUGFS_FWSTATS_ADD(isr, low_rssi); 813 814 DEBUGFS_FWSTATS_ADD(wep, addr_key_count); 815 DEBUGFS_FWSTATS_ADD(wep, default_key_count); 816 /* skipping wep.reserved */ 817 DEBUGFS_FWSTATS_ADD(wep, key_not_found); 818 DEBUGFS_FWSTATS_ADD(wep, decrypt_fail); 819 DEBUGFS_FWSTATS_ADD(wep, packets); 820 DEBUGFS_FWSTATS_ADD(wep, interrupt); 821 822 DEBUGFS_FWSTATS_ADD(pwr, ps_enter); 823 DEBUGFS_FWSTATS_ADD(pwr, elp_enter); 824 DEBUGFS_FWSTATS_ADD(pwr, missing_bcns); 825 DEBUGFS_FWSTATS_ADD(pwr, wake_on_host); 826 DEBUGFS_FWSTATS_ADD(pwr, wake_on_timer_exp); 827 DEBUGFS_FWSTATS_ADD(pwr, tx_with_ps); 828 DEBUGFS_FWSTATS_ADD(pwr, tx_without_ps); 829 DEBUGFS_FWSTATS_ADD(pwr, rcvd_beacons); 830 DEBUGFS_FWSTATS_ADD(pwr, power_save_off); 831 DEBUGFS_FWSTATS_ADD(pwr, enable_ps); 832 DEBUGFS_FWSTATS_ADD(pwr, disable_ps); 833 DEBUGFS_FWSTATS_ADD(pwr, fix_tsf_ps); 834 /* skipping cont_miss_bcns_spread for now */ 835 DEBUGFS_FWSTATS_ADD(pwr, rcvd_awake_beacons); 836 837 DEBUGFS_FWSTATS_ADD(mic, rx_pkts); 838 DEBUGFS_FWSTATS_ADD(mic, calc_failure); 839 840 DEBUGFS_FWSTATS_ADD(aes, encrypt_fail); 841 DEBUGFS_FWSTATS_ADD(aes, decrypt_fail); 842 DEBUGFS_FWSTATS_ADD(aes, encrypt_packets); 843 DEBUGFS_FWSTATS_ADD(aes, decrypt_packets); 844 DEBUGFS_FWSTATS_ADD(aes, encrypt_interrupt); 845 DEBUGFS_FWSTATS_ADD(aes, decrypt_interrupt); 846 847 DEBUGFS_FWSTATS_ADD(event, heart_beat); 848 DEBUGFS_FWSTATS_ADD(event, calibration); 849 DEBUGFS_FWSTATS_ADD(event, rx_mismatch); 850 DEBUGFS_FWSTATS_ADD(event, rx_mem_empty); 851 DEBUGFS_FWSTATS_ADD(event, rx_pool); 852 DEBUGFS_FWSTATS_ADD(event, oom_late); 853 DEBUGFS_FWSTATS_ADD(event, phy_transmit_error); 854 DEBUGFS_FWSTATS_ADD(event, tx_stuck); 855 856 DEBUGFS_FWSTATS_ADD(ps, pspoll_timeouts); 857 DEBUGFS_FWSTATS_ADD(ps, upsd_timeouts); 858 DEBUGFS_FWSTATS_ADD(ps, upsd_max_sptime); 859 DEBUGFS_FWSTATS_ADD(ps, upsd_max_apturn); 860 DEBUGFS_FWSTATS_ADD(ps, pspoll_max_apturn); 861 DEBUGFS_FWSTATS_ADD(ps, pspoll_utilization); 862 DEBUGFS_FWSTATS_ADD(ps, upsd_utilization); 863 864 DEBUGFS_FWSTATS_ADD(rxpipe, rx_prep_beacon_drop); 865 DEBUGFS_FWSTATS_ADD(rxpipe, descr_host_int_trig_rx_data); 866 DEBUGFS_FWSTATS_ADD(rxpipe, beacon_buffer_thres_host_int_trig_rx_data); 867 DEBUGFS_FWSTATS_ADD(rxpipe, missed_beacon_host_int_trig_rx_data); 868 DEBUGFS_FWSTATS_ADD(rxpipe, tx_xfr_host_int_trig_rx_data); 869 870 DEBUGFS_ADD(tx_queue_len, rootdir); 871 DEBUGFS_ADD(retry_count, rootdir); 872 DEBUGFS_ADD(excessive_retries, rootdir); 873 874 DEBUGFS_ADD(gpio_power, rootdir); 875 DEBUGFS_ADD(start_recovery, rootdir); 876 DEBUGFS_ADD(driver_state, rootdir); 877 DEBUGFS_ADD(vifs_state, rootdir); 878 DEBUGFS_ADD(dtim_interval, rootdir); 879 DEBUGFS_ADD(beacon_interval, rootdir); 880 DEBUGFS_ADD(beacon_filtering, rootdir); 881 882 streaming = debugfs_create_dir("rx_streaming", rootdir); 883 if (!streaming || IS_ERR(streaming)) 884 goto err; 885 886 DEBUGFS_ADD_PREFIX(rx_streaming, interval, streaming); 887 DEBUGFS_ADD_PREFIX(rx_streaming, always, streaming); 888 889 890 return 0; 891 892err: 893 if (IS_ERR(entry)) 894 ret = PTR_ERR(entry); 895 else 896 ret = -ENOMEM; 897 898 return ret; 899} 900 901void wl1271_debugfs_reset(struct wl1271 *wl) 902{ 903 if (!wl->stats.fw_stats) 904 return; 905 906 memset(wl->stats.fw_stats, 0, sizeof(*wl->stats.fw_stats)); 907 wl->stats.retry_count = 0; 908 wl->stats.excessive_retries = 0; 909} 910 911int wl1271_debugfs_init(struct wl1271 *wl) 912{ 913 int ret; 914 struct dentry *rootdir; 915 916 rootdir = debugfs_create_dir(KBUILD_MODNAME, 917 wl->hw->wiphy->debugfsdir); 918 919 if (IS_ERR(rootdir)) { 920 ret = PTR_ERR(rootdir); 921 goto err; 922 } 923 924 wl->stats.fw_stats = kzalloc(sizeof(*wl->stats.fw_stats), 925 GFP_KERNEL); 926 927 if (!wl->stats.fw_stats) { 928 ret = -ENOMEM; 929 goto err_fw; 930 } 931 932 wl->stats.fw_stats_update = jiffies; 933 934 ret = wl1271_debugfs_add_files(wl, rootdir); 935 936 if (ret < 0) 937 goto err_file; 938 939 return 0; 940 941err_file: 942 kfree(wl->stats.fw_stats); 943 wl->stats.fw_stats = NULL; 944 945err_fw: 946 debugfs_remove_recursive(rootdir); 947 948err: 949 return ret; 950} 951 952void wl1271_debugfs_exit(struct wl1271 *wl) 953{ 954 kfree(wl->stats.fw_stats); 955 wl->stats.fw_stats = NULL; 956} 957