diff options
Diffstat (limited to 'net/mac80211/debugfs_sta.c')
| -rw-r--r-- | net/mac80211/debugfs_sta.c | 65 | 
1 files changed, 64 insertions, 1 deletions
diff --git a/net/mac80211/debugfs_sta.c b/net/mac80211/debugfs_sta.c index 6bc9b07c3ed..e763f1529dd 100644 --- a/net/mac80211/debugfs_sta.c +++ b/net/mac80211/debugfs_sta.c @@ -39,6 +39,13 @@ static const struct file_operations sta_ ##name## _ops = {		\  	.open = mac80211_open_file_generic,				\  } +#define STA_OPS_RW(name)						\ +static const struct file_operations sta_ ##name## _ops = {		\ +	.read = sta_##name##_read,					\ +	.write = sta_##name##_write,					\ +	.open = mac80211_open_file_generic,				\ +} +  #define STA_FILE(name, field, format)					\  		STA_READ_##format(name, field)				\  		STA_OPS(name) @@ -156,7 +163,63 @@ static ssize_t sta_agg_status_read(struct file *file, char __user *userbuf,  	return simple_read_from_buffer(userbuf, count, ppos, buf, p - buf);  } -STA_OPS(agg_status); + +static ssize_t sta_agg_status_write(struct file *file, const char __user *userbuf, +				    size_t count, loff_t *ppos) +{ +	char _buf[12], *buf = _buf; +	struct sta_info *sta = file->private_data; +	bool start, tx; +	unsigned long tid; +	int ret; + +	if (count > sizeof(_buf)) +		return -EINVAL; + +	if (copy_from_user(buf, userbuf, count)) +		return -EFAULT; + +	buf[sizeof(_buf) - 1] = '\0'; + +	if (strncmp(buf, "tx ", 3) == 0) { +		buf += 3; +		tx = true; +	} else if (strncmp(buf, "rx ", 3) == 0) { +		buf += 3; +		tx = false; +	} else +		return -EINVAL; + +	if (strncmp(buf, "start ", 6) == 0) { +		buf += 6; +		start = true; +		if (!tx) +			return -EINVAL; +	} else if (strncmp(buf, "stop ", 5) == 0) { +		buf += 5; +		start = false; +	} else +		return -EINVAL; + +	tid = simple_strtoul(buf, NULL, 0); + +	if (tid >= STA_TID_NUM) +		return -EINVAL; + +	if (tx) { +		if (start) +			ret = ieee80211_start_tx_ba_session(&sta->sta, tid); +		else +			ret = ieee80211_stop_tx_ba_session(&sta->sta, tid, +							   WLAN_BACK_RECIPIENT); +	} else { +		__ieee80211_stop_rx_ba_session(sta, tid, WLAN_BACK_RECIPIENT, 3); +		ret = 0; +	} + +	return ret ?: count; +} +STA_OPS_RW(agg_status);  static ssize_t sta_ht_capa_read(struct file *file, char __user *userbuf,  				size_t count, loff_t *ppos)  |