aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/wl12xx/wl1271_cmd.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/wl12xx/wl1271_cmd.c')
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_cmd.c473
1 files changed, 322 insertions, 151 deletions
diff --git a/drivers/net/wireless/wl12xx/wl1271_cmd.c b/drivers/net/wireless/wl12xx/wl1271_cmd.c
index 2a4351ff54dc..e7832f3318eb 100644
--- a/drivers/net/wireless/wl12xx/wl1271_cmd.c
+++ b/drivers/net/wireless/wl12xx/wl1271_cmd.c
@@ -26,10 +26,12 @@
26#include <linux/crc7.h> 26#include <linux/crc7.h>
27#include <linux/spi/spi.h> 27#include <linux/spi/spi.h>
28#include <linux/etherdevice.h> 28#include <linux/etherdevice.h>
29#include <linux/slab.h>
29 30
30#include "wl1271.h" 31#include "wl1271.h"
31#include "wl1271_reg.h" 32#include "wl1271_reg.h"
32#include "wl1271_spi.h" 33#include "wl1271_spi.h"
34#include "wl1271_io.h"
33#include "wl1271_acx.h" 35#include "wl1271_acx.h"
34#include "wl12xx_80211.h" 36#include "wl12xx_80211.h"
35#include "wl1271_cmd.h" 37#include "wl1271_cmd.h"
@@ -42,26 +44,28 @@
42 * @buf: buffer containing the command, must work with dma 44 * @buf: buffer containing the command, must work with dma
43 * @len: length of the buffer 45 * @len: length of the buffer
44 */ 46 */
45int wl1271_cmd_send(struct wl1271 *wl, u16 id, void *buf, size_t len) 47int wl1271_cmd_send(struct wl1271 *wl, u16 id, void *buf, size_t len,
48 size_t res_len)
46{ 49{
47 struct wl1271_cmd_header *cmd; 50 struct wl1271_cmd_header *cmd;
48 unsigned long timeout; 51 unsigned long timeout;
49 u32 intr; 52 u32 intr;
50 int ret = 0; 53 int ret = 0;
54 u16 status;
51 55
52 cmd = buf; 56 cmd = buf;
53 cmd->id = id; 57 cmd->id = cpu_to_le16(id);
54 cmd->status = 0; 58 cmd->status = 0;
55 59
56 WARN_ON(len % 4 != 0); 60 WARN_ON(len % 4 != 0);
57 61
58 wl1271_spi_mem_write(wl, wl->cmd_box_addr, buf, len); 62 wl1271_write(wl, wl->cmd_box_addr, buf, len, false);
59 63
60 wl1271_reg_write32(wl, ACX_REG_INTERRUPT_TRIG, INTR_TRIG_CMD); 64 wl1271_write32(wl, ACX_REG_INTERRUPT_TRIG, INTR_TRIG_CMD);
61 65
62 timeout = jiffies + msecs_to_jiffies(WL1271_COMMAND_TIMEOUT); 66 timeout = jiffies + msecs_to_jiffies(WL1271_COMMAND_TIMEOUT);
63 67
64 intr = wl1271_reg_read32(wl, ACX_REG_INTERRUPT_NO_CLEAR); 68 intr = wl1271_read32(wl, ACX_REG_INTERRUPT_NO_CLEAR);
65 while (!(intr & WL1271_ACX_INTR_CMD_COMPLETE)) { 69 while (!(intr & WL1271_ACX_INTR_CMD_COMPLETE)) {
66 if (time_after(jiffies, timeout)) { 70 if (time_after(jiffies, timeout)) {
67 wl1271_error("command complete timeout"); 71 wl1271_error("command complete timeout");
@@ -71,17 +75,28 @@ int wl1271_cmd_send(struct wl1271 *wl, u16 id, void *buf, size_t len)
71 75
72 msleep(1); 76 msleep(1);
73 77
74 intr = wl1271_reg_read32(wl, ACX_REG_INTERRUPT_NO_CLEAR); 78 intr = wl1271_read32(wl, ACX_REG_INTERRUPT_NO_CLEAR);
75 } 79 }
76 80
77 wl1271_reg_write32(wl, ACX_REG_INTERRUPT_ACK, 81 /* read back the status code of the command */
78 WL1271_ACX_INTR_CMD_COMPLETE); 82 if (res_len == 0)
83 res_len = sizeof(struct wl1271_cmd_header);
84 wl1271_read(wl, wl->cmd_box_addr, cmd, res_len, false);
85
86 status = le16_to_cpu(cmd->status);
87 if (status != CMD_STATUS_SUCCESS) {
88 wl1271_error("command execute failure %d", status);
89 ret = -EIO;
90 }
91
92 wl1271_write32(wl, ACX_REG_INTERRUPT_ACK,
93 WL1271_ACX_INTR_CMD_COMPLETE);
79 94
80out: 95out:
81 return ret; 96 return ret;
82} 97}
83 98
84int wl1271_cmd_cal_channel_tune(struct wl1271 *wl) 99static int wl1271_cmd_cal_channel_tune(struct wl1271 *wl)
85{ 100{
86 struct wl1271_cmd_cal_channel_tune *cmd; 101 struct wl1271_cmd_cal_channel_tune *cmd;
87 int ret = 0; 102 int ret = 0;
@@ -104,7 +119,7 @@ int wl1271_cmd_cal_channel_tune(struct wl1271 *wl)
104 return ret; 119 return ret;
105} 120}
106 121
107int wl1271_cmd_cal_update_ref_point(struct wl1271 *wl) 122static int wl1271_cmd_cal_update_ref_point(struct wl1271 *wl)
108{ 123{
109 struct wl1271_cmd_cal_update_ref_point *cmd; 124 struct wl1271_cmd_cal_update_ref_point *cmd;
110 int ret = 0; 125 int ret = 0;
@@ -129,7 +144,7 @@ int wl1271_cmd_cal_update_ref_point(struct wl1271 *wl)
129 return ret; 144 return ret;
130} 145}
131 146
132int wl1271_cmd_cal_p2g(struct wl1271 *wl) 147static int wl1271_cmd_cal_p2g(struct wl1271 *wl)
133{ 148{
134 struct wl1271_cmd_cal_p2g *cmd; 149 struct wl1271_cmd_cal_p2g *cmd;
135 int ret = 0; 150 int ret = 0;
@@ -150,7 +165,7 @@ int wl1271_cmd_cal_p2g(struct wl1271 *wl)
150 return ret; 165 return ret;
151} 166}
152 167
153int wl1271_cmd_cal(struct wl1271 *wl) 168static int wl1271_cmd_cal(struct wl1271 *wl)
154{ 169{
155 /* 170 /*
156 * FIXME: we must make sure that we're not sleeping when calibration 171 * FIXME: we must make sure that we're not sleeping when calibration
@@ -175,11 +190,68 @@ int wl1271_cmd_cal(struct wl1271 *wl)
175 return ret; 190 return ret;
176} 191}
177 192
178int wl1271_cmd_join(struct wl1271 *wl, u8 bss_type, u8 dtim_interval, 193int wl1271_cmd_general_parms(struct wl1271 *wl)
179 u16 beacon_interval, u8 wait) 194{
195 struct wl1271_general_parms_cmd *gen_parms;
196 int ret;
197
198 if (!wl->nvs)
199 return -ENODEV;
200
201 gen_parms = kzalloc(sizeof(*gen_parms), GFP_KERNEL);
202 if (!gen_parms)
203 return -ENOMEM;
204
205 gen_parms->test.id = TEST_CMD_INI_FILE_GENERAL_PARAM;
206
207 memcpy(gen_parms->params, wl->nvs->general_params,
208 WL1271_NVS_GENERAL_PARAMS_SIZE);
209
210 ret = wl1271_cmd_test(wl, gen_parms, sizeof(*gen_parms), 0);
211 if (ret < 0)
212 wl1271_warning("CMD_INI_FILE_GENERAL_PARAM failed");
213
214 kfree(gen_parms);
215 return ret;
216}
217
218int wl1271_cmd_radio_parms(struct wl1271 *wl)
219{
220 struct wl1271_radio_parms_cmd *radio_parms;
221 struct conf_radio_parms *rparam = &wl->conf.init.radioparam;
222 int ret;
223
224 if (!wl->nvs)
225 return -ENODEV;
226
227 radio_parms = kzalloc(sizeof(*radio_parms), GFP_KERNEL);
228 if (!radio_parms)
229 return -ENOMEM;
230
231 radio_parms->test.id = TEST_CMD_INI_FILE_RADIO_PARAM;
232
233 memcpy(radio_parms->stat_radio_params, wl->nvs->stat_radio_params,
234 WL1271_NVS_STAT_RADIO_PARAMS_SIZE);
235 memcpy(radio_parms->dyn_radio_params,
236 wl->nvs->dyn_radio_params[rparam->fem],
237 WL1271_NVS_DYN_RADIO_PARAMS_SIZE);
238
239 /* FIXME: current NVS is missing 5GHz parameters */
240
241 wl1271_dump(DEBUG_CMD, "TEST_CMD_INI_FILE_RADIO_PARAM: ",
242 radio_parms, sizeof(*radio_parms));
243
244 ret = wl1271_cmd_test(wl, radio_parms, sizeof(*radio_parms), 0);
245 if (ret < 0)
246 wl1271_warning("CMD_INI_FILE_RADIO_PARAM failed");
247
248 kfree(radio_parms);
249 return ret;
250}
251
252int wl1271_cmd_join(struct wl1271 *wl)
180{ 253{
181 static bool do_cal = true; 254 static bool do_cal = true;
182 unsigned long timeout;
183 struct wl1271_cmd_join *join; 255 struct wl1271_cmd_join *join;
184 int ret, i; 256 int ret, i;
185 u8 *bssid; 257 u8 *bssid;
@@ -193,7 +265,6 @@ int wl1271_cmd_join(struct wl1271 *wl, u8 bss_type, u8 dtim_interval,
193 do_cal = false; 265 do_cal = false;
194 } 266 }
195 267
196
197 join = kzalloc(sizeof(*join), GFP_KERNEL); 268 join = kzalloc(sizeof(*join), GFP_KERNEL);
198 if (!join) { 269 if (!join) {
199 ret = -ENOMEM; 270 ret = -ENOMEM;
@@ -207,15 +278,34 @@ int wl1271_cmd_join(struct wl1271 *wl, u8 bss_type, u8 dtim_interval,
207 for (i = 0; i < ETH_ALEN; i++) 278 for (i = 0; i < ETH_ALEN; i++)
208 bssid[i] = wl->bssid[ETH_ALEN - i - 1]; 279 bssid[i] = wl->bssid[ETH_ALEN - i - 1];
209 280
210 join->rx_config_options = wl->rx_config; 281 join->rx_config_options = cpu_to_le32(wl->rx_config);
211 join->rx_filter_options = wl->rx_filter; 282 join->rx_filter_options = cpu_to_le32(wl->rx_filter);
283 join->bss_type = wl->bss_type;
284
285 /*
286 * FIXME: disable temporarily all filters because after commit
287 * 9cef8737 "mac80211: fix managed mode BSSID handling" broke
288 * association. The filter logic needs to be implemented properly
289 * and once that is done, this hack can be removed.
290 */
291 join->rx_config_options = cpu_to_le32(0);
292 join->rx_filter_options = cpu_to_le32(WL1271_DEFAULT_RX_FILTER);
293
294 if (wl->band == IEEE80211_BAND_2GHZ)
295 join->basic_rate_set = cpu_to_le32(CONF_HW_BIT_RATE_1MBPS |
296 CONF_HW_BIT_RATE_2MBPS |
297 CONF_HW_BIT_RATE_5_5MBPS |
298 CONF_HW_BIT_RATE_11MBPS);
299 else {
300 join->bss_type |= WL1271_JOIN_CMD_BSS_TYPE_5GHZ;
301 join->basic_rate_set = cpu_to_le32(CONF_HW_BIT_RATE_6MBPS |
302 CONF_HW_BIT_RATE_12MBPS |
303 CONF_HW_BIT_RATE_24MBPS);
304 }
212 305
213 join->basic_rate_set = RATE_MASK_1MBPS | RATE_MASK_2MBPS | 306 join->beacon_interval = cpu_to_le16(WL1271_DEFAULT_BEACON_INT);
214 RATE_MASK_5_5MBPS | RATE_MASK_11MBPS; 307 join->dtim_interval = WL1271_DEFAULT_DTIM_PERIOD;
215 308
216 join->beacon_interval = beacon_interval;
217 join->dtim_interval = dtim_interval;
218 join->bss_type = bss_type;
219 join->channel = wl->channel; 309 join->channel = wl->channel;
220 join->ssid_len = wl->ssid_len; 310 join->ssid_len = wl->ssid_len;
221 memcpy(join->ssid, wl->ssid, wl->ssid_len); 311 memcpy(join->ssid, wl->ssid, wl->ssid_len);
@@ -228,21 +318,22 @@ int wl1271_cmd_join(struct wl1271 *wl, u8 bss_type, u8 dtim_interval,
228 318
229 join->ctrl |= wl->session_counter << WL1271_JOIN_CMD_TX_SESSION_OFFSET; 319 join->ctrl |= wl->session_counter << WL1271_JOIN_CMD_TX_SESSION_OFFSET;
230 320
321 /* reset TX security counters */
322 wl->tx_security_last_seq = 0;
323 wl->tx_security_seq_16 = 0;
324 wl->tx_security_seq_32 = 0;
231 325
232 ret = wl1271_cmd_send(wl, CMD_START_JOIN, join, sizeof(*join)); 326 ret = wl1271_cmd_send(wl, CMD_START_JOIN, join, sizeof(*join), 0);
233 if (ret < 0) { 327 if (ret < 0) {
234 wl1271_error("failed to initiate cmd join"); 328 wl1271_error("failed to initiate cmd join");
235 goto out_free; 329 goto out_free;
236 } 330 }
237 331
238 timeout = msecs_to_jiffies(JOIN_TIMEOUT);
239
240 /* 332 /*
241 * ugly hack: we should wait for JOIN_EVENT_COMPLETE_ID but to 333 * ugly hack: we should wait for JOIN_EVENT_COMPLETE_ID but to
242 * simplify locking we just sleep instead, for now 334 * simplify locking we just sleep instead, for now
243 */ 335 */
244 if (wait) 336 msleep(10);
245 msleep(10);
246 337
247out_free: 338out_free:
248 kfree(join); 339 kfree(join);
@@ -262,34 +353,21 @@ out:
262int wl1271_cmd_test(struct wl1271 *wl, void *buf, size_t buf_len, u8 answer) 353int wl1271_cmd_test(struct wl1271 *wl, void *buf, size_t buf_len, u8 answer)
263{ 354{
264 int ret; 355 int ret;
356 size_t res_len = 0;
265 357
266 wl1271_debug(DEBUG_CMD, "cmd test"); 358 wl1271_debug(DEBUG_CMD, "cmd test");
267 359
268 ret = wl1271_cmd_send(wl, CMD_TEST, buf, buf_len); 360 if (answer)
361 res_len = buf_len;
362
363 ret = wl1271_cmd_send(wl, CMD_TEST, buf, buf_len, res_len);
269 364
270 if (ret < 0) { 365 if (ret < 0) {
271 wl1271_warning("TEST command failed"); 366 wl1271_warning("TEST command failed");
272 return ret; 367 return ret;
273 } 368 }
274 369
275 if (answer) { 370 return ret;
276 struct wl1271_command *cmd_answer;
277
278 /*
279 * The test command got in, we can read the answer.
280 * The answer would be a wl1271_command, where the
281 * parameter array contains the actual answer.
282 */
283 wl1271_spi_mem_read(wl, wl->cmd_box_addr, buf, buf_len);
284
285 cmd_answer = buf;
286
287 if (cmd_answer->header.status != CMD_STATUS_SUCCESS)
288 wl1271_error("TEST command answer error: %d",
289 cmd_answer->header.status);
290 }
291
292 return 0;
293} 371}
294 372
295/** 373/**
@@ -307,26 +385,15 @@ int wl1271_cmd_interrogate(struct wl1271 *wl, u16 id, void *buf, size_t len)
307 385
308 wl1271_debug(DEBUG_CMD, "cmd interrogate"); 386 wl1271_debug(DEBUG_CMD, "cmd interrogate");
309 387
310 acx->id = id; 388 acx->id = cpu_to_le16(id);
311 389
312 /* payload length, does not include any headers */ 390 /* payload length, does not include any headers */
313 acx->len = len - sizeof(*acx); 391 acx->len = cpu_to_le16(len - sizeof(*acx));
314 392
315 ret = wl1271_cmd_send(wl, CMD_INTERROGATE, acx, sizeof(*acx)); 393 ret = wl1271_cmd_send(wl, CMD_INTERROGATE, acx, sizeof(*acx), len);
316 if (ret < 0) { 394 if (ret < 0)
317 wl1271_error("INTERROGATE command failed"); 395 wl1271_error("INTERROGATE command failed");
318 goto out;
319 }
320
321 /* the interrogate command got in, we can read the answer */
322 wl1271_spi_mem_read(wl, wl->cmd_box_addr, buf, len);
323
324 acx = buf;
325 if (acx->cmd.status != CMD_STATUS_SUCCESS)
326 wl1271_error("INTERROGATE command error: %d",
327 acx->cmd.status);
328 396
329out:
330 return ret; 397 return ret;
331} 398}
332 399
@@ -345,12 +412,12 @@ int wl1271_cmd_configure(struct wl1271 *wl, u16 id, void *buf, size_t len)
345 412
346 wl1271_debug(DEBUG_CMD, "cmd configure"); 413 wl1271_debug(DEBUG_CMD, "cmd configure");
347 414
348 acx->id = id; 415 acx->id = cpu_to_le16(id);
349 416
350 /* payload length, does not include any headers */ 417 /* payload length, does not include any headers */
351 acx->len = len - sizeof(*acx); 418 acx->len = cpu_to_le16(len - sizeof(*acx));
352 419
353 ret = wl1271_cmd_send(wl, CMD_CONFIGURE, acx, len); 420 ret = wl1271_cmd_send(wl, CMD_CONFIGURE, acx, len, 0);
354 if (ret < 0) { 421 if (ret < 0) {
355 wl1271_warning("CONFIGURE command NOK"); 422 wl1271_warning("CONFIGURE command NOK");
356 return ret; 423 return ret;
@@ -359,7 +426,7 @@ int wl1271_cmd_configure(struct wl1271 *wl, u16 id, void *buf, size_t len)
359 return 0; 426 return 0;
360} 427}
361 428
362int wl1271_cmd_data_path(struct wl1271 *wl, u8 channel, bool enable) 429int wl1271_cmd_data_path(struct wl1271 *wl, bool enable)
363{ 430{
364 struct cmd_enabledisable_path *cmd; 431 struct cmd_enabledisable_path *cmd;
365 int ret; 432 int ret;
@@ -373,7 +440,8 @@ int wl1271_cmd_data_path(struct wl1271 *wl, u8 channel, bool enable)
373 goto out; 440 goto out;
374 } 441 }
375 442
376 cmd->channel = channel; 443 /* the channel here is only used for calibration, so hardcoded to 1 */
444 cmd->channel = 1;
377 445
378 if (enable) { 446 if (enable) {
379 cmd_rx = CMD_ENABLE_RX; 447 cmd_rx = CMD_ENABLE_RX;
@@ -383,39 +451,38 @@ int wl1271_cmd_data_path(struct wl1271 *wl, u8 channel, bool enable)
383 cmd_tx = CMD_DISABLE_TX; 451 cmd_tx = CMD_DISABLE_TX;
384 } 452 }
385 453
386 ret = wl1271_cmd_send(wl, cmd_rx, cmd, sizeof(*cmd)); 454 ret = wl1271_cmd_send(wl, cmd_rx, cmd, sizeof(*cmd), 0);
387 if (ret < 0) { 455 if (ret < 0) {
388 wl1271_error("rx %s cmd for channel %d failed", 456 wl1271_error("rx %s cmd for channel %d failed",
389 enable ? "start" : "stop", channel); 457 enable ? "start" : "stop", cmd->channel);
390 goto out; 458 goto out;
391 } 459 }
392 460
393 wl1271_debug(DEBUG_BOOT, "rx %s cmd channel %d", 461 wl1271_debug(DEBUG_BOOT, "rx %s cmd channel %d",
394 enable ? "start" : "stop", channel); 462 enable ? "start" : "stop", cmd->channel);
395 463
396 ret = wl1271_cmd_send(wl, cmd_tx, cmd, sizeof(*cmd)); 464 ret = wl1271_cmd_send(wl, cmd_tx, cmd, sizeof(*cmd), 0);
397 if (ret < 0) { 465 if (ret < 0) {
398 wl1271_error("tx %s cmd for channel %d failed", 466 wl1271_error("tx %s cmd for channel %d failed",
399 enable ? "start" : "stop", channel); 467 enable ? "start" : "stop", cmd->channel);
400 return ret; 468 return ret;
401 } 469 }
402 470
403 wl1271_debug(DEBUG_BOOT, "tx %s cmd channel %d", 471 wl1271_debug(DEBUG_BOOT, "tx %s cmd channel %d",
404 enable ? "start" : "stop", channel); 472 enable ? "start" : "stop", cmd->channel);
405 473
406out: 474out:
407 kfree(cmd); 475 kfree(cmd);
408 return ret; 476 return ret;
409} 477}
410 478
411int wl1271_cmd_ps_mode(struct wl1271 *wl, u8 ps_mode) 479int wl1271_cmd_ps_mode(struct wl1271 *wl, u8 ps_mode, bool send)
412{ 480{
413 struct wl1271_cmd_ps_params *ps_params = NULL; 481 struct wl1271_cmd_ps_params *ps_params = NULL;
414 int ret = 0; 482 int ret = 0;
415 483
416 /* FIXME: this should be in ps.c */ 484 /* FIXME: this should be in ps.c */
417 ret = wl1271_acx_wake_up_conditions(wl, WAKE_UP_EVENT_DTIM_BITMAP, 485 ret = wl1271_acx_wake_up_conditions(wl);
418 wl->listen_int);
419 if (ret < 0) { 486 if (ret < 0) {
420 wl1271_error("couldn't set wake up conditions"); 487 wl1271_error("couldn't set wake up conditions");
421 goto out; 488 goto out;
@@ -430,13 +497,13 @@ int wl1271_cmd_ps_mode(struct wl1271 *wl, u8 ps_mode)
430 } 497 }
431 498
432 ps_params->ps_mode = ps_mode; 499 ps_params->ps_mode = ps_mode;
433 ps_params->send_null_data = 1; 500 ps_params->send_null_data = send;
434 ps_params->retries = 5; 501 ps_params->retries = 5;
435 ps_params->hang_over_period = 128; 502 ps_params->hang_over_period = 128;
436 ps_params->null_data_rate = 1; /* 1 Mbps */ 503 ps_params->null_data_rate = cpu_to_le32(1); /* 1 Mbps */
437 504
438 ret = wl1271_cmd_send(wl, CMD_SET_PS_MODE, ps_params, 505 ret = wl1271_cmd_send(wl, CMD_SET_PS_MODE, ps_params,
439 sizeof(*ps_params)); 506 sizeof(*ps_params), 0);
440 if (ret < 0) { 507 if (ret < 0) {
441 wl1271_error("cmd set_ps_mode failed"); 508 wl1271_error("cmd set_ps_mode failed");
442 goto out; 509 goto out;
@@ -464,22 +531,17 @@ int wl1271_cmd_read_memory(struct wl1271 *wl, u32 addr, void *answer,
464 WARN_ON(len > MAX_READ_SIZE); 531 WARN_ON(len > MAX_READ_SIZE);
465 len = min_t(size_t, len, MAX_READ_SIZE); 532 len = min_t(size_t, len, MAX_READ_SIZE);
466 533
467 cmd->addr = addr; 534 cmd->addr = cpu_to_le32(addr);
468 cmd->size = len; 535 cmd->size = cpu_to_le32(len);
469 536
470 ret = wl1271_cmd_send(wl, CMD_READ_MEMORY, cmd, sizeof(*cmd)); 537 ret = wl1271_cmd_send(wl, CMD_READ_MEMORY, cmd, sizeof(*cmd),
538 sizeof(*cmd));
471 if (ret < 0) { 539 if (ret < 0) {
472 wl1271_error("read memory command failed: %d", ret); 540 wl1271_error("read memory command failed: %d", ret);
473 goto out; 541 goto out;
474 } 542 }
475 543
476 /* the read command got in, we can now read the answer */ 544 /* the read command got in */
477 wl1271_spi_mem_read(wl, wl->cmd_box_addr, cmd, sizeof(*cmd));
478
479 if (cmd->header.status != CMD_STATUS_SUCCESS)
480 wl1271_error("error in read command result: %d",
481 cmd->header.status);
482
483 memcpy(answer, cmd->value, len); 545 memcpy(answer, cmd->value, len);
484 546
485out: 547out:
@@ -488,16 +550,33 @@ out:
488} 550}
489 551
490int wl1271_cmd_scan(struct wl1271 *wl, u8 *ssid, size_t len, 552int wl1271_cmd_scan(struct wl1271 *wl, u8 *ssid, size_t len,
491 u8 active_scan, u8 high_prio, u8 num_channels, 553 u8 active_scan, u8 high_prio, u8 band,
492 u8 probe_requests) 554 u8 probe_requests)
493{ 555{
494 556
495 struct wl1271_cmd_trigger_scan_to *trigger = NULL; 557 struct wl1271_cmd_trigger_scan_to *trigger = NULL;
496 struct wl1271_cmd_scan *params = NULL; 558 struct wl1271_cmd_scan *params = NULL;
497 int i, ret; 559 struct ieee80211_channel *channels;
560 int i, j, n_ch, ret;
498 u16 scan_options = 0; 561 u16 scan_options = 0;
562 u8 ieee_band;
563
564 if (band == WL1271_SCAN_BAND_2_4_GHZ)
565 ieee_band = IEEE80211_BAND_2GHZ;
566 else if (band == WL1271_SCAN_BAND_DUAL && wl1271_11a_enabled())
567 ieee_band = IEEE80211_BAND_2GHZ;
568 else if (band == WL1271_SCAN_BAND_5_GHZ && wl1271_11a_enabled())
569 ieee_band = IEEE80211_BAND_5GHZ;
570 else
571 return -EINVAL;
572
573 if (wl->hw->wiphy->bands[ieee_band]->channels == NULL)
574 return -EINVAL;
499 575
500 if (wl->scanning) 576 channels = wl->hw->wiphy->bands[ieee_band]->channels;
577 n_ch = wl->hw->wiphy->bands[ieee_band]->n_channels;
578
579 if (test_bit(WL1271_FLAG_SCANNING, &wl->flags))
501 return -EINVAL; 580 return -EINVAL;
502 581
503 params = kzalloc(sizeof(*params), GFP_KERNEL); 582 params = kzalloc(sizeof(*params), GFP_KERNEL);
@@ -512,32 +591,43 @@ int wl1271_cmd_scan(struct wl1271 *wl, u8 *ssid, size_t len,
512 scan_options |= WL1271_SCAN_OPT_PASSIVE; 591 scan_options |= WL1271_SCAN_OPT_PASSIVE;
513 if (high_prio) 592 if (high_prio)
514 scan_options |= WL1271_SCAN_OPT_PRIORITY_HIGH; 593 scan_options |= WL1271_SCAN_OPT_PRIORITY_HIGH;
515 params->params.scan_options = scan_options; 594 params->params.scan_options = cpu_to_le16(scan_options);
516 595
517 params->params.num_channels = num_channels;
518 params->params.num_probe_requests = probe_requests; 596 params->params.num_probe_requests = probe_requests;
519 params->params.tx_rate = cpu_to_le32(RATE_MASK_2MBPS); 597 /* Let the fw autodetect suitable tx_rate for probes */
598 params->params.tx_rate = 0;
520 params->params.tid_trigger = 0; 599 params->params.tid_trigger = 0;
521 params->params.scan_tag = WL1271_SCAN_DEFAULT_TAG; 600 params->params.scan_tag = WL1271_SCAN_DEFAULT_TAG;
522 601
523 for (i = 0; i < num_channels; i++) { 602 if (band == WL1271_SCAN_BAND_DUAL)
524 params->channels[i].min_duration = 603 params->params.band = WL1271_SCAN_BAND_2_4_GHZ;
525 cpu_to_le32(WL1271_SCAN_CHAN_MIN_DURATION); 604 else
526 params->channels[i].max_duration = 605 params->params.band = band;
527 cpu_to_le32(WL1271_SCAN_CHAN_MAX_DURATION); 606
528 memset(&params->channels[i].bssid_lsb, 0xff, 4); 607 for (i = 0, j = 0; i < n_ch && i < WL1271_SCAN_MAX_CHANNELS; i++) {
529 memset(&params->channels[i].bssid_msb, 0xff, 2); 608 if (!(channels[i].flags & IEEE80211_CHAN_DISABLED)) {
530 params->channels[i].early_termination = 0; 609 params->channels[j].min_duration =
531 params->channels[i].tx_power_att = WL1271_SCAN_CURRENT_TX_PWR; 610 cpu_to_le32(WL1271_SCAN_CHAN_MIN_DURATION);
532 params->channels[i].channel = i + 1; 611 params->channels[j].max_duration =
612 cpu_to_le32(WL1271_SCAN_CHAN_MAX_DURATION);
613 memset(&params->channels[j].bssid_lsb, 0xff, 4);
614 memset(&params->channels[j].bssid_msb, 0xff, 2);
615 params->channels[j].early_termination = 0;
616 params->channels[j].tx_power_att =
617 WL1271_SCAN_CURRENT_TX_PWR;
618 params->channels[j].channel = channels[i].hw_value;
619 j++;
620 }
533 } 621 }
534 622
623 params->params.num_channels = j;
624
535 if (len && ssid) { 625 if (len && ssid) {
536 params->params.ssid_len = len; 626 params->params.ssid_len = len;
537 memcpy(params->params.ssid, ssid, len); 627 memcpy(params->params.ssid, ssid, len);
538 } 628 }
539 629
540 ret = wl1271_cmd_build_probe_req(wl, ssid, len); 630 ret = wl1271_cmd_build_probe_req(wl, ssid, len, ieee_band);
541 if (ret < 0) { 631 if (ret < 0) {
542 wl1271_error("PROBE request template failed"); 632 wl1271_error("PROBE request template failed");
543 goto out; 633 goto out;
@@ -553,7 +643,7 @@ int wl1271_cmd_scan(struct wl1271 *wl, u8 *ssid, size_t len,
553 trigger->timeout = 0; 643 trigger->timeout = 0;
554 644
555 ret = wl1271_cmd_send(wl, CMD_TRIGGER_SCAN_TO, trigger, 645 ret = wl1271_cmd_send(wl, CMD_TRIGGER_SCAN_TO, trigger,
556 sizeof(*trigger)); 646 sizeof(*trigger), 0);
557 if (ret < 0) { 647 if (ret < 0) {
558 wl1271_error("trigger scan to failed for hw scan"); 648 wl1271_error("trigger scan to failed for hw scan");
559 goto out; 649 goto out;
@@ -561,21 +651,25 @@ int wl1271_cmd_scan(struct wl1271 *wl, u8 *ssid, size_t len,
561 651
562 wl1271_dump(DEBUG_SCAN, "SCAN: ", params, sizeof(*params)); 652 wl1271_dump(DEBUG_SCAN, "SCAN: ", params, sizeof(*params));
563 653
564 wl->scanning = true; 654 set_bit(WL1271_FLAG_SCANNING, &wl->flags);
655 if (wl1271_11a_enabled()) {
656 wl->scan.state = band;
657 if (band == WL1271_SCAN_BAND_DUAL) {
658 wl->scan.active = active_scan;
659 wl->scan.high_prio = high_prio;
660 wl->scan.probe_requests = probe_requests;
661 if (len && ssid) {
662 wl->scan.ssid_len = len;
663 memcpy(wl->scan.ssid, ssid, len);
664 } else
665 wl->scan.ssid_len = 0;
666 }
667 }
565 668
566 ret = wl1271_cmd_send(wl, CMD_SCAN, params, sizeof(*params)); 669 ret = wl1271_cmd_send(wl, CMD_SCAN, params, sizeof(*params), 0);
567 if (ret < 0) { 670 if (ret < 0) {
568 wl1271_error("SCAN failed"); 671 wl1271_error("SCAN failed");
569 goto out; 672 clear_bit(WL1271_FLAG_SCANNING, &wl->flags);
570 }
571
572 wl1271_spi_mem_read(wl, wl->cmd_box_addr, params, sizeof(*params));
573
574 if (params->header.status != CMD_STATUS_SUCCESS) {
575 wl1271_error("Scan command error: %d",
576 params->header.status);
577 wl->scanning = false;
578 ret = -EIO;
579 goto out; 673 goto out;
580 } 674 }
581 675
@@ -603,14 +697,14 @@ int wl1271_cmd_template_set(struct wl1271 *wl, u16 template_id,
603 697
604 cmd->len = cpu_to_le16(buf_len); 698 cmd->len = cpu_to_le16(buf_len);
605 cmd->template_type = template_id; 699 cmd->template_type = template_id;
606 cmd->enabled_rates = ACX_RATE_MASK_UNSPECIFIED; 700 cmd->enabled_rates = cpu_to_le32(wl->conf.tx.rc_conf.enabled_rates);
607 cmd->short_retry_limit = ACX_RATE_RETRY_LIMIT; 701 cmd->short_retry_limit = wl->conf.tx.rc_conf.short_retry_limit;
608 cmd->long_retry_limit = ACX_RATE_RETRY_LIMIT; 702 cmd->long_retry_limit = wl->conf.tx.rc_conf.long_retry_limit;
609 703
610 if (buf) 704 if (buf)
611 memcpy(cmd->template_data, buf, buf_len); 705 memcpy(cmd->template_data, buf, buf_len);
612 706
613 ret = wl1271_cmd_send(wl, CMD_SET_TEMPLATE, cmd, sizeof(*cmd)); 707 ret = wl1271_cmd_send(wl, CMD_SET_TEMPLATE, cmd, sizeof(*cmd), 0);
614 if (ret < 0) { 708 if (ret < 0) {
615 wl1271_warning("cmd set_template failed: %d", ret); 709 wl1271_warning("cmd set_template failed: %d", ret);
616 goto out_free; 710 goto out_free;
@@ -623,30 +717,62 @@ out:
623 return ret; 717 return ret;
624} 718}
625 719
626static int wl1271_build_basic_rates(char *rates) 720static int wl1271_build_basic_rates(u8 *rates, u8 band)
627{ 721{
628 u8 index = 0; 722 u8 index = 0;
629 723
630 rates[index++] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_1MB; 724 if (band == IEEE80211_BAND_2GHZ) {
631 rates[index++] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_2MB; 725 rates[index++] =
632 rates[index++] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_5MB; 726 IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_1MB;
633 rates[index++] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_11MB; 727 rates[index++] =
728 IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_2MB;
729 rates[index++] =
730 IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_5MB;
731 rates[index++] =
732 IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_11MB;
733 } else if (band == IEEE80211_BAND_5GHZ) {
734 rates[index++] =
735 IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_6MB;
736 rates[index++] =
737 IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_12MB;
738 rates[index++] =
739 IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_24MB;
740 } else {
741 wl1271_error("build_basic_rates invalid band: %d", band);
742 }
634 743
635 return index; 744 return index;
636} 745}
637 746
638static int wl1271_build_extended_rates(char *rates) 747static int wl1271_build_extended_rates(u8 *rates, u8 band)
639{ 748{
640 u8 index = 0; 749 u8 index = 0;
641 750
642 rates[index++] = IEEE80211_OFDM_RATE_6MB; 751 if (band == IEEE80211_BAND_2GHZ) {
643 rates[index++] = IEEE80211_OFDM_RATE_9MB; 752 rates[index++] = IEEE80211_OFDM_RATE_6MB;
644 rates[index++] = IEEE80211_OFDM_RATE_12MB; 753 rates[index++] = IEEE80211_OFDM_RATE_9MB;
645 rates[index++] = IEEE80211_OFDM_RATE_18MB; 754 rates[index++] = IEEE80211_OFDM_RATE_12MB;
646 rates[index++] = IEEE80211_OFDM_RATE_24MB; 755 rates[index++] = IEEE80211_OFDM_RATE_18MB;
647 rates[index++] = IEEE80211_OFDM_RATE_36MB; 756 rates[index++] = IEEE80211_OFDM_RATE_24MB;
648 rates[index++] = IEEE80211_OFDM_RATE_48MB; 757 rates[index++] = IEEE80211_OFDM_RATE_36MB;
649 rates[index++] = IEEE80211_OFDM_RATE_54MB; 758 rates[index++] = IEEE80211_OFDM_RATE_48MB;
759 rates[index++] = IEEE80211_OFDM_RATE_54MB;
760 } else if (band == IEEE80211_BAND_5GHZ) {
761 rates[index++] =
762 IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_9MB;
763 rates[index++] =
764 IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_18MB;
765 rates[index++] =
766 IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_24MB;
767 rates[index++] =
768 IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_36MB;
769 rates[index++] =
770 IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_48MB;
771 rates[index++] =
772 IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_54MB;
773 } else {
774 wl1271_error("build_basic_rates invalid band: %d", band);
775 }
650 776
651 return index; 777 return index;
652} 778}
@@ -665,7 +791,8 @@ int wl1271_cmd_build_null_data(struct wl1271 *wl)
665 791
666 memcpy(template.header.sa, wl->mac_addr, ETH_ALEN); 792 memcpy(template.header.sa, wl->mac_addr, ETH_ALEN);
667 template.header.frame_ctl = cpu_to_le16(IEEE80211_FTYPE_DATA | 793 template.header.frame_ctl = cpu_to_le16(IEEE80211_FTYPE_DATA |
668 IEEE80211_STYPE_NULLFUNC); 794 IEEE80211_STYPE_NULLFUNC |
795 IEEE80211_FCTL_TODS);
669 796
670 return wl1271_cmd_template_set(wl, CMD_TEMPL_NULL_DATA, &template, 797 return wl1271_cmd_template_set(wl, CMD_TEMPL_NULL_DATA, &template,
671 sizeof(template)); 798 sizeof(template));
@@ -678,7 +805,10 @@ int wl1271_cmd_build_ps_poll(struct wl1271 *wl, u16 aid)
678 805
679 memcpy(template.bssid, wl->bssid, ETH_ALEN); 806 memcpy(template.bssid, wl->bssid, ETH_ALEN);
680 memcpy(template.ta, wl->mac_addr, ETH_ALEN); 807 memcpy(template.ta, wl->mac_addr, ETH_ALEN);
681 template.aid = aid; 808
809 /* aid in PS-Poll has its two MSBs each set to 1 */
810 template.aid = cpu_to_le16(1 << 15 | 1 << 14 | aid);
811
682 template.fc = cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_PSPOLL); 812 template.fc = cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_PSPOLL);
683 813
684 return wl1271_cmd_template_set(wl, CMD_TEMPL_PS_POLL, &template, 814 return wl1271_cmd_template_set(wl, CMD_TEMPL_PS_POLL, &template,
@@ -686,12 +816,14 @@ int wl1271_cmd_build_ps_poll(struct wl1271 *wl, u16 aid)
686 816
687} 817}
688 818
689int wl1271_cmd_build_probe_req(struct wl1271 *wl, u8 *ssid, size_t ssid_len) 819int wl1271_cmd_build_probe_req(struct wl1271 *wl, u8 *ssid, size_t ssid_len,
820 u8 band)
690{ 821{
691 struct wl12xx_probe_req_template template; 822 struct wl12xx_probe_req_template template;
692 struct wl12xx_ie_rates *rates; 823 struct wl12xx_ie_rates *rates;
693 char *ptr; 824 char *ptr;
694 u16 size; 825 u16 size;
826 int ret;
695 827
696 ptr = (char *)&template; 828 ptr = (char *)&template;
697 size = sizeof(struct ieee80211_header); 829 size = sizeof(struct ieee80211_header);
@@ -713,20 +845,25 @@ int wl1271_cmd_build_probe_req(struct wl1271 *wl, u8 *ssid, size_t ssid_len)
713 /* Basic Rates */ 845 /* Basic Rates */
714 rates = (struct wl12xx_ie_rates *)ptr; 846 rates = (struct wl12xx_ie_rates *)ptr;
715 rates->header.id = WLAN_EID_SUPP_RATES; 847 rates->header.id = WLAN_EID_SUPP_RATES;
716 rates->header.len = wl1271_build_basic_rates(rates->rates); 848 rates->header.len = wl1271_build_basic_rates(rates->rates, band);
717 size += sizeof(struct wl12xx_ie_header) + rates->header.len; 849 size += sizeof(struct wl12xx_ie_header) + rates->header.len;
718 ptr += sizeof(struct wl12xx_ie_header) + rates->header.len; 850 ptr += sizeof(struct wl12xx_ie_header) + rates->header.len;
719 851
720 /* Extended rates */ 852 /* Extended rates */
721 rates = (struct wl12xx_ie_rates *)ptr; 853 rates = (struct wl12xx_ie_rates *)ptr;
722 rates->header.id = WLAN_EID_EXT_SUPP_RATES; 854 rates->header.id = WLAN_EID_EXT_SUPP_RATES;
723 rates->header.len = wl1271_build_extended_rates(rates->rates); 855 rates->header.len = wl1271_build_extended_rates(rates->rates, band);
724 size += sizeof(struct wl12xx_ie_header) + rates->header.len; 856 size += sizeof(struct wl12xx_ie_header) + rates->header.len;
725 857
726 wl1271_dump(DEBUG_SCAN, "PROBE REQ: ", &template, size); 858 wl1271_dump(DEBUG_SCAN, "PROBE REQ: ", &template, size);
727 859
728 return wl1271_cmd_template_set(wl, CMD_TEMPL_CFG_PROBE_REQ_2_4, 860 if (band == IEEE80211_BAND_2GHZ)
729 &template, size); 861 ret = wl1271_cmd_template_set(wl, CMD_TEMPL_CFG_PROBE_REQ_2_4,
862 &template, size);
863 else
864 ret = wl1271_cmd_template_set(wl, CMD_TEMPL_CFG_PROBE_REQ_5,
865 &template, size);
866 return ret;
730} 867}
731 868
732int wl1271_cmd_set_default_wep_key(struct wl1271 *wl, u8 id) 869int wl1271_cmd_set_default_wep_key(struct wl1271 *wl, u8 id)
@@ -743,10 +880,10 @@ int wl1271_cmd_set_default_wep_key(struct wl1271 *wl, u8 id)
743 } 880 }
744 881
745 cmd->id = id; 882 cmd->id = id;
746 cmd->key_action = KEY_SET_ID; 883 cmd->key_action = cpu_to_le16(KEY_SET_ID);
747 cmd->key_type = KEY_WEP; 884 cmd->key_type = KEY_WEP;
748 885
749 ret = wl1271_cmd_send(wl, CMD_SET_KEYS, cmd, sizeof(*cmd)); 886 ret = wl1271_cmd_send(wl, CMD_SET_KEYS, cmd, sizeof(*cmd), 0);
750 if (ret < 0) { 887 if (ret < 0) {
751 wl1271_warning("cmd set_default_wep_key failed: %d", ret); 888 wl1271_warning("cmd set_default_wep_key failed: %d", ret);
752 goto out; 889 goto out;
@@ -759,7 +896,8 @@ out:
759} 896}
760 897
761int wl1271_cmd_set_key(struct wl1271 *wl, u16 action, u8 id, u8 key_type, 898int wl1271_cmd_set_key(struct wl1271 *wl, u16 action, u8 id, u8 key_type,
762 u8 key_size, const u8 *key, const u8 *addr) 899 u8 key_size, const u8 *key, const u8 *addr,
900 u32 tx_seq_32, u16 tx_seq_16)
763{ 901{
764 struct wl1271_cmd_set_keys *cmd; 902 struct wl1271_cmd_set_keys *cmd;
765 int ret = 0; 903 int ret = 0;
@@ -773,16 +911,18 @@ int wl1271_cmd_set_key(struct wl1271 *wl, u16 action, u8 id, u8 key_type,
773 if (key_type != KEY_WEP) 911 if (key_type != KEY_WEP)
774 memcpy(cmd->addr, addr, ETH_ALEN); 912 memcpy(cmd->addr, addr, ETH_ALEN);
775 913
776 cmd->key_action = action; 914 cmd->key_action = cpu_to_le16(action);
777 cmd->key_size = key_size; 915 cmd->key_size = key_size;
778 cmd->key_type = key_type; 916 cmd->key_type = key_type;
779 917
918 cmd->ac_seq_num16[0] = cpu_to_le16(tx_seq_16);
919 cmd->ac_seq_num32[0] = cpu_to_le32(tx_seq_32);
920
780 /* we have only one SSID profile */ 921 /* we have only one SSID profile */
781 cmd->ssid_profile = 0; 922 cmd->ssid_profile = 0;
782 923
783 cmd->id = id; 924 cmd->id = id;
784 925
785 /* FIXME: this is from wl1251, needs to be checked */
786 if (key_type == KEY_TKIP) { 926 if (key_type == KEY_TKIP) {
787 /* 927 /*
788 * We get the key in the following form: 928 * We get the key in the following form:
@@ -800,10 +940,10 @@ int wl1271_cmd_set_key(struct wl1271 *wl, u16 action, u8 id, u8 key_type,
800 940
801 wl1271_dump(DEBUG_CRYPT, "TARGET KEY: ", cmd, sizeof(*cmd)); 941 wl1271_dump(DEBUG_CRYPT, "TARGET KEY: ", cmd, sizeof(*cmd));
802 942
803 ret = wl1271_cmd_send(wl, CMD_SET_KEYS, cmd, sizeof(*cmd)); 943 ret = wl1271_cmd_send(wl, CMD_SET_KEYS, cmd, sizeof(*cmd), 0);
804 if (ret < 0) { 944 if (ret < 0) {
805 wl1271_warning("could not set keys"); 945 wl1271_warning("could not set keys");
806 goto out; 946 goto out;
807 } 947 }
808 948
809out: 949out:
@@ -811,3 +951,34 @@ out:
811 951
812 return ret; 952 return ret;
813} 953}
954
955int wl1271_cmd_disconnect(struct wl1271 *wl)
956{
957 struct wl1271_cmd_disconnect *cmd;
958 int ret = 0;
959
960 wl1271_debug(DEBUG_CMD, "cmd disconnect");
961
962 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
963 if (!cmd) {
964 ret = -ENOMEM;
965 goto out;
966 }
967
968 cmd->rx_config_options = cpu_to_le32(wl->rx_config);
969 cmd->rx_filter_options = cpu_to_le32(wl->rx_filter);
970 /* disconnect reason is not used in immediate disconnections */
971 cmd->type = DISCONNECT_IMMEDIATE;
972
973 ret = wl1271_cmd_send(wl, CMD_DISCONNECT, cmd, sizeof(*cmd), 0);
974 if (ret < 0) {
975 wl1271_error("failed to send disconnect command");
976 goto out_free;
977 }
978
979out_free:
980 kfree(cmd);
981
982out:
983 return ret;
984}