aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/wl12xx/testmode.c
diff options
context:
space:
mode:
authorKalle Valo <kvalo@qca.qualcomm.com>2011-12-16 14:10:39 -0500
committerKalle Valo <kvalo@qca.qualcomm.com>2011-12-16 14:10:39 -0500
commit7e95e365d5399647a41e10059e4b09826b82d78b (patch)
tree305c9968798adae3d9484657339fa39d2a5fdaac /drivers/net/wireless/wl12xx/testmode.c
parent3ca9d1fc9aa64077645a26c396de9399b49ea226 (diff)
parent5bd5e9a6ae5137a61d0b5c277eac61892d89fc4f (diff)
Merge remote branch 'wireless-next/master' into ath6kl-next
Conflicts: drivers/net/wireless/ath/ath6kl/init.c
Diffstat (limited to 'drivers/net/wireless/wl12xx/testmode.c')
-rw-r--r--drivers/net/wireless/wl12xx/testmode.c77
1 files changed, 58 insertions, 19 deletions
diff --git a/drivers/net/wireless/wl12xx/testmode.c b/drivers/net/wireless/wl12xx/testmode.c
index 4ae8effaee22..25093c0cb0ed 100644
--- a/drivers/net/wireless/wl12xx/testmode.c
+++ b/drivers/net/wireless/wl12xx/testmode.c
@@ -26,8 +26,10 @@
26#include <net/genetlink.h> 26#include <net/genetlink.h>
27 27
28#include "wl12xx.h" 28#include "wl12xx.h"
29#include "debug.h"
29#include "acx.h" 30#include "acx.h"
30#include "reg.h" 31#include "reg.h"
32#include "ps.h"
31 33
32#define WL1271_TM_MAX_DATA_LENGTH 1024 34#define WL1271_TM_MAX_DATA_LENGTH 1024
33 35
@@ -36,6 +38,7 @@ enum wl1271_tm_commands {
36 WL1271_TM_CMD_TEST, 38 WL1271_TM_CMD_TEST,
37 WL1271_TM_CMD_INTERROGATE, 39 WL1271_TM_CMD_INTERROGATE,
38 WL1271_TM_CMD_CONFIGURE, 40 WL1271_TM_CMD_CONFIGURE,
41 WL1271_TM_CMD_NVS_PUSH, /* Not in use. Keep to not break ABI */
39 WL1271_TM_CMD_SET_PLT_MODE, 42 WL1271_TM_CMD_SET_PLT_MODE,
40 WL1271_TM_CMD_RECOVER, 43 WL1271_TM_CMD_RECOVER,
41 44
@@ -87,31 +90,47 @@ static int wl1271_tm_cmd_test(struct wl1271 *wl, struct nlattr *tb[])
87 return -EMSGSIZE; 90 return -EMSGSIZE;
88 91
89 mutex_lock(&wl->mutex); 92 mutex_lock(&wl->mutex);
90 ret = wl1271_cmd_test(wl, buf, buf_len, answer);
91 mutex_unlock(&wl->mutex);
92 93
94 if (wl->state == WL1271_STATE_OFF) {
95 ret = -EINVAL;
96 goto out;
97 }
98
99 ret = wl1271_ps_elp_wakeup(wl);
100 if (ret < 0)
101 goto out;
102
103 ret = wl1271_cmd_test(wl, buf, buf_len, answer);
93 if (ret < 0) { 104 if (ret < 0) {
94 wl1271_warning("testmode cmd test failed: %d", ret); 105 wl1271_warning("testmode cmd test failed: %d", ret);
95 return ret; 106 goto out_sleep;
96 } 107 }
97 108
98 if (answer) { 109 if (answer) {
99 len = nla_total_size(buf_len); 110 len = nla_total_size(buf_len);
100 skb = cfg80211_testmode_alloc_reply_skb(wl->hw->wiphy, len); 111 skb = cfg80211_testmode_alloc_reply_skb(wl->hw->wiphy, len);
101 if (!skb) 112 if (!skb) {
102 return -ENOMEM; 113 ret = -ENOMEM;
114 goto out_sleep;
115 }
103 116
104 NLA_PUT(skb, WL1271_TM_ATTR_DATA, buf_len, buf); 117 NLA_PUT(skb, WL1271_TM_ATTR_DATA, buf_len, buf);
105 ret = cfg80211_testmode_reply(skb); 118 ret = cfg80211_testmode_reply(skb);
106 if (ret < 0) 119 if (ret < 0)
107 return ret; 120 goto out_sleep;
108 } 121 }
109 122
110 return 0; 123out_sleep:
124 wl1271_ps_elp_sleep(wl);
125out:
126 mutex_unlock(&wl->mutex);
127
128 return ret;
111 129
112nla_put_failure: 130nla_put_failure:
113 kfree_skb(skb); 131 kfree_skb(skb);
114 return -EMSGSIZE; 132 ret = -EMSGSIZE;
133 goto out_sleep;
115} 134}
116 135
117static int wl1271_tm_cmd_interrogate(struct wl1271 *wl, struct nlattr *tb[]) 136static int wl1271_tm_cmd_interrogate(struct wl1271 *wl, struct nlattr *tb[])
@@ -128,33 +147,53 @@ static int wl1271_tm_cmd_interrogate(struct wl1271 *wl, struct nlattr *tb[])
128 147
129 ie_id = nla_get_u8(tb[WL1271_TM_ATTR_IE_ID]); 148 ie_id = nla_get_u8(tb[WL1271_TM_ATTR_IE_ID]);
130 149
150 mutex_lock(&wl->mutex);
151
152 if (wl->state == WL1271_STATE_OFF) {
153 ret = -EINVAL;
154 goto out;
155 }
156
157 ret = wl1271_ps_elp_wakeup(wl);
158 if (ret < 0)
159 goto out;
160
131 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); 161 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
132 if (!cmd) 162 if (!cmd) {
133 return -ENOMEM; 163 ret = -ENOMEM;
164 goto out_sleep;
165 }
134 166
135 mutex_lock(&wl->mutex);
136 ret = wl1271_cmd_interrogate(wl, ie_id, cmd, sizeof(*cmd)); 167 ret = wl1271_cmd_interrogate(wl, ie_id, cmd, sizeof(*cmd));
137 mutex_unlock(&wl->mutex);
138
139 if (ret < 0) { 168 if (ret < 0) {
140 wl1271_warning("testmode cmd interrogate failed: %d", ret); 169 wl1271_warning("testmode cmd interrogate failed: %d", ret);
141 kfree(cmd); 170 goto out_free;
142 return ret;
143 } 171 }
144 172
145 skb = cfg80211_testmode_alloc_reply_skb(wl->hw->wiphy, sizeof(*cmd)); 173 skb = cfg80211_testmode_alloc_reply_skb(wl->hw->wiphy, sizeof(*cmd));
146 if (!skb) { 174 if (!skb) {
147 kfree(cmd); 175 ret = -ENOMEM;
148 return -ENOMEM; 176 goto out_free;
149 } 177 }
150 178
151 NLA_PUT(skb, WL1271_TM_ATTR_DATA, sizeof(*cmd), cmd); 179 NLA_PUT(skb, WL1271_TM_ATTR_DATA, sizeof(*cmd), cmd);
180 ret = cfg80211_testmode_reply(skb);
181 if (ret < 0)
182 goto out_free;
183
184out_free:
185 kfree(cmd);
186out_sleep:
187 wl1271_ps_elp_sleep(wl);
188out:
189 mutex_unlock(&wl->mutex);
152 190
153 return 0; 191 return ret;
154 192
155nla_put_failure: 193nla_put_failure:
156 kfree_skb(skb); 194 kfree_skb(skb);
157 return -EMSGSIZE; 195 ret = -EMSGSIZE;
196 goto out_free;
158} 197}
159 198
160static int wl1271_tm_cmd_configure(struct wl1271 *wl, struct nlattr *tb[]) 199static int wl1271_tm_cmd_configure(struct wl1271 *wl, struct nlattr *tb[])