2012-10-05 15:42:59

by Mohammed Shafi Shajakhan

[permalink] [raw]
Subject: [RFC 1/3] ath6kl: Add support to send DELBA

From: Mohammed Shafi Shajakhan <[email protected]>

Add support to send DELBA to the client by making
use of the DELBA_REQ wmi command with the following
parameters: tid, initiator/recipient, aid.

example: echo "0 0 1" > delba_req, echo "0 1 1" > delba_req

Signed-off-by: Mohammed Shafi Shajakhan <[email protected]>
---
drivers/net/wireless/ath/ath6kl/debug.c | 57 +++++++++++++++++++++++++++++++
drivers/net/wireless/ath/ath6kl/wmi.c | 18 ++++++++++
drivers/net/wireless/ath/ath6kl/wmi.h | 7 ++++
3 files changed, 82 insertions(+), 0 deletions(-)

diff --git a/drivers/net/wireless/ath/ath6kl/debug.c b/drivers/net/wireless/ath/ath6kl/debug.c
index 15cfe30..933028f 100644
--- a/drivers/net/wireless/ath/ath6kl/debug.c
+++ b/drivers/net/wireless/ath/ath6kl/debug.c
@@ -1725,6 +1725,59 @@ static const struct file_operations fops_power_params = {
.llseek = default_llseek,
};

+static ssize_t ath6kl_send_delba_req_write(struct file *file,
+ const char __user *user_buf,
+ size_t count, loff_t *ppos)
+{
+ struct ath6kl *ar = file->private_data;
+ struct ath6kl_vif *vif;
+ char buf[100];
+ ssize_t len = 0;
+ char *sptr, *token;
+ u8 tid = 0, direction = 0, aid = 0;
+
+ vif = ath6kl_vif_first(ar);
+ if (!vif)
+ return -EIO;
+
+ len = min(count, sizeof(buf) - 1);
+ if (copy_from_user(buf, user_buf, len))
+ return -EFAULT;
+
+ buf[len] = '\0';
+ sptr = buf;
+
+ token = strsep(&sptr, " ");
+ if (!token)
+ return -EINVAL;
+ if (kstrtou8(token, 0, &tid))
+ return -EINVAL;
+
+ token = strsep(&sptr, " ");
+ if (!token)
+ return -EINVAL;
+ if (kstrtou8(token, 0, &direction))
+ return -EINVAL;
+
+ token = strsep(&sptr, " ");
+ if (!token)
+ return -EINVAL;
+ if (kstrtou8(token, 0, &aid))
+ return -EINVAL;
+
+ ath6kl_wmi_send_delba_req_cmd(ar->wmi, vif->fw_vif_idx,
+ tid, direction, aid);
+
+ return count;
+}
+
+static const struct file_operations fops_delba_req = {
+ .write = ath6kl_send_delba_req_write,
+ .open = simple_open,
+ .owner = THIS_MODULE,
+ .llseek = default_llseek,
+};
+
void ath6kl_debug_init(struct ath6kl *ar)
{
skb_queue_head_init(&ar->debug.fwlog_queue);
@@ -1812,6 +1865,10 @@ int ath6kl_debug_init_fs(struct ath6kl *ar)
debugfs_create_file("power_params", S_IWUSR, ar->debugfs_phy, ar,
&fops_power_params);

+ debugfs_create_file("delba_req", S_IWUSR, ar->debugfs_phy, ar,
+ &fops_delba_req);
+
+
return 0;
}

diff --git a/drivers/net/wireless/ath/ath6kl/wmi.c b/drivers/net/wireless/ath/ath6kl/wmi.c
index f3aeebb..4914831 100644
--- a/drivers/net/wireless/ath/ath6kl/wmi.c
+++ b/drivers/net/wireless/ath/ath6kl/wmi.c
@@ -3774,6 +3774,24 @@ int ath6kl_wmi_set_inact_period(struct wmi *wmi, u8 if_idx, int inact_timeout)
NO_SYNC_WMIFLAG);
}

