aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorKalle Valo <kalle.valo@nokia.com>2009-06-12 07:14:19 -0400
committerJohn W. Linville <linville@tuxdriver.com>2009-07-10 14:57:41 -0400
commitff25839bf0c99e828c26864a24417a36a6b6a31e (patch)
treee5891ed357f4285f788056e270df7664b4d5aa13 /drivers
parentc4f9f16b309b65f9f578ec4ba78b3efa106cf65d (diff)
wl12xx: cmd and acx interface rework
Rework cmd and acx interfaces, it was just too confusing earlier. Now all commands need to contain all the needed headers, either just cmd headers or both cmd and acx headers. This accomplish to remove the extra copy done for each command. The interfaces are now properly documented as well. Also try to make all commands safe for DMA transfers. I might have missed some, but most of them should be fixed now. And this is not all! As a free bonus you will also get some cosmetic cleanups and code reorganisation. Order today! Signed-off-by: Kalle Valo <kalle.valo@nokia.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/wireless/wl12xx/acx.c690
-rw-r--r--drivers/net/wireless/wl12xx/acx.h126
-rw-r--r--drivers/net/wireless/wl12xx/cmd.c311
-rw-r--r--drivers/net/wireless/wl12xx/cmd.h168
-rw-r--r--drivers/net/wireless/wl12xx/main.c87
-rw-r--r--drivers/net/wireless/wl12xx/ps.c2
-rw-r--r--drivers/net/wireless/wl12xx/ps.h2
-rw-r--r--drivers/net/wireless/wl12xx/rx.c27
-rw-r--r--drivers/net/wireless/wl12xx/wl1251.c74
9 files changed, 896 insertions, 591 deletions
diff --git a/drivers/net/wireless/wl12xx/acx.c b/drivers/net/wireless/wl12xx/acx.c
index 1cfd458ad5ab..d0daf69558f0 100644
--- a/drivers/net/wireless/wl12xx/acx.c
+++ b/drivers/net/wireless/wl12xx/acx.c
@@ -13,126 +13,160 @@
13int wl12xx_acx_frame_rates(struct wl12xx *wl, u8 ctrl_rate, u8 ctrl_mod, 13int wl12xx_acx_frame_rates(struct wl12xx *wl, u8 ctrl_rate, u8 ctrl_mod,
14 u8 mgt_rate, u8 mgt_mod) 14 u8 mgt_rate, u8 mgt_mod)
15{ 15{
16 struct acx_fw_gen_frame_rates *rates;
16 int ret; 17 int ret;
17 struct acx_fw_gen_frame_rates rates;
18 18
19 wl12xx_debug(DEBUG_ACX, "acx frame rates"); 19 wl12xx_debug(DEBUG_ACX, "acx frame rates");
20 20
21 rates.header.id = ACX_FW_GEN_FRAME_RATES; 21 rates = kzalloc(sizeof(*rates), GFP_KERNEL);
22 rates.header.len = sizeof(struct acx_fw_gen_frame_rates) - 22 if (!rates) {
23 sizeof(struct acx_header); 23 ret = -ENOMEM;
24 goto out;
25 }
24 26
25 rates.tx_ctrl_frame_rate = ctrl_rate; 27 rates->tx_ctrl_frame_rate = ctrl_rate;
26 rates.tx_ctrl_frame_mod = ctrl_mod; 28 rates->tx_ctrl_frame_mod = ctrl_mod;
27 rates.tx_mgt_frame_rate = mgt_rate; 29 rates->tx_mgt_frame_rate = mgt_rate;
28 rates.tx_mgt_frame_mod = mgt_mod; 30 rates->tx_mgt_frame_mod = mgt_mod;
29 31
30 ret = wl12xx_cmd_configure(wl, &rates, sizeof(rates)); 32 ret = wl12xx_cmd_configure(wl, ACX_FW_GEN_FRAME_RATES,
33 rates, sizeof(*rates));
31 if (ret < 0) { 34 if (ret < 0) {
32 wl12xx_error("Failed to set FW rates and modulation"); 35 wl12xx_error("Failed to set FW rates and modulation");
33 return ret; 36 goto out;
34 } 37 }
35 38
36 return 0; 39out:
40 kfree(rates);
41 return ret;
37} 42}
38 43
39 44
40int wl12xx_acx_station_id(struct wl12xx *wl) 45int wl12xx_acx_station_id(struct wl12xx *wl)
41{ 46{
47 struct acx_dot11_station_id *mac;
42 int ret, i; 48 int ret, i;
43 struct dot11_station_id mac;
44 49
45 wl12xx_debug(DEBUG_ACX, "acx dot11_station_id"); 50 wl12xx_debug(DEBUG_ACX, "acx dot11_station_id");
46 51
47 mac.header.id = DOT11_STATION_ID; 52 mac = kzalloc(sizeof(*mac), GFP_KERNEL);
48 mac.header.len = sizeof(mac) - sizeof(struct acx_header); 53 if (!mac) {
54 ret = -ENOMEM;
55 goto out;
56 }
49 57
50 for (i = 0; i < ETH_ALEN; i++) 58 for (i = 0; i < ETH_ALEN; i++)
51 mac.mac[i] = wl->mac_addr[ETH_ALEN - 1 - i]; 59 mac->mac[i] = wl->mac_addr[ETH_ALEN - 1 - i];
52 60
53 ret = wl12xx_cmd_configure(wl, &mac, sizeof(mac)); 61 ret = wl12xx_cmd_configure(wl, DOT11_STATION_ID, mac, sizeof(*mac));
54 if (ret < 0) 62 if (ret < 0)
55 return ret; 63 goto out;
56 64
57 return 0; 65out:
66 kfree(mac);
67 return ret;
58} 68}
59 69
60int wl12xx_acx_default_key(struct wl12xx *wl, u8 key_id) 70int wl12xx_acx_default_key(struct wl12xx *wl, u8 key_id)
61{ 71{
62 struct acx_dot11_default_key default_key; 72 struct acx_dot11_default_key *default_key;
63 int ret; 73 int ret;
64 74
65 wl12xx_debug(DEBUG_ACX, "acx dot11_default_key (%d)", key_id); 75 wl12xx_debug(DEBUG_ACX, "acx dot11_default_key (%d)", key_id);
66 76
67 default_key.header.id = DOT11_DEFAULT_KEY; 77 default_key = kzalloc(sizeof(*default_key), GFP_KERNEL);
68 default_key.header.len = sizeof(default_key) - 78 if (!default_key) {
69 sizeof(struct acx_header); 79 ret = -ENOMEM;
80 goto out;
81 }
70 82
71 default_key.id = key_id; 83 default_key->id = key_id;
72 84
73 ret = wl12xx_cmd_configure(wl, &default_key, sizeof(default_key)); 85 ret = wl12xx_cmd_configure(wl, DOT11_DEFAULT_KEY,
86 default_key, sizeof(*default_key));
74 if (ret < 0) { 87 if (ret < 0) {
75 wl12xx_error("Couldnt set default key"); 88 wl12xx_error("Couldnt set default key");
76 return ret; 89 goto out;
77 } 90 }
78 91
79 wl->default_key = key_id; 92 wl->default_key = key_id;
80 93
81 return 0; 94out:
95 kfree(default_key);
96 return ret;
82} 97}
83 98
84int wl12xx_acx_wake_up_conditions(struct wl12xx *wl, u8 listen_interval) 99int wl12xx_acx_wake_up_conditions(struct wl12xx *wl, u8 listen_interval)
85{ 100{
86 struct acx_wake_up_condition wake_up; 101 struct acx_wake_up_condition *wake_up;
102 int ret;
87 103
88 wl12xx_debug(DEBUG_ACX, "acx wake up conditions"); 104 wl12xx_debug(DEBUG_ACX, "acx wake up conditions");
89 105
90 wake_up.header.id = ACX_WAKE_UP_CONDITIONS; 106 wake_up = kzalloc(sizeof(*wake_up), GFP_KERNEL);
91 wake_up.header.len = sizeof(wake_up) - sizeof(struct acx_header); 107 if (!wake_up) {
108 ret = -ENOMEM;
109 goto out;
110 }
92 111
93 wake_up.wake_up_event = WAKE_UP_EVENT_DTIM_BITMAP; 112 wake_up->wake_up_event = WAKE_UP_EVENT_DTIM_BITMAP;
94 wake_up.listen_interval = listen_interval; 113 wake_up->listen_interval = listen_interval;
95 114
96 return wl12xx_cmd_configure(wl, &wake_up, sizeof(wake_up)); 115 ret = wl12xx_cmd_configure(wl, ACX_WAKE_UP_CONDITIONS,
116 wake_up, sizeof(*wake_up));
117 if (ret < 0) {
118 wl12xx_warning("could not set wake up conditions: %d", ret);
119 goto out;
120 }
121
122out:
123 kfree(wake_up);
124 return ret;
97} 125}
98 126
99int wl12xx_acx_sleep_auth(struct wl12xx *wl, u8 sleep_auth) 127int wl12xx_acx_sleep_auth(struct wl12xx *wl, u8 sleep_auth)
100{ 128{
129 struct acx_sleep_auth *auth;
101 int ret; 130 int ret;
102 struct acx_sleep_auth auth;
103 131
104 wl12xx_debug(DEBUG_ACX, "acx sleep auth"); 132 wl12xx_debug(DEBUG_ACX, "acx sleep auth");
105 133
106 auth.header.id = ACX_SLEEP_AUTH; 134 auth = kzalloc(sizeof(*auth), GFP_KERNEL);
107 auth.header.len = sizeof(auth) - sizeof(struct acx_header); 135 if (!auth) {
136 ret = -ENOMEM;
137 goto out;
138 }
108 139
109 auth.sleep_auth = sleep_auth; 140 auth->sleep_auth = sleep_auth;
110 141
111 ret = wl12xx_cmd_configure(wl, &auth, sizeof(auth)); 142 ret = wl12xx_cmd_configure(wl, ACX_SLEEP_AUTH, auth, sizeof(*auth));
112 if (ret < 0) 143 if (ret < 0)
113 return ret; 144 return ret;
114 145
115 return 0; 146out:
147 kfree(auth);
148 return ret;
116} 149}
117 150
118int wl12xx_acx_fw_version(struct wl12xx *wl, char *buf, size_t len) 151int wl12xx_acx_fw_version(struct wl12xx *wl, char *buf, size_t len)
119{ 152{
120 struct wl12xx_command cmd;
121 struct acx_revision *rev; 153 struct acx_revision *rev;
122 int ret; 154 int ret;
123 155
124 wl12xx_debug(DEBUG_ACX, "acx fw rev"); 156 wl12xx_debug(DEBUG_ACX, "acx fw rev");
125 157
126 memset(&cmd, 0, sizeof(cmd)); 158 rev = kzalloc(sizeof(*rev), GFP_KERNEL);
159 if (!rev) {
160 ret = -ENOMEM;
161 goto out;
162 }
127 163
128 ret = wl12xx_cmd_interrogate(wl, ACX_FW_REV, sizeof(*rev), &cmd); 164 ret = wl12xx_cmd_interrogate(wl, ACX_FW_REV, rev, sizeof(*rev));
129 if (ret < 0) { 165 if (ret < 0) {
130 wl12xx_warning("ACX_FW_REV interrogate failed"); 166 wl12xx_warning("ACX_FW_REV interrogate failed");
131 return ret; 167 goto out;
132 } 168 }
133 169
134 rev = (struct acx_revision *) &cmd.parameters;
135
136 /* be careful with the buffer sizes */ 170 /* be careful with the buffer sizes */
137 strncpy(buf, rev->fw_version, min(len, sizeof(rev->fw_version))); 171 strncpy(buf, rev->fw_version, min(len, sizeof(rev->fw_version)));
138 172
@@ -143,12 +177,14 @@ int wl12xx_acx_fw_version(struct wl12xx *wl, char *buf, size_t len)
143 */ 177 */
144 buf[min(len, sizeof(rev->fw_version)) - 1] = '\0'; 178 buf[min(len, sizeof(rev->fw_version)) - 1] = '\0';
145 179
146 return 0; 180out:
181 kfree(rev);
182 return ret;
147} 183}
148 184
149int wl12xx_acx_tx_power(struct wl12xx *wl, int power) 185int wl12xx_acx_tx_power(struct wl12xx *wl, int power)
150{ 186{
151 struct acx_current_tx_power ie; 187 struct acx_current_tx_power *acx;
152 int ret; 188 int ret;
153 189
154 wl12xx_debug(DEBUG_ACX, "acx dot11_cur_tx_pwr"); 190 wl12xx_debug(DEBUG_ACX, "acx dot11_cur_tx_pwr");
@@ -156,534 +192,648 @@ int wl12xx_acx_tx_power(struct wl12xx *wl, int power)
156 if (power < 0 || power > 25) 192 if (power < 0 || power > 25)
157 return -EINVAL; 193 return -EINVAL;
158 194
159 memset(&ie, 0, sizeof(ie)); 195 acx = kzalloc(sizeof(*acx), GFP_KERNEL);
196 if (!acx) {
197 ret = -ENOMEM;
198 goto out;
199 }
160 200
161 ie.header.id = DOT11_CUR_TX_PWR; 201 acx->current_tx_power = power * 10;
162 ie.header.len = sizeof(ie) - sizeof(struct acx_header);
163 ie.current_tx_power = power * 10;
164 202
165 ret = wl12xx_cmd_configure(wl, &ie, sizeof(ie)); 203 ret = wl12xx_cmd_configure(wl, DOT11_CUR_TX_PWR, acx, sizeof(*acx));
166 if (ret < 0) { 204 if (ret < 0) {
167 wl12xx_warning("configure of tx power failed: %d", ret); 205 wl12xx_warning("configure of tx power failed: %d", ret);
168 return ret; 206 goto out;
169 } 207 }
170 208
171 return 0; 209out:
210 kfree(acx);
211 return ret;
172} 212}
173 213
174int wl12xx_acx_feature_cfg(struct wl12xx *wl) 214int wl12xx_acx_feature_cfg(struct wl12xx *wl)
175{ 215{
176 struct acx_feature_config feature; 216 struct acx_feature_config *feature;
177 int ret; 217 int ret;
178 218
179 wl12xx_debug(DEBUG_ACX, "acx feature cfg"); 219 wl12xx_debug(DEBUG_ACX, "acx feature cfg");
180 220
181 memset(&feature, 0, sizeof(feature)); 221 feature = kzalloc(sizeof(*feature), GFP_KERNEL);
182 222 if (!feature) {
183 feature.header.id = ACX_FEATURE_CFG; 223 ret = -ENOMEM;
184 feature.header.len = sizeof(feature) - sizeof(struct acx_header); 224 goto out;
225 }
185 226
186 /* DF_ENCRYPTION_DISABLE and DF_SNIFF_MODE_ENABLE are disabled */ 227 /* DF_ENCRYPTION_DISABLE and DF_SNIFF_MODE_ENABLE are disabled */
187 feature.data_flow_options = 0; 228 feature->data_flow_options = 0;
188 feature.options = 0; 229 feature->options = 0;
189 230
190 ret = wl12xx_cmd_configure(wl, &feature, sizeof(feature)); 231 ret = wl12xx_cmd_configure(wl, ACX_FEATURE_CFG,
191 if (ret < 0) 232 feature, sizeof(*feature));
233 if (ret < 0) {
192 wl12xx_error("Couldnt set HW encryption"); 234 wl12xx_error("Couldnt set HW encryption");
235 goto out;
236 }
193 237
238out:
239 kfree(feature);
194 return ret; 240 return ret;
195} 241}
196 242
197int wl12xx_acx_mem_map(struct wl12xx *wl, void *mem_map, size_t len) 243int wl12xx_acx_mem_map(struct wl12xx *wl, struct acx_header *mem_map,
244 size_t len)
198{ 245{
199 struct wl12xx_command cmd;
200 int ret; 246 int ret;
201 247
202 wl12xx_debug(DEBUG_ACX, "acx mem map"); 248 wl12xx_debug(DEBUG_ACX, "acx mem map");
203 249
204 ret = wl12xx_cmd_interrogate(wl, ACX_MEM_MAP, len, &cmd); 250 ret = wl12xx_cmd_interrogate(wl, ACX_MEM_MAP, mem_map, len);
205 if (ret < 0) 251 if (ret < 0)
206 return ret; 252 return ret;
207 else if (cmd.status != CMD_STATUS_SUCCESS)
208 return -EIO;
209
210 memcpy(mem_map, &cmd.parameters, len);
211 253
212 return 0; 254 return 0;
213} 255}
214 256
215int wl12xx_acx_data_path_params(struct wl12xx *wl, 257int wl12xx_acx_data_path_params(struct wl12xx *wl,
216 struct acx_data_path_params_resp *data_path) 258 struct acx_data_path_params_resp *resp)
217{ 259{
218 struct acx_data_path_params params; 260 struct acx_data_path_params *params;
219 struct wl12xx_command cmd;
220 int ret; 261 int ret;
221 262
222 wl12xx_debug(DEBUG_ACX, "acx data path params"); 263 wl12xx_debug(DEBUG_ACX, "acx data path params");
223 264
224 params.rx_packet_ring_chunk_size = DP_RX_PACKET_RING_CHUNK_SIZE; 265 params = kzalloc(sizeof(*params), GFP_KERNEL);
225 params.tx_packet_ring_chunk_size = DP_TX_PACKET_RING_CHUNK_SIZE; 266 if (!params) {
267 ret = -ENOMEM;
268 goto out;
269 }
226 270
227 params.rx_packet_ring_chunk_num = DP_RX_PACKET_RING_CHUNK_NUM; 271 params->rx_packet_ring_chunk_size = DP_RX_PACKET_RING_CHUNK_SIZE;
228 params.tx_packet_ring_chunk_num = DP_TX_PACKET_RING_CHUNK_NUM; 272 params->tx_packet_ring_chunk_size = DP_TX_PACKET_RING_CHUNK_SIZE;
229 273
230 params.tx_complete_threshold = 1; 274 params->rx_packet_ring_chunk_num = DP_RX_PACKET_RING_CHUNK_NUM;
275 params->tx_packet_ring_chunk_num = DP_TX_PACKET_RING_CHUNK_NUM;
231 276
232 params.tx_complete_ring_depth = FW_TX_CMPLT_BLOCK_SIZE; 277 params->tx_complete_threshold = 1;
233 278
234 params.tx_complete_timeout = DP_TX_COMPLETE_TIME_OUT; 279 params->tx_complete_ring_depth = FW_TX_CMPLT_BLOCK_SIZE;
235 280
236 params.header.id = ACX_DATA_PATH_PARAMS; 281 params->tx_complete_timeout = DP_TX_COMPLETE_TIME_OUT;
237 params.header.len = sizeof(params) - sizeof(struct acx_header);
238 282
239 ret = wl12xx_cmd_configure(wl, &params, sizeof(params)); 283 ret = wl12xx_cmd_configure(wl, ACX_DATA_PATH_PARAMS,
284 params, sizeof(*params));
240 if (ret < 0) 285 if (ret < 0)
241 return ret; 286 goto out;
242
243 287
288 /* FIXME: shouldn't this be ACX_DATA_PATH_RESP_PARAMS? */
244 ret = wl12xx_cmd_interrogate(wl, ACX_DATA_PATH_PARAMS, 289 ret = wl12xx_cmd_interrogate(wl, ACX_DATA_PATH_PARAMS,
245 sizeof(struct acx_data_path_params_resp), 290 resp, sizeof(*resp));
246 &cmd);
247 291
248 if (ret < 0) { 292 if (ret < 0) {
249 wl12xx_warning("failed to read data path parameters: %d", ret); 293 wl12xx_warning("failed to read data path parameters: %d", ret);
250 return ret; 294 goto out;
251 } else if (cmd.status != CMD_STATUS_SUCCESS) { 295 } else if (resp->header.cmd.status != CMD_STATUS_SUCCESS) {
252 wl12xx_warning("data path parameter acx status failed"); 296 wl12xx_warning("data path parameter acx status failed");
253 return -EIO; 297 ret = -EIO;
298 goto out;
254 } 299 }
255 300
256 memcpy(data_path, &cmd.parameters, sizeof(*data_path)); 301out:
257 302 kfree(params);
258 return 0; 303 return ret;
259} 304}
260 305
261int wl12xx_acx_rx_msdu_life_time(struct wl12xx *wl, u32 life_time) 306int wl12xx_acx_rx_msdu_life_time(struct wl12xx *wl, u32 life_time)
262{ 307{
263 struct rx_msdu_lifetime msdu_lifetime; 308 struct acx_rx_msdu_lifetime *acx;
264 int ret; 309 int ret;
265 310
266 wl12xx_debug(DEBUG_ACX, "acx rx msdu life time"); 311 wl12xx_debug(DEBUG_ACX, "acx rx msdu life time");
267 312
268 msdu_lifetime.header.id = DOT11_RX_MSDU_LIFE_TIME; 313 acx = kzalloc(sizeof(*acx), GFP_KERNEL);
269 msdu_lifetime.header.len = sizeof(msdu_lifetime) - 314 if (!acx) {
270 sizeof(struct acx_header); 315 ret = -ENOMEM;
271 msdu_lifetime.lifetime = life_time; 316 goto out;
317 }
272 318
273 ret = wl12xx_cmd_configure(wl, &msdu_lifetime, sizeof(msdu_lifetime)); 319 ret = wl12xx_cmd_configure(wl, DOT11_RX_MSDU_LIFE_TIME,
320 acx, sizeof(*acx));
274 if (ret < 0) { 321 if (ret < 0) {
275 wl12xx_warning("failed to set rx msdu life time: %d", ret); 322 wl12xx_warning("failed to set rx msdu life time: %d", ret);
276 return ret; 323 goto out;
277 } 324 }
278 325
279 return 0; 326out:
327 kfree(acx);
328 return ret;
280} 329}
281 330
282int wl12xx_acx_rx_config(struct wl12xx *wl, u32 config, u32 filter) 331int wl12xx_acx_rx_config(struct wl12xx *wl, u32 config, u32 filter)
283{ 332{
284 struct acx_rx_config rx_config; 333 struct acx_rx_config *rx_config;
285 int ret; 334 int ret;
286 335
287 wl12xx_debug(DEBUG_ACX, "acx rx config"); 336 wl12xx_debug(DEBUG_ACX, "acx rx config");
288 337
289 rx_config.header.id = ACX_RX_CFG; 338 rx_config = kzalloc(sizeof(*rx_config), GFP_KERNEL);
290 rx_config.header.len = sizeof(rx_config) - sizeof(struct acx_header); 339 if (!rx_config) {
291 rx_config.config_options = config; 340 ret = -ENOMEM;
292 rx_config.filter_options = filter; 341 goto out;
342 }
343
344 rx_config->config_options = config;
345 rx_config->filter_options = filter;
293 346
294 ret = wl12xx_cmd_configure(wl, &rx_config, sizeof(rx_config)); 347 ret = wl12xx_cmd_configure(wl, ACX_RX_CFG,
348 rx_config, sizeof(*rx_config));
295 if (ret < 0) { 349 if (ret < 0) {
296 wl12xx_warning("failed to set rx config: %d", ret); 350 wl12xx_warning("failed to set rx config: %d", ret);
297 return ret; 351 goto out;
298 } 352 }
299 353
300 return 0; 354out:
355 kfree(rx_config);
356 return ret;
301} 357}
302 358
303int wl12xx_acx_pd_threshold(struct wl12xx *wl) 359int wl12xx_acx_pd_threshold(struct wl12xx *wl)
304{ 360{
305 struct acx_packet_detection packet_detection; 361 struct acx_packet_detection *pd;
306 int ret; 362 int ret;
307 363
308 wl12xx_debug(DEBUG_ACX, "acx data pd threshold"); 364 wl12xx_debug(DEBUG_ACX, "acx data pd threshold");
309 365
366 pd = kzalloc(sizeof(*pd), GFP_KERNEL);
367 if (!pd) {
368 ret = -ENOMEM;
369 goto out;
370 }
371
310 /* FIXME: threshold value not set */ 372 /* FIXME: threshold value not set */
311 packet_detection.header.id = ACX_PD_THRESHOLD;
312 packet_detection.header.len = sizeof(packet_detection) -
313 sizeof(struct acx_header);
314 373
315 ret = wl12xx_cmd_configure(wl, &packet_detection, 374 ret = wl12xx_cmd_configure(wl, ACX_PD_THRESHOLD, pd, sizeof(*pd));
316 sizeof(packet_detection));
317 if (ret < 0) { 375 if (ret < 0) {
318 wl12xx_warning("failed to set pd threshold: %d", ret); 376 wl12xx_warning("failed to set pd threshold: %d", ret);
319 return ret; 377 goto out;
320 } 378 }
321 379
380out:
381 kfree(pd);
322 return 0; 382 return 0;
323} 383}
324 384
325int wl12xx_acx_slot(struct wl12xx *wl, enum acx_slot_type slot_time) 385int wl12xx_acx_slot(struct wl12xx *wl, enum acx_slot_type slot_time)
326{ 386{
327 struct acx_slot slot; 387 struct acx_slot *slot;
328 int ret; 388 int ret;
329 389
330 wl12xx_debug(DEBUG_ACX, "acx slot"); 390 wl12xx_debug(DEBUG_ACX, "acx slot");
331 391
332 slot.header.id = ACX_SLOT; 392 slot = kzalloc(sizeof(*slot), GFP_KERNEL);
333 slot.header.len = sizeof(slot) - sizeof(struct acx_header); 393 if (!slot) {
394 ret = -ENOMEM;
395 goto out;
396 }
334 397
335 slot.wone_index = STATION_WONE_INDEX; 398 slot->wone_index = STATION_WONE_INDEX;
336 slot.slot_time = slot_time; 399 slot->slot_time = slot_time;
337 400
338 ret = wl12xx_cmd_configure(wl, &slot, sizeof(slot)); 401 ret = wl12xx_cmd_configure(wl, ACX_SLOT, slot, sizeof(*slot));
339 if (ret < 0) { 402 if (ret < 0) {
340 wl12xx_warning("failed to set slot time: %d", ret); 403 wl12xx_warning("failed to set slot time: %d", ret);
341 return ret; 404 goto out;
342 } 405 }
343 406
344 return 0; 407out:
408 kfree(slot);
409 return ret;
345} 410}
346 411
347int wl12xx_acx_group_address_tbl(struct wl12xx *wl) 412int wl12xx_acx_group_address_tbl(struct wl12xx *wl)
348{ 413{
349 struct multicast_grp_addr_start multicast; 414 struct acx_dot11_grp_addr_tbl *acx;
350 int ret; 415 int ret;
351 416
352 wl12xx_debug(DEBUG_ACX, "acx group address tbl"); 417 wl12xx_debug(DEBUG_ACX, "acx group address tbl");
353 418
354 /* MAC filtering */ 419 acx = kzalloc(sizeof(*acx), GFP_KERNEL);
355 multicast.header.id = DOT11_GROUP_ADDRESS_TBL; 420 if (!acx) {
356 multicast.header.len = sizeof(multicast) - sizeof(struct acx_header); 421 ret = -ENOMEM;
422 goto out;
423 }
357 424
358 multicast.enabled = 0; 425 /* MAC filtering */
359 multicast.num_groups = 0; 426 acx->enabled = 0;
360 memset(multicast.mac_table, 0, ADDRESS_GROUP_MAX_LEN); 427 acx->num_groups = 0;
428 memset(acx->mac_table, 0, ADDRESS_GROUP_MAX_LEN);
361 429
362 ret = wl12xx_cmd_configure(wl, &multicast, sizeof(multicast)); 430 ret = wl12xx_cmd_configure(wl, DOT11_GROUP_ADDRESS_TBL,
431 acx, sizeof(*acx));
363 if (ret < 0) { 432 if (ret < 0) {
364 wl12xx_warning("failed to set group addr table: %d", ret); 433 wl12xx_warning("failed to set group addr table: %d", ret);
365 return ret; 434 goto out;
366 } 435 }
367 436
368 return 0; 437out:
438 kfree(acx);
439 return ret;
369} 440}
370 441
371int wl12xx_acx_service_period_timeout(struct wl12xx *wl) 442int wl12xx_acx_service_period_timeout(struct wl12xx *wl)
372{ 443{
373 struct acx_rx_timeout rx_timeout; 444 struct acx_rx_timeout *rx_timeout;
374 int ret; 445 int ret;
375 446
376 wl12xx_debug(DEBUG_ACX, "acx service period timeout"); 447 rx_timeout = kzalloc(sizeof(*rx_timeout), GFP_KERNEL);
448 if (!rx_timeout) {
449 ret = -ENOMEM;
450 goto out;
451 }
377 452
378 /* RX timeout */ 453 wl12xx_debug(DEBUG_ACX, "acx service period timeout");
379 rx_timeout.header.id = ACX_SERVICE_PERIOD_TIMEOUT;
380 rx_timeout.header.len = sizeof(rx_timeout) - sizeof(struct acx_header);
381 454
382 rx_timeout.ps_poll_timeout = RX_TIMEOUT_PS_POLL_DEF; 455 rx_timeout->ps_poll_timeout = RX_TIMEOUT_PS_POLL_DEF;
383 rx_timeout.upsd_timeout = RX_TIMEOUT_UPSD_DEF; 456 rx_timeout->upsd_timeout = RX_TIMEOUT_UPSD_DEF;
384 457
385 ret = wl12xx_cmd_configure(wl, &rx_timeout, sizeof(rx_timeout)); 458 ret = wl12xx_cmd_configure(wl, ACX_SERVICE_PERIOD_TIMEOUT,
459 rx_timeout, sizeof(*rx_timeout));
386 if (ret < 0) { 460 if (ret < 0) {
387 wl12xx_warning("failed to set service period timeout: %d", 461 wl12xx_warning("failed to set service period timeout: %d",
388 ret); 462 ret);
389 return ret; 463 goto out;
390 } 464 }
391 465
392 return 0; 466out:
467 kfree(rx_timeout);
468 return ret;
393} 469}
394 470
395int wl12xx_acx_rts_threshold(struct wl12xx *wl, u16 rts_threshold) 471int wl12xx_acx_rts_threshold(struct wl12xx *wl, u16 rts_threshold)
396{ 472{
397 struct acx_rts_threshold rts; 473 struct acx_rts_threshold *rts;
398 int ret; 474 int ret;
399 475
400 wl12xx_debug(DEBUG_ACX, "acx rts threshold"); 476 wl12xx_debug(DEBUG_ACX, "acx rts threshold");
401 477
402 rts.header.id = DOT11_RTS_THRESHOLD; 478 rts = kzalloc(sizeof(*rts), GFP_KERNEL);
403 rts.header.len = sizeof(rts) - sizeof(struct acx_header); 479 if (!rts) {
480 ret = -ENOMEM;
481 goto out;
482 }
404 483
405 rts.threshold = rts_threshold; 484 rts->threshold = rts_threshold;
406 485
407 ret = wl12xx_cmd_configure(wl, &rts, sizeof(rts)); 486 ret = wl12xx_cmd_configure(wl, DOT11_RTS_THRESHOLD, rts, sizeof(*rts));
408 if (ret < 0) { 487 if (ret < 0) {
409 wl12xx_warning("failed to set rts threshold: %d", ret); 488 wl12xx_warning("failed to set rts threshold: %d", ret);
410 return ret; 489 goto out;
411 } 490 }
412 491
413 return 0; 492out:
493 kfree(rts);
494 return ret;
414} 495}
415 496
416int wl12xx_acx_beacon_filter_opt(struct wl12xx *wl) 497int wl12xx_acx_beacon_filter_opt(struct wl12xx *wl)
417{ 498{
418 struct acx_beacon_filter_option beacon_filter; 499 struct acx_beacon_filter_option *beacon_filter;
419 int ret; 500 int ret;
420 501
421 wl12xx_debug(DEBUG_ACX, "acx beacon filter opt"); 502 wl12xx_debug(DEBUG_ACX, "acx beacon filter opt");
422 503
423 beacon_filter.header.id = ACX_BEACON_FILTER_OPT; 504 beacon_filter = kzalloc(sizeof(*beacon_filter), GFP_KERNEL);
424 beacon_filter.header.len = sizeof(beacon_filter) - 505 if (!beacon_filter) {
425 sizeof(struct acx_header); 506 ret = -ENOMEM;
507 goto out;
508 }
426 509
427 beacon_filter.enable = 0; 510 beacon_filter->enable = 0;
428 beacon_filter.max_num_beacons = 0; 511 beacon_filter->max_num_beacons = 0;
429 512
430 ret = wl12xx_cmd_configure(wl, &beacon_filter, sizeof(beacon_filter)); 513 ret = wl12xx_cmd_configure(wl, ACX_BEACON_FILTER_OPT,
514 beacon_filter, sizeof(*beacon_filter));
431 if (ret < 0) { 515 if (ret < 0) {
432 wl12xx_warning("failed to set beacon filter opt: %d", ret); 516 wl12xx_warning("failed to set beacon filter opt: %d", ret);
433 return ret; 517 goto out;
434 } 518 }
435 519
436 return 0; 520out:
521 kfree(beacon_filter);
522 return ret;
437} 523}
438 524
439int wl12xx_acx_beacon_filter_table(struct wl12xx *wl) 525int wl12xx_acx_beacon_filter_table(struct wl12xx *wl)
440{ 526{
441 struct acx_beacon_filter_ie_table ie_table; 527 struct acx_beacon_filter_ie_table *ie_table;
442 int ret; 528 int ret;
443 529
444 wl12xx_debug(DEBUG_ACX, "acx beacon filter table"); 530 wl12xx_debug(DEBUG_ACX, "acx beacon filter table");
445 531
446 ie_table.header.id = ACX_BEACON_FILTER_TABLE; 532 ie_table = kzalloc(sizeof(*ie_table), GFP_KERNEL);
447 ie_table.header.len = sizeof(ie_table) - sizeof(struct acx_header); 533 if (!ie_table) {
534 ret = -ENOMEM;
535 goto out;
536 }
448 537
449 ie_table.num_ie = 0; 538 ie_table->num_ie = 0;
450 memset(ie_table.table, 0, BEACON_FILTER_TABLE_MAX_SIZE); 539 memset(ie_table->table, 0, BEACON_FILTER_TABLE_MAX_SIZE);
451 540
452 ret = wl12xx_cmd_configure(wl, &ie_table, sizeof(ie_table)); 541 ret = wl12xx_cmd_configure(wl, ACX_BEACON_FILTER_TABLE,
542 ie_table, sizeof(*ie_table));
453 if (ret < 0) { 543 if (ret < 0) {
454 wl12xx_warning("failed to set beacon filter table: %d", ret); 544 wl12xx_warning("failed to set beacon filter table: %d", ret);
455 return ret; 545 goto out;
456 } 546 }
457 547
458 return 0; 548out:
549 kfree(ie_table);
550 return ret;
459} 551}
460 552
461int wl12xx_acx_sg_enable(struct wl12xx *wl) 553int wl12xx_acx_sg_enable(struct wl12xx *wl)
462{ 554{
463 struct acx_bt_wlan_coex pta; 555 struct acx_bt_wlan_coex *pta;
464 int ret; 556 int ret;
465 557
466 wl12xx_debug(DEBUG_ACX, "acx sg enable"); 558 wl12xx_debug(DEBUG_ACX, "acx sg enable");
467 559
468 pta.header.id = ACX_SG_ENABLE; 560 pta = kzalloc(sizeof(*pta), GFP_KERNEL);
469 pta.header.len = sizeof(pta) - sizeof(struct acx_header); 561 if (!pta) {
562 ret = -ENOMEM;
563 goto out;
564 }
470 565
471 pta.enable = SG_ENABLE; 566 pta->enable = SG_ENABLE;
472 567
473 ret = wl12xx_cmd_configure(wl, &pta, sizeof(pta)); 568 ret = wl12xx_cmd_configure(wl, ACX_SG_ENABLE, pta, sizeof(*pta));
474 if (ret < 0) { 569 if (ret < 0) {
475 wl12xx_warning("failed to set softgemini enable: %d", ret); 570 wl12xx_warning("failed to set softgemini enable: %d", ret);
476 return ret; 571 goto out;
477 } 572 }
478 573
479 return 0; 574out:
575 kfree(pta);
576 return ret;
480} 577}
481 578
482int wl12xx_acx_sg_cfg(struct wl12xx *wl) 579int wl12xx_acx_sg_cfg(struct wl12xx *wl)
483{ 580{
484 struct acx_bt_wlan_coex_param param; 581 struct acx_bt_wlan_coex_param *param;
485 int ret; 582 int ret;
486 583
487 wl12xx_debug(DEBUG_ACX, "acx sg cfg"); 584 wl12xx_debug(DEBUG_ACX, "acx sg cfg");
488 585
586 param = kzalloc(sizeof(*param), GFP_KERNEL);
587 if (!param) {
588 ret = -ENOMEM;
589 goto out;
590 }
591
489 /* BT-WLAN coext parameters */ 592 /* BT-WLAN coext parameters */
490 param.header.id = ACX_SG_CFG; 593 param->min_rate = RATE_INDEX_24MBPS;
491 param.header.len = sizeof(param) - sizeof(struct acx_header); 594 param->bt_hp_max_time = PTA_BT_HP_MAXTIME_DEF;
492 595 param->wlan_hp_max_time = PTA_WLAN_HP_MAX_TIME_DEF;
493 param.min_rate = RATE_INDEX_24MBPS; 596 param->sense_disable_timer = PTA_SENSE_DISABLE_TIMER_DEF;
494 param.bt_hp_max_time = PTA_BT_HP_MAXTIME_DEF; 597 param->rx_time_bt_hp = PTA_PROTECTIVE_RX_TIME_DEF;
495 param.wlan_hp_max_time = PTA_WLAN_HP_MAX_TIME_DEF; 598 param->tx_time_bt_hp = PTA_PROTECTIVE_TX_TIME_DEF;
496 param.sense_disable_timer = PTA_SENSE_DISABLE_TIMER_DEF; 599 param->rx_time_bt_hp_fast = PTA_PROTECTIVE_RX_TIME_FAST_DEF;
497 param.rx_time_bt_hp = PTA_PROTECTIVE_RX_TIME_DEF; 600 param->tx_time_bt_hp_fast = PTA_PROTECTIVE_TX_TIME_FAST_DEF;
498 param.tx_time_bt_hp = PTA_PROTECTIVE_TX_TIME_DEF; 601 param->wlan_cycle_fast = PTA_CYCLE_TIME_FAST_DEF;
499 param.rx_time_bt_hp_fast = PTA_PROTECTIVE_RX_TIME_FAST_DEF; 602 param->bt_anti_starvation_period = PTA_ANTI_STARVE_PERIOD_DEF;
500 param.tx_time_bt_hp_fast = PTA_PROTECTIVE_TX_TIME_FAST_DEF; 603 param->next_bt_lp_packet = PTA_TIMEOUT_NEXT_BT_LP_PACKET_DEF;
501 param.wlan_cycle_fast = PTA_CYCLE_TIME_FAST_DEF; 604 param->wake_up_beacon = PTA_TIME_BEFORE_BEACON_DEF;
502 param.bt_anti_starvation_period = PTA_ANTI_STARVE_PERIOD_DEF; 605 param->hp_dm_max_guard_time = PTA_HPDM_MAX_TIME_DEF;
503 param.next_bt_lp_packet = PTA_TIMEOUT_NEXT_BT_LP_PACKET_DEF; 606 param->next_wlan_packet = PTA_TIME_OUT_NEXT_WLAN_DEF;
504 param.wake_up_beacon = PTA_TIME_BEFORE_BEACON_DEF; 607 param->antenna_type = PTA_ANTENNA_TYPE_DEF;
505 param.hp_dm_max_guard_time = PTA_HPDM_MAX_TIME_DEF; 608 param->signal_type = PTA_SIGNALING_TYPE_DEF;
506 param.next_wlan_packet = PTA_TIME_OUT_NEXT_WLAN_DEF; 609 param->afh_leverage_on = PTA_AFH_LEVERAGE_ON_DEF;
507 param.antenna_type = PTA_ANTENNA_TYPE_DEF; 610 param->quiet_cycle_num = PTA_NUMBER_QUIET_CYCLE_DEF;
508 param.signal_type = PTA_SIGNALING_TYPE_DEF; 611 param->max_cts = PTA_MAX_NUM_CTS_DEF;
509 param.afh_leverage_on = PTA_AFH_LEVERAGE_ON_DEF; 612 param->wlan_packets_num = PTA_NUMBER_OF_WLAN_PACKETS_DEF;
510 param.quiet_cycle_num = PTA_NUMBER_QUIET_CYCLE_DEF; 613 param->bt_packets_num = PTA_NUMBER_OF_BT_PACKETS_DEF;
511 param.max_cts = PTA_MAX_NUM_CTS_DEF; 614 param->missed_rx_avalanche = PTA_RX_FOR_AVALANCHE_DEF;
512 param.wlan_packets_num = PTA_NUMBER_OF_WLAN_PACKETS_DEF; 615 param->wlan_elp_hp = PTA_ELP_HP_DEF;
513 param.bt_packets_num = PTA_NUMBER_OF_BT_PACKETS_DEF; 616 param->bt_anti_starvation_cycles = PTA_ANTI_STARVE_NUM_CYCLE_DEF;
514 param.missed_rx_avalanche = PTA_RX_FOR_AVALANCHE_DEF; 617 param->ack_mode_dual_ant = PTA_ACK_MODE_DEF;
515 param.wlan_elp_hp = PTA_ELP_HP_DEF; 618 param->pa_sd_enable = PTA_ALLOW_PA_SD_DEF;
516 param.bt_anti_starvation_cycles = PTA_ANTI_STARVE_NUM_CYCLE_DEF; 619 param->pta_auto_mode_enable = PTA_AUTO_MODE_NO_CTS_DEF;
517 param.ack_mode_dual_ant = PTA_ACK_MODE_DEF; 620 param->bt_hp_respected_num = PTA_BT_HP_RESPECTED_DEF;
518 param.pa_sd_enable = PTA_ALLOW_PA_SD_DEF; 621
519 param.pta_auto_mode_enable = PTA_AUTO_MODE_NO_CTS_DEF; 622 ret = wl12xx_cmd_configure(wl, ACX_SG_CFG, param, sizeof(*param));
520 param.bt_hp_respected_num = PTA_BT_HP_RESPECTED_DEF;
521
522 ret = wl12xx_cmd_configure(wl, &param, sizeof(param));
523 if (ret < 0) { 623 if (ret < 0) {
524 wl12xx_warning("failed to set sg config: %d", ret); 624 wl12xx_warning("failed to set sg config: %d", ret);
525 return ret; 625 goto out;
526 } 626 }
527 627
528 return 0; 628out:
629 kfree(param);
630 return ret;
529} 631}
530 632
531int wl12xx_acx_cca_threshold(struct wl12xx *wl) 633int wl12xx_acx_cca_threshold(struct wl12xx *wl)
532{ 634{
533 struct acx_energy_detection detection; 635 struct acx_energy_detection *detection;
534 int ret; 636 int ret;
535 637
536 wl12xx_debug(DEBUG_ACX, "acx cca threshold"); 638 wl12xx_debug(DEBUG_ACX, "acx cca threshold");
537 639
538 detection.header.id = ACX_CCA_THRESHOLD; 640 detection = kzalloc(sizeof(*detection), GFP_KERNEL);
539 detection.header.len = sizeof(detection) - sizeof(struct acx_header); 641 if (!detection) {
642 ret = -ENOMEM;
643 goto out;
644 }
540 645
541 detection.rx_cca_threshold = CCA_THRSH_DISABLE_ENERGY_D; 646 detection->rx_cca_threshold = CCA_THRSH_DISABLE_ENERGY_D;
542 detection.tx_energy_detection = 0; 647 detection->tx_energy_detection = 0;
543 648
544 ret = wl12xx_cmd_configure(wl, &detection, sizeof(detection)); 649 ret = wl12xx_cmd_configure(wl, ACX_CCA_THRESHOLD,
650 detection, sizeof(*detection));
545 if (ret < 0) { 651 if (ret < 0) {
546 wl12xx_warning("failed to set cca threshold: %d", ret); 652 wl12xx_warning("failed to set cca threshold: %d", ret);
547 return ret; 653 return ret;
548 } 654 }
549 655
550 return 0; 656out:
657 kfree(detection);
658 return ret;
551} 659}
552 660
553int wl12xx_acx_bcn_dtim_options(struct wl12xx *wl) 661int wl12xx_acx_bcn_dtim_options(struct wl12xx *wl)
554{ 662{
555 struct acx_beacon_broadcast bb; 663 struct acx_beacon_broadcast *bb;
556 int ret; 664 int ret;
557 665
558 wl12xx_debug(DEBUG_ACX, "acx bcn dtim options"); 666 wl12xx_debug(DEBUG_ACX, "acx bcn dtim options");
559 667
560 bb.header.id = ACX_BCN_DTIM_OPTIONS; 668 bb = kzalloc(sizeof(*bb), GFP_KERNEL);
561 bb.header.len = sizeof(bb) - sizeof(struct acx_header); 669 if (!bb) {
670 ret = -ENOMEM;
671 goto out;
672 }
562 673
563 bb.beacon_rx_timeout = BCN_RX_TIMEOUT_DEF_VALUE; 674 bb->beacon_rx_timeout = BCN_RX_TIMEOUT_DEF_VALUE;
564 bb.broadcast_timeout = BROADCAST_RX_TIMEOUT_DEF_VALUE; 675 bb->broadcast_timeout = BROADCAST_RX_TIMEOUT_DEF_VALUE;
565 bb.rx_broadcast_in_ps = RX_BROADCAST_IN_PS_DEF_VALUE; 676 bb->rx_broadcast_in_ps = RX_BROADCAST_IN_PS_DEF_VALUE;
566 bb.ps_poll_threshold = CONSECUTIVE_PS_POLL_FAILURE_DEF; 677 bb->ps_poll_threshold = CONSECUTIVE_PS_POLL_FAILURE_DEF;
567 678
568 ret = wl12xx_cmd_configure(wl, &bb, sizeof(bb)); 679 ret = wl12xx_cmd_configure(wl, ACX_BCN_DTIM_OPTIONS, bb, sizeof(*bb));
569 if (ret < 0) { 680 if (ret < 0) {
570 wl12xx_warning("failed to set rx config: %d", ret); 681 wl12xx_warning("failed to set rx config: %d", ret);
571 return ret; 682 goto out;
572 } 683 }
573 684
574 return 0; 685out:
686 kfree(bb);
687 return ret;
575} 688}
576 689
577int wl12xx_acx_aid(struct wl12xx *wl, u16 aid) 690int wl12xx_acx_aid(struct wl12xx *wl, u16 aid)
578{ 691{
579 struct acx_aid acx_aid; 692 struct acx_aid *acx_aid;
580 int ret; 693 int ret;
581 694
582 wl12xx_debug(DEBUG_ACX, "acx aid"); 695 wl12xx_debug(DEBUG_ACX, "acx aid");
583 696
584 acx_aid.header.id = ACX_AID; 697 acx_aid = kzalloc(sizeof(*acx_aid), GFP_KERNEL);
585 acx_aid.header.len = sizeof(acx_aid) - sizeof(struct acx_header); 698 if (!acx_aid) {
699 ret = -ENOMEM;
700 goto out;
701 }
586 702
587 acx_aid.aid = aid; 703 acx_aid->aid = aid;
588 704
589 ret = wl12xx_cmd_configure(wl, &acx_aid, sizeof(acx_aid)); 705 ret = wl12xx_cmd_configure(wl, ACX_AID, acx_aid, sizeof(*acx_aid));
590 if (ret < 0) { 706 if (ret < 0) {
591 wl12xx_warning("failed to set aid: %d", ret); 707 wl12xx_warning("failed to set aid: %d", ret);
592 return ret; 708 goto out;
593 } 709 }
594 710
595 return 0; 711out:
712 kfree(acx_aid);
713 return ret;
596} 714}
597 715
598int wl12xx_acx_event_mbox_mask(struct wl12xx *wl, u32 event_mask) 716int wl12xx_acx_event_mbox_mask(struct wl12xx *wl, u32 event_mask)
599{ 717{
600 struct acx_event_mask mask; 718 struct acx_event_mask *mask;
601 int ret; 719 int ret;
602 720
603 wl12xx_debug(DEBUG_ACX, "acx event mbox mask"); 721 wl12xx_debug(DEBUG_ACX, "acx event mbox mask");
604 722
605 mask.header.id = ACX_EVENT_MBOX_MASK; 723 mask = kzalloc(sizeof(*mask), GFP_KERNEL);
606 mask.header.len = sizeof(mask) - sizeof(struct acx_header); 724 if (!mask) {
725 ret = -ENOMEM;
726 goto out;
727 }
607 728
608 /* high event mask is unused */ 729 /* high event mask is unused */
609 mask.high_event_mask = 0xffffffff; 730 mask->high_event_mask = 0xffffffff;
610 731
611 mask.event_mask = event_mask; 732 mask->event_mask = event_mask;
612 733
613 ret = wl12xx_cmd_configure(wl, &mask, sizeof(mask)); 734 ret = wl12xx_cmd_configure(wl, ACX_EVENT_MBOX_MASK,
735 mask, sizeof(*mask));
614 if (ret < 0) { 736 if (ret < 0) {
615 wl12xx_warning("failed to set aid: %d", ret); 737 wl12xx_warning("failed to set aid: %d", ret);
616 return ret; 738 goto out;
617 } 739 }
618 740
619 return 0; 741out:
742 kfree(mask);
743 return ret;
620} 744}
621 745
622int wl12xx_acx_set_preamble(struct wl12xx *wl, enum acx_preamble_type preamble) 746int wl12xx_acx_set_preamble(struct wl12xx *wl, enum acx_preamble_type preamble)
623{ 747{
624 struct acx_preamble ie; 748 struct acx_preamble *acx;
625 int ret; 749 int ret;
626 750
627 wl12xx_debug(DEBUG_ACX, "acx_set_preamble"); 751 wl12xx_debug(DEBUG_ACX, "acx_set_preamble");
628 752
629 memset(&ie, 0, sizeof(ie)); 753 acx = kzalloc(sizeof(*acx), GFP_KERNEL);
754 if (!acx) {
755 ret = -ENOMEM;
756 goto out;
757 }
630 758
631 ie.header.id = ACX_PREAMBLE_TYPE; 759 acx->preamble = preamble;
632 ie.header.len = sizeof(ie) - sizeof(struct acx_header); 760
633 ie.preamble = preamble; 761 ret = wl12xx_cmd_configure(wl, ACX_PREAMBLE_TYPE, acx, sizeof(*acx));
634 ret = wl12xx_cmd_configure(wl, &ie, sizeof(ie));
635 if (ret < 0) { 762 if (ret < 0) {
636 wl12xx_warning("Setting of preamble failed: %d", ret); 763 wl12xx_warning("Setting of preamble failed: %d", ret);
637 return ret; 764 goto out;
638 } 765 }
639 return 0; 766
767out:
768 kfree(acx);
769 return ret;
640} 770}
641 771
642int wl12xx_acx_cts_protect(struct wl12xx *wl, 772int wl12xx_acx_cts_protect(struct wl12xx *wl,
643 enum acx_ctsprotect_type ctsprotect) 773 enum acx_ctsprotect_type ctsprotect)
644{ 774{
645 struct acx_ctsprotect ie; 775 struct acx_ctsprotect *acx;
646 int ret; 776 int ret;
647 777
648 wl12xx_debug(DEBUG_ACX, "acx_set_ctsprotect"); 778 wl12xx_debug(DEBUG_ACX, "acx_set_ctsprotect");
649 779
650 memset(&ie, 0, sizeof(ie)); 780 acx = kzalloc(sizeof(*acx), GFP_KERNEL);
781 if (!acx) {
782 ret = -ENOMEM;
783 goto out;
784 }
785
786 acx->ctsprotect = ctsprotect;
651 787
652 ie.header.id = ACX_CTS_PROTECTION; 788 ret = wl12xx_cmd_configure(wl, ACX_CTS_PROTECTION, acx, sizeof(*acx));
653 ie.header.len = sizeof(ie) - sizeof(struct acx_header);
654 ie.ctsprotect = ctsprotect;
655 ret = wl12xx_cmd_configure(wl, &ie, sizeof(ie));
656 if (ret < 0) { 789 if (ret < 0) {
657 wl12xx_warning("Setting of ctsprotect failed: %d", ret); 790 wl12xx_warning("Setting of ctsprotect failed: %d", ret);
658 return ret; 791 goto out;
659 } 792 }
660 return 0; 793
794out:
795 kfree(acx);
796 return ret;
661} 797}
662 798
663int wl12xx_acx_statistics(struct wl12xx *wl, struct acx_statistics *stats) 799int wl12xx_acx_tsf_info(struct wl12xx *wl, u64 *mactime)
664{ 800{
665 struct wl12xx_command *answer; 801 struct acx_tsf_info *tsf_info;
666 int ret; 802 int ret;
667 803
668 wl12xx_debug(DEBUG_ACX, "acx statistics"); 804 tsf_info = kzalloc(sizeof(*tsf_info), GFP_KERNEL);
669 805 if (!tsf_info) {
670 answer = kmalloc(sizeof(*answer), GFP_KERNEL);
671 if (!answer) {
672 wl12xx_warning("could not allocate memory for acx statistics");
673 ret = -ENOMEM; 806 ret = -ENOMEM;
674 goto out; 807 goto out;
675 } 808 }
676 809
677 ret = wl12xx_cmd_interrogate(wl, ACX_STATISTICS, sizeof(*answer), 810 ret = wl12xx_cmd_interrogate(wl, ACX_TSF_INFO,
678 answer); 811 tsf_info, sizeof(*tsf_info));
679 if (ret < 0) { 812 if (ret < 0) {
680 wl12xx_warning("acx statistics failed: %d", ret); 813 wl12xx_warning("ACX_FW_REV interrogate failed");
681 goto out; 814 goto out;
682 } 815 }
683 816
684 memcpy(stats, answer->parameters, sizeof(*stats)); 817 *mactime = tsf_info->current_tsf_lsb |
818 (tsf_info->current_tsf_msb << 31);
685 819
686out: 820out:
687 kfree(answer); 821 kfree(tsf_info);
688 return ret; 822 return ret;
689} 823}
824
825int wl12xx_acx_statistics(struct wl12xx *wl, struct acx_statistics *stats)
826{
827 int ret;
828
829 wl12xx_debug(DEBUG_ACX, "acx statistics");
830
831 ret = wl12xx_cmd_interrogate(wl, ACX_STATISTICS, stats,
832 sizeof(*stats));
833 if (ret < 0) {
834 wl12xx_warning("acx statistics failed: %d", ret);
835 return -ENOMEM;
836 }
837
838 return 0;
839}
diff --git a/drivers/net/wireless/wl12xx/acx.h b/drivers/net/wireless/wl12xx/acx.h
index fb2d2340993c..549e537d2e6e 100644
--- a/drivers/net/wireless/wl12xx/acx.h
+++ b/drivers/net/wireless/wl12xx/acx.h
@@ -26,10 +26,16 @@
26#define __WL12XX_ACX_H__ 26#define __WL12XX_ACX_H__
27 27
28#include "wl12xx.h" 28#include "wl12xx.h"
29#include "cmd.h"
29 30
30/* Target's information element */ 31/* Target's information element */
31struct acx_header { 32struct acx_header {
33 struct wl12xx_cmd_header cmd;
34
35 /* acx (or information element) header */
32 u16 id; 36 u16 id;
37
38 /* payload length (not including headers */
33 u16 len; 39 u16 len;
34}; 40};
35 41
@@ -107,25 +113,6 @@ struct acx_sleep_auth {
107 u8 padding[3]; 113 u8 padding[3];
108} __attribute__ ((packed)); 114} __attribute__ ((packed));
109 115
110#define TIM_ELE_ID 5
111#define PARTIAL_VBM_MAX 251
112
113struct tim {
114 u8 identity;
115 u8 length;
116 u8 dtim_count;
117 u8 dtim_period;
118 u8 bitmap_ctrl;
119 u8 pvb_field[PARTIAL_VBM_MAX]; /* Partial Virtual Bitmap */
120} __attribute__ ((packed));
121
122/* Virtual Bit Map update */
123struct vbm_update_request {
124 __le16 len;
125 u8 padding[2];
126 struct tim tim;
127} __attribute__ ((packed));
128
129enum { 116enum {
130 HOSTIF_PCI_MASTER_HOST_INDIRECT, 117 HOSTIF_PCI_MASTER_HOST_INDIRECT,
131 HOSTIF_PCI_MASTER_HOST_DIRECT, 118 HOSTIF_PCI_MASTER_HOST_DIRECT,
@@ -202,7 +189,7 @@ struct acx_data_path_params_resp {
202#define RX_MSDU_LIFETIME_MAX 0xFFFFFFFF 189#define RX_MSDU_LIFETIME_MAX 0xFFFFFFFF
203#define RX_MSDU_LIFETIME_DEF 512000 190#define RX_MSDU_LIFETIME_DEF 512000
204 191
205struct rx_msdu_lifetime { 192struct acx_rx_msdu_lifetime {
206 struct acx_header header; 193 struct acx_header header;
207 194
208 /* 195 /*
@@ -368,7 +355,7 @@ struct acx_slot {
368#define ADDRESS_GROUP_MAX (8) 355#define ADDRESS_GROUP_MAX (8)
369#define ADDRESS_GROUP_MAX_LEN (ETH_ALEN * ADDRESS_GROUP_MAX) 356#define ADDRESS_GROUP_MAX_LEN (ETH_ALEN * ADDRESS_GROUP_MAX)
370 357
371struct multicast_grp_addr_start { 358struct acx_dot11_grp_addr_tbl {
372 struct acx_header header; 359 struct acx_header header;
373 360
374 u8 enabled; 361 u8 enabled;
@@ -730,22 +717,13 @@ struct acx_fw_gen_frame_rates {
730} __attribute__ ((packed)); 717} __attribute__ ((packed));
731 718
732/* STA MAC */ 719/* STA MAC */
733struct dot11_station_id { 720struct acx_dot11_station_id {
734 struct acx_header header; 721 struct acx_header header;
735 722
736 u8 mac[ETH_ALEN]; 723 u8 mac[ETH_ALEN];
737 u8 pad[2]; 724 u8 pad[2];
738} __attribute__ ((packed)); 725} __attribute__ ((packed));
739 726
740/* HW encryption keys */
741#define NUM_ACCESS_CATEGORIES_COPY 4
742#define MAX_KEY_SIZE 32
743
744/* When set, disable HW encryption */
745#define DF_ENCRYPTION_DISABLE 0x01
746/* When set, disable HW decryption */
747#define DF_SNIFF_MODE_ENABLE 0x80
748
749struct acx_feature_config { 727struct acx_feature_config {
750 struct acx_header header; 728 struct acx_header header;
751 729
@@ -753,67 +731,6 @@ struct acx_feature_config {
753 u32 data_flow_options; 731 u32 data_flow_options;
754} __attribute__ ((packed)); 732} __attribute__ ((packed));
755 733
756enum acx_key_action {
757 KEY_ADD_OR_REPLACE = 1,
758 KEY_REMOVE = 2,
759 KEY_SET_ID = 3,
760 MAX_KEY_ACTION = 0xffff,
761};
762
763enum acx_key_type {
764 KEY_WEP_DEFAULT = 0,
765 KEY_WEP_ADDR = 1,
766 KEY_AES_GROUP = 4,
767 KEY_AES_PAIRWISE = 5,
768 KEY_WEP_GROUP = 6,
769 KEY_TKIP_MIC_GROUP = 10,
770 KEY_TKIP_MIC_PAIRWISE = 11,
771};
772
773/*
774 *
775 * key_type_e key size key format
776 * ---------- --------- ----------
777 * 0x00 5, 13, 29 Key data
778 * 0x01 5, 13, 29 Key data
779 * 0x04 16 16 bytes of key data
780 * 0x05 16 16 bytes of key data
781 * 0x0a 32 16 bytes of TKIP key data
782 * 8 bytes of RX MIC key data
783 * 8 bytes of TX MIC key data
784 * 0x0b 32 16 bytes of TKIP key data
785 * 8 bytes of RX MIC key data
786 * 8 bytes of TX MIC key data
787 *
788 */
789
790struct acx_set_key {
791 /* Ignored for default WEP key */
792 u8 addr[ETH_ALEN];
793
794 /* key_action_e */
795 u16 key_action;
796
797 u16 reserved_1;
798
799 /* key size in bytes */
800 u8 key_size;
801
802 /* key_type_e */
803 u8 key_type;
804 u8 ssid_profile;
805
806 /*
807 * TKIP, AES: frame's key id field.
808 * For WEP default key: key id;
809 */
810 u8 id;
811 u8 reserved_2[6];
812 u8 key[MAX_KEY_SIZE];
813 u16 ac_seq_num16[NUM_ACCESS_CATEGORIES_COPY];
814 u32 ac_seq_num32[NUM_ACCESS_CATEGORIES_COPY];
815} __attribute__ ((packed));
816
817struct acx_current_tx_power { 734struct acx_current_tx_power {
818 struct acx_header header; 735 struct acx_header header;
819 736
@@ -839,26 +756,6 @@ struct acx_tsf_info {
839 u8 pad[3]; 756 u8 pad[3];
840} __attribute__ ((packed)); 757} __attribute__ ((packed));
841 758
842/* 802.11 PS */
843enum acx_ps_mode {
844 STATION_ACTIVE_MODE,
845 STATION_POWER_SAVE_MODE
846};
847
848struct acx_ps_params {
849 u8 ps_mode; /* STATION_* */
850 u8 send_null_data; /* Do we have to send NULL data packet ? */
851 u8 retries; /* Number of retires for the initial NULL data packet */
852
853 /*
854 * TUs during which the target stays awake after switching
855 * to power save mode.
856 */
857 u8 hang_over_period;
858 u16 null_data_rate;
859 u8 pad[2];
860} __attribute__ ((packed));
861
862enum acx_wake_up_event { 759enum acx_wake_up_event {
863 WAKE_UP_EVENT_BEACON_BITMAP = 0x01, /* Wake on every Beacon*/ 760 WAKE_UP_EVENT_BEACON_BITMAP = 0x01, /* Wake on every Beacon*/
864 WAKE_UP_EVENT_DTIM_BITMAP = 0x02, /* Wake on every DTIM*/ 761 WAKE_UP_EVENT_DTIM_BITMAP = 0x02, /* Wake on every DTIM*/
@@ -892,6 +789,7 @@ enum acx_preamble_type {
892 789
893struct acx_preamble { 790struct acx_preamble {
894 struct acx_header header; 791 struct acx_header header;
792
895 /* 793 /*
896 * When set, the WiLink transmits the frames with a short preamble and 794 * When set, the WiLink transmits the frames with a short preamble and
897 * when cleared, the WiLink transmits the frames with a long preamble. 795 * when cleared, the WiLink transmits the frames with a long preamble.
@@ -1219,7 +1117,8 @@ int wl12xx_acx_sleep_auth(struct wl12xx *wl, u8 sleep_auth);
1219int wl12xx_acx_fw_version(struct wl12xx *wl, char *buf, size_t len); 1117int wl12xx_acx_fw_version(struct wl12xx *wl, char *buf, size_t len);
1220int wl12xx_acx_tx_power(struct wl12xx *wl, int power); 1118int wl12xx_acx_tx_power(struct wl12xx *wl, int power);
1221int wl12xx_acx_feature_cfg(struct wl12xx *wl); 1119int wl12xx_acx_feature_cfg(struct wl12xx *wl);
1222int wl12xx_acx_mem_map(struct wl12xx *wl, void *mem_map, size_t len); 1120int wl12xx_acx_mem_map(struct wl12xx *wl,
1121 struct acx_header *mem_map, size_t len);
1223int wl12xx_acx_data_path_params(struct wl12xx *wl, 1122int wl12xx_acx_data_path_params(struct wl12xx *wl,
1224 struct acx_data_path_params_resp *data_path); 1123 struct acx_data_path_params_resp *data_path);
1225int wl12xx_acx_rx_msdu_life_time(struct wl12xx *wl, u32 life_time); 1124int wl12xx_acx_rx_msdu_life_time(struct wl12xx *wl, u32 life_time);
@@ -1241,5 +1140,6 @@ int wl12xx_acx_set_preamble(struct wl12xx *wl, enum acx_preamble_type preamble);
1241int wl12xx_acx_cts_protect(struct wl12xx *wl, 1140int wl12xx_acx_cts_protect(struct wl12xx *wl,
1242 enum acx_ctsprotect_type ctsprotect); 1141 enum acx_ctsprotect_type ctsprotect);
1243int wl12xx_acx_statistics(struct wl12xx *wl, struct acx_statistics *stats); 1142int wl12xx_acx_statistics(struct wl12xx *wl, struct acx_statistics *stats);
1143int wl12xx_acx_tsf_info(struct wl12xx *wl, u64 *mactime);
1244 1144
1245#endif /* __WL12XX_ACX_H__ */ 1145#endif /* __WL12XX_ACX_H__ */
diff --git a/drivers/net/wireless/wl12xx/cmd.c b/drivers/net/wireless/wl12xx/cmd.c
index f73ab602b7ae..0a02cdde935b 100644
--- a/drivers/net/wireless/wl12xx/cmd.c
+++ b/drivers/net/wireless/wl12xx/cmd.c
@@ -9,24 +9,32 @@
9#include "reg.h" 9#include "reg.h"
10#include "spi.h" 10#include "spi.h"
11#include "ps.h" 11#include "ps.h"
12 12#include "acx.h"
13int wl12xx_cmd_send(struct wl12xx *wl, u16 type, void *buf, size_t buf_len) 13
14/**
15 * send command to firmware
16 *
17 * @wl: wl struct
18 * @id: command id
19 * @buf: buffer containing the command, must work with dma
20 * @len: length of the buffer
21 */
22int wl12xx_cmd_send(struct wl12xx *wl, u16 id, void *buf, size_t len)
14{ 23{
15 struct wl12xx_command cmd; 24 struct wl12xx_cmd_header *cmd;
16 unsigned long timeout; 25 unsigned long timeout;
17 size_t cmd_len;
18 u32 intr; 26 u32 intr;
19 int ret = 0; 27 int ret = 0;
20 28
21 memset(&cmd, 0, sizeof(cmd)); 29 cmd = buf;
22 cmd.id = type; 30 cmd->id = id;
23 cmd.status = 0; 31 cmd->status = 0;
24 memcpy(cmd.parameters, buf, buf_len); 32
25 cmd_len = ALIGN(buf_len, 4) + CMDMBOX_HEADER_LEN; 33 WARN_ON(len % 4 != 0);
26 34
27 wl12xx_ps_elp_wakeup(wl); 35 wl12xx_ps_elp_wakeup(wl);
28 36
29 wl12xx_spi_mem_write(wl, wl->cmd_box_addr, &cmd, cmd_len); 37 wl12xx_spi_mem_write(wl, wl->cmd_box_addr, buf, len);
30 38
31 wl12xx_reg_write32(wl, ACX_REG_INTERRUPT_TRIG, INTR_TRIG_CMD); 39 wl12xx_reg_write32(wl, ACX_REG_INTERRUPT_TRIG, INTR_TRIG_CMD);
32 40
@@ -54,21 +62,42 @@ out:
54 return ret; 62 return ret;
55} 63}
56 64
65/**
66 * send test command to firmware
67 *
68 * @wl: wl struct
69 * @buf: buffer containing the command, without headers, no dma requirements
70 * @len: length of the buffer
71 * @answer: is answer needed
72 *
73 * FIXME: cmd_test users need to be converted to the new interface
74 */
57int wl12xx_cmd_test(struct wl12xx *wl, void *buf, size_t buf_len, u8 answer) 75int wl12xx_cmd_test(struct wl12xx *wl, void *buf, size_t buf_len, u8 answer)
58{ 76{
77 struct wl12xx_command *cmd;
78 size_t cmd_len;
59 int ret; 79 int ret;
60 80
61 wl12xx_debug(DEBUG_CMD, "cmd test"); 81 wl12xx_debug(DEBUG_CMD, "cmd test");
62 82
63 ret = wl12xx_cmd_send(wl, CMD_TEST, buf, buf_len); 83 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
84 if (!cmd) {
85 ret = -ENOMEM;
86 goto out;
87 }
88
89 memcpy(cmd->parameters, buf, buf_len);
90
91 /* FIXME: ugly */
92 cmd_len = sizeof(struct wl12xx_cmd_header) + buf_len;
93
94 ret = wl12xx_cmd_send(wl, CMD_TEST, cmd, cmd_len);
64 if (ret < 0) { 95 if (ret < 0) {
65 wl12xx_warning("TEST command failed"); 96 wl12xx_warning("TEST command failed");
66 return ret; 97 goto out;
67 } 98 }
68 99
69 if (answer) { 100 if (answer) {
70 struct wl12xx_command *cmd_answer;
71
72 /* 101 /*
73 * The test command got in, we can read the answer. 102 * The test command got in, we can read the answer.
74 * The answer would be a wl12xx_command, where the 103 * The answer would be a wl12xx_command, where the
@@ -77,109 +106,146 @@ int wl12xx_cmd_test(struct wl12xx *wl, void *buf, size_t buf_len, u8 answer)
77 106
78 wl12xx_ps_elp_wakeup(wl); 107 wl12xx_ps_elp_wakeup(wl);
79 108
80 wl12xx_spi_mem_read(wl, wl->cmd_box_addr, buf, buf_len); 109 wl12xx_spi_mem_read(wl, wl->cmd_box_addr, cmd, cmd_len);
81 110
82 wl12xx_ps_elp_sleep(wl); 111 wl12xx_ps_elp_sleep(wl);
83 112
84 cmd_answer = buf; 113 if (cmd->header.status != CMD_STATUS_SUCCESS)
85 if (cmd_answer->status != CMD_STATUS_SUCCESS)
86 wl12xx_error("TEST command answer error: %d", 114 wl12xx_error("TEST command answer error: %d",
87 cmd_answer->status); 115 cmd->header.status);
116 memcpy(buf, cmd->parameters, buf_len);
88 } 117 }
89 118
90 return 0; 119out:
120 kfree(cmd);
121 return ret;
91} 122}
92 123
93 124/**
94int wl12xx_cmd_interrogate(struct wl12xx *wl, u16 ie_id, u16 ie_len, 125 * read acx from firmware
95 void *answer) 126 *
127 * @wl: wl struct
128 * @id: acx id
129 * @buf: buffer for the response, including all headers, must work with dma
130 * @len: lenght of buf
131 */
132int wl12xx_cmd_interrogate(struct wl12xx *wl, u16 id, void *buf, size_t len)
96{ 133{
97 struct wl12xx_command *cmd; 134 struct acx_header *acx = buf;
98 struct acx_header header;
99 int ret; 135 int ret;
100 136
101 wl12xx_debug(DEBUG_CMD, "cmd interrogate"); 137 wl12xx_debug(DEBUG_CMD, "cmd interrogate");
102 138
103 header.id = ie_id; 139 acx->id = id;
104 header.len = ie_len - sizeof(header);
105 140
106 ret = wl12xx_cmd_send(wl, CMD_INTERROGATE, &header, sizeof(header)); 141 /* payload length, does not include any headers */
142 acx->len = len - sizeof(*acx);
143
144 ret = wl12xx_cmd_send(wl, CMD_INTERROGATE, acx, sizeof(*acx));
107 if (ret < 0) { 145 if (ret < 0) {
108 wl12xx_error("INTERROGATE command failed"); 146 wl12xx_error("INTERROGATE command failed");
109 return ret; 147 goto out;
110 } 148 }
111 149
112 wl12xx_ps_elp_wakeup(wl); 150 wl12xx_ps_elp_wakeup(wl);
113 151
114 /* the interrogate command got in, we can read the answer */ 152 /* the interrogate command got in, we can read the answer */
115 wl12xx_spi_mem_read(wl, wl->cmd_box_addr, answer, 153 wl12xx_spi_mem_read(wl, wl->cmd_box_addr, buf, len);
116 CMDMBOX_HEADER_LEN + ie_len);
117 154
118 wl12xx_ps_elp_sleep(wl); 155 wl12xx_ps_elp_sleep(wl);
119 156
120 cmd = answer; 157 acx = buf;
121 if (cmd->status != CMD_STATUS_SUCCESS) 158 if (acx->cmd.status != CMD_STATUS_SUCCESS)
122 wl12xx_error("INTERROGATE command error: %d", 159 wl12xx_error("INTERROGATE command error: %d",
123 cmd->status); 160 acx->cmd.status);
124
125 return 0;
126 161
162out:
163 return ret;
127} 164}
128 165
129int wl12xx_cmd_configure(struct wl12xx *wl, void *ie, int ie_len) 166/**
167 * write acx value to firmware
168 *
169 * @wl: wl struct
170 * @id: acx id
171 * @buf: buffer containing acx, including all headers, must work with dma
172 * @len: length of buf
173 */
174int wl12xx_cmd_configure(struct wl12xx *wl, u16 id, void *buf, size_t len)
130{ 175{
176 struct acx_header *acx = buf;
131 int ret; 177 int ret;
132 178
133 wl12xx_debug(DEBUG_CMD, "cmd configure"); 179 wl12xx_debug(DEBUG_CMD, "cmd configure");
134 180
135 ret = wl12xx_cmd_send(wl, CMD_CONFIGURE, ie, 181 acx->id = id;
136 ie_len); 182
183 /* payload length, does not include any headers */
184 acx->len = len - sizeof(*acx);
185
186 ret = wl12xx_cmd_send(wl, CMD_CONFIGURE, acx, len);
137 if (ret < 0) { 187 if (ret < 0) {
138 wl12xx_warning("CONFIGURE command NOK"); 188 wl12xx_warning("CONFIGURE command NOK");
139 return ret; 189 return ret;
140 } 190 }
141 191
142 return 0; 192 return 0;
143
144} 193}
145 194
146int wl12xx_cmd_vbm(struct wl12xx *wl, u8 identity, 195int wl12xx_cmd_vbm(struct wl12xx *wl, u8 identity,
147 void *bitmap, u16 bitmap_len, u8 bitmap_control) 196 void *bitmap, u16 bitmap_len, u8 bitmap_control)
148{ 197{
149 struct vbm_update_request vbm; 198 struct wl12xx_cmd_vbm_update *vbm;
150 int ret; 199 int ret;
151 200
152 wl12xx_debug(DEBUG_CMD, "cmd vbm"); 201 wl12xx_debug(DEBUG_CMD, "cmd vbm");
153 202
203 vbm = kzalloc(sizeof(*vbm), GFP_KERNEL);
204 if (!vbm) {
205 ret = -ENOMEM;
206 goto out;
207 }
208
154 /* Count and period will be filled by the target */ 209 /* Count and period will be filled by the target */
155 vbm.tim.bitmap_ctrl = bitmap_control; 210 vbm->tim.bitmap_ctrl = bitmap_control;
156 if (bitmap_len > PARTIAL_VBM_MAX) { 211 if (bitmap_len > PARTIAL_VBM_MAX) {
157 wl12xx_warning("cmd vbm len is %d B, truncating to %d", 212 wl12xx_warning("cmd vbm len is %d B, truncating to %d",
158 bitmap_len, PARTIAL_VBM_MAX); 213 bitmap_len, PARTIAL_VBM_MAX);
159 bitmap_len = PARTIAL_VBM_MAX; 214 bitmap_len = PARTIAL_VBM_MAX;
160 } 215 }
161 memcpy(vbm.tim.pvb_field, bitmap, bitmap_len); 216 memcpy(vbm->tim.pvb_field, bitmap, bitmap_len);
162 vbm.tim.identity = identity; 217 vbm->tim.identity = identity;
163 vbm.tim.length = bitmap_len + 3; 218 vbm->tim.length = bitmap_len + 3;
164 219
165 vbm.len = cpu_to_le16(bitmap_len + 5); 220 vbm->len = cpu_to_le16(bitmap_len + 5);
166 221
167 ret = wl12xx_cmd_send(wl, CMD_VBM, &vbm, sizeof(vbm)); 222 ret = wl12xx_cmd_send(wl, CMD_VBM, vbm, sizeof(*vbm));
168 if (ret < 0) { 223 if (ret < 0) {
169 wl12xx_error("VBM command failed"); 224 wl12xx_error("VBM command failed");
170 return ret; 225 goto out;
171 } 226 }
172 227
228out:
229 kfree(vbm);
173 return 0; 230 return 0;
174} 231}
175 232
176int wl12xx_cmd_data_path(struct wl12xx *wl, u8 channel, u8 enable) 233int wl12xx_cmd_data_path(struct wl12xx *wl, u8 channel, bool enable)
177{ 234{
235 struct cmd_enabledisable_path *cmd;
178 int ret; 236 int ret;
179 u16 cmd_rx, cmd_tx; 237 u16 cmd_rx, cmd_tx;
180 238
181 wl12xx_debug(DEBUG_CMD, "cmd data path"); 239 wl12xx_debug(DEBUG_CMD, "cmd data path");
182 240
241 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
242 if (!cmd) {
243 ret = -ENOMEM;
244 goto out;
245 }
246
247 cmd->channel = channel;
248
183 if (enable) { 249 if (enable) {
184 cmd_rx = CMD_ENABLE_RX; 250 cmd_rx = CMD_ENABLE_RX;
185 cmd_tx = CMD_ENABLE_TX; 251 cmd_tx = CMD_ENABLE_TX;
@@ -188,17 +254,17 @@ int wl12xx_cmd_data_path(struct wl12xx *wl, u8 channel, u8 enable)
188 cmd_tx = CMD_DISABLE_TX; 254 cmd_tx = CMD_DISABLE_TX;
189 } 255 }
190 256
191 ret = wl12xx_cmd_send(wl, cmd_rx, &channel, sizeof(channel)); 257 ret = wl12xx_cmd_send(wl, cmd_rx, cmd, sizeof(*cmd));
192 if (ret < 0) { 258 if (ret < 0) {
193 wl12xx_error("rx %s cmd for channel %d failed", 259 wl12xx_error("rx %s cmd for channel %d failed",
194 enable ? "start" : "stop", channel); 260 enable ? "start" : "stop", channel);
195 return ret; 261 goto out;
196 } 262 }
197 263
198 wl12xx_debug(DEBUG_BOOT, "rx %s cmd channel %d", 264 wl12xx_debug(DEBUG_BOOT, "rx %s cmd channel %d",
199 enable ? "start" : "stop", channel); 265 enable ? "start" : "stop", channel);
200 266
201 ret = wl12xx_cmd_send(wl, cmd_tx, &channel, sizeof(channel)); 267 ret = wl12xx_cmd_send(wl, cmd_tx, cmd, sizeof(*cmd));
202 if (ret < 0) { 268 if (ret < 0) {
203 wl12xx_error("tx %s cmd for channel %d failed", 269 wl12xx_error("tx %s cmd for channel %d failed",
204 enable ? "start" : "stop", channel); 270 enable ? "start" : "stop", channel);
@@ -208,48 +274,56 @@ int wl12xx_cmd_data_path(struct wl12xx *wl, u8 channel, u8 enable)
208 wl12xx_debug(DEBUG_BOOT, "tx %s cmd channel %d", 274 wl12xx_debug(DEBUG_BOOT, "tx %s cmd channel %d",
209 enable ? "start" : "stop", channel); 275 enable ? "start" : "stop", channel);
210 276
211 return 0; 277out:
278 kfree(cmd);
279 return ret;
212} 280}
213 281
214int wl12xx_cmd_join(struct wl12xx *wl, u8 bss_type, u8 dtim_interval, 282int wl12xx_cmd_join(struct wl12xx *wl, u8 bss_type, u8 dtim_interval,
215 u16 beacon_interval, u8 wait) 283 u16 beacon_interval, u8 wait)
216{ 284{
217 unsigned long timeout; 285 unsigned long timeout;
218 struct cmd_join join = {}; 286 struct cmd_join *join;
219 int ret, i; 287 int ret, i;
220 u8 *bssid; 288 u8 *bssid;
221 289
290 join = kzalloc(sizeof(*join), GFP_KERNEL);
291 if (!join) {
292 ret = -ENOMEM;
293 goto out;
294 }
295
222 /* FIXME: this should be in main.c */ 296 /* FIXME: this should be in main.c */
223 ret = wl12xx_acx_frame_rates(wl, DEFAULT_HW_GEN_TX_RATE, 297 ret = wl12xx_acx_frame_rates(wl, DEFAULT_HW_GEN_TX_RATE,
224 DEFAULT_HW_GEN_MODULATION_TYPE, 298 DEFAULT_HW_GEN_MODULATION_TYPE,
225 wl->tx_mgmt_frm_rate, 299 wl->tx_mgmt_frm_rate,
226 wl->tx_mgmt_frm_mod); 300 wl->tx_mgmt_frm_mod);
227 if (ret < 0) 301 if (ret < 0)
228 return ret; 302 goto out;
229 303
230 wl12xx_debug(DEBUG_CMD, "cmd join"); 304 wl12xx_debug(DEBUG_CMD, "cmd join");
231 305
232 /* Reverse order BSSID */ 306 /* Reverse order BSSID */
233 bssid = (u8 *)&join.bssid_lsb; 307 bssid = (u8 *) &join->bssid_lsb;
234 for (i = 0; i < ETH_ALEN; i++) 308 for (i = 0; i < ETH_ALEN; i++)
235 bssid[i] = wl->bssid[ETH_ALEN - i - 1]; 309 bssid[i] = wl->bssid[ETH_ALEN - i - 1];
236 310
237 join.rx_config_options = wl->rx_config; 311 join->rx_config_options = wl->rx_config;
238 join.rx_filter_options = wl->rx_filter; 312 join->rx_filter_options = wl->rx_filter;
239 313
240 join.basic_rate_set = RATE_MASK_1MBPS | RATE_MASK_2MBPS | 314 join->basic_rate_set = RATE_MASK_1MBPS | RATE_MASK_2MBPS |
241 RATE_MASK_5_5MBPS | RATE_MASK_11MBPS; 315 RATE_MASK_5_5MBPS | RATE_MASK_11MBPS;
242 316
243 join.beacon_interval = beacon_interval; 317 join->beacon_interval = beacon_interval;
244 join.dtim_interval = dtim_interval; 318 join->dtim_interval = dtim_interval;
245 join.bss_type = bss_type; 319 join->bss_type = bss_type;
246 join.channel = wl->channel; 320 join->channel = wl->channel;
247 join.ctrl = JOIN_CMD_CTRL_TX_FLUSH; 321 join->ctrl = JOIN_CMD_CTRL_TX_FLUSH;
248 322
249 ret = wl12xx_cmd_send(wl, CMD_START_JOIN, &join, sizeof(join)); 323 ret = wl12xx_cmd_send(wl, CMD_START_JOIN, join, sizeof(*join));
250 if (ret < 0) { 324 if (ret < 0) {
251 wl12xx_error("failed to initiate cmd join"); 325 wl12xx_error("failed to initiate cmd join");
252 return ret; 326 goto out;
253 } 327 }
254 328
255 timeout = msecs_to_jiffies(JOIN_TIMEOUT); 329 timeout = msecs_to_jiffies(JOIN_TIMEOUT);
@@ -261,93 +335,120 @@ int wl12xx_cmd_join(struct wl12xx *wl, u8 bss_type, u8 dtim_interval,
261 if (wait) 335 if (wait)
262 msleep(10); 336 msleep(10);
263 337
264 return 0; 338out:
339 kfree(join);
340 return ret;
265} 341}
266 342
267int wl12xx_cmd_ps_mode(struct wl12xx *wl, u8 ps_mode) 343int wl12xx_cmd_ps_mode(struct wl12xx *wl, u8 ps_mode)
268{ 344{
269 int ret; 345 struct wl12xx_cmd_ps_params *ps_params = NULL;
270 struct acx_ps_params ps_params; 346 int ret = 0;
271 347
272 /* FIXME: this should be in ps.c */ 348 /* FIXME: this should be in ps.c */
273 ret = wl12xx_acx_wake_up_conditions(wl, wl->listen_int); 349 ret = wl12xx_acx_wake_up_conditions(wl, wl->listen_int);
274 if (ret < 0) { 350 if (ret < 0) {
275 wl12xx_error("Couldnt set wake up conditions"); 351 wl12xx_error("couldn't set wake up conditions");
276 return ret; 352 goto out;
277 } 353 }
278 354
279 wl12xx_debug(DEBUG_CMD, "cmd set ps mode"); 355 wl12xx_debug(DEBUG_CMD, "cmd set ps mode");
280 356
281 ps_params.ps_mode = ps_mode; 357 ps_params = kzalloc(sizeof(*ps_params), GFP_KERNEL);
282 ps_params.send_null_data = 1; 358 if (!ps_params) {
283 ps_params.retries = 5; 359 ret = -ENOMEM;
284 ps_params.hang_over_period = 128; 360 goto out;
285 ps_params.null_data_rate = 1; /* 1 Mbps */ 361 }
362
363 ps_params->ps_mode = ps_mode;
364 ps_params->send_null_data = 1;
365 ps_params->retries = 5;
366 ps_params->hang_over_period = 128;
367 ps_params->null_data_rate = 1; /* 1 Mbps */
286 368
287 ret = wl12xx_cmd_send(wl, CMD_SET_PS_MODE, &ps_params, 369 ret = wl12xx_cmd_send(wl, CMD_SET_PS_MODE, ps_params,
288 sizeof(ps_params)); 370 sizeof(*ps_params));
289 if (ret < 0) { 371 if (ret < 0) {
290 wl12xx_error("cmd set_ps_mode failed"); 372 wl12xx_error("cmd set_ps_mode failed");
291 return ret; 373 goto out;
292 } 374 }
293 375
294 return 0; 376out:
377 kfree(ps_params);
378 return ret;
295} 379}
296 380
297int wl12xx_cmd_read_memory(struct wl12xx *wl, u32 addr, u32 len, void *answer) 381int wl12xx_cmd_read_memory(struct wl12xx *wl, u32 addr, void *answer,
382 size_t len)
298{ 383{
299 struct cmd_read_write_memory mem_cmd, *mem_answer; 384 struct cmd_read_write_memory *cmd;
300 struct wl12xx_command cmd; 385 int ret = 0;
301 int ret;
302 386
303 wl12xx_debug(DEBUG_CMD, "cmd read memory"); 387 wl12xx_debug(DEBUG_CMD, "cmd read memory");
304 388
305 memset(&mem_cmd, 0, sizeof(mem_cmd)); 389 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
306 mem_cmd.addr = addr; 390 if (!cmd) {
307 mem_cmd.size = len; 391 ret = -ENOMEM;
392 goto out;
393 }
394
395 WARN_ON(len > MAX_READ_SIZE);
396 len = min_t(size_t, len, MAX_READ_SIZE);
397
398 cmd->addr = addr;
399 cmd->size = len;
308 400
309 ret = wl12xx_cmd_send(wl, CMD_READ_MEMORY, &mem_cmd, sizeof(mem_cmd)); 401 ret = wl12xx_cmd_send(wl, CMD_READ_MEMORY, cmd, sizeof(*cmd));
310 if (ret < 0) { 402 if (ret < 0) {
311 wl12xx_error("read memory command failed: %d", ret); 403 wl12xx_error("read memory command failed: %d", ret);
312 return ret; 404 goto out;
313 } 405 }
314 406
315 /* the read command got in, we can now read the answer */ 407 /* the read command got in, we can now read the answer */
316 wl12xx_spi_mem_read(wl, wl->cmd_box_addr, &cmd, 408 wl12xx_spi_mem_read(wl, wl->cmd_box_addr, cmd, sizeof(*cmd));
317 CMDMBOX_HEADER_LEN + sizeof(mem_cmd));
318 409
319 if (cmd.status != CMD_STATUS_SUCCESS) 410 if (cmd->header.status != CMD_STATUS_SUCCESS)
320 wl12xx_error("error in read command result: %d", cmd.status); 411 wl12xx_error("error in read command result: %d",
412 cmd->header.status);
321 413
322 mem_answer = (struct cmd_read_write_memory *) cmd.parameters; 414 memcpy(answer, cmd->value, len);
323 memcpy(answer, mem_answer->value, len);
324 415
325 return 0; 416out:
417 kfree(cmd);
418 return ret;
326} 419}
327 420
328int wl12xx_cmd_template_set(struct wl12xx *wl, u16 cmd_id, 421int wl12xx_cmd_template_set(struct wl12xx *wl, u16 cmd_id,
329 void *buf, size_t buf_len) 422 void *buf, size_t buf_len)
330{ 423{
331 struct wl12xx_cmd_packet_template template; 424 struct wl12xx_cmd_packet_template *cmd;
332 int ret; 425 size_t cmd_len;
426 int ret = 0;
333 427
334 wl12xx_debug(DEBUG_CMD, "cmd template %d", cmd_id); 428 wl12xx_debug(DEBUG_CMD, "cmd template %d", cmd_id);
335 429
336 memset(&template, 0, sizeof(template));
337
338 WARN_ON(buf_len > WL12XX_MAX_TEMPLATE_SIZE); 430 WARN_ON(buf_len > WL12XX_MAX_TEMPLATE_SIZE);
339 buf_len = min_t(size_t, buf_len, WL12XX_MAX_TEMPLATE_SIZE); 431 buf_len = min_t(size_t, buf_len, WL12XX_MAX_TEMPLATE_SIZE);
340 template.size = cpu_to_le16(buf_len); 432 cmd_len = ALIGN(sizeof(*cmd) + buf_len, 4);
433
434 cmd = kzalloc(cmd_len, GFP_KERNEL);
435 if (!cmd) {
436 ret = -ENOMEM;
437 goto out;
438 }
439
440 cmd->size = cpu_to_le16(buf_len);
341 441
342 if (buf) 442 if (buf)
343 memcpy(template.template, buf, buf_len); 443 memcpy(cmd->data, buf, buf_len);
344 444
345 ret = wl12xx_cmd_send(wl, cmd_id, &template, 445 ret = wl12xx_cmd_send(wl, cmd_id, cmd, cmd_len);
346 sizeof(template.size) + buf_len);
347 if (ret < 0) { 446 if (ret < 0) {
348 wl12xx_warning("cmd set_template failed: %d", ret); 447 wl12xx_warning("cmd set_template failed: %d", ret);
349 return ret; 448 goto out;
350 } 449 }
351 450
352 return 0; 451out:
452 kfree(cmd);
453 return ret;
353} 454}
diff --git a/drivers/net/wireless/wl12xx/cmd.h b/drivers/net/wireless/wl12xx/cmd.h
index aa307dcd081f..7aef1f24352d 100644
--- a/drivers/net/wireless/wl12xx/cmd.h
+++ b/drivers/net/wireless/wl12xx/cmd.h
@@ -27,31 +27,26 @@
27 27
28#include "wl12xx.h" 28#include "wl12xx.h"
29 29
30struct acx_header;
31
30int wl12xx_cmd_send(struct wl12xx *wl, u16 type, void *buf, size_t buf_len); 32int wl12xx_cmd_send(struct wl12xx *wl, u16 type, void *buf, size_t buf_len);
31int wl12xx_cmd_test(struct wl12xx *wl, void *buf, size_t buf_len, u8 answer); 33int wl12xx_cmd_test(struct wl12xx *wl, void *buf, size_t buf_len, u8 answer);
32int wl12xx_cmd_interrogate(struct wl12xx *wl, u16 ie_id, u16 ie_len, 34int wl12xx_cmd_interrogate(struct wl12xx *wl, u16 id, void *buf, size_t len);
33 void *answer); 35int wl12xx_cmd_configure(struct wl12xx *wl, u16 id, void *buf, size_t len);
34int wl12xx_cmd_configure(struct wl12xx *wl, void *ie, int ie_len);
35int wl12xx_cmd_vbm(struct wl12xx *wl, u8 identity, 36int wl12xx_cmd_vbm(struct wl12xx *wl, u8 identity,
36 void *bitmap, u16 bitmap_len, u8 bitmap_control); 37 void *bitmap, u16 bitmap_len, u8 bitmap_control);
37int wl12xx_cmd_data_path(struct wl12xx *wl, u8 channel, u8 enable); 38int wl12xx_cmd_data_path(struct wl12xx *wl, u8 channel, bool enable);
38int wl12xx_cmd_join(struct wl12xx *wl, u8 bss_type, u8 dtim_interval, 39int wl12xx_cmd_join(struct wl12xx *wl, u8 bss_type, u8 dtim_interval,
39 u16 beacon_interval, u8 wait); 40 u16 beacon_interval, u8 wait);
40int wl12xx_cmd_ps_mode(struct wl12xx *wl, u8 ps_mode); 41int wl12xx_cmd_ps_mode(struct wl12xx *wl, u8 ps_mode);
41int wl12xx_cmd_read_memory(struct wl12xx *wl, u32 addr, u32 len, void *answer); 42int wl12xx_cmd_read_memory(struct wl12xx *wl, u32 addr, void *answer,
43 size_t len);
42int wl12xx_cmd_template_set(struct wl12xx *wl, u16 cmd_id, 44int wl12xx_cmd_template_set(struct wl12xx *wl, u16 cmd_id,
43 void *buf, size_t buf_len); 45 void *buf, size_t buf_len);
44 46
45/* unit ms */ 47/* unit ms */
46#define WL12XX_COMMAND_TIMEOUT 2000 48#define WL12XX_COMMAND_TIMEOUT 2000
47 49
48#define WL12XX_MAX_TEMPLATE_SIZE 300
49
50struct wl12xx_cmd_packet_template {
51 __le16 size;
52 u8 template[WL12XX_MAX_TEMPLATE_SIZE];
53} __attribute__ ((packed));
54
55enum wl12xx_commands { 50enum wl12xx_commands {
56 CMD_RESET = 0, 51 CMD_RESET = 0,
57 CMD_INTERROGATE = 1, /*use this to read information elements*/ 52 CMD_INTERROGATE = 1, /*use this to read information elements*/
@@ -100,9 +95,15 @@ enum wl12xx_commands {
100 95
101#define MAX_CMD_PARAMS 572 96#define MAX_CMD_PARAMS 572
102 97
103struct wl12xx_command { 98struct wl12xx_cmd_header {
104 u16 id; 99 u16 id;
105 u16 status; 100 u16 status;
101 /* payload */
102 u8 data[0];
103} __attribute__ ((packed));
104
105struct wl12xx_command {
106 struct wl12xx_cmd_header header;
106 u8 parameters[MAX_CMD_PARAMS]; 107 u8 parameters[MAX_CMD_PARAMS];
107}; 108};
108 109
@@ -144,6 +145,8 @@ enum {
144#define MAX_READ_SIZE 256 145#define MAX_READ_SIZE 256
145 146
146struct cmd_read_write_memory { 147struct cmd_read_write_memory {
148 struct wl12xx_cmd_header header;
149
147 /* The address of the memory to read from or write to.*/ 150 /* The address of the memory to read from or write to.*/
148 u32 addr; 151 u32 addr;
149 152
@@ -211,6 +214,8 @@ struct basic_scan_channel_parameters {
211#define SCAN_MAX_NUM_OF_CHANNELS 16 214#define SCAN_MAX_NUM_OF_CHANNELS 16
212 215
213struct cmd_scan { 216struct cmd_scan {
217 struct wl12xx_cmd_header header;
218
214 struct basic_scan_parameters params; 219 struct basic_scan_parameters params;
215 struct basic_scan_channel_parameters channels[SCAN_MAX_NUM_OF_CHANNELS]; 220 struct basic_scan_channel_parameters channels[SCAN_MAX_NUM_OF_CHANNELS];
216} __attribute__ ((packed)); 221} __attribute__ ((packed));
@@ -227,6 +232,8 @@ enum {
227 232
228 233
229struct cmd_join { 234struct cmd_join {
235 struct wl12xx_cmd_header header;
236
230 u32 bssid_lsb; 237 u32 bssid_lsb;
231 u16 bssid_msb; 238 u16 bssid_msb;
232 u16 beacon_interval; /* in TBTTs */ 239 u16 beacon_interval; /* in TBTTs */
@@ -261,5 +268,140 @@ struct cmd_join {
261 u8 reserved; 268 u8 reserved;
262} __attribute__ ((packed)); 269} __attribute__ ((packed));
263 270
271struct cmd_enabledisable_path {
272 struct wl12xx_cmd_header header;
273
274 u8 channel;
275 u8 padding[3];
276} __attribute__ ((packed));
277
278#define WL12XX_MAX_TEMPLATE_SIZE 300
279
280struct wl12xx_cmd_packet_template {
281 struct wl12xx_cmd_header header;
282
283 __le16 size;
284 u8 data[0];
285} __attribute__ ((packed));
286
287#define TIM_ELE_ID 5
288#define PARTIAL_VBM_MAX 251
289
290struct wl12xx_tim {
291 u8 identity;
292 u8 length;
293 u8 dtim_count;
294 u8 dtim_period;
295 u8 bitmap_ctrl;
296 u8 pvb_field[PARTIAL_VBM_MAX]; /* Partial Virtual Bitmap */
297} __attribute__ ((packed));
298
299/* Virtual Bit Map update */
300struct wl12xx_cmd_vbm_update {
301 struct wl12xx_cmd_header header;
302 __le16 len;
303 u8 padding[2];
304 struct wl12xx_tim tim;
305} __attribute__ ((packed));
306
307enum wl12xx_cmd_ps_mode {
308 STATION_ACTIVE_MODE,
309 STATION_POWER_SAVE_MODE
310};
311
312struct wl12xx_cmd_ps_params {
313 struct wl12xx_cmd_header header;
314
315 u8 ps_mode; /* STATION_* */
316 u8 send_null_data; /* Do we have to send NULL data packet ? */
317 u8 retries; /* Number of retires for the initial NULL data packet */
318
319 /*
320 * TUs during which the target stays awake after switching
321 * to power save mode.
322 */
323 u8 hang_over_period;
324 u16 null_data_rate;
325 u8 pad[2];
326} __attribute__ ((packed));
327
328struct wl12xx_cmd_trigger_scan_to {
329 struct wl12xx_cmd_header header;
330
331 u32 timeout;
332};
333
334/* HW encryption keys */
335#define NUM_ACCESS_CATEGORIES_COPY 4
336#define MAX_KEY_SIZE 32
337
338/* When set, disable HW encryption */
339#define DF_ENCRYPTION_DISABLE 0x01
340/* When set, disable HW decryption */
341#define DF_SNIFF_MODE_ENABLE 0x80
342
343enum wl12xx_cmd_key_action {
344 KEY_ADD_OR_REPLACE = 1,
345 KEY_REMOVE = 2,
346 KEY_SET_ID = 3,
347 MAX_KEY_ACTION = 0xffff,
348};
349
350enum wl12xx_cmd_key_type {
351 KEY_WEP_DEFAULT = 0,
352 KEY_WEP_ADDR = 1,
353 KEY_AES_GROUP = 4,
354 KEY_AES_PAIRWISE = 5,
355 KEY_WEP_GROUP = 6,
356 KEY_TKIP_MIC_GROUP = 10,
357 KEY_TKIP_MIC_PAIRWISE = 11,
358};
359
360/*
361 *
362 * key_type_e key size key format
363 * ---------- --------- ----------
364 * 0x00 5, 13, 29 Key data
365 * 0x01 5, 13, 29 Key data
366 * 0x04 16 16 bytes of key data
367 * 0x05 16 16 bytes of key data
368 * 0x0a 32 16 bytes of TKIP key data
369 * 8 bytes of RX MIC key data
370 * 8 bytes of TX MIC key data
371 * 0x0b 32 16 bytes of TKIP key data
372 * 8 bytes of RX MIC key data
373 * 8 bytes of TX MIC key data
374 *
375 */
376
377struct wl12xx_cmd_set_keys {
378 struct wl12xx_cmd_header header;
379
380 /* Ignored for default WEP key */
381 u8 addr[ETH_ALEN];
382
383 /* key_action_e */
384 u16 key_action;
385
386 u16 reserved_1;
387
388 /* key size in bytes */
389 u8 key_size;
390
391 /* key_type_e */
392 u8 key_type;
393 u8 ssid_profile;
394
395 /*
396 * TKIP, AES: frame's key id field.
397 * For WEP default key: key id;
398 */
399 u8 id;
400 u8 reserved_2[6];
401 u8 key[MAX_KEY_SIZE];
402 u16 ac_seq_num16[NUM_ACCESS_CATEGORIES_COPY];
403 u32 ac_seq_num32[NUM_ACCESS_CATEGORIES_COPY];
404} __attribute__ ((packed));
405
264 406
265#endif /* __WL12XX_CMD_H__ */ 407#endif /* __WL12XX_CMD_H__ */
diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c
index 603d6114882e..c6a454439711 100644
--- a/drivers/net/wireless/wl12xx/main.c
+++ b/drivers/net/wireless/wl12xx/main.c
@@ -618,7 +618,8 @@ static void wl12xx_op_configure_filter(struct ieee80211_hw *hw,
618} 618}
619 619
620/* HW encryption */ 620/* HW encryption */
621static int wl12xx_set_key_type(struct wl12xx *wl, struct acx_set_key *key, 621static int wl12xx_set_key_type(struct wl12xx *wl,
622 struct wl12xx_cmd_set_keys *key,
622 enum set_key_cmd cmd, 623 enum set_key_cmd cmd,
623 struct ieee80211_key_conf *mac80211_key, 624 struct ieee80211_key_conf *mac80211_key,
624 const u8 *addr) 625 const u8 *addr)
@@ -661,7 +662,7 @@ static int wl12xx_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
661 struct ieee80211_key_conf *key) 662 struct ieee80211_key_conf *key)
662{ 663{
663 struct wl12xx *wl = hw->priv; 664 struct wl12xx *wl = hw->priv;
664 struct acx_set_key wl_key; 665 struct wl12xx_cmd_set_keys *wl_cmd;
665 const u8 *addr; 666 const u8 *addr;
666 int ret; 667 int ret;
667 668
@@ -670,7 +671,11 @@ static int wl12xx_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
670 671
671 wl12xx_debug(DEBUG_MAC80211, "mac80211 set key"); 672 wl12xx_debug(DEBUG_MAC80211, "mac80211 set key");
672 673
673 memset(&wl_key, 0, sizeof(wl_key)); 674 wl_cmd = kzalloc(sizeof(*wl_cmd), GFP_KERNEL);
675 if (!wl_cmd) {
676 ret = -ENOMEM;
677 goto out;
678 }
674 679
675 addr = sta ? sta->addr : bcast_addr; 680 addr = sta ? sta->addr : bcast_addr;
676 681
@@ -680,59 +685,69 @@ static int wl12xx_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
680 key->alg, key->keyidx, key->keylen, key->flags); 685 key->alg, key->keyidx, key->keylen, key->flags);
681 wl12xx_dump(DEBUG_CRYPT, "KEY: ", key->key, key->keylen); 686 wl12xx_dump(DEBUG_CRYPT, "KEY: ", key->key, key->keylen);
682 687
688 if (is_zero_ether_addr(addr)) {
689 /* We dont support TX only encryption */
690 ret = -EOPNOTSUPP;
691 goto out;
692 }
693
683 mutex_lock(&wl->mutex); 694 mutex_lock(&wl->mutex);
684 695
685 switch (cmd) { 696 switch (cmd) {
686 case SET_KEY: 697 case SET_KEY:
687 wl_key.key_action = KEY_ADD_OR_REPLACE; 698 wl_cmd->key_action = KEY_ADD_OR_REPLACE;
688 break; 699 break;
689 case DISABLE_KEY: 700 case DISABLE_KEY:
690 wl_key.key_action = KEY_REMOVE; 701 wl_cmd->key_action = KEY_REMOVE;
691 break; 702 break;
692 default: 703 default:
693 wl12xx_error("Unsupported key cmd 0x%x", cmd); 704 wl12xx_error("Unsupported key cmd 0x%x", cmd);
694 break; 705 break;
695 } 706 }
696 707
697 ret = wl12xx_set_key_type(wl, &wl_key, cmd, key, addr); 708 ret = wl12xx_set_key_type(wl, wl_cmd, cmd, key, addr);
698 if (ret < 0) { 709 if (ret < 0) {
699 wl12xx_error("Set KEY type failed"); 710 wl12xx_error("Set KEY type failed");
700 goto out; 711 goto out_unlock;
701 } 712 }
702 713
703 if (wl_key.key_type != KEY_WEP_DEFAULT) 714 if (wl_cmd->key_type != KEY_WEP_DEFAULT)
704 memcpy(wl_key.addr, addr, ETH_ALEN); 715 memcpy(wl_cmd->addr, addr, ETH_ALEN);
705 716
706 if ((wl_key.key_type == KEY_TKIP_MIC_GROUP) || 717 if ((wl_cmd->key_type == KEY_TKIP_MIC_GROUP) ||
707 (wl_key.key_type == KEY_TKIP_MIC_PAIRWISE)) { 718 (wl_cmd->key_type == KEY_TKIP_MIC_PAIRWISE)) {
708 /* 719 /*
709 * We get the key in the following form: 720 * We get the key in the following form:
710 * TKIP (16 bytes) - TX MIC (8 bytes) - RX MIC (8 bytes) 721 * TKIP (16 bytes) - TX MIC (8 bytes) - RX MIC (8 bytes)
711 * but the target is expecting: 722 * but the target is expecting:
712 * TKIP - RX MIC - TX MIC 723 * TKIP - RX MIC - TX MIC
713 */ 724 */
714 memcpy(wl_key.key, key->key, 16); 725 memcpy(wl_cmd->key, key->key, 16);
715 memcpy(wl_key.key + 16, key->key + 24, 8); 726 memcpy(wl_cmd->key + 16, key->key + 24, 8);
716 memcpy(wl_key.key + 24, key->key + 16, 8); 727 memcpy(wl_cmd->key + 24, key->key + 16, 8);
717 728
718 } else { 729 } else {
719 memcpy(wl_key.key, key->key, key->keylen); 730 memcpy(wl_cmd->key, key->key, key->keylen);
720 } 731 }
721 wl_key.key_size = key->keylen; 732 wl_cmd->key_size = key->keylen;
722 733
723 wl_key.id = key->keyidx; 734 wl_cmd->id = key->keyidx;
724 wl_key.ssid_profile = 0; 735 wl_cmd->ssid_profile = 0;
725 736
726 wl12xx_dump(DEBUG_CRYPT, "TARGET KEY: ", &wl_key, sizeof(wl_key)); 737 wl12xx_dump(DEBUG_CRYPT, "TARGET KEY: ", wl_cmd, sizeof(*wl_cmd));
727 738
728 if (wl12xx_cmd_send(wl, CMD_SET_KEYS, &wl_key, sizeof(wl_key)) < 0) { 739 ret = wl12xx_cmd_send(wl, CMD_SET_KEYS, wl_cmd, sizeof(*wl_cmd));
729 wl12xx_error("Set KEY failed"); 740 if (ret < 0) {
730 ret = -EOPNOTSUPP; 741 wl12xx_warning("could not set keys");
731 goto out; 742 goto out_unlock;
732 } 743 }
733 744
734out: 745out_unlock:
735 mutex_unlock(&wl->mutex); 746 mutex_unlock(&wl->mutex);
747
748out:
749 kfree(wl_cmd);
750
736 return ret; 751 return ret;
737} 752}
738 753
@@ -812,11 +827,10 @@ static int wl12xx_hw_scan(struct wl12xx *wl, u8 *ssid, size_t len,
812 u8 active_scan, u8 high_prio, u8 num_channels, 827 u8 active_scan, u8 high_prio, u8 num_channels,
813 u8 probe_requests) 828 u8 probe_requests)
814{ 829{
830 struct wl12xx_cmd_trigger_scan_to *trigger = NULL;
831 struct cmd_scan *params = NULL;
815 int i, ret; 832 int i, ret;
816 u32 split_scan = 0;
817 u16 scan_options = 0; 833 u16 scan_options = 0;
818 struct cmd_scan *params;
819 struct wl12xx_command *cmd_answer;
820 834
821 if (wl->scanning) 835 if (wl->scanning)
822 return -EINVAL; 836 return -EINVAL;
@@ -870,10 +884,16 @@ static int wl12xx_hw_scan(struct wl12xx *wl, u8 *ssid, size_t len,
870 goto out; 884 goto out;
871 } 885 }
872 886
873 ret = wl12xx_cmd_send(wl, CMD_TRIGGER_SCAN_TO, &split_scan, 887 trigger = kzalloc(sizeof(*trigger), GFP_KERNEL);
874 sizeof(u32)); 888 if (!trigger)
889 goto out;
890
891 trigger->timeout = 0;
892
893 ret = wl12xx_cmd_send(wl, CMD_TRIGGER_SCAN_TO, trigger,
894 sizeof(*trigger));
875 if (ret < 0) { 895 if (ret < 0) {
876 wl12xx_error("Split SCAN failed"); 896 wl12xx_error("trigger scan to failed for hw scan");
877 goto out; 897 goto out;
878 } 898 }
879 899
@@ -887,10 +907,9 @@ static int wl12xx_hw_scan(struct wl12xx *wl, u8 *ssid, size_t len,
887 907
888 wl12xx_spi_mem_read(wl, wl->cmd_box_addr, params, sizeof(*params)); 908 wl12xx_spi_mem_read(wl, wl->cmd_box_addr, params, sizeof(*params));
889 909
890 cmd_answer = (struct wl12xx_command *) params; 910 if (params->header.status != CMD_STATUS_SUCCESS) {
891 if (cmd_answer->status != CMD_STATUS_SUCCESS) {
892 wl12xx_error("TEST command answer error: %d", 911 wl12xx_error("TEST command answer error: %d",
893 cmd_answer->status); 912 params->header.status);
894 wl->scanning = false; 913 wl->scanning = false;
895 ret = -EIO; 914 ret = -EIO;
896 goto out; 915 goto out;
@@ -942,7 +961,7 @@ static void wl12xx_op_bss_info_changed(struct ieee80211_hw *hw,
942 struct ieee80211_bss_conf *bss_conf, 961 struct ieee80211_bss_conf *bss_conf,
943 u32 changed) 962 u32 changed)
944{ 963{
945 enum acx_ps_mode mode; 964 enum wl12xx_cmd_ps_mode mode;
946 struct wl12xx *wl = hw->priv; 965 struct wl12xx *wl = hw->priv;
947 struct sk_buff *beacon; 966 struct sk_buff *beacon;
948 int ret; 967 int ret;
diff --git a/drivers/net/wireless/wl12xx/ps.c b/drivers/net/wireless/wl12xx/ps.c
index 83a10117330b..fe5e2d13acf2 100644
--- a/drivers/net/wireless/wl12xx/ps.c
+++ b/drivers/net/wireless/wl12xx/ps.c
@@ -114,7 +114,7 @@ static int wl12xx_ps_set_elp(struct wl12xx *wl, bool enable)
114 return 0; 114 return 0;
115} 115}
116 116
117int wl12xx_ps_set_mode(struct wl12xx *wl, enum acx_ps_mode mode) 117int wl12xx_ps_set_mode(struct wl12xx *wl, enum wl12xx_cmd_ps_mode mode)
118{ 118{
119 int ret; 119 int ret;
120 120
diff --git a/drivers/net/wireless/wl12xx/ps.h b/drivers/net/wireless/wl12xx/ps.h
index 5d7c52553830..ad61b4a0b5ee 100644
--- a/drivers/net/wireless/wl12xx/ps.h
+++ b/drivers/net/wireless/wl12xx/ps.h
@@ -28,7 +28,7 @@
28#include "wl12xx.h" 28#include "wl12xx.h"
29#include "acx.h" 29#include "acx.h"
30 30
31int wl12xx_ps_set_mode(struct wl12xx *wl, enum acx_ps_mode mode); 31int wl12xx_ps_set_mode(struct wl12xx *wl, enum wl12xx_cmd_ps_mode mode);
32void wl12xx_ps_elp_sleep(struct wl12xx *wl); 32void wl12xx_ps_elp_sleep(struct wl12xx *wl);
33int wl12xx_ps_elp_wakeup(struct wl12xx *wl); 33int wl12xx_ps_elp_wakeup(struct wl12xx *wl);
34 34
diff --git a/drivers/net/wireless/wl12xx/rx.c b/drivers/net/wireless/wl12xx/rx.c
index 981ea259eb89..5fd916a0b254 100644
--- a/drivers/net/wireless/wl12xx/rx.c
+++ b/drivers/net/wireless/wl12xx/rx.c
@@ -48,6 +48,9 @@ static void wl12xx_rx_status(struct wl12xx *wl,
48 struct ieee80211_rx_status *status, 48 struct ieee80211_rx_status *status,
49 u8 beacon) 49 u8 beacon)
50{ 50{
51 u64 mactime;
52 int ret;
53
51 memset(status, 0, sizeof(struct ieee80211_rx_status)); 54 memset(status, 0, sizeof(struct ieee80211_rx_status));
52 55
53 status->band = IEEE80211_BAND_2GHZ; 56 status->band = IEEE80211_BAND_2GHZ;
@@ -62,27 +65,9 @@ static void wl12xx_rx_status(struct wl12xx *wl,
62 * this one must be atomic, while our SPI routines can sleep. 65 * this one must be atomic, while our SPI routines can sleep.
63 */ 66 */
64 if ((wl->bss_type == BSS_TYPE_IBSS) && beacon) { 67 if ((wl->bss_type == BSS_TYPE_IBSS) && beacon) {
65 u64 mactime; 68 ret = wl12xx_acx_tsf_info(wl, &mactime);
66 int ret; 69 if (ret == 0)
67 struct wl12xx_command cmd; 70 status->mactime = mactime;
68 struct acx_tsf_info *tsf_info;
69
70 memset(&cmd, 0, sizeof(cmd));
71
72 ret = wl12xx_cmd_interrogate(wl, ACX_TSF_INFO,
73 sizeof(struct acx_tsf_info),
74 &cmd);
75 if (ret < 0) {
76 wl12xx_warning("ACX_FW_REV interrogate failed");
77 return;
78 }
79
80 tsf_info = (struct acx_tsf_info *)&(cmd.parameters);
81
82 mactime = tsf_info->current_tsf_lsb |
83 (tsf_info->current_tsf_msb << 31);
84
85 status->mactime = mactime;
86 } 71 }
87 72
88 status->signal = desc->rssi; 73 status->signal = desc->rssi;
diff --git a/drivers/net/wireless/wl12xx/wl1251.c b/drivers/net/wireless/wl12xx/wl1251.c
index ce1561a41fa4..1a352cf8c3ec 100644
--- a/drivers/net/wireless/wl12xx/wl1251.c
+++ b/drivers/net/wireless/wl12xx/wl1251.c
@@ -297,45 +297,48 @@ out:
297 297
298static int wl1251_mem_cfg(struct wl12xx *wl) 298static int wl1251_mem_cfg(struct wl12xx *wl)
299{ 299{
300 struct wl1251_acx_config_memory mem_conf; 300 struct wl1251_acx_config_memory *mem_conf;
301 int ret, i; 301 int ret, i;
302 302
303 wl12xx_debug(DEBUG_ACX, "wl1251 mem cfg"); 303 wl12xx_debug(DEBUG_ACX, "wl1251 mem cfg");
304 304
305 mem_conf = kzalloc(sizeof(*mem_conf), GFP_KERNEL);
306 if (!mem_conf) {
307 ret = -ENOMEM;
308 goto out;
309 }
310
305 /* memory config */ 311 /* memory config */
306 mem_conf.mem_config.num_stations = cpu_to_le16(DEFAULT_NUM_STATIONS); 312 mem_conf->mem_config.num_stations = cpu_to_le16(DEFAULT_NUM_STATIONS);
307 mem_conf.mem_config.rx_mem_block_num = 35; 313 mem_conf->mem_config.rx_mem_block_num = 35;
308 mem_conf.mem_config.tx_min_mem_block_num = 64; 314 mem_conf->mem_config.tx_min_mem_block_num = 64;
309 mem_conf.mem_config.num_tx_queues = MAX_TX_QUEUES; 315 mem_conf->mem_config.num_tx_queues = MAX_TX_QUEUES;
310 mem_conf.mem_config.host_if_options = HOSTIF_PKT_RING; 316 mem_conf->mem_config.host_if_options = HOSTIF_PKT_RING;
311 mem_conf.mem_config.num_ssid_profiles = 1; 317 mem_conf->mem_config.num_ssid_profiles = 1;
312 mem_conf.mem_config.debug_buffer_size = 318 mem_conf->mem_config.debug_buffer_size =
313 cpu_to_le16(TRACE_BUFFER_MAX_SIZE); 319 cpu_to_le16(TRACE_BUFFER_MAX_SIZE);
314 320
315 /* RX queue config */ 321 /* RX queue config */
316 mem_conf.rx_queue_config.dma_address = 0; 322 mem_conf->rx_queue_config.dma_address = 0;
317 mem_conf.rx_queue_config.num_descs = ACX_RX_DESC_DEF; 323 mem_conf->rx_queue_config.num_descs = ACX_RX_DESC_DEF;
318 mem_conf.rx_queue_config.priority = DEFAULT_RXQ_PRIORITY; 324 mem_conf->rx_queue_config.priority = DEFAULT_RXQ_PRIORITY;
319 mem_conf.rx_queue_config.type = DEFAULT_RXQ_TYPE; 325 mem_conf->rx_queue_config.type = DEFAULT_RXQ_TYPE;
320 326
321 /* TX queue config */ 327 /* TX queue config */
322 for (i = 0; i < MAX_TX_QUEUES; i++) { 328 for (i = 0; i < MAX_TX_QUEUES; i++) {
323 mem_conf.tx_queue_config[i].num_descs = ACX_TX_DESC_DEF; 329 mem_conf->tx_queue_config[i].num_descs = ACX_TX_DESC_DEF;
324 mem_conf.tx_queue_config[i].attributes = i; 330 mem_conf->tx_queue_config[i].attributes = i;
325 } 331 }
326 332
327 mem_conf.header.id = ACX_MEM_CFG; 333 ret = wl12xx_cmd_configure(wl, ACX_MEM_CFG, mem_conf,
328 mem_conf.header.len = sizeof(struct wl1251_acx_config_memory) - 334 sizeof(*mem_conf));
329 sizeof(struct acx_header); 335 if (ret < 0) {
330 mem_conf.header.len -=
331 (MAX_TX_QUEUE_CONFIGS - mem_conf.mem_config.num_tx_queues) *
332 sizeof(struct wl1251_acx_tx_queue_config);
333
334 ret = wl12xx_cmd_configure(wl, &mem_conf,
335 sizeof(struct wl1251_acx_config_memory));
336 if (ret < 0)
337 wl12xx_warning("wl1251 mem config failed: %d", ret); 336 wl12xx_warning("wl1251 mem config failed: %d", ret);
337 goto out;
338 }
338 339
340out:
341 kfree(mem_conf);
339 return ret; 342 return ret;
340} 343}
341 344
@@ -529,28 +532,33 @@ static int wl1251_hw_init_txq_fill(u8 qid,
529 532
530static int wl1251_hw_init_tx_queue_config(struct wl12xx *wl) 533static int wl1251_hw_init_tx_queue_config(struct wl12xx *wl)
531{ 534{
532 struct acx_tx_queue_qos_config config; 535 struct acx_tx_queue_qos_config *config;
533 struct wl1251_acx_mem_map *wl_mem_map = wl->target_mem_map; 536 struct wl1251_acx_mem_map *wl_mem_map = wl->target_mem_map;
534 int ret, i; 537 int ret, i;
535 538
536 wl12xx_debug(DEBUG_ACX, "acx tx queue config"); 539 wl12xx_debug(DEBUG_ACX, "acx tx queue config");
537 540
538 config.header.id = ACX_TX_QUEUE_CFG; 541 config = kzalloc(sizeof(*config), GFP_KERNEL);
539 config.header.len = sizeof(struct acx_tx_queue_qos_config) - 542 if (!config) {
540 sizeof(struct acx_header); 543 ret = -ENOMEM;
544 goto out;
545 }
541 546
542 for (i = 0; i < MAX_NUM_OF_AC; i++) { 547 for (i = 0; i < MAX_NUM_OF_AC; i++) {
543 ret = wl1251_hw_init_txq_fill(i, &config, 548 ret = wl1251_hw_init_txq_fill(i, config,
544 wl_mem_map->num_tx_mem_blocks); 549 wl_mem_map->num_tx_mem_blocks);
545 if (ret < 0) 550 if (ret < 0)
546 return ret; 551 goto out;
547 552
548 ret = wl12xx_cmd_configure(wl, &config, sizeof(config)); 553 ret = wl12xx_cmd_configure(wl, ACX_TX_QUEUE_CFG,
554 config, sizeof(*config));
549 if (ret < 0) 555 if (ret < 0)
550 return ret; 556 goto out;
551 } 557 }
552 558
553 return 0; 559out:
560 kfree(config);
561 return ret;
554} 562}
555 563
556static int wl1251_hw_init_data_path_config(struct wl12xx *wl) 564static int wl1251_hw_init_data_path_config(struct wl12xx *wl)