690d545e6a
Signed-off-by: Felix Fietkau <nbd@openwrt.org> SVN-Revision: 47286
144 lines
3.9 KiB
Diff
144 lines
3.9 KiB
Diff
This adds a bwmode debugfs file which can be used to set alternate
|
|
channel operating bandwidths. Only tested with AR5413 and only at
|
|
5 and 20 mhz channels.
|
|
|
|
Signed-off-by: Pat Erley <pat-lkml at erley.org>
|
|
---
|
|
Other devices will need to be added to the switch in write_file_bwmode
|
|
|
|
drivers/net/wireless/ath/ath5k/debug.c | 86 ++++++++++++++++++++++++++++++++
|
|
1 files changed, 86 insertions(+), 0 deletions(-)
|
|
|
|
--- a/drivers/net/wireless/ath/ath5k/debug.c
|
|
+++ b/drivers/net/wireless/ath/ath5k/debug.c
|
|
@@ -823,6 +823,97 @@ static const struct file_operations fops
|
|
.llseek = default_llseek,
|
|
};
|
|
|
|
+/* debugfs: bwmode */
|
|
+
|
|
+static ssize_t read_file_bwmode(struct file *file, char __user *user_buf,
|
|
+ size_t count, loff_t *ppos)
|
|
+{
|
|
+ struct ath5k_hw *ah = file->private_data;
|
|
+ char buf[15];
|
|
+ unsigned int len = 0;
|
|
+
|
|
+ int cur_ah_bwmode = ah->ah_bwmode_debug;
|
|
+
|
|
+#define print_selected(MODE, LABEL) \
|
|
+ if (cur_ah_bwmode == MODE) \
|
|
+ len += snprintf(buf+len, sizeof(buf)-len, "[%s]", LABEL); \
|
|
+ else \
|
|
+ len += snprintf(buf+len, sizeof(buf)-len, "%s", LABEL); \
|
|
+ len += snprintf(buf+len, sizeof(buf)-len, " ");
|
|
+
|
|
+ print_selected(AR5K_BWMODE_5MHZ, "5");
|
|
+ print_selected(AR5K_BWMODE_10MHZ, "10");
|
|
+ print_selected(AR5K_BWMODE_DEFAULT, "20");
|
|
+ print_selected(AR5K_BWMODE_40MHZ, "40");
|
|
+#undef print_selected
|
|
+
|
|
+ len += snprintf(buf+len, sizeof(buf)-len, "\n");
|
|
+
|
|
+ return simple_read_from_buffer(user_buf, count, ppos, buf, len);
|
|
+}
|
|
+
|
|
+static ssize_t write_file_bwmode(struct file *file,
|
|
+ const char __user *userbuf,
|
|
+ size_t count, loff_t *ppos)
|
|
+{
|
|
+ struct ath5k_hw *ah = file->private_data;
|
|
+ char buf[3];
|
|
+ int bw = 20;
|
|
+ int tobwmode = AR5K_BWMODE_DEFAULT;
|
|
+
|
|
+ if (copy_from_user(buf, userbuf, min(count, sizeof(buf))))
|
|
+ return -EFAULT;
|
|
+
|
|
+ /* TODO: Add check for active interface */
|
|
+
|
|
+ if(strncmp(buf, "5", 1) == 0 ) {
|
|
+ tobwmode = AR5K_BWMODE_5MHZ;
|
|
+ bw = 5;
|
|
+ } else if ( strncmp(buf, "10", 2) == 0 ) {
|
|
+ tobwmode = AR5K_BWMODE_10MHZ;
|
|
+ bw = 10;
|
|
+ } else if ( strncmp(buf, "20", 2) == 0 ) {
|
|
+ tobwmode = AR5K_BWMODE_DEFAULT;
|
|
+ bw = 20;
|
|
+ } else if ( strncmp(buf, "40", 2) == 0 ) {
|
|
+ tobwmode = AR5K_BWMODE_40MHZ;
|
|
+ bw = 40;
|
|
+ } else
|
|
+ return -EINVAL;
|
|
+
|
|
+ ATH5K_INFO(ah, "Changing to %imhz channel width[%i]\n",
|
|
+ bw, tobwmode);
|
|
+
|
|
+ switch (ah->ah_radio) {
|
|
+ /* TODO: only define radios that actually support 5/10mhz channels */
|
|
+ case AR5K_RF5413:
|
|
+ case AR5K_RF5110:
|
|
+ case AR5K_RF5111:
|
|
+ case AR5K_RF5112:
|
|
+ case AR5K_RF2413:
|
|
+ case AR5K_RF2316:
|
|
+ case AR5K_RF2317:
|
|
+ case AR5K_RF2425:
|
|
+ if(ah->ah_bwmode_debug != tobwmode) {
|
|
+ mutex_lock(&ah->lock);
|
|
+ ah->ah_bwmode = tobwmode;
|
|
+ ah->ah_bwmode_debug = tobwmode;
|
|
+ mutex_unlock(&ah->lock);
|
|
+ }
|
|
+ break;
|
|
+ default:
|
|
+ return -EOPNOTSUPP;
|
|
+ }
|
|
+ return count;
|
|
+}
|
|
+
|
|
+static const struct file_operations fops_bwmode = {
|
|
+ .read = read_file_bwmode,
|
|
+ .write = write_file_bwmode,
|
|
+ .open = simple_open,
|
|
+ .owner = THIS_MODULE,
|
|
+ .llseek = default_llseek,
|
|
+};
|
|
|
|
/* debugfs: queues etc */
|
|
|
|
@@ -1010,6 +1101,9 @@ ath5k_debug_init_device(struct ath5k_hw
|
|
debugfs_create_file("beacon", S_IWUSR | S_IRUSR, phydir, ah,
|
|
&fops_beacon);
|
|
|
|
+ debugfs_create_file("bwmode", S_IWUSR | S_IRUSR, phydir, ah,
|
|
+ &fops_bwmode);
|
|
+
|
|
debugfs_create_file("reset", S_IWUSR, phydir, ah, &fops_reset);
|
|
|
|
debugfs_create_file("antenna", S_IWUSR | S_IRUSR, phydir, ah,
|
|
--- a/drivers/net/wireless/ath/ath5k/ath5k.h
|
|
+++ b/drivers/net/wireless/ath/ath5k/ath5k.h
|
|
@@ -1372,6 +1372,7 @@ struct ath5k_hw {
|
|
u8 ah_coverage_class;
|
|
bool ah_ack_bitrate_high;
|
|
u8 ah_bwmode;
|
|
+ u8 ah_bwmode_debug;
|
|
bool ah_short_slot;
|
|
|
|
/* Antenna Control */
|
|
--- a/drivers/net/wireless/ath/ath5k/base.c
|
|
+++ b/drivers/net/wireless/ath/ath5k/base.c
|
|
@@ -466,6 +466,9 @@ ath5k_chan_set(struct ath5k_hw *ah, stru
|
|
return -EINVAL;
|
|
}
|
|
|
|
+ if (ah->ah_bwmode_debug != AR5K_BWMODE_DEFAULT)
|
|
+ ah->ah_bwmode = ah->ah_bwmode_debug;
|
|
+
|
|
/*
|
|
* To switch channels clear any pending DMA operations;
|
|
* wait long enough for the RX fifo to drain, reset the
|