1 /* 2 * This file is part of wl1271 3 * 4 * Copyright (C) 2009 Nokia Corporation 5 * 6 * Contact: Luciano Coelho <[email protected]> 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 #include <linux/module.h> 29 #include <linux/pm_runtime.h> 30 31 #include "wlcore.h" 32 #include "debug.h" 33 #include "acx.h" 34 #include "ps.h" 35 #include "io.h" 36 #include "tx.h" 37 #include "hw_ops.h" 38 39 /* ms */ 40 #define WL1271_DEBUGFS_STATS_LIFETIME 1000 41 42 #define WLCORE_MAX_BLOCK_SIZE ((size_t)(4*PAGE_SIZE)) 43 44 /* debugfs macros idea from mac80211 */ 45 int wl1271_format_buffer(char __user *userbuf, size_t count, 46 loff_t *ppos, char *fmt, ...) 47 { 48 va_list args; 49 char buf[DEBUGFS_FORMAT_BUFFER_SIZE]; 50 int res; 51 52 va_start(args, fmt); 53 res = vscnprintf(buf, sizeof(buf), fmt, args); 54 va_end(args); 55 56 return simple_read_from_buffer(userbuf, count, ppos, buf, res); 57 } 58 EXPORT_SYMBOL_GPL(wl1271_format_buffer); 59 60 void wl1271_debugfs_update_stats(struct wl1271 *wl) 61 { 62 int ret; 63 64 mutex_lock(&wl->mutex); 65 66 if (unlikely(wl->state != WLCORE_STATE_ON)) 67 goto out; 68 69 ret = pm_runtime_get_sync(wl->dev); 70 if (ret < 0) { 71 pm_runtime_put_noidle(wl->dev); 72 goto out; 73 } 74 75 if (!wl->plt && 76 time_after(jiffies, wl->stats.fw_stats_update + 77 msecs_to_jiffies(WL1271_DEBUGFS_STATS_LIFETIME))) { 78 wl1271_acx_statistics(wl, wl->stats.fw_stats); 79 wl->stats.fw_stats_update = jiffies; 80 } 81 82 pm_runtime_put(wl->dev); 83 84 out: 85 mutex_unlock(&wl->mutex); 86 } 87 EXPORT_SYMBOL_GPL(wl1271_debugfs_update_stats); 88 89 DEBUGFS_READONLY_FILE(retry_count, "%u", wl->stats.retry_count); 90 DEBUGFS_READONLY_FILE(excessive_retries, "%u", 91 wl->stats.excessive_retries); 92 93 static ssize_t tx_queue_len_read(struct file *file, char __user *userbuf, 94 size_t count, loff_t *ppos) 95 { 96 struct wl1271 *wl = file->private_data; 97 u32 queue_len; 98 char buf[20]; 99 int res; 100 101 queue_len = wl1271_tx_total_queue_count(wl); 102 103 res = scnprintf(buf, sizeof(buf), "%u\n", queue_len); 104 return simple_read_from_buffer(userbuf, count, ppos, buf, res); 105 } 106 107 static const struct file_operations tx_queue_len_ops = { 108 .read = tx_queue_len_read, 109 .open = simple_open, 110 .llseek = default_llseek, 111 }; 112 113 static void chip_op_handler(struct wl1271 *wl, unsigned long value, 114 void *arg) 115 { 116 int ret; 117 int (*chip_op) (struct wl1271 *wl); 118 119 if (!arg) { 120 wl1271_warning("debugfs chip_op_handler with no callback"); 121 return; 122 } 123 124 ret = pm_runtime_get_sync(wl->dev); 125 if (ret < 0) { 126 pm_runtime_put_noidle(wl->dev); 127 128 return; 129 } 130 131 chip_op = arg; 132 chip_op(wl); 133 134 pm_runtime_put(wl->dev); 135 } 136 137 138 static inline void no_write_handler(struct wl1271 *wl, 139 unsigned long value, 140 unsigned long param) 141 { 142 } 143 144 #define WL12XX_CONF_DEBUGFS(param, conf_sub_struct, \ 145 min_val, max_val, write_handler_locked, \ 146 write_handler_arg) \ 147 static ssize_t param##_read(struct file *file, \ 148 char __user *user_buf, \ 149 size_t count, loff_t *ppos) \ 150 { \ 151 struct wl1271 *wl = file->private_data; \ 152 return wl1271_format_buffer(user_buf, count, \ 153 ppos, "%d\n", \ 154 wl->conf.conf_sub_struct.param); \ 155 } \ 156 \ 157 static ssize_t param##_write(struct file *file, \ 158 const char __user *user_buf, \ 159 size_t count, loff_t *ppos) \ 160 { \ 161 struct wl1271 *wl = file->private_data; \ 162 unsigned long value; \ 163 int ret; \ 164 \ 165 ret = kstrtoul_from_user(user_buf, count, 10, &value); \ 166 if (ret < 0) { \ 167 wl1271_warning("illegal value for " #param); \ 168 return -EINVAL; \ 169 } \ 170 \ 171 if (value < min_val || value > max_val) { \ 172 wl1271_warning(#param " is not in valid range"); \ 173 return -ERANGE; \ 174 } \ 175 \ 176 mutex_lock(&wl->mutex); \ 177 wl->conf.conf_sub_struct.param = value; \ 178 \ 179 write_handler_locked(wl, value, write_handler_arg); \ 180 \ 181 mutex_unlock(&wl->mutex); \ 182 return count; \ 183 } \ 184 \ 185 static const struct file_operations param##_ops = { \ 186 .read = param##_read, \ 187 .write = param##_write, \ 188 .open = simple_open, \ 189 .llseek = default_llseek, \ 190 }; 191 192 WL12XX_CONF_DEBUGFS(irq_pkt_threshold, rx, 0, 65535, 193 chip_op_handler, wl1271_acx_init_rx_interrupt) 194 WL12XX_CONF_DEBUGFS(irq_blk_threshold, rx, 0, 65535, 195 chip_op_handler, wl1271_acx_init_rx_interrupt) 196 WL12XX_CONF_DEBUGFS(irq_timeout, rx, 0, 100, 197 chip_op_handler, wl1271_acx_init_rx_interrupt) 198 199 static ssize_t gpio_power_read(struct file *file, char __user *user_buf, 200 size_t count, loff_t *ppos) 201 { 202 struct wl1271 *wl = file->private_data; 203 bool state = test_bit(WL1271_FLAG_GPIO_POWER, &wl->flags); 204 205 int res; 206 char buf[10]; 207 208 res = scnprintf(buf, sizeof(buf), "%d\n", state); 209 210 return simple_read_from_buffer(user_buf, count, ppos, buf, res); 211 } 212 213 static ssize_t gpio_power_write(struct file *file, 214 const char __user *user_buf, 215 size_t count, loff_t *ppos) 216 { 217 struct wl1271 *wl = file->private_data; 218 unsigned long value; 219 int ret; 220 221 ret = kstrtoul_from_user(user_buf, count, 10, &value); 222 if (ret < 0) { 223 wl1271_warning("illegal value in gpio_power"); 224 return -EINVAL; 225 } 226 227 mutex_lock(&wl->mutex); 228 229 if (value) 230 wl1271_power_on(wl); 231 else 232 wl1271_power_off(wl); 233 234 mutex_unlock(&wl->mutex); 235 return count; 236 } 237 238 static const struct file_operations gpio_power_ops = { 239 .read = gpio_power_read, 240 .write = gpio_power_write, 241 .open = simple_open, 242 .llseek = default_llseek, 243 }; 244 245 static ssize_t start_recovery_write(struct file *file, 246 const char __user *user_buf, 247 size_t count, loff_t *ppos) 248 { 249 struct wl1271 *wl = file->private_data; 250 251 mutex_lock(&wl->mutex); 252 wl12xx_queue_recovery_work(wl); 253 mutex_unlock(&wl->mutex); 254 255 return count; 256 } 257 258 static const struct file_operations start_recovery_ops = { 259 .write = start_recovery_write, 260 .open = simple_open, 261 .llseek = default_llseek, 262 }; 263 264 static ssize_t dynamic_ps_timeout_read(struct file *file, char __user *user_buf, 265 size_t count, loff_t *ppos) 266 { 267 struct wl1271 *wl = file->private_data; 268 269 return wl1271_format_buffer(user_buf, count, 270 ppos, "%d\n", 271 wl->conf.conn.dynamic_ps_timeout); 272 } 273 274 static ssize_t dynamic_ps_timeout_write(struct file *file, 275 const char __user *user_buf, 276 size_t count, loff_t *ppos) 277 { 278 struct wl1271 *wl = file->private_data; 279 struct wl12xx_vif *wlvif; 280 unsigned long value; 281 int ret; 282 283 ret = kstrtoul_from_user(user_buf, count, 10, &value); 284 if (ret < 0) { 285 wl1271_warning("illegal value in dynamic_ps"); 286 return -EINVAL; 287 } 288 289 if (value < 1 || value > 65535) { 290 wl1271_warning("dynamic_ps_timeout is not in valid range"); 291 return -ERANGE; 292 } 293 294 mutex_lock(&wl->mutex); 295 296 wl->conf.conn.dynamic_ps_timeout = value; 297 298 if (unlikely(wl->state != WLCORE_STATE_ON)) 299 goto out; 300 301 ret = pm_runtime_get_sync(wl->dev); 302 if (ret < 0) { 303 pm_runtime_put_noidle(wl->dev); 304 goto out; 305 } 306 307 /* In case we're already in PSM, trigger it again to set new timeout 308 * immediately without waiting for re-association 309 */ 310 311 wl12xx_for_each_wlvif_sta(wl, wlvif) { 312 if (test_bit(WLVIF_FLAG_IN_PS, &wlvif->flags)) 313 wl1271_ps_set_mode(wl, wlvif, STATION_AUTO_PS_MODE); 314 } 315 316 pm_runtime_put(wl->dev); 317 318 out: 319 mutex_unlock(&wl->mutex); 320 return count; 321 } 322 323 static const struct file_operations dynamic_ps_timeout_ops = { 324 .read = dynamic_ps_timeout_read, 325 .write = dynamic_ps_timeout_write, 326 .open = simple_open, 327 .llseek = default_llseek, 328 }; 329 330 static ssize_t forced_ps_read(struct file *file, char __user *user_buf, 331 size_t count, loff_t *ppos) 332 { 333 struct wl1271 *wl = file->private_data; 334 335 return wl1271_format_buffer(user_buf, count, 336 ppos, "%d\n", 337 wl->conf.conn.forced_ps); 338 } 339 340 static ssize_t forced_ps_write(struct file *file, 341 const char __user *user_buf, 342 size_t count, loff_t *ppos) 343 { 344 struct wl1271 *wl = file->private_data; 345 struct wl12xx_vif *wlvif; 346 unsigned long value; 347 int ret, ps_mode; 348 349 ret = kstrtoul_from_user(user_buf, count, 10, &value); 350 if (ret < 0) { 351 wl1271_warning("illegal value in forced_ps"); 352 return -EINVAL; 353 } 354 355 if (value != 1 && value != 0) { 356 wl1271_warning("forced_ps should be either 0 or 1"); 357 return -ERANGE; 358 } 359 360 mutex_lock(&wl->mutex); 361 362 if (wl->conf.conn.forced_ps == value) 363 goto out; 364 365 wl->conf.conn.forced_ps = value; 366 367 if (unlikely(wl->state != WLCORE_STATE_ON)) 368 goto out; 369 370 ret = pm_runtime_get_sync(wl->dev); 371 if (ret < 0) { 372 pm_runtime_put_noidle(wl->dev); 373 goto out; 374 } 375 376 /* In case we're already in PSM, trigger it again to switch mode 377 * immediately without waiting for re-association 378 */ 379 380 ps_mode = value ? STATION_POWER_SAVE_MODE : STATION_AUTO_PS_MODE; 381 382 wl12xx_for_each_wlvif_sta(wl, wlvif) { 383 if (test_bit(WLVIF_FLAG_IN_PS, &wlvif->flags)) 384 wl1271_ps_set_mode(wl, wlvif, ps_mode); 385 } 386 387 pm_runtime_put(wl->dev); 388 389 out: 390 mutex_unlock(&wl->mutex); 391 return count; 392 } 393 394 static const struct file_operations forced_ps_ops = { 395 .read = forced_ps_read, 396 .write = forced_ps_write, 397 .open = simple_open, 398 .llseek = default_llseek, 399 }; 400 401 static ssize_t split_scan_timeout_read(struct file *file, char __user *user_buf, 402 size_t count, loff_t *ppos) 403 { 404 struct wl1271 *wl = file->private_data; 405 406 return wl1271_format_buffer(user_buf, count, 407 ppos, "%d\n", 408 wl->conf.scan.split_scan_timeout / 1000); 409 } 410 411 static ssize_t split_scan_timeout_write(struct file *file, 412 const char __user *user_buf, 413 size_t count, loff_t *ppos) 414 { 415 struct wl1271 *wl = file->private_data; 416 unsigned long value; 417 int ret; 418 419 ret = kstrtoul_from_user(user_buf, count, 10, &value); 420 if (ret < 0) { 421 wl1271_warning("illegal value in split_scan_timeout"); 422 return -EINVAL; 423 } 424 425 if (value == 0) 426 wl1271_info("split scan will be disabled"); 427 428 mutex_lock(&wl->mutex); 429 430 wl->conf.scan.split_scan_timeout = value * 1000; 431 432 mutex_unlock(&wl->mutex); 433 return count; 434 } 435 436 static const struct file_operations split_scan_timeout_ops = { 437 .read = split_scan_timeout_read, 438 .write = split_scan_timeout_write, 439 .open = simple_open, 440 .llseek = default_llseek, 441 }; 442 443 static ssize_t driver_state_read(struct file *file, char __user *user_buf, 444 size_t count, loff_t *ppos) 445 { 446 struct wl1271 *wl = file->private_data; 447 int res = 0; 448 ssize_t ret; 449 char *buf; 450 struct wl12xx_vif *wlvif; 451 452 #define DRIVER_STATE_BUF_LEN 1024 453 454 buf = kmalloc(DRIVER_STATE_BUF_LEN, GFP_KERNEL); 455 if (!buf) 456 return -ENOMEM; 457 458 mutex_lock(&wl->mutex); 459 460 #define DRIVER_STATE_PRINT(x, fmt) \ 461 (res += scnprintf(buf + res, DRIVER_STATE_BUF_LEN - res,\ 462 #x " = " fmt "\n", wl->x)) 463 464 #define DRIVER_STATE_PRINT_GENERIC(x, fmt, args...) \ 465 (res += scnprintf(buf + res, DRIVER_STATE_BUF_LEN - res,\ 466 #x " = " fmt "\n", args)) 467 468 #define DRIVER_STATE_PRINT_LONG(x) DRIVER_STATE_PRINT(x, "%ld") 469 #define DRIVER_STATE_PRINT_INT(x) DRIVER_STATE_PRINT(x, "%d") 470 #define DRIVER_STATE_PRINT_STR(x) DRIVER_STATE_PRINT(x, "%s") 471 #define DRIVER_STATE_PRINT_LHEX(x) DRIVER_STATE_PRINT(x, "0x%lx") 472 #define DRIVER_STATE_PRINT_HEX(x) DRIVER_STATE_PRINT(x, "0x%x") 473 474 wl12xx_for_each_wlvif_sta(wl, wlvif) { 475 if (!test_bit(WLVIF_FLAG_STA_ASSOCIATED, &wlvif->flags)) 476 continue; 477 478 DRIVER_STATE_PRINT_GENERIC(channel, "%d (%s)", wlvif->channel, 479 wlvif->p2p ? "P2P-CL" : "STA"); 480 } 481 482 wl12xx_for_each_wlvif_ap(wl, wlvif) 483 DRIVER_STATE_PRINT_GENERIC(channel, "%d (%s)", wlvif->channel, 484 wlvif->p2p ? "P2P-GO" : "AP"); 485 486 DRIVER_STATE_PRINT_INT(tx_blocks_available); 487 DRIVER_STATE_PRINT_INT(tx_allocated_blocks); 488 DRIVER_STATE_PRINT_INT(tx_allocated_pkts[0]); 489 DRIVER_STATE_PRINT_INT(tx_allocated_pkts[1]); 490 DRIVER_STATE_PRINT_INT(tx_allocated_pkts[2]); 491 DRIVER_STATE_PRINT_INT(tx_allocated_pkts[3]); 492 DRIVER_STATE_PRINT_INT(tx_frames_cnt); 493 DRIVER_STATE_PRINT_LHEX(tx_frames_map[0]); 494 DRIVER_STATE_PRINT_INT(tx_queue_count[0]); 495 DRIVER_STATE_PRINT_INT(tx_queue_count[1]); 496 DRIVER_STATE_PRINT_INT(tx_queue_count[2]); 497 DRIVER_STATE_PRINT_INT(tx_queue_count[3]); 498 DRIVER_STATE_PRINT_INT(tx_packets_count); 499 DRIVER_STATE_PRINT_INT(tx_results_count); 500 DRIVER_STATE_PRINT_LHEX(flags); 501 DRIVER_STATE_PRINT_INT(tx_blocks_freed); 502 DRIVER_STATE_PRINT_INT(rx_counter); 503 DRIVER_STATE_PRINT_INT(state); 504 DRIVER_STATE_PRINT_INT(band); 505 DRIVER_STATE_PRINT_INT(power_level); 506 DRIVER_STATE_PRINT_INT(sg_enabled); 507 DRIVER_STATE_PRINT_INT(enable_11a); 508 DRIVER_STATE_PRINT_INT(noise); 509 DRIVER_STATE_PRINT_LHEX(ap_fw_ps_map); 510 DRIVER_STATE_PRINT_LHEX(ap_ps_map); 511 DRIVER_STATE_PRINT_HEX(quirks); 512 DRIVER_STATE_PRINT_HEX(irq); 513 /* TODO: ref_clock and tcxo_clock were moved to wl12xx priv */ 514 DRIVER_STATE_PRINT_HEX(hw_pg_ver); 515 DRIVER_STATE_PRINT_HEX(irq_flags); 516 DRIVER_STATE_PRINT_HEX(chip.id); 517 DRIVER_STATE_PRINT_STR(chip.fw_ver_str); 518 DRIVER_STATE_PRINT_STR(chip.phy_fw_ver_str); 519 DRIVER_STATE_PRINT_INT(recovery_count); 520 521 #undef DRIVER_STATE_PRINT_INT 522 #undef DRIVER_STATE_PRINT_LONG 523 #undef DRIVER_STATE_PRINT_HEX 524 #undef DRIVER_STATE_PRINT_LHEX 525 #undef DRIVER_STATE_PRINT_STR 526 #undef DRIVER_STATE_PRINT 527 #undef DRIVER_STATE_BUF_LEN 528 529 mutex_unlock(&wl->mutex); 530 531 ret = simple_read_from_buffer(user_buf, count, ppos, buf, res); 532 kfree(buf); 533 return ret; 534 } 535 536 static const struct file_operations driver_state_ops = { 537 .read = driver_state_read, 538 .open = simple_open, 539 .llseek = default_llseek, 540 }; 541 542 static ssize_t vifs_state_read(struct file *file, char __user *user_buf, 543 size_t count, loff_t *ppos) 544 { 545 struct wl1271 *wl = file->private_data; 546 struct wl12xx_vif *wlvif; 547 int ret, res = 0; 548 const int buf_size = 4096; 549 char *buf; 550 char tmp_buf[64]; 551 552 buf = kzalloc(buf_size, GFP_KERNEL); 553 if (!buf) 554 return -ENOMEM; 555 556 mutex_lock(&wl->mutex); 557 558 #define VIF_STATE_PRINT(x, fmt) \ 559 (res += scnprintf(buf + res, buf_size - res, \ 560 #x " = " fmt "\n", wlvif->x)) 561 562 #define VIF_STATE_PRINT_LONG(x) VIF_STATE_PRINT(x, "%ld") 563 #define VIF_STATE_PRINT_INT(x) VIF_STATE_PRINT(x, "%d") 564 #define VIF_STATE_PRINT_STR(x) VIF_STATE_PRINT(x, "%s") 565 #define VIF_STATE_PRINT_LHEX(x) VIF_STATE_PRINT(x, "0x%lx") 566 #define VIF_STATE_PRINT_LLHEX(x) VIF_STATE_PRINT(x, "0x%llx") 567 #define VIF_STATE_PRINT_HEX(x) VIF_STATE_PRINT(x, "0x%x") 568 569 #define VIF_STATE_PRINT_NSTR(x, len) \ 570 do { \ 571 memset(tmp_buf, 0, sizeof(tmp_buf)); \ 572 memcpy(tmp_buf, wlvif->x, \ 573 min_t(u8, len, sizeof(tmp_buf) - 1)); \ 574 res += scnprintf(buf + res, buf_size - res, \ 575 #x " = %s\n", tmp_buf); \ 576 } while (0) 577 578 wl12xx_for_each_wlvif(wl, wlvif) { 579 VIF_STATE_PRINT_INT(role_id); 580 VIF_STATE_PRINT_INT(bss_type); 581 VIF_STATE_PRINT_LHEX(flags); 582 VIF_STATE_PRINT_INT(p2p); 583 VIF_STATE_PRINT_INT(dev_role_id); 584 VIF_STATE_PRINT_INT(dev_hlid); 585 586 if (wlvif->bss_type == BSS_TYPE_STA_BSS || 587 wlvif->bss_type == BSS_TYPE_IBSS) { 588 VIF_STATE_PRINT_INT(sta.hlid); 589 VIF_STATE_PRINT_INT(sta.basic_rate_idx); 590 VIF_STATE_PRINT_INT(sta.ap_rate_idx); 591 VIF_STATE_PRINT_INT(sta.p2p_rate_idx); 592 VIF_STATE_PRINT_INT(sta.qos); 593 } else { 594 VIF_STATE_PRINT_INT(ap.global_hlid); 595 VIF_STATE_PRINT_INT(ap.bcast_hlid); 596 VIF_STATE_PRINT_LHEX(ap.sta_hlid_map[0]); 597 VIF_STATE_PRINT_INT(ap.mgmt_rate_idx); 598 VIF_STATE_PRINT_INT(ap.bcast_rate_idx); 599 VIF_STATE_PRINT_INT(ap.ucast_rate_idx[0]); 600 VIF_STATE_PRINT_INT(ap.ucast_rate_idx[1]); 601 VIF_STATE_PRINT_INT(ap.ucast_rate_idx[2]); 602 VIF_STATE_PRINT_INT(ap.ucast_rate_idx[3]); 603 } 604 VIF_STATE_PRINT_INT(last_tx_hlid); 605 VIF_STATE_PRINT_INT(tx_queue_count[0]); 606 VIF_STATE_PRINT_INT(tx_queue_count[1]); 607 VIF_STATE_PRINT_INT(tx_queue_count[2]); 608 VIF_STATE_PRINT_INT(tx_queue_count[3]); 609 VIF_STATE_PRINT_LHEX(links_map[0]); 610 VIF_STATE_PRINT_NSTR(ssid, wlvif->ssid_len); 611 VIF_STATE_PRINT_INT(band); 612 VIF_STATE_PRINT_INT(channel); 613 VIF_STATE_PRINT_HEX(bitrate_masks[0]); 614 VIF_STATE_PRINT_HEX(bitrate_masks[1]); 615 VIF_STATE_PRINT_HEX(basic_rate_set); 616 VIF_STATE_PRINT_HEX(basic_rate); 617 VIF_STATE_PRINT_HEX(rate_set); 618 VIF_STATE_PRINT_INT(beacon_int); 619 VIF_STATE_PRINT_INT(default_key); 620 VIF_STATE_PRINT_INT(aid); 621 VIF_STATE_PRINT_INT(psm_entry_retry); 622 VIF_STATE_PRINT_INT(power_level); 623 VIF_STATE_PRINT_INT(rssi_thold); 624 VIF_STATE_PRINT_INT(last_rssi_event); 625 VIF_STATE_PRINT_INT(ba_support); 626 VIF_STATE_PRINT_INT(ba_allowed); 627 VIF_STATE_PRINT_LLHEX(total_freed_pkts); 628 } 629 630 #undef VIF_STATE_PRINT_INT 631 #undef VIF_STATE_PRINT_LONG 632 #undef VIF_STATE_PRINT_HEX 633 #undef VIF_STATE_PRINT_LHEX 634 #undef VIF_STATE_PRINT_LLHEX 635 #undef VIF_STATE_PRINT_STR 636 #undef VIF_STATE_PRINT_NSTR 637 #undef VIF_STATE_PRINT 638 639 mutex_unlock(&wl->mutex); 640 641 ret = simple_read_from_buffer(user_buf, count, ppos, buf, res); 642 kfree(buf); 643 return ret; 644 } 645 646 static const struct file_operations vifs_state_ops = { 647 .read = vifs_state_read, 648 .open = simple_open, 649 .llseek = default_llseek, 650 }; 651 652 static ssize_t dtim_interval_read(struct file *file, char __user *user_buf, 653 size_t count, loff_t *ppos) 654 { 655 struct wl1271 *wl = file->private_data; 656 u8 value; 657 658 if (wl->conf.conn.wake_up_event == CONF_WAKE_UP_EVENT_DTIM || 659 wl->conf.conn.wake_up_event == CONF_WAKE_UP_EVENT_N_DTIM) 660 value = wl->conf.conn.listen_interval; 661 else 662 value = 0; 663 664 return wl1271_format_buffer(user_buf, count, ppos, "%d\n", value); 665 } 666 667 static ssize_t dtim_interval_write(struct file *file, 668 const char __user *user_buf, 669 size_t count, loff_t *ppos) 670 { 671 struct wl1271 *wl = file->private_data; 672 unsigned long value; 673 int ret; 674 675 ret = kstrtoul_from_user(user_buf, count, 10, &value); 676 if (ret < 0) { 677 wl1271_warning("illegal value for dtim_interval"); 678 return -EINVAL; 679 } 680 681 if (value < 1 || value > 10) { 682 wl1271_warning("dtim value is not in valid range"); 683 return -ERANGE; 684 } 685 686 mutex_lock(&wl->mutex); 687 688 wl->conf.conn.listen_interval = value; 689 /* for some reason there are different event types for 1 and >1 */ 690 if (value == 1) 691 wl->conf.conn.wake_up_event = CONF_WAKE_UP_EVENT_DTIM; 692 else 693 wl->conf.conn.wake_up_event = CONF_WAKE_UP_EVENT_N_DTIM; 694 695 /* 696 * we don't reconfigure ACX_WAKE_UP_CONDITIONS now, so it will only 697 * take effect on the next time we enter psm. 698 */ 699 mutex_unlock(&wl->mutex); 700 return count; 701 } 702 703 static const struct file_operations dtim_interval_ops = { 704 .read = dtim_interval_read, 705 .write = dtim_interval_write, 706 .open = simple_open, 707 .llseek = default_llseek, 708 }; 709 710 711 712 static ssize_t suspend_dtim_interval_read(struct file *file, 713 char __user *user_buf, 714 size_t count, loff_t *ppos) 715 { 716 struct wl1271 *wl = file->private_data; 717 u8 value; 718 719 if (wl->conf.conn.suspend_wake_up_event == CONF_WAKE_UP_EVENT_DTIM || 720 wl->conf.conn.suspend_wake_up_event == CONF_WAKE_UP_EVENT_N_DTIM) 721 value = wl->conf.conn.suspend_listen_interval; 722 else 723 value = 0; 724 725 return wl1271_format_buffer(user_buf, count, ppos, "%d\n", value); 726 } 727 728 static ssize_t suspend_dtim_interval_write(struct file *file, 729 const char __user *user_buf, 730 size_t count, loff_t *ppos) 731 { 732 struct wl1271 *wl = file->private_data; 733 unsigned long value; 734 int ret; 735 736 ret = kstrtoul_from_user(user_buf, count, 10, &value); 737 if (ret < 0) { 738 wl1271_warning("illegal value for suspend_dtim_interval"); 739 return -EINVAL; 740 } 741 742 if (value < 1 || value > 10) { 743 wl1271_warning("suspend_dtim value is not in valid range"); 744 return -ERANGE; 745 } 746 747 mutex_lock(&wl->mutex); 748 749 wl->conf.conn.suspend_listen_interval = value; 750 /* for some reason there are different event types for 1 and >1 */ 751 if (value == 1) 752 wl->conf.conn.suspend_wake_up_event = CONF_WAKE_UP_EVENT_DTIM; 753 else 754 wl->conf.conn.suspend_wake_up_event = CONF_WAKE_UP_EVENT_N_DTIM; 755 756 mutex_unlock(&wl->mutex); 757 return count; 758 } 759 760 761 static const struct file_operations suspend_dtim_interval_ops = { 762 .read = suspend_dtim_interval_read, 763 .write = suspend_dtim_interval_write, 764 .open = simple_open, 765 .llseek = default_llseek, 766 }; 767 768 static ssize_t beacon_interval_read(struct file *file, char __user *user_buf, 769 size_t count, loff_t *ppos) 770 { 771 struct wl1271 *wl = file->private_data; 772 u8 value; 773 774 if (wl->conf.conn.wake_up_event == CONF_WAKE_UP_EVENT_BEACON || 775 wl->conf.conn.wake_up_event == CONF_WAKE_UP_EVENT_N_BEACONS) 776 value = wl->conf.conn.listen_interval; 777 else 778 value = 0; 779 780 return wl1271_format_buffer(user_buf, count, ppos, "%d\n", value); 781 } 782 783 static ssize_t beacon_interval_write(struct file *file, 784 const char __user *user_buf, 785 size_t count, loff_t *ppos) 786 { 787 struct wl1271 *wl = file->private_data; 788 unsigned long value; 789 int ret; 790 791 ret = kstrtoul_from_user(user_buf, count, 10, &value); 792 if (ret < 0) { 793 wl1271_warning("illegal value for beacon_interval"); 794 return -EINVAL; 795 } 796 797 if (value < 1 || value > 255) { 798 wl1271_warning("beacon interval value is not in valid range"); 799 return -ERANGE; 800 } 801 802 mutex_lock(&wl->mutex); 803 804 wl->conf.conn.listen_interval = value; 805 /* for some reason there are different event types for 1 and >1 */ 806 if (value == 1) 807 wl->conf.conn.wake_up_event = CONF_WAKE_UP_EVENT_BEACON; 808 else 809 wl->conf.conn.wake_up_event = CONF_WAKE_UP_EVENT_N_BEACONS; 810 811 /* 812 * we don't reconfigure ACX_WAKE_UP_CONDITIONS now, so it will only 813 * take effect on the next time we enter psm. 814 */ 815 mutex_unlock(&wl->mutex); 816 return count; 817 } 818 819 static const struct file_operations beacon_interval_ops = { 820 .read = beacon_interval_read, 821 .write = beacon_interval_write, 822 .open = simple_open, 823 .llseek = default_llseek, 824 }; 825 826 static ssize_t rx_streaming_interval_write(struct file *file, 827 const char __user *user_buf, 828 size_t count, loff_t *ppos) 829 { 830 struct wl1271 *wl = file->private_data; 831 struct wl12xx_vif *wlvif; 832 unsigned long value; 833 int ret; 834 835 ret = kstrtoul_from_user(user_buf, count, 10, &value); 836 if (ret < 0) { 837 wl1271_warning("illegal value in rx_streaming_interval!"); 838 return -EINVAL; 839 } 840 841 /* valid values: 0, 10-100 */ 842 if (value && (value < 10 || value > 100)) { 843 wl1271_warning("value is not in range!"); 844 return -ERANGE; 845 } 846 847 mutex_lock(&wl->mutex); 848 849 wl->conf.rx_streaming.interval = value; 850 851 ret = pm_runtime_get_sync(wl->dev); 852 if (ret < 0) { 853 pm_runtime_put_noidle(wl->dev); 854 goto out; 855 } 856 857 wl12xx_for_each_wlvif_sta(wl, wlvif) { 858 wl1271_recalc_rx_streaming(wl, wlvif); 859 } 860 861 pm_runtime_put(wl->dev); 862 out: 863 mutex_unlock(&wl->mutex); 864 return count; 865 } 866 867 static ssize_t rx_streaming_interval_read(struct file *file, 868 char __user *userbuf, 869 size_t count, loff_t *ppos) 870 { 871 struct wl1271 *wl = file->private_data; 872 return wl1271_format_buffer(userbuf, count, ppos, 873 "%d\n", wl->conf.rx_streaming.interval); 874 } 875 876 static const struct file_operations rx_streaming_interval_ops = { 877 .read = rx_streaming_interval_read, 878 .write = rx_streaming_interval_write, 879 .open = simple_open, 880 .llseek = default_llseek, 881 }; 882 883 static ssize_t rx_streaming_always_write(struct file *file, 884 const char __user *user_buf, 885 size_t count, loff_t *ppos) 886 { 887 struct wl1271 *wl = file->private_data; 888 struct wl12xx_vif *wlvif; 889 unsigned long value; 890 int ret; 891 892 ret = kstrtoul_from_user(user_buf, count, 10, &value); 893 if (ret < 0) { 894 wl1271_warning("illegal value in rx_streaming_write!"); 895 return -EINVAL; 896 } 897 898 /* valid values: 0, 10-100 */ 899 if (!(value == 0 || value == 1)) { 900 wl1271_warning("value is not in valid!"); 901 return -EINVAL; 902 } 903 904 mutex_lock(&wl->mutex); 905 906 wl->conf.rx_streaming.always = value; 907 908 ret = pm_runtime_get_sync(wl->dev); 909 if (ret < 0) { 910 pm_runtime_put_noidle(wl->dev); 911 goto out; 912 } 913 914 wl12xx_for_each_wlvif_sta(wl, wlvif) { 915 wl1271_recalc_rx_streaming(wl, wlvif); 916 } 917 918 pm_runtime_put(wl->dev); 919 out: 920 mutex_unlock(&wl->mutex); 921 return count; 922 } 923 924 static ssize_t rx_streaming_always_read(struct file *file, 925 char __user *userbuf, 926 size_t count, loff_t *ppos) 927 { 928 struct wl1271 *wl = file->private_data; 929 return wl1271_format_buffer(userbuf, count, ppos, 930 "%d\n", wl->conf.rx_streaming.always); 931 } 932 933 static const struct file_operations rx_streaming_always_ops = { 934 .read = rx_streaming_always_read, 935 .write = rx_streaming_always_write, 936 .open = simple_open, 937 .llseek = default_llseek, 938 }; 939 940 static ssize_t beacon_filtering_write(struct file *file, 941 const char __user *user_buf, 942 size_t count, loff_t *ppos) 943 { 944 struct wl1271 *wl = file->private_data; 945 struct wl12xx_vif *wlvif; 946 unsigned long value; 947 int ret; 948 949 ret = kstrtoul_from_user(user_buf, count, 0, &value); 950 if (ret < 0) { 951 wl1271_warning("illegal value for beacon_filtering!"); 952 return -EINVAL; 953 } 954 955 mutex_lock(&wl->mutex); 956 957 ret = pm_runtime_get_sync(wl->dev); 958 if (ret < 0) { 959 pm_runtime_put_noidle(wl->dev); 960 goto out; 961 } 962 963 wl12xx_for_each_wlvif(wl, wlvif) { 964 ret = wl1271_acx_beacon_filter_opt(wl, wlvif, !!value); 965 } 966 967 pm_runtime_put(wl->dev); 968 out: 969 mutex_unlock(&wl->mutex); 970 return count; 971 } 972 973 static const struct file_operations beacon_filtering_ops = { 974 .write = beacon_filtering_write, 975 .open = simple_open, 976 .llseek = default_llseek, 977 }; 978 979 static ssize_t fw_stats_raw_read(struct file *file, 980 char __user *userbuf, 981 size_t count, loff_t *ppos) 982 { 983 struct wl1271 *wl = file->private_data; 984 985 wl1271_debugfs_update_stats(wl); 986 987 return simple_read_from_buffer(userbuf, count, ppos, 988 wl->stats.fw_stats, 989 wl->stats.fw_stats_len); 990 } 991 992 static const struct file_operations fw_stats_raw_ops = { 993 .read = fw_stats_raw_read, 994 .open = simple_open, 995 .llseek = default_llseek, 996 }; 997 998 static ssize_t sleep_auth_read(struct file *file, char __user *user_buf, 999 size_t count, loff_t *ppos) 1000 { 1001 struct wl1271 *wl = file->private_data; 1002 1003 return wl1271_format_buffer(user_buf, count, 1004 ppos, "%d\n", 1005 wl->sleep_auth); 1006 } 1007 1008 static ssize_t sleep_auth_write(struct file *file, 1009 const char __user *user_buf, 1010 size_t count, loff_t *ppos) 1011 { 1012 struct wl1271 *wl = file->private_data; 1013 unsigned long value; 1014 int ret; 1015 1016 ret = kstrtoul_from_user(user_buf, count, 0, &value); 1017 if (ret < 0) { 1018 wl1271_warning("illegal value in sleep_auth"); 1019 return -EINVAL; 1020 } 1021 1022 if (value > WL1271_PSM_MAX) { 1023 wl1271_warning("sleep_auth must be between 0 and %d", 1024 WL1271_PSM_MAX); 1025 return -ERANGE; 1026 } 1027 1028 mutex_lock(&wl->mutex); 1029 1030 wl->conf.conn.sta_sleep_auth = value; 1031 1032 if (unlikely(wl->state != WLCORE_STATE_ON)) { 1033 /* this will show up on "read" in case we are off */ 1034 wl->sleep_auth = value; 1035 goto out; 1036 } 1037 1038 ret = pm_runtime_get_sync(wl->dev); 1039 if (ret < 0) { 1040 pm_runtime_put_noidle(wl->dev); 1041 goto out; 1042 } 1043 1044 ret = wl1271_acx_sleep_auth(wl, value); 1045 if (ret < 0) 1046 goto out_sleep; 1047 1048 out_sleep: 1049 pm_runtime_put(wl->dev); 1050 out: 1051 mutex_unlock(&wl->mutex); 1052 return count; 1053 } 1054 1055 static const struct file_operations sleep_auth_ops = { 1056 .read = sleep_auth_read, 1057 .write = sleep_auth_write, 1058 .open = simple_open, 1059 .llseek = default_llseek, 1060 }; 1061 1062 static ssize_t dev_mem_read(struct file *file, 1063 char __user *user_buf, size_t count, 1064 loff_t *ppos) 1065 { 1066 struct wl1271 *wl = file->private_data; 1067 struct wlcore_partition_set part, old_part; 1068 size_t bytes = count; 1069 int ret; 1070 char *buf; 1071 1072 /* only requests of dword-aligned size and offset are supported */ 1073 if (bytes % 4) 1074 return -EINVAL; 1075 1076 if (*ppos % 4) 1077 return -EINVAL; 1078 1079 /* function should return in reasonable time */ 1080 bytes = min(bytes, WLCORE_MAX_BLOCK_SIZE); 1081 1082 if (bytes == 0) 1083 return -EINVAL; 1084 1085 memset(&part, 0, sizeof(part)); 1086 part.mem.start = *ppos; 1087 part.mem.size = bytes; 1088 1089 buf = kmalloc(bytes, GFP_KERNEL); 1090 if (!buf) 1091 return -ENOMEM; 1092 1093 mutex_lock(&wl->mutex); 1094 1095 if (unlikely(wl->state == WLCORE_STATE_OFF)) { 1096 ret = -EFAULT; 1097 goto skip_read; 1098 } 1099 1100 /* 1101 * Don't fail if elp_wakeup returns an error, so the device's memory 1102 * could be read even if the FW crashed 1103 */ 1104 pm_runtime_get_sync(wl->dev); 1105 1106 /* store current partition and switch partition */ 1107 memcpy(&old_part, &wl->curr_part, sizeof(old_part)); 1108 ret = wlcore_set_partition(wl, &part); 1109 if (ret < 0) 1110 goto part_err; 1111 1112 ret = wlcore_raw_read(wl, 0, buf, bytes, false); 1113 if (ret < 0) 1114 goto read_err; 1115 1116 read_err: 1117 /* recover partition */ 1118 ret = wlcore_set_partition(wl, &old_part); 1119 if (ret < 0) 1120 goto part_err; 1121 1122 part_err: 1123 pm_runtime_put(wl->dev); 1124 1125 skip_read: 1126 mutex_unlock(&wl->mutex); 1127 1128 if (ret == 0) { 1129 ret = copy_to_user(user_buf, buf, bytes); 1130 if (ret < bytes) { 1131 bytes -= ret; 1132 *ppos += bytes; 1133 ret = 0; 1134 } else { 1135 ret = -EFAULT; 1136 } 1137 } 1138 1139 kfree(buf); 1140 1141 return ((ret == 0) ? bytes : ret); 1142 } 1143 1144 static ssize_t dev_mem_write(struct file *file, const char __user *user_buf, 1145 size_t count, loff_t *ppos) 1146 { 1147 struct wl1271 *wl = file->private_data; 1148 struct wlcore_partition_set part, old_part; 1149 size_t bytes = count; 1150 int ret; 1151 char *buf; 1152 1153 /* only requests of dword-aligned size and offset are supported */ 1154 if (bytes % 4) 1155 return -EINVAL; 1156 1157 if (*ppos % 4) 1158 return -EINVAL; 1159 1160 /* function should return in reasonable time */ 1161 bytes = min(bytes, WLCORE_MAX_BLOCK_SIZE); 1162 1163 if (bytes == 0) 1164 return -EINVAL; 1165 1166 memset(&part, 0, sizeof(part)); 1167 part.mem.start = *ppos; 1168 part.mem.size = bytes; 1169 1170 buf = memdup_user(user_buf, bytes); 1171 if (IS_ERR(buf)) 1172 return PTR_ERR(buf); 1173 1174 mutex_lock(&wl->mutex); 1175 1176 if (unlikely(wl->state == WLCORE_STATE_OFF)) { 1177 ret = -EFAULT; 1178 goto skip_write; 1179 } 1180 1181 /* 1182 * Don't fail if elp_wakeup returns an error, so the device's memory 1183 * could be read even if the FW crashed 1184 */ 1185 pm_runtime_get_sync(wl->dev); 1186 1187 /* store current partition and switch partition */ 1188 memcpy(&old_part, &wl->curr_part, sizeof(old_part)); 1189 ret = wlcore_set_partition(wl, &part); 1190 if (ret < 0) 1191 goto part_err; 1192 1193 ret = wlcore_raw_write(wl, 0, buf, bytes, false); 1194 if (ret < 0) 1195 goto write_err; 1196 1197 write_err: 1198 /* recover partition */ 1199 ret = wlcore_set_partition(wl, &old_part); 1200 if (ret < 0) 1201 goto part_err; 1202 1203 part_err: 1204 pm_runtime_put(wl->dev); 1205 1206 skip_write: 1207 mutex_unlock(&wl->mutex); 1208 1209 if (ret == 0) 1210 *ppos += bytes; 1211 1212 kfree(buf); 1213 1214 return ((ret == 0) ? bytes : ret); 1215 } 1216 1217 static loff_t dev_mem_seek(struct file *file, loff_t offset, int orig) 1218 { 1219 /* only requests of dword-aligned size and offset are supported */ 1220 if (offset % 4) 1221 return -EINVAL; 1222 1223 return no_seek_end_llseek(file, offset, orig); 1224 } 1225 1226 static const struct file_operations dev_mem_ops = { 1227 .open = simple_open, 1228 .read = dev_mem_read, 1229 .write = dev_mem_write, 1230 .llseek = dev_mem_seek, 1231 }; 1232 1233 static ssize_t fw_logger_read(struct file *file, char __user *user_buf, 1234 size_t count, loff_t *ppos) 1235 { 1236 struct wl1271 *wl = file->private_data; 1237 1238 return wl1271_format_buffer(user_buf, count, 1239 ppos, "%d\n", 1240 wl->conf.fwlog.output); 1241 } 1242 1243 static ssize_t fw_logger_write(struct file *file, 1244 const char __user *user_buf, 1245 size_t count, loff_t *ppos) 1246 { 1247 struct wl1271 *wl = file->private_data; 1248 unsigned long value; 1249 int ret; 1250 1251 ret = kstrtoul_from_user(user_buf, count, 0, &value); 1252 if (ret < 0) { 1253 wl1271_warning("illegal value in fw_logger"); 1254 return -EINVAL; 1255 } 1256 1257 if ((value > 2) || (value == 0)) { 1258 wl1271_warning("fw_logger value must be 1-UART 2-SDIO"); 1259 return -ERANGE; 1260 } 1261 1262 if (wl->conf.fwlog.output == 0) { 1263 wl1271_warning("invalid operation - fw logger disabled by default, please change mode via wlconf"); 1264 return -EINVAL; 1265 } 1266 1267 mutex_lock(&wl->mutex); 1268 ret = pm_runtime_get_sync(wl->dev); 1269 if (ret < 0) { 1270 pm_runtime_put_noidle(wl->dev); 1271 count = ret; 1272 goto out; 1273 } 1274 1275 wl->conf.fwlog.output = value; 1276 1277 ret = wl12xx_cmd_config_fwlog(wl); 1278 1279 pm_runtime_put(wl->dev); 1280 1281 out: 1282 mutex_unlock(&wl->mutex); 1283 return count; 1284 } 1285 1286 static const struct file_operations fw_logger_ops = { 1287 .open = simple_open, 1288 .read = fw_logger_read, 1289 .write = fw_logger_write, 1290 .llseek = default_llseek, 1291 }; 1292 1293 static int wl1271_debugfs_add_files(struct wl1271 *wl, 1294 struct dentry *rootdir) 1295 { 1296 int ret = 0; 1297 struct dentry *entry, *streaming; 1298 1299 DEBUGFS_ADD(tx_queue_len, rootdir); 1300 DEBUGFS_ADD(retry_count, rootdir); 1301 DEBUGFS_ADD(excessive_retries, rootdir); 1302 1303 DEBUGFS_ADD(gpio_power, rootdir); 1304 DEBUGFS_ADD(start_recovery, rootdir); 1305 DEBUGFS_ADD(driver_state, rootdir); 1306 DEBUGFS_ADD(vifs_state, rootdir); 1307 DEBUGFS_ADD(dtim_interval, rootdir); 1308 DEBUGFS_ADD(suspend_dtim_interval, rootdir); 1309 DEBUGFS_ADD(beacon_interval, rootdir); 1310 DEBUGFS_ADD(beacon_filtering, rootdir); 1311 DEBUGFS_ADD(dynamic_ps_timeout, rootdir); 1312 DEBUGFS_ADD(forced_ps, rootdir); 1313 DEBUGFS_ADD(split_scan_timeout, rootdir); 1314 DEBUGFS_ADD(irq_pkt_threshold, rootdir); 1315 DEBUGFS_ADD(irq_blk_threshold, rootdir); 1316 DEBUGFS_ADD(irq_timeout, rootdir); 1317 DEBUGFS_ADD(fw_stats_raw, rootdir); 1318 DEBUGFS_ADD(sleep_auth, rootdir); 1319 DEBUGFS_ADD(fw_logger, rootdir); 1320 1321 streaming = debugfs_create_dir("rx_streaming", rootdir); 1322 if (!streaming || IS_ERR(streaming)) 1323 goto err; 1324 1325 DEBUGFS_ADD_PREFIX(rx_streaming, interval, streaming); 1326 DEBUGFS_ADD_PREFIX(rx_streaming, always, streaming); 1327 1328 DEBUGFS_ADD_PREFIX(dev, mem, rootdir); 1329 1330 return 0; 1331 1332 err: 1333 if (IS_ERR(entry)) 1334 ret = PTR_ERR(entry); 1335 else 1336 ret = -ENOMEM; 1337 1338 return ret; 1339 } 1340 1341 void wl1271_debugfs_reset(struct wl1271 *wl) 1342 { 1343 if (!wl->stats.fw_stats) 1344 return; 1345 1346 memset(wl->stats.fw_stats, 0, wl->stats.fw_stats_len); 1347 wl->stats.retry_count = 0; 1348 wl->stats.excessive_retries = 0; 1349 } 1350 1351 int wl1271_debugfs_init(struct wl1271 *wl) 1352 { 1353 int ret; 1354 struct dentry *rootdir; 1355 1356 rootdir = debugfs_create_dir(KBUILD_MODNAME, 1357 wl->hw->wiphy->debugfsdir); 1358 1359 if (IS_ERR(rootdir)) { 1360 ret = PTR_ERR(rootdir); 1361 goto out; 1362 } 1363 1364 wl->stats.fw_stats = kzalloc(wl->stats.fw_stats_len, GFP_KERNEL); 1365 if (!wl->stats.fw_stats) { 1366 ret = -ENOMEM; 1367 goto out_remove; 1368 } 1369 1370 wl->stats.fw_stats_update = jiffies; 1371 1372 ret = wl1271_debugfs_add_files(wl, rootdir); 1373 if (ret < 0) 1374 goto out_exit; 1375 1376 ret = wlcore_debugfs_init(wl, rootdir); 1377 if (ret < 0) 1378 goto out_exit; 1379 1380 goto out; 1381 1382 out_exit: 1383 wl1271_debugfs_exit(wl); 1384 1385 out_remove: 1386 debugfs_remove_recursive(rootdir); 1387 1388 out: 1389 return ret; 1390 } 1391 1392 void wl1271_debugfs_exit(struct wl1271 *wl) 1393 { 1394 kfree(wl->stats.fw_stats); 1395 wl->stats.fw_stats = NULL; 1396 } 1397