diff options
author | Thomas Pedersen <twpedersen@qca.qualcomm.com> | 2011-12-30 04:57:00 -0500 |
---|---|---|
committer | Kalle Valo <kvalo@qca.qualcomm.com> | 2012-01-02 11:50:42 -0500 |
commit | 4f34dacea117029dbad1f0f50d68207b97546d1e (patch) | |
tree | a24eaf6691176efa6c043216dd75afdf83f09c1c /drivers | |
parent | 792ecb33080f4e315695e0fe21cf3a3c2a514dd0 (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.c | 102 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath6kl/testmode.h | 6 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath6kl/wmi.c | 6 |
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 | ||
31 | enum ath6kl_tm_cmd { | 32 | enum 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 | ||
44 | void ath6kl_tm_rx_report_event(struct ath6kl *ar, void *buf, size_t buf_len) | 45 | void 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 | |||
59 | static 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 | |||
106 | out: | ||
107 | up(&ar->sem); | ||
108 | |||
109 | return ret; | ||
110 | 61 | ||
111 | nla_put_failure: | 62 | nla_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 | ||
116 | int ath6kl_tm_cmd(struct wiphy *wiphy, void *data, int len) | 67 | int 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 | ||
21 | void ath6kl_tm_rx_report_event(struct ath6kl *ar, void *buf, size_t buf_len); | 21 | void ath6kl_tm_rx_event(struct ath6kl *ar, void *buf, size_t buf_len); |
22 | int ath6kl_tm_cmd(struct wiphy *wiphy, void *data, int len); | 22 | int ath6kl_tm_cmd(struct wiphy *wiphy, void *data, int len); |
23 | 23 | ||
24 | #else | 24 | #else |
25 | 25 | ||
26 | static inline void ath6kl_tm_rx_report_event(struct ath6kl *ar, void *buf, | 26 | static 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 | ||
1148 | static int ath6kl_wmi_tcmd_test_report_rx(struct wmi *wmi, u8 *datap, int len) | 1148 | static 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"); |