aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
authorEliad Peller <eliad@wizery.com>2011-05-15 04:10:30 -0400
committerLuciano Coelho <coelho@ti.com>2011-06-27 03:15:50 -0400
commitc84368e01a00f449d97e8a59e1b0c24dcf70a8b3 (patch)
tree94e76522214288a5ca6f932e53740ee5bda6a343 /drivers/net
parent77ddaa108f727b5ef3be004b952d2c3d3ffc48e5 (diff)
wl12xx: add rx_streaming debugfs entry
Allow control over rx_streaming interval and operation mode (always/only on coex) via debugfs. e.g. echo 100 > /debug/ieee80211/phy0/wl12xx/rx_streaming/interval echo 1 > /debug/ieee80211/phy0/wl12xx/rx_streaming/always Signed-off-by: Eliad Peller <eliad@wizery.com> Signed-off-by: Luciano Coelho <coelho@ti.com>
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/wireless/wl12xx/debugfs.c136
1 files changed, 135 insertions, 1 deletions
diff --git a/drivers/net/wireless/wl12xx/debugfs.c b/drivers/net/wireless/wl12xx/debugfs.c
index f1f8df9b6cd7..c3f19463474d 100644
--- a/drivers/net/wireless/wl12xx/debugfs.c
+++ b/drivers/net/wireless/wl12xx/debugfs.c
@@ -71,6 +71,14 @@ static const struct file_operations name## _ops = { \
71 if (!entry || IS_ERR(entry)) \ 71 if (!entry || IS_ERR(entry)) \
72 goto err; \ 72 goto err; \
73 73
74#define DEBUGFS_ADD_PREFIX(prefix, name, parent) \
75 do { \
76 entry = debugfs_create_file(#name, 0400, parent, \
77 wl, &prefix## _## name## _ops); \
78 if (!entry || IS_ERR(entry)) \
79 goto err; \
80 } while (0);
81
74#define DEBUGFS_FWSTATS_FILE(sub, name, fmt) \ 82#define DEBUGFS_FWSTATS_FILE(sub, name, fmt) \
75static ssize_t sub## _ ##name## _read(struct file *file, \ 83static ssize_t sub## _ ##name## _read(struct file *file, \
76 char __user *userbuf, \ 84 char __user *userbuf, \
@@ -527,11 +535,129 @@ static const struct file_operations beacon_interval_ops = {
527 .llseek = default_llseek, 535 .llseek = default_llseek,
528}; 536};
529 537
538static ssize_t rx_streaming_interval_write(struct file *file,
539 const char __user *user_buf,
540 size_t count, loff_t *ppos)
541{
542 struct wl1271 *wl = file->private_data;
543 char buf[10];
544 size_t len;
545 unsigned long value;
546 int ret;
547
548 len = min(count, sizeof(buf) - 1);
549 if (copy_from_user(buf, user_buf, len))
550 return -EFAULT;
551 buf[len] = '\0';
552
553 ret = kstrtoul(buf, 0, &value);
554 if (ret < 0) {
555 wl1271_warning("illegal value in rx_streaming_interval!");
556 return -EINVAL;
557 }
558
559 /* valid values: 0, 10-100 */
560 if (value && (value < 10 || value > 100)) {
561 wl1271_warning("value is not in range!");
562 return -ERANGE;
563 }
564
565 mutex_lock(&wl->mutex);
566
567 wl->conf.rx_streaming.interval = value;
568
569 ret = wl1271_ps_elp_wakeup(wl);
570 if (ret < 0)
571 goto out;
572
573 wl1271_recalc_rx_streaming(wl);
574
575 wl1271_ps_elp_sleep(wl);
576out:
577 mutex_unlock(&wl->mutex);
578 return count;
579}
580
581static ssize_t rx_streaming_interval_read(struct file *file,
582 char __user *userbuf,
583 size_t count, loff_t *ppos)
584{
585 struct wl1271 *wl = file->private_data;
586 return wl1271_format_buffer(userbuf, count, ppos,
587 "%d\n", wl->conf.rx_streaming.interval);
588}
589
590static const struct file_operations rx_streaming_interval_ops = {
591 .read = rx_streaming_interval_read,
592 .write = rx_streaming_interval_write,
593 .open = wl1271_open_file_generic,
594 .llseek = default_llseek,
595};
596
597static ssize_t rx_streaming_always_write(struct file *file,
598 const char __user *user_buf,
599 size_t count, loff_t *ppos)
600{
601 struct wl1271 *wl = file->private_data;
602 char buf[10];
603 size_t len;
604 unsigned long value;
605 int ret;
606
607 len = min(count, sizeof(buf) - 1);
608 if (copy_from_user(buf, user_buf, len))
609 return -EFAULT;
610 buf[len] = '\0';
611
612 ret = kstrtoul(buf, 0, &value);
613 if (ret < 0) {
614 wl1271_warning("illegal value in rx_streaming_write!");
615 return -EINVAL;
616 }
617
618 /* valid values: 0, 10-100 */
619 if (!(value == 0 || value == 1)) {
620 wl1271_warning("value is not in valid!");
621 return -EINVAL;
622 }
623
624 mutex_lock(&wl->mutex);
625
626 wl->conf.rx_streaming.always = value;
627
628 ret = wl1271_ps_elp_wakeup(wl);
629 if (ret < 0)
630 goto out;
631
632 wl1271_recalc_rx_streaming(wl);
633
634 wl1271_ps_elp_sleep(wl);
635out:
636 mutex_unlock(&wl->mutex);
637 return count;
638}
639
640static ssize_t rx_streaming_always_read(struct file *file,
641 char __user *userbuf,
642 size_t count, loff_t *ppos)
643{
644 struct wl1271 *wl = file->private_data;
645 return wl1271_format_buffer(userbuf, count, ppos,
646 "%d\n", wl->conf.rx_streaming.always);
647}
648
649static const struct file_operations rx_streaming_always_ops = {
650 .read = rx_streaming_always_read,
651 .write = rx_streaming_always_write,
652 .open = wl1271_open_file_generic,
653 .llseek = default_llseek,
654};
655
530static int wl1271_debugfs_add_files(struct wl1271 *wl, 656static int wl1271_debugfs_add_files(struct wl1271 *wl,
531 struct dentry *rootdir) 657 struct dentry *rootdir)
532{ 658{
533 int ret = 0; 659 int ret = 0;
534 struct dentry *entry, *stats; 660 struct dentry *entry, *stats, *streaming;
535 661
536 stats = debugfs_create_dir("fw-statistics", rootdir); 662 stats = debugfs_create_dir("fw-statistics", rootdir);
537 if (!stats || IS_ERR(stats)) { 663 if (!stats || IS_ERR(stats)) {
@@ -640,6 +766,14 @@ static int wl1271_debugfs_add_files(struct wl1271 *wl,
640 DEBUGFS_ADD(dtim_interval, rootdir); 766 DEBUGFS_ADD(dtim_interval, rootdir);
641 DEBUGFS_ADD(beacon_interval, rootdir); 767 DEBUGFS_ADD(beacon_interval, rootdir);
642 768
769 streaming = debugfs_create_dir("rx_streaming", rootdir);
770 if (!streaming || IS_ERR(streaming))
771 goto err;
772
773 DEBUGFS_ADD_PREFIX(rx_streaming, interval, streaming);
774 DEBUGFS_ADD_PREFIX(rx_streaming, always, streaming);
775
776
643 return 0; 777 return 0;
644 778
645err: 779err: