From 9452ad74bbada2fcdbd91259f02ed8e979d838e8 Mon Sep 17 00:00:00 2001
From: Travis Kemen <thepeople@openwrt.org>
Date: Wed, 4 Jul 2012 00:09:18 +0000
Subject: [PATCH] commit patch from
 https://lists.ath5k.org/pipermail/ath5k-devel/2011-November/005043.html,
 fixed up for newer ath5k and added in more radios.

SVN-Revision: 32595
---
 .../440-ath5k_channel_bw_debugfs.patch        | 116 ++++++++++++++++++
 1 file changed, 116 insertions(+)
 create mode 100644 package/mac80211/patches/440-ath5k_channel_bw_debugfs.patch

diff --git a/package/mac80211/patches/440-ath5k_channel_bw_debugfs.patch b/package/mac80211/patches/440-ath5k_channel_bw_debugfs.patch
new file mode 100644
index 000000000000..0d53d5c03705
--- /dev/null
+++ b/package/mac80211/patches/440-ath5k_channel_bw_debugfs.patch
@@ -0,0 +1,116 @@
+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(-)
+
+diff --git a/drivers/net/wireless/ath/ath5k/debug.c b/drivers/net/wireless/ath/ath5k/debug.c
+index 8c5ce8b..bb41066 100644
+--- a/drivers/net/wireless/ath/ath5k/debug.c
++++ b/drivers/net/wireless/ath/ath5k/debug.c
+@@ -815,6 +815,89 @@ static const struct file_operations fops_ani = {
+ 	.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;
++
++#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 != tobwmode) {
++				mutex_lock(&ah->lock);
++				ah->ah_bwmode = 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 */
+ 
+@@ -906,6 +989,9 @@ ath5k_debug_init_device(struct ath5k_hw *ah)
+ 	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,
+-- 
-- 
2.30.2