+int ath6kl_wmi_send_delba_req_cmd(struct wmi *wmi, u8 if_idx,
+ u8 tid, u8 direction, u8 aid)
+{
+ struct sk_buff *skb;
+ struct wmi_delba_req_cmd *cmd;
+
+ skb = ath6kl_wmi_get_new_buf(sizeof(*cmd));
+ if (!skb)
+ return -ENOMEM;
+
+ cmd = (struct wmi_delba_req_cmd *) skb->data;
+ cmd->is_sender_initiator = direction;
+ cmd->tid = (tid & 0xf) | (aid << 4);
+
+ return ath6kl_wmi_cmd_send(wmi, if_idx, skb, WMI_DELBA_REQ_CMDID,
+ NO_SYNC_WMIFLAG);
+}
+
static void ath6kl_wmi_hb_challenge_resp_event(struct wmi *wmi, u8 *datap,
int len)
{
diff --git a/drivers/net/wireless/ath/ath6kl/wmi.h b/drivers/net/wireless/ath/ath6kl/wmi.h
index 98b1755..7ec7bec 100644
--- a/drivers/net/wireless/ath/ath6kl/wmi.h
+++ b/drivers/net/wireless/ath/ath6kl/wmi.h
@@ -2382,6 +2382,11 @@ struct wmi_disable_11b_rates_cmd {
u8 disable;
} __packed;

+struct wmi_delba_req_cmd {
+ u8 tid;
+ u8 is_sender_initiator;
+} __packed;
+
struct wmi_set_appie_extended_cmd {
u8 role_id;
u8 mgmt_frm_type;
@@ -2717,6 +2722,8 @@ int ath6kl_wmi_set_inact_period(struct wmi *wmi, u8 if_idx, int inact_timeout);
void ath6kl_wmi_sscan_timer(unsigned long ptr);

int ath6kl_wmi_get_challenge_resp_cmd(struct wmi *wmi, u32 cookie, u32 source);
+int ath6kl_wmi_send_delba_req_cmd(struct wmi *wmi, u8 if_idx, u8 tid,
+ u8 is_sender_initiator, u8 aid);

struct ath6kl_vif *ath6kl_get_vif_by_index(struct ath6kl *ar, u8 if_idx);
void *ath6kl_wmi_init(struct ath6kl *devt);
--
1.7.0.4



2012-10-05 15:43:08

by Mohammed Shafi Shajakhan

[permalink] [raw]
Subject: [RFC 2/3] ath6kl: Add support to send ADDBA request from userspace

From: Mohammed Shafi Shajakhan <[email protected]>

Support sending ADDBA request to the client with
the following parameters tid, aid.

usage: echo "0 1" > addba_req

Signed-off-by: Mohammed Shafi Shajakhan <[email protected]>
---
drivers/net/wireless/ath/ath6kl/debug.c | 50 +++++++++++++++++++++++++++++++
drivers/net/wireless/ath/ath6kl/wmi.c | 16 ++++++++++
drivers/net/wireless/ath/ath6kl/wmi.h | 5 +++
3 files changed, 71 insertions(+), 0 deletions(-)

diff --git a/drivers/net/wireless/ath/ath6kl/debug.c b/drivers/net/wireless/ath/ath6kl/debug.c
index 933028f..bd5abf0 100644
--- a/drivers/net/wireless/ath/ath6kl/debug.c
+++ b/drivers/net/wireless/ath/ath6kl/debug.c
@@ -1778,6 +1778,53 @@ static const struct file_operations fops_delba_req = {
.llseek = default_llseek,
};

+static ssize_t ath6kl_send_addba_req_write(struct file *file,
+ const char __user *user_buf,
+ size_t count, loff_t *ppos)
+{
+ struct ath6kl *ar = file->private_data;
+ struct ath6kl_vif *vif;
+ char buf[100];
+ ssize_t len = 0;
+ char *sptr, *token;
+ u8 tid = 0, aid = 0;
+
+ vif = ath6kl_vif_first(ar);
+ if (!vif)
+ return -EIO;
+
+ len = min(count, sizeof(buf) - 1);
+ if (copy_from_user(buf, user_buf, len))
+ return -EFAULT;
+
+ buf[len] = '\0';
+ sptr = buf;
+
+ token = strsep(&sptr, " ");
+ if (!token)
+ return -EINVAL;
+ if (kstrtou8(token, 0, &tid))
+ return -EINVAL;
+
+ token = strsep(&sptr, " ");
+ if (!token)
+ return -EINVAL;
+ if (kstrtou8(token, 0, &aid))
+ return -EINVAL;
+
+ ath6kl_wmi_send_addba_req_cmd(ar->wmi, vif->fw_vif_idx,
+ tid, aid);
+
+ return count;
+}
+
+static const struct file_operations fops_addba_req = {
+ .write = ath6kl_send_addba_req_write,
+ .open = simple_open,
+ .owner = THIS_MODULE,
+ .llseek = default_llseek,
+};
+
void ath6kl_debug_init(struct ath6kl *ar)
{
skb_queue_head_init(&ar->debug.fwlog_queue);
@@ -1868,6 +1915,9 @@ int ath6kl_debug_init_fs(struct ath6kl *ar)
debugfs_create_file("delba_req", S_IWUSR, ar->debugfs_phy, ar,
&fops_delba_req);

+ debugfs_create_file("addba_req", S_IWUSR, ar->debugfs_phy, ar,
+ &fops_addba_req);
+

return 0;
}
diff --git a/drivers/net/wireless/ath/ath6kl/wmi.c b/drivers/net/wireless/ath/ath6kl/wmi.c
index 4914831..183f573 100644
--- a/drivers/net/wireless/ath/ath6kl/wmi.c
+++ b/drivers/net/wireless/ath/ath6kl/wmi.c
@@ -3792,6 +3792,22 @@ int ath6kl_wmi_send_delba_req_cmd(struct wmi *wmi, u8 if_idx,
NO_SYNC_WMIFLAG);
}

+int ath6kl_wmi_send_addba_req_cmd(struct wmi *wmi, u8 if_idx, u8 tid, u8 aid)
+{
+ struct sk_buff *skb;
+ struct wmi_addba_req_cmd *cmd;
+
+ skb = ath6kl_wmi_get_new_buf(sizeof(*cmd));
+ if (!skb)
+ return -ENOMEM;
+
+ cmd = (struct wmi_addba_req_cmd_req_cmd *) skb->data;
+ cmd->tid = (tid & 0xf) | (aid << 4);
+
+ return ath6kl_wmi_cmd_send(wmi, if_idx, skb, WMI_ADDBA_REQ_CMDID,
+ NO_SYNC_WMIFLAG);
+}
+
static void ath6kl_wmi_hb_challenge_resp_event(struct wmi *wmi, u8 *datap,
int len)
{
diff --git a/drivers/net/wireless/ath/ath6kl/wmi.h b/drivers/net/wireless/ath/ath6kl/wmi.h
index 7ec7bec..9be7123 100644
--- a/drivers/net/wireless/ath/ath6kl/wmi.h
+++ b/drivers/net/wireless/ath/ath6kl/wmi.h
@@ -2387,6 +2387,10 @@ struct wmi_delba_req_cmd {
u8 is_sender_initiator;
} __packed;

+struct wmi_addba_req_cmd {
+ u8 tid;
+} __packed;
+
struct wmi_set_appie_extended_cmd {
u8 role_id;
u8 mgmt_frm_type;
@@ -2724,6 +2728,7 @@ void ath6kl_wmi_sscan_timer(unsigned long ptr);
int ath6kl_wmi_get_challenge_resp_cmd(struct wmi *wmi, u32 cookie, u32 source);
int ath6kl_wmi_send_delba_req_cmd(struct wmi *wmi, u8 if_idx, u8 tid,
u8 is_sender_initiator, u8 aid);
+int ath6kl_wmi_send_addba_req_cmd(struct wmi *wmi, u8 if_idx, u8 tid, u8 aid);

struct ath6kl_vif *ath6kl_get_vif_by_index(struct ath6kl *ar, u8 if_idx);
void *ath6kl_wmi_init(struct ath6kl *devt);
--
1.7.0.4


2012-10-05 15:43:21

by Mohammed Shafi Shajakhan

[permalink] [raw]
Subject: [RFC 3/3] ath6kl: Support allow aggregation for each tids

From: Mohammed Shafi Shajakhan <[email protected]>

Add support to have tx/rx mask for tids where aggregation
can be allowed.

Signed-off-by: Mohammed Shafi Shajakhan <[email protected]>
---
drivers/net/wireless/ath/ath6kl/debug.c | 49 +++++++++++++++++++++++++++++++
drivers/net/wireless/ath/ath6kl/wmi.c | 19 ++++++++++++
drivers/net/wireless/ath/ath6kl/wmi.h | 13 ++++++++
3 files changed, 81 insertions(+), 0 deletions(-)

diff --git a/drivers/net/wireless/ath/ath6kl/debug.c b/drivers/net/wireless/ath/ath6kl/debug.c
index bd5abf0..50b1773 100644
--- a/drivers/net/wireless/ath/ath6kl/debug.c
+++ b/drivers/net/wireless/ath/ath6kl/debug.c
@@ -1825,6 +1825,53 @@ static const struct file_operations fops_addba_req = {
.llseek = default_llseek,
};

+static ssize_t ath6kl_allow_aggr_write(struct file *file,
+ const char __user *user_buf,
+ size_t count, loff_t *ppos)
+{
+ struct ath6kl *ar = file->private_data;
+ struct ath6kl_vif *vif;
+ char buf[100];
+ ssize_t len = 0;
+ char *sptr, *token;
+ u16 tx_allow_aggr = 0, rx_allow_aggr = 0;
+
+ vif = ath6kl_vif_first(ar);
+ if (!vif)
+ return -EIO;
+
+ len = min(count, sizeof(buf) - 1);
+ if (copy_from_user(buf, user_buf, len))
+ return -EFAULT;
+
+ buf[len] = '\0';
+ sptr = buf;
+
+ token = strsep(&sptr, " ");
+ if (!token)
+ return -EINVAL;
+ if (kstrtou16(token, 0, &tx_allow_aggr))
+ return -EINVAL;
+
+ token = strsep(&sptr, " ");
+ if (!token)
+ return -EINVAL;
+ if (kstrtou16(token, 0, &rx_allow_aggr))
+ return -EINVAL;
+
+ ath6kl_wmi_allow_aggr_cmd(ar->wmi, vif->fw_vif_idx,
+ tx_allow_aggr, rx_allow_aggr);
+
+ return count;
+}
+
+static const struct file_operations fops_allow_aggr = {
+ .write = ath6kl_allow_aggr_write,
+ .open = simple_open,
+ .owner = THIS_MODULE,
+ .llseek = default_llseek,
+};
+
void ath6kl_debug_init(struct ath6kl *ar)
{
skb_queue_head_init(&ar->debug.fwlog_queue);
@@ -1918,6 +1965,8 @@ int ath6kl_debug_init_fs(struct ath6kl *ar)
debugfs_create_file("addba_req", S_IWUSR, ar->debugfs_phy, ar,
&fops_addba_req);

+ debugfs_create_file("allow_aggr", S_IWUSR, ar->debugfs_phy, ar,
+ &fops_allow_aggr);

return 0;
}
diff --git a/drivers/net/wireless/ath/ath6kl/wmi.c b/drivers/net/wireless/ath/ath6kl/wmi.c
index 183f573..072e78c 100644
--- a/drivers/net/wireless/ath/ath6kl/wmi.c
+++ b/drivers/net/wireless/ath/ath6kl/wmi.c
@@ -3808,6 +3808,25 @@ int ath6kl_wmi_send_addba_req_cmd(struct wmi *wmi, u8 if_idx, u8 tid, u8 aid)
NO_SYNC_WMIFLAG);
}

+int ath6kl_wmi_allow_aggr_cmd(struct wmi *wmi, u8 if_idx,
+ u16 tx_allow_aggr, u16 rx_allow_aggr)
+{
+ struct sk_buff *skb;
+ struct wmi_allow_aggr_cmd *cmd;
+
+ skb = ath6kl_wmi_get_new_buf(sizeof(*cmd));
+ if (!skb)
+ return -ENOMEM;
+
+ cmd = (struct wmi_allow_aggr_cmd *) skb->data;
+ cmd->tx_allow_aggr = cpu_to_le16(tx_allow_aggr);
+ cmd->rx_allow_aggr = cpu_to_le16(rx_allow_aggr);
+
+
+ return ath6kl_wmi_cmd_send(wmi, if_idx, skb, WMI_ALLOW_AGGR_CMDID,
+ NO_SYNC_WMIFLAG);
+}
+
static void ath6kl_wmi_hb_challenge_resp_event(struct wmi *wmi, u8 *datap,
int len)
{
diff --git a/drivers/net/wireless/ath/ath6kl/wmi.h b/drivers/net/wireless/ath/ath6kl/wmi.h
index 9be7123..845d535 100644
--- a/drivers/net/wireless/ath/ath6kl/wmi.h
+++ b/drivers/net/wireless/ath/ath6kl/wmi.h
@@ -2391,6 +2391,17 @@ struct wmi_addba_req_cmd {
u8 tid;
} __packed;

+/*
+ * 16 bit mask to allow uplink/downlink
+ * ADDBA request negotiation, with each
+ * bit postion maps to corresponding tid.
+ */
+
+struct wmi_allow_aggr_cmd {
+ __le16 tx_allow_aggr;
+ __le16 rx_allow_aggr;
+} __packed;
+
struct wmi_set_appie_extended_cmd {
u8 role_id;
u8 mgmt_frm_type;
@@ -2729,6 +2740,8 @@ int ath6kl_wmi_get_challenge_resp_cmd(struct wmi *wmi, u32 cookie, u32 source);
int ath6kl_wmi_send_delba_req_cmd(struct wmi *wmi, u8 if_idx, u8 tid,
u8 is_sender_initiator, u8 aid);
int ath6kl_wmi_send_addba_req_cmd(struct wmi *wmi, u8 if_idx, u8 tid, u8 aid);
+int ath6kl_wmi_allow_aggr_cmd(struct wmi *wmi, u8 if_idx,
+ u16 tx_allow_aggr, u16 rx_allow_aggr);

struct ath6kl_vif *ath6kl_get_vif_by_index(struct ath6kl *ar, u8 if_idx);
void *ath6kl_wmi_init(struct ath6kl *devt);
--
1.7.0.4