root/drivers/net/wireless/ti/wlcore/debugfs.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. wl1271_format_buffer
  2. wl1271_debugfs_update_stats
  3. tx_queue_len_read
  4. chip_op_handler
  5. no_write_handler
  6. WL12XX_CONF_DEBUGFS
  7. gpio_power_write
  8. start_recovery_write
  9. dynamic_ps_timeout_read
  10. dynamic_ps_timeout_write
  11. forced_ps_read
  12. forced_ps_write
  13. split_scan_timeout_read
  14. split_scan_timeout_write
  15. driver_state_read
  16. vifs_state_read
  17. dtim_interval_read
  18. dtim_interval_write
  19. suspend_dtim_interval_read
  20. suspend_dtim_interval_write
  21. beacon_interval_read
  22. beacon_interval_write
  23. rx_streaming_interval_write
  24. rx_streaming_interval_read
  25. rx_streaming_always_write
  26. rx_streaming_always_read
  27. beacon_filtering_write
  28. fw_stats_raw_read
  29. sleep_auth_read
  30. sleep_auth_write
  31. dev_mem_read
  32. dev_mem_write
  33. dev_mem_seek
  34. fw_logger_read
  35. fw_logger_write
  36. wl1271_debugfs_add_files
  37. wl1271_debugfs_reset
  38. wl1271_debugfs_init
  39. wl1271_debugfs_exit

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

/* [<][>][^][v][top][bottom][index][help] */