aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorThomas Pedersen <twpedersen@qca.qualcomm.com>2011-12-30 04:57:00 -0500
committerKalle Valo <kvalo@qca.qualcomm.com>2012-01-02 11:50:42 -0500
commit4f34dacea117029dbad1f0f50d68207b97546d1e (patch)
treea24eaf6691176efa6c043216dd75afdf83f09c1c /drivers
parent792ecb33080f4e315695e0fe21cf3a3c2a514dd0 (diff)
ath6kl: send TCMD response through testmode events
ath6kl no longer knows what it is transmitting through cfg80211_testmode, and simply passes opaque buffers between userspace and the firmware. Leave the CONT_RX enum for backwards compatibility. kvalo: change ATH6KL_TM_CMD_RX_REPORT to return -EOPNOTSUPP Signed-off-by: Thomas Pedersen <twpedersen@qca.qualcomm.com> Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/wireless/ath/ath6kl/testmode.c102
-rw-r--r--drivers/net/wireless/ath/ath6kl/testmode.h6
-rw-r--r--drivers/net/wireless/ath/ath6kl/wmi.c6
3 files changed, 23 insertions, 91 deletions
diff --git a/drivers/net/wireless/ath/ath6kl/testmode.c b/drivers/net/wireless/ath/ath6kl/testmode.c
index 381eb66a605f..f0cd61d6188a 100644
--- a/drivers/net/wireless/ath/ath6kl/testmode.c
+++ b/drivers/net/wireless/ath/ath6kl/testmode.c
@@ -15,6 +15,7 @@
15 */ 15 */
16 16
17#include "testmode.h" 17#include "testmode.h"
18#include "debug.h"
18 19
19#include <net/netlink.h> 20#include <net/netlink.h>
20 21
@@ -30,7 +31,7 @@ enum ath6kl_tm_attr {
30 31
31enum ath6kl_tm_cmd { 32enum ath6kl_tm_cmd {
32 ATH6KL_TM_CMD_TCMD = 0, 33 ATH6KL_TM_CMD_TCMD = 0,
33 ATH6KL_TM_CMD_RX_REPORT = 1, 34 ATH6KL_TM_CMD_RX_REPORT = 1, /* not used anymore */
34}; 35};
35 36
36#define ATH6KL_TM_DATA_MAX_LEN 5000 37#define ATH6KL_TM_DATA_MAX_LEN 5000
@@ -41,84 +42,33 @@ static const struct nla_policy ath6kl_tm_policy[ATH6KL_TM_ATTR_MAX + 1] = {
41 .len = ATH6KL_TM_DATA_MAX_LEN }, 42 .len = ATH6KL_TM_DATA_MAX_LEN },
42}; 43};
43 44
44void ath6kl_tm_rx_report_event(struct ath6kl *ar, void *buf, size_t buf_len) 45void ath6kl_tm_rx_event(struct ath6kl *ar, void *buf, size_t buf_len)
45{ 46{
46 if (down_interruptible(&ar->sem)) 47 struct sk_buff *skb;
47 return;
48
49 kfree(ar->tm.rx_report);
50
51 ar->tm.rx_report = kmemdup(buf, buf_len, GFP_KERNEL);
52 ar->tm.rx_report_len = buf_len;
53
54 up(&ar->sem);
55
56 wake_up(&ar->event_wq);
57}
58
59static int ath6kl_tm_rx_report(struct ath6kl *ar, void *buf, size_t buf_len,
60 struct sk_buff *skb)
61{
62 int ret = 0;
63 long left;
64
65 if (down_interruptible(&ar->sem))
66 return -ERESTARTSYS;
67
68 if (!test_bit(WMI_READY, &ar->flag)) {
69 ret = -EIO;
70 goto out;
71 }
72
73 if (test_bit(DESTROY_IN_PROGRESS, &ar->flag)) {
74 ret = -EBUSY;
75 goto out;
76 }
77
78 if (ath6kl_wmi_test_cmd(ar->wmi, buf, buf_len) < 0) {
79 up(&ar->sem);
80 return -EIO;
81 }
82
83 left = wait_event_interruptible_timeout(ar->event_wq,
84 ar->tm.rx_report != NULL,
85 WMI_TIMEOUT);
86 48
87 if (left == 0) { 49 if (!buf || buf_len == 0)
88 ret = -ETIMEDOUT; 50 return;
89 goto out;
90 } else if (left < 0) {
91 ret = left;
92 goto out;
93 }
94 51
95 if (ar->tm.rx_report == NULL || ar->tm.rx_report_len == 0) { 52 skb = cfg80211_testmode_alloc_event_skb(ar->wiphy, buf_len, GFP_KERNEL);
96 ret = -EINVAL; 53 if (!skb) {
97 goto out; 54 ath6kl_warn("failed to allocate testmode rx skb!\n");
55 return;
98 } 56 }
99 57 NLA_PUT_U32(skb, ATH6KL_TM_ATTR_CMD, ATH6KL_TM_CMD_TCMD);
100 NLA_PUT(skb, ATH6KL_TM_ATTR_DATA, ar->tm.rx_report_len, 58 NLA_PUT(skb, ATH6KL_TM_ATTR_DATA, buf_len, buf);
101 ar->tm.rx_report); 59 cfg80211_testmode_event(skb, GFP_KERNEL);
102 60 return;
103 kfree(ar->tm.rx_report);
104 ar->tm.rx_report = NULL;
105
106out:
107 up(&ar->sem);
108
109 return ret;
110 61
111nla_put_failure: 62nla_put_failure:
112 ret = -ENOBUFS; 63 kfree_skb(skb);
113 goto out; 64 ath6kl_warn("nla_put failed on testmode rx skb!\n");
114} 65}
115 66
116int ath6kl_tm_cmd(struct wiphy *wiphy, void *data, int len) 67int ath6kl_tm_cmd(struct wiphy *wiphy, void *data, int len)
117{ 68{
118 struct ath6kl *ar = wiphy_priv(wiphy); 69 struct ath6kl *ar = wiphy_priv(wiphy);
119 struct nlattr *tb[ATH6KL_TM_ATTR_MAX + 1]; 70 struct nlattr *tb[ATH6KL_TM_ATTR_MAX + 1];
120 int err, buf_len, reply_len; 71 int err, buf_len;
121 struct sk_buff *skb;
122 void *buf; 72 void *buf;
123 73
124 err = nla_parse(tb, ATH6KL_TM_ATTR_MAX, data, len, 74 err = nla_parse(tb, ATH6KL_TM_ATTR_MAX, data, len,
@@ -143,24 +93,6 @@ int ath6kl_tm_cmd(struct wiphy *wiphy, void *data, int len)
143 93
144 break; 94 break;
145 case ATH6KL_TM_CMD_RX_REPORT: 95 case ATH6KL_TM_CMD_RX_REPORT:
146 if (!tb[ATH6KL_TM_ATTR_DATA])
147 return -EINVAL;
148
149 buf = nla_data(tb[ATH6KL_TM_ATTR_DATA]);
150 buf_len = nla_len(tb[ATH6KL_TM_ATTR_DATA]);
151
152 reply_len = nla_total_size(ATH6KL_TM_DATA_MAX_LEN);
153 skb = cfg80211_testmode_alloc_reply_skb(wiphy, reply_len);
154 if (!skb)
155 return -ENOMEM;
156
157 err = ath6kl_tm_rx_report(ar, buf, buf_len, skb);
158 if (err < 0) {
159 kfree_skb(skb);
160 return err;
161 }
162
163 return cfg80211_testmode_reply(skb);
164 default: 96 default:
165 return -EOPNOTSUPP; 97 return -EOPNOTSUPP;
166 } 98 }
diff --git a/drivers/net/wireless/ath/ath6kl/testmode.h b/drivers/net/wireless/ath/ath6kl/testmode.h
index 43dffcc11fb1..7fd47a62d078 100644
--- a/drivers/net/wireless/ath/ath6kl/testmode.h
+++ b/drivers/net/wireless/ath/ath6kl/testmode.h
@@ -18,13 +18,13 @@
18 18
19#ifdef CONFIG_NL80211_TESTMODE 19#ifdef CONFIG_NL80211_TESTMODE
20 20
21void ath6kl_tm_rx_report_event(struct ath6kl *ar, void *buf, size_t buf_len); 21void ath6kl_tm_rx_event(struct ath6kl *ar, void *buf, size_t buf_len);
22int ath6kl_tm_cmd(struct wiphy *wiphy, void *data, int len); 22int ath6kl_tm_cmd(struct wiphy *wiphy, void *data, int len);
23 23
24#else 24#else
25 25
26static inline void ath6kl_tm_rx_report_event(struct ath6kl *ar, void *buf, 26static inline void ath6kl_tm_rx_event(struct ath6kl *ar, void *buf,
27 size_t buf_len) 27 size_t buf_len)
28{ 28{
29} 29}
30 30
diff --git a/drivers/net/wireless/ath/ath6kl/wmi.c b/drivers/net/wireless/ath/ath6kl/wmi.c
index 1e31c38abb4f..c6ca660d270a 100644
--- a/drivers/net/wireless/ath/ath6kl/wmi.c
+++ b/drivers/net/wireless/ath/ath6kl/wmi.c
@@ -1145,9 +1145,9 @@ static int ath6kl_wmi_bitrate_reply_rx(struct wmi *wmi, u8 *datap, int len)
1145 return 0; 1145 return 0;
1146} 1146}
1147 1147
1148static int ath6kl_wmi_tcmd_test_report_rx(struct wmi *wmi, u8 *datap, int len) 1148static int ath6kl_wmi_test_rx(struct wmi *wmi, u8 *datap, int len)
1149{ 1149{
1150 ath6kl_tm_rx_report_event(wmi->parent_dev, datap, len); 1150 ath6kl_tm_rx_event(wmi->parent_dev, datap, len);
1151 1151
1152 return 0; 1152 return 0;
1153} 1153}
@@ -3402,7 +3402,7 @@ int ath6kl_wmi_control_rx(struct wmi *wmi, struct sk_buff *skb)
3402 break; 3402 break;
3403 case WMI_TEST_EVENTID: 3403 case WMI_TEST_EVENTID:
3404 ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_TEST_EVENTID\n"); 3404 ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_TEST_EVENTID\n");
3405 ret = ath6kl_wmi_tcmd_test_report_rx(wmi, datap, len); 3405 ret = ath6kl_wmi_test_rx(wmi, datap, len);
3406 break; 3406 break;
3407 case WMI_GET_FIXRATES_CMDID: 3407 case WMI_GET_FIXRATES_CMDID:
3408 ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_GET_FIXRATES_CMDID\n"); 3408 ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_GET_FIXRATES_CMDID\n");