]> git.karo-electronics.de Git - mv-sheeva.git/blobdiff - net/mac80211/debugfs_sta.c
Merge branch 'wireless-next-2.6' of git://git.kernel.org/pub/scm/linux/kernel/git...
[mv-sheeva.git] / net / mac80211 / debugfs_sta.c
index 6bc9b07c3edad96ab20d2c366686701f5bf72be2..e763f1529ddbca6ce54c3af0dd848cd96c643f61 100644 (file)
@@ -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)