0d53d5c0370567a21c711d3432c1a863fac7f5ea
[openwrt.git] / package / mac80211 / patches / 440-ath5k_channel_bw_debugfs.patch
1 This adds a bwmode debugfs file which can be used to set alternate
2 channel operating bandwidths.  Only tested with AR5413 and only at
3 5 and 20 mhz channels.
4
5 Signed-off-by: Pat Erley <pat-lkml at erley.org>
6 ---
7 Other devices will need to be added to the switch in  write_file_bwmode
8
9 drivers/net/wireless/ath/ath5k/debug.c |   86 ++++++++++++++++++++++++++++++++
10  1 files changed, 86 insertions(+), 0 deletions(-)
11
12 diff --git a/drivers/net/wireless/ath/ath5k/debug.c b/drivers/net/wireless/ath/ath5k/debug.c
13 index 8c5ce8b..bb41066 100644
14 --- a/drivers/net/wireless/ath/ath5k/debug.c
15 +++ b/drivers/net/wireless/ath/ath5k/debug.c
16 @@ -815,6 +815,89 @@ static const struct file_operations fops_ani = {
17         .llseek = default_llseek,
18  };
19  
20 +/* debugfs: bwmode */
21 +
22 +static ssize_t read_file_bwmode(struct file *file, char __user *user_buf,
23 +                                  size_t count, loff_t *ppos)
24 +{
25 +       struct ath5k_hw *ah = file->private_data;
26 +       char buf[15];
27 +       unsigned int len = 0;
28 +
29 +       int cur_ah_bwmode = ah->ah_bwmode;
30 +
31 +#define print_selected(MODE, LABEL) \
32 +       if (cur_ah_bwmode == MODE) \
33 +               len += snprintf(buf+len, sizeof(buf)-len, "[%s]", LABEL); \
34 +       else \
35 +               len += snprintf(buf+len, sizeof(buf)-len, "%s", LABEL); \
36 +       len += snprintf(buf+len, sizeof(buf)-len, " ");
37 +
38 +       print_selected(AR5K_BWMODE_5MHZ, "5");
39 +       print_selected(AR5K_BWMODE_10MHZ, "10");
40 +       print_selected(AR5K_BWMODE_DEFAULT, "20");
41 +       print_selected(AR5K_BWMODE_40MHZ, "40");
42 +#undef print_selected
43 +
44 +       len += snprintf(buf+len, sizeof(buf)-len, "\n");
45 +
46 +       return simple_read_from_buffer(user_buf, count, ppos, buf, len);
47 +}
48 +
49 +static ssize_t write_file_bwmode(struct file *file,
50 +                                const char __user *userbuf,
51 +                                size_t count, loff_t *ppos)
52 +{
53 +       struct ath5k_hw *ah = file->private_data;
54 +       char buf[3];
55 +       int bw = 20;
56 +       int tobwmode = AR5K_BWMODE_DEFAULT;
57 +
58 +       if (copy_from_user(buf, userbuf, min(count, sizeof(buf))))
59 +               return -EFAULT;
60 +
61 +       /* TODO: Add check for active interface */
62 +
63 +       if(strncmp(buf, "5", 1) == 0 ) {
64 +               tobwmode = AR5K_BWMODE_5MHZ;
65 +               bw = 5;
66 +       } else if ( strncmp(buf, "10", 2) == 0 ) {
67 +               tobwmode = AR5K_BWMODE_10MHZ;
68 +               bw = 10;
69 +       } else if ( strncmp(buf, "20", 2) == 0 ) {
70 +               tobwmode = AR5K_BWMODE_DEFAULT;
71 +               bw = 20;
72 +       } else if ( strncmp(buf, "40", 2) == 0 ) {
73 +               tobwmode = AR5K_BWMODE_40MHZ;
74 +               bw = 40;
75 +       } else
76 +               return -EINVAL;
77 +
78 +       ATH5K_INFO(ah, "Changing to %imhz channel width[%i]\n",
79 +               bw, tobwmode);
80 +
81 +       switch (ah->ah_radio) {
82 +               /* TODO: only define radios that actually support 5/10mhz channels */
83 +               case AR5K_RF5413: case AR5K_RF5110: case AR5K_RF5111: case AR5K_RF5112: case AR5K_RF2413: case AR5K_RF2316: case AR5K_RF2317: case AR5K_RF2425:
84 +                       if(ah->ah_bwmode != tobwmode) {
85 +                               mutex_lock(&ah->lock);
86 +                               ah->ah_bwmode = tobwmode;
87 +                               mutex_unlock(&ah->lock);
88 +                       }
89 +                       break;
90 +               default:
91 +                       return -EOPNOTSUPP;
92 +       }
93 +       return count;
94 +}
95 +
96 +static const struct file_operations fops_bwmode = {
97 +       .read = read_file_bwmode,
98 +       .write = write_file_bwmode,
99 +       .open = simple_open,
100 +       .owner = THIS_MODULE,
101 +       .llseek = default_llseek,
102 +};
103  
104  /* debugfs: queues etc */
105  
106 @@ -906,6 +989,9 @@ ath5k_debug_init_device(struct ath5k_hw *ah)
107         debugfs_create_file("beacon", S_IWUSR | S_IRUSR, phydir, ah,
108                             &fops_beacon);
109  
110 +       debugfs_create_file("bwmode", S_IWUSR | S_IRUSR, phydir, ah,
111 +                           &fops_bwmode);
112 +
113         debugfs_create_file("reset", S_IWUSR, phydir, ah, &fops_reset);
114  
115         debugfs_create_file("antenna", S_IWUSR | S_IRUSR, phydir, ah,
116 --