diff options
| -rw-r--r-- | package/mac80211/patches/440-ath5k_channel_bw_debugfs.patch | 116 | 
1 files changed, 116 insertions, 0 deletions
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 000000000..0d53d5c03 --- /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, +--   | 
