wl1271: implement cmd_disconnect
[linux-2.6.git] / drivers / net / wireless / wl12xx / wl1271_cmd.c
1 /*
2  * This file is part of wl1271
3  *
4  * Copyright (C) 2009 Nokia Corporation
5  *
6  * Contact: Luciano Coelho <luciano.coelho@nokia.com>
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License
10  * version 2 as published by the Free Software Foundation.
11  *
12  * This program is distributed in the hope that it will be useful, but
13  * WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20  * 02110-1301 USA
21  *
22  */
23
24 #include <linux/module.h>
25 #include <linux/platform_device.h>
26 #include <linux/crc7.h>
27 #include <linux/spi/spi.h>
28 #include <linux/etherdevice.h>
29
30 #include "wl1271.h"
31 #include "wl1271_reg.h"
32 #include "wl1271_spi.h"
33 #include "wl1271_acx.h"
34 #include "wl12xx_80211.h"
35 #include "wl1271_cmd.h"
36
37 /*
38  * send command to firmware
39  *
40  * @wl: wl struct
41  * @id: command id
42  * @buf: buffer containing the command, must work with dma
43  * @len: length of the buffer
44  */
45 int wl1271_cmd_send(struct wl1271 *wl, u16 id, void *buf, size_t len)
46 {
47         struct wl1271_cmd_header *cmd;
48         unsigned long timeout;
49         u32 intr;
50         int ret = 0;
51
52         cmd = buf;
53         cmd->id = id;
54         cmd->status = 0;
55
56         WARN_ON(len % 4 != 0);
57
58         wl1271_spi_mem_write(wl, wl->cmd_box_addr, buf, len);
59
60         wl1271_reg_write32(wl, ACX_REG_INTERRUPT_TRIG, INTR_TRIG_CMD);
61
62         timeout = jiffies + msecs_to_jiffies(WL1271_COMMAND_TIMEOUT);
63
64         intr = wl1271_reg_read32(wl, ACX_REG_INTERRUPT_NO_CLEAR);
65         while (!(intr & WL1271_ACX_INTR_CMD_COMPLETE)) {
66                 if (time_after(jiffies, timeout)) {
67                         wl1271_error("command complete timeout");
68                         ret = -ETIMEDOUT;
69                         goto out;
70                 }
71
72                 msleep(1);
73
74                 intr = wl1271_reg_read32(wl, ACX_REG_INTERRUPT_NO_CLEAR);
75         }
76
77         wl1271_reg_write32(wl, ACX_REG_INTERRUPT_ACK,
78                            WL1271_ACX_INTR_CMD_COMPLETE);
79
80 out:
81         return ret;
82 }
83
84 int wl1271_cmd_cal_channel_tune(struct wl1271 *wl)
85 {
86         struct wl1271_cmd_cal_channel_tune *cmd;
87         int ret = 0;
88
89         cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
90         if (!cmd)
91                 return -ENOMEM;
92
93         cmd->test.id = TEST_CMD_CHANNEL_TUNE;
94
95         cmd->band = WL1271_CHANNEL_TUNE_BAND_2_4;
96         /* set up any channel, 7 is in the middle of the range */
97         cmd->channel = 7;
98
99         ret = wl1271_cmd_test(wl, cmd, sizeof(*cmd), 0);
100         if (ret < 0)
101                 wl1271_warning("TEST_CMD_CHANNEL_TUNE failed");
102
103         kfree(cmd);
104         return ret;
105 }
106
107 int wl1271_cmd_cal_update_ref_point(struct wl1271 *wl)
108 {
109         struct wl1271_cmd_cal_update_ref_point *cmd;
110         int ret = 0;
111
112         cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
113         if (!cmd)
114                 return -ENOMEM;
115
116         cmd->test.id = TEST_CMD_UPDATE_PD_REFERENCE_POINT;
117
118         /* FIXME: still waiting for the correct values */
119         cmd->ref_power    = 0;
120         cmd->ref_detector = 0;
121
122         cmd->sub_band     = WL1271_PD_REFERENCE_POINT_BAND_B_G;
123
124         ret = wl1271_cmd_test(wl, cmd, sizeof(*cmd), 0);
125         if (ret < 0)
126                 wl1271_warning("TEST_CMD_UPDATE_PD_REFERENCE_POINT failed");
127
128         kfree(cmd);
129         return ret;
130 }
131
132 int wl1271_cmd_cal_p2g(struct wl1271 *wl)
133 {
134         struct wl1271_cmd_cal_p2g *cmd;
135         int ret = 0;
136
137         cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
138         if (!cmd)
139                 return -ENOMEM;
140
141         cmd->test.id = TEST_CMD_P2G_CAL;
142
143         cmd->sub_band_mask = WL1271_CAL_P2G_BAND_B_G;
144
145         ret = wl1271_cmd_test(wl, cmd, sizeof(*cmd), 0);
146         if (ret < 0)
147                 wl1271_warning("TEST_CMD_P2G_CAL failed");
148
149         kfree(cmd);
150         return ret;
151 }
152
153 int wl1271_cmd_cal(struct wl1271 *wl)
154 {
155         /*
156          * FIXME: we must make sure that we're not sleeping when calibration
157          * is done
158          */
159         int ret;
160
161         wl1271_notice("performing tx calibration");
162
163         ret = wl1271_cmd_cal_channel_tune(wl);
164         if (ret < 0)
165                 return ret;
166
167         ret = wl1271_cmd_cal_update_ref_point(wl);
168         if (ret < 0)
169                 return ret;
170
171         ret = wl1271_cmd_cal_p2g(wl);
172         if (ret < 0)
173                 return ret;
174
175         return ret;
176 }
177
178 int wl1271_cmd_join(struct wl1271 *wl)
179 {
180         static bool do_cal = true;
181         struct wl1271_cmd_join *join;
182         int ret, i;
183         u8 *bssid;
184
185         /* FIXME: remove when we get calibration from the factory */
186         if (do_cal) {
187                 ret = wl1271_cmd_cal(wl);
188                 if (ret < 0)
189                         wl1271_warning("couldn't calibrate");
190                 else
191                         do_cal = false;
192         }
193
194         join = kzalloc(sizeof(*join), GFP_KERNEL);
195         if (!join) {
196                 ret = -ENOMEM;
197                 goto out;
198         }
199
200         wl1271_debug(DEBUG_CMD, "cmd join");
201
202         /* Reverse order BSSID */
203         bssid = (u8 *) &join->bssid_lsb;
204         for (i = 0; i < ETH_ALEN; i++)
205                 bssid[i] = wl->bssid[ETH_ALEN - i - 1];
206
207         join->rx_config_options = wl->rx_config;
208         join->rx_filter_options = wl->rx_filter;
209
210         /*
211          * FIXME: disable temporarily all filters because after commit
212          * 9cef8737 "mac80211: fix managed mode BSSID handling" broke
213          * association. The filter logic needs to be implemented properly
214          * and once that is done, this hack can be removed.
215          */
216         join->rx_config_options = 0;
217         join->rx_filter_options = WL1271_DEFAULT_RX_FILTER;
218
219         join->basic_rate_set = RATE_MASK_1MBPS | RATE_MASK_2MBPS |
220                 RATE_MASK_5_5MBPS | RATE_MASK_11MBPS;
221
222         join->beacon_interval = wl->beacon_int;
223         join->dtim_interval = wl->dtim_period;
224         join->bss_type = wl->bss_type;
225         join->channel = wl->channel;
226         join->ssid_len = wl->ssid_len;
227         memcpy(join->ssid, wl->ssid, wl->ssid_len);
228         join->ctrl = WL1271_JOIN_CMD_CTRL_TX_FLUSH;
229
230         /* increment the session counter */
231         wl->session_counter++;
232         if (wl->session_counter >= SESSION_COUNTER_MAX)
233                 wl->session_counter = 0;
234
235         join->ctrl |= wl->session_counter << WL1271_JOIN_CMD_TX_SESSION_OFFSET;
236
237         /* reset TX security counters */
238         wl->tx_security_last_seq = 0;
239         wl->tx_security_seq_16 = 0;
240         wl->tx_security_seq_32 = 0;
241
242         ret = wl1271_cmd_send(wl, CMD_START_JOIN, join, sizeof(*join));
243         if (ret < 0) {
244                 wl1271_error("failed to initiate cmd join");
245                 goto out_free;
246         }
247
248         /*
249          * ugly hack: we should wait for JOIN_EVENT_COMPLETE_ID but to
250          * simplify locking we just sleep instead, for now
251          */
252         msleep(10);
253
254 out_free:
255         kfree(join);
256
257 out:
258         return ret;
259 }
260
261 /**
262  * send test command to firmware
263  *
264  * @wl: wl struct
265  * @buf: buffer containing the command, with all headers, must work with dma
266  * @len: length of the buffer
267  * @answer: is answer needed
268  */
269 int wl1271_cmd_test(struct wl1271 *wl, void *buf, size_t buf_len, u8 answer)
270 {
271         int ret;
272
273         wl1271_debug(DEBUG_CMD, "cmd test");
274
275         ret = wl1271_cmd_send(wl, CMD_TEST, buf, buf_len);
276
277         if (ret < 0) {
278                 wl1271_warning("TEST command failed");
279                 return ret;
280         }
281
282         if (answer) {
283                 struct wl1271_command *cmd_answer;
284
285                 /*
286                  * The test command got in, we can read the answer.
287                  * The answer would be a wl1271_command, where the
288                  * parameter array contains the actual answer.
289                  */
290                 wl1271_spi_mem_read(wl, wl->cmd_box_addr, buf, buf_len);
291
292                 cmd_answer = buf;
293
294                 if (cmd_answer->header.status != CMD_STATUS_SUCCESS)
295                         wl1271_error("TEST command answer error: %d",
296                                      cmd_answer->header.status);
297         }
298
299         return 0;
300 }
301
302 /**
303  * read acx from firmware
304  *
305  * @wl: wl struct
306  * @id: acx id
307  * @buf: buffer for the response, including all headers, must work with dma
308  * @len: lenght of buf
309  */
310 int wl1271_cmd_interrogate(struct wl1271 *wl, u16 id, void *buf, size_t len)
311 {
312         struct acx_header *acx = buf;
313         int ret;
314
315         wl1271_debug(DEBUG_CMD, "cmd interrogate");
316
317         acx->id = id;
318
319         /* payload length, does not include any headers */
320         acx->len = len - sizeof(*acx);
321
322         ret = wl1271_cmd_send(wl, CMD_INTERROGATE, acx, sizeof(*acx));
323         if (ret < 0) {
324                 wl1271_error("INTERROGATE command failed");
325                 goto out;
326         }
327
328         /* the interrogate command got in, we can read the answer */
329         wl1271_spi_mem_read(wl, wl->cmd_box_addr, buf, len);
330
331         acx = buf;
332         if (acx->cmd.status != CMD_STATUS_SUCCESS)
333                 wl1271_error("INTERROGATE command error: %d",
334                              acx->cmd.status);
335
336 out:
337         return ret;
338 }
339
340 /**
341  * write acx value to firmware
342  *
343  * @wl: wl struct
344  * @id: acx id
345  * @buf: buffer containing acx, including all headers, must work with dma
346  * @len: length of buf
347  */
348 int wl1271_cmd_configure(struct wl1271 *wl, u16 id, void *buf, size_t len)
349 {
350         struct acx_header *acx = buf;
351         int ret;
352
353         wl1271_debug(DEBUG_CMD, "cmd configure");
354
355         acx->id = id;
356
357         /* payload length, does not include any headers */
358         acx->len = len - sizeof(*acx);
359
360         ret = wl1271_cmd_send(wl, CMD_CONFIGURE, acx, len);
361         if (ret < 0) {
362                 wl1271_warning("CONFIGURE command NOK");
363                 return ret;
364         }
365
366         return 0;
367 }
368
369 int wl1271_cmd_data_path(struct wl1271 *wl, u8 channel, bool enable)
370 {
371         struct cmd_enabledisable_path *cmd;
372         int ret;
373         u16 cmd_rx, cmd_tx;
374
375         wl1271_debug(DEBUG_CMD, "cmd data path");
376
377         cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
378         if (!cmd) {
379                 ret = -ENOMEM;
380                 goto out;
381         }
382
383         cmd->channel = channel;
384
385         if (enable) {
386                 cmd_rx = CMD_ENABLE_RX;
387                 cmd_tx = CMD_ENABLE_TX;
388         } else {
389                 cmd_rx = CMD_DISABLE_RX;
390                 cmd_tx = CMD_DISABLE_TX;
391         }
392
393         ret = wl1271_cmd_send(wl, cmd_rx, cmd, sizeof(*cmd));
394         if (ret < 0) {
395                 wl1271_error("rx %s cmd for channel %d failed",
396                              enable ? "start" : "stop", channel);
397                 goto out;
398         }
399
400         wl1271_debug(DEBUG_BOOT, "rx %s cmd channel %d",
401                      enable ? "start" : "stop", channel);
402
403         ret = wl1271_cmd_send(wl, cmd_tx, cmd, sizeof(*cmd));
404         if (ret < 0) {
405                 wl1271_error("tx %s cmd for channel %d failed",
406                              enable ? "start" : "stop", channel);
407                 return ret;
408         }
409
410         wl1271_debug(DEBUG_BOOT, "tx %s cmd channel %d",
411                      enable ? "start" : "stop", channel);
412
413 out:
414         kfree(cmd);
415         return ret;
416 }
417
418 int wl1271_cmd_ps_mode(struct wl1271 *wl, u8 ps_mode)
419 {
420         struct wl1271_cmd_ps_params *ps_params = NULL;
421         int ret = 0;
422
423         /* FIXME: this should be in ps.c */
424         ret = wl1271_acx_wake_up_conditions(wl, WAKE_UP_EVENT_DTIM_BITMAP,
425                                             wl->listen_int);
426         if (ret < 0) {
427                 wl1271_error("couldn't set wake up conditions");
428                 goto out;
429         }
430
431         wl1271_debug(DEBUG_CMD, "cmd set ps mode");
432
433         ps_params = kzalloc(sizeof(*ps_params), GFP_KERNEL);
434         if (!ps_params) {
435                 ret = -ENOMEM;
436                 goto out;
437         }
438
439         ps_params->ps_mode = ps_mode;
440         ps_params->send_null_data = 1;
441         ps_params->retries = 5;
442         ps_params->hang_over_period = 128;
443         ps_params->null_data_rate = 1; /* 1 Mbps */
444
445         ret = wl1271_cmd_send(wl, CMD_SET_PS_MODE, ps_params,
446                               sizeof(*ps_params));
447         if (ret < 0) {
448                 wl1271_error("cmd set_ps_mode failed");
449                 goto out;
450         }
451
452 out:
453         kfree(ps_params);
454         return ret;
455 }
456
457 int wl1271_cmd_read_memory(struct wl1271 *wl, u32 addr, void *answer,
458                            size_t len)
459 {
460         struct cmd_read_write_memory *cmd;
461         int ret = 0;
462
463         wl1271_debug(DEBUG_CMD, "cmd read memory");
464
465         cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
466         if (!cmd) {
467                 ret = -ENOMEM;
468                 goto out;
469         }
470
471         WARN_ON(len > MAX_READ_SIZE);
472         len = min_t(size_t, len, MAX_READ_SIZE);
473
474         cmd->addr = addr;
475         cmd->size = len;
476
477         ret = wl1271_cmd_send(wl, CMD_READ_MEMORY, cmd, sizeof(*cmd));
478         if (ret < 0) {
479                 wl1271_error("read memory command failed: %d", ret);
480                 goto out;
481         }
482
483         /* the read command got in, we can now read the answer */
484         wl1271_spi_mem_read(wl, wl->cmd_box_addr, cmd, sizeof(*cmd));
485
486         if (cmd->header.status != CMD_STATUS_SUCCESS)
487                 wl1271_error("error in read command result: %d",
488                              cmd->header.status);
489
490         memcpy(answer, cmd->value, len);
491
492 out:
493         kfree(cmd);
494         return ret;
495 }
496
497 int wl1271_cmd_scan(struct wl1271 *wl, u8 *ssid, size_t len,
498                     u8 active_scan, u8 high_prio, u8 num_channels,
499                     u8 probe_requests)
500 {
501
502         struct wl1271_cmd_trigger_scan_to *trigger = NULL;
503         struct wl1271_cmd_scan *params = NULL;
504         int i, ret;
505         u16 scan_options = 0;
506
507         if (wl->scanning)
508                 return -EINVAL;
509
510         params = kzalloc(sizeof(*params), GFP_KERNEL);
511         if (!params)
512                 return -ENOMEM;
513
514         params->params.rx_config_options = cpu_to_le32(CFG_RX_ALL_GOOD);
515         params->params.rx_filter_options =
516                 cpu_to_le32(CFG_RX_PRSP_EN | CFG_RX_MGMT_EN | CFG_RX_BCN_EN);
517
518         if (!active_scan)
519                 scan_options |= WL1271_SCAN_OPT_PASSIVE;
520         if (high_prio)
521                 scan_options |= WL1271_SCAN_OPT_PRIORITY_HIGH;
522         params->params.scan_options = scan_options;
523
524         params->params.num_channels = num_channels;
525         params->params.num_probe_requests = probe_requests;
526         params->params.tx_rate = cpu_to_le32(RATE_MASK_2MBPS);
527         params->params.tid_trigger = 0;
528         params->params.scan_tag = WL1271_SCAN_DEFAULT_TAG;
529
530         for (i = 0; i < num_channels; i++) {
531                 params->channels[i].min_duration =
532                         cpu_to_le32(WL1271_SCAN_CHAN_MIN_DURATION);
533                 params->channels[i].max_duration =
534                         cpu_to_le32(WL1271_SCAN_CHAN_MAX_DURATION);
535                 memset(&params->channels[i].bssid_lsb, 0xff, 4);
536                 memset(&params->channels[i].bssid_msb, 0xff, 2);
537                 params->channels[i].early_termination = 0;
538                 params->channels[i].tx_power_att = WL1271_SCAN_CURRENT_TX_PWR;
539                 params->channels[i].channel = i + 1;
540         }
541
542         if (len && ssid) {
543                 params->params.ssid_len = len;
544                 memcpy(params->params.ssid, ssid, len);
545         }
546
547         ret = wl1271_cmd_build_probe_req(wl, ssid, len);
548         if (ret < 0) {
549                 wl1271_error("PROBE request template failed");
550                 goto out;
551         }
552
553         trigger = kzalloc(sizeof(*trigger), GFP_KERNEL);
554         if (!trigger) {
555                 ret = -ENOMEM;
556                 goto out;
557         }
558
559         /* disable the timeout */
560         trigger->timeout = 0;
561
562         ret = wl1271_cmd_send(wl, CMD_TRIGGER_SCAN_TO, trigger,
563                               sizeof(*trigger));
564         if (ret < 0) {
565                 wl1271_error("trigger scan to failed for hw scan");
566                 goto out;
567         }
568
569         wl1271_dump(DEBUG_SCAN, "SCAN: ", params, sizeof(*params));
570
571         wl->scanning = true;
572
573         ret = wl1271_cmd_send(wl, CMD_SCAN, params, sizeof(*params));
574         if (ret < 0) {
575                 wl1271_error("SCAN failed");
576                 goto out;
577         }
578
579         wl1271_spi_mem_read(wl, wl->cmd_box_addr, params, sizeof(*params));
580
581         if (params->header.status != CMD_STATUS_SUCCESS) {
582                 wl1271_error("Scan command error: %d",
583                              params->header.status);
584                 wl->scanning = false;
585                 ret = -EIO;
586                 goto out;
587         }
588
589 out:
590         kfree(params);
591         return ret;
592 }
593
594 int wl1271_cmd_template_set(struct wl1271 *wl, u16 template_id,
595                             void *buf, size_t buf_len)
596 {
597         struct wl1271_cmd_template_set *cmd;
598         int ret = 0;
599
600         wl1271_debug(DEBUG_CMD, "cmd template_set %d", template_id);
601
602         WARN_ON(buf_len > WL1271_CMD_TEMPL_MAX_SIZE);
603         buf_len = min_t(size_t, buf_len, WL1271_CMD_TEMPL_MAX_SIZE);
604
605         cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
606         if (!cmd) {
607                 ret = -ENOMEM;
608                 goto out;
609         }
610
611         cmd->len = cpu_to_le16(buf_len);
612         cmd->template_type = template_id;
613         cmd->enabled_rates = ACX_RATE_MASK_UNSPECIFIED;
614         cmd->short_retry_limit = ACX_RATE_RETRY_LIMIT;
615         cmd->long_retry_limit = ACX_RATE_RETRY_LIMIT;
616
617         if (buf)
618                 memcpy(cmd->template_data, buf, buf_len);
619
620         ret = wl1271_cmd_send(wl, CMD_SET_TEMPLATE, cmd, sizeof(*cmd));
621         if (ret < 0) {
622                 wl1271_warning("cmd set_template failed: %d", ret);
623                 goto out_free;
624         }
625
626 out_free:
627         kfree(cmd);
628
629 out:
630         return ret;
631 }
632
633 static int wl1271_build_basic_rates(char *rates)
634 {
635         u8 index = 0;
636
637         rates[index++] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_1MB;
638         rates[index++] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_2MB;
639         rates[index++] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_5MB;
640         rates[index++] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_11MB;
641
642         return index;
643 }
644
645 static int wl1271_build_extended_rates(char *rates)
646 {
647         u8 index = 0;
648
649         rates[index++] = IEEE80211_OFDM_RATE_6MB;
650         rates[index++] = IEEE80211_OFDM_RATE_9MB;
651         rates[index++] = IEEE80211_OFDM_RATE_12MB;
652         rates[index++] = IEEE80211_OFDM_RATE_18MB;
653         rates[index++] = IEEE80211_OFDM_RATE_24MB;
654         rates[index++] = IEEE80211_OFDM_RATE_36MB;
655         rates[index++] = IEEE80211_OFDM_RATE_48MB;
656         rates[index++] = IEEE80211_OFDM_RATE_54MB;
657
658         return index;
659 }
660
661 int wl1271_cmd_build_null_data(struct wl1271 *wl)
662 {
663         struct wl12xx_null_data_template template;
664
665         if (!is_zero_ether_addr(wl->bssid)) {
666                 memcpy(template.header.da, wl->bssid, ETH_ALEN);
667                 memcpy(template.header.bssid, wl->bssid, ETH_ALEN);
668         } else {
669                 memset(template.header.da, 0xff, ETH_ALEN);
670                 memset(template.header.bssid, 0xff, ETH_ALEN);
671         }
672
673         memcpy(template.header.sa, wl->mac_addr, ETH_ALEN);
674         template.header.frame_ctl = cpu_to_le16(IEEE80211_FTYPE_DATA |
675                                                 IEEE80211_STYPE_NULLFUNC);
676
677         return wl1271_cmd_template_set(wl, CMD_TEMPL_NULL_DATA, &template,
678                                        sizeof(template));
679
680 }
681
682 int wl1271_cmd_build_ps_poll(struct wl1271 *wl, u16 aid)
683 {
684         struct wl12xx_ps_poll_template template;
685
686         memcpy(template.bssid, wl->bssid, ETH_ALEN);
687         memcpy(template.ta, wl->mac_addr, ETH_ALEN);
688
689         /* aid in PS-Poll has its two MSBs each set to 1 */
690         template.aid = cpu_to_le16(1 << 15 | 1 << 14 | aid);
691
692         template.fc = cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_PSPOLL);
693
694         return wl1271_cmd_template_set(wl, CMD_TEMPL_PS_POLL, &template,
695                                        sizeof(template));
696
697 }
698
699 int wl1271_cmd_build_probe_req(struct wl1271 *wl, u8 *ssid, size_t ssid_len)
700 {
701         struct wl12xx_probe_req_template template;
702         struct wl12xx_ie_rates *rates;
703         char *ptr;
704         u16 size;
705
706         ptr = (char *)&template;
707         size = sizeof(struct ieee80211_header);
708
709         memset(template.header.da, 0xff, ETH_ALEN);
710         memset(template.header.bssid, 0xff, ETH_ALEN);
711         memcpy(template.header.sa, wl->mac_addr, ETH_ALEN);
712         template.header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_PROBE_REQ);
713
714         /* IEs */
715         /* SSID */
716         template.ssid.header.id = WLAN_EID_SSID;
717         template.ssid.header.len = ssid_len;
718         if (ssid_len && ssid)
719                 memcpy(template.ssid.ssid, ssid, ssid_len);
720         size += sizeof(struct wl12xx_ie_header) + ssid_len;
721         ptr += size;
722
723         /* Basic Rates */
724         rates = (struct wl12xx_ie_rates *)ptr;
725         rates->header.id = WLAN_EID_SUPP_RATES;
726         rates->header.len = wl1271_build_basic_rates(rates->rates);
727         size += sizeof(struct wl12xx_ie_header) + rates->header.len;
728         ptr += sizeof(struct wl12xx_ie_header) + rates->header.len;
729
730         /* Extended rates */
731         rates = (struct wl12xx_ie_rates *)ptr;
732         rates->header.id = WLAN_EID_EXT_SUPP_RATES;
733         rates->header.len = wl1271_build_extended_rates(rates->rates);
734         size += sizeof(struct wl12xx_ie_header) + rates->header.len;
735
736         wl1271_dump(DEBUG_SCAN, "PROBE REQ: ", &template, size);
737
738         return wl1271_cmd_template_set(wl, CMD_TEMPL_CFG_PROBE_REQ_2_4,
739                                        &template, size);
740 }
741
742 int wl1271_cmd_set_default_wep_key(struct wl1271 *wl, u8 id)
743 {
744         struct wl1271_cmd_set_keys *cmd;
745         int ret = 0;
746
747         wl1271_debug(DEBUG_CMD, "cmd set_default_wep_key %d", id);
748
749         cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
750         if (!cmd) {
751                 ret = -ENOMEM;
752                 goto out;
753         }
754
755         cmd->id = id;
756         cmd->key_action = KEY_SET_ID;
757         cmd->key_type = KEY_WEP;
758
759         ret = wl1271_cmd_send(wl, CMD_SET_KEYS, cmd, sizeof(*cmd));
760         if (ret < 0) {
761                 wl1271_warning("cmd set_default_wep_key failed: %d", ret);
762                 goto out;
763         }
764
765 out:
766         kfree(cmd);
767
768         return ret;
769 }
770
771 int wl1271_cmd_set_key(struct wl1271 *wl, u16 action, u8 id, u8 key_type,
772                        u8 key_size, const u8 *key, const u8 *addr,
773                        u32 tx_seq_32, u16 tx_seq_16)
774 {
775         struct wl1271_cmd_set_keys *cmd;
776         int ret = 0;
777
778         cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
779         if (!cmd) {
780                 ret = -ENOMEM;
781                 goto out;
782         }
783
784         if (key_type != KEY_WEP)
785                 memcpy(cmd->addr, addr, ETH_ALEN);
786
787         cmd->key_action = action;
788         cmd->key_size = key_size;
789         cmd->key_type = key_type;
790
791         cmd->ac_seq_num16[0] = tx_seq_16;
792         cmd->ac_seq_num32[0] = tx_seq_32;
793
794         /* we have only one SSID profile */
795         cmd->ssid_profile = 0;
796
797         cmd->id = id;
798
799         if (key_type == KEY_TKIP) {
800                 /*
801                  * We get the key in the following form:
802                  * TKIP (16 bytes) - TX MIC (8 bytes) - RX MIC (8 bytes)
803                  * but the target is expecting:
804                  * TKIP - RX MIC - TX MIC
805                  */
806                 memcpy(cmd->key, key, 16);
807                 memcpy(cmd->key + 16, key + 24, 8);
808                 memcpy(cmd->key + 24, key + 16, 8);
809
810         } else {
811                 memcpy(cmd->key, key, key_size);
812         }
813
814         wl1271_dump(DEBUG_CRYPT, "TARGET KEY: ", cmd, sizeof(*cmd));
815
816         ret = wl1271_cmd_send(wl, CMD_SET_KEYS, cmd, sizeof(*cmd));
817         if (ret < 0) {
818                 wl1271_warning("could not set keys");
819                 goto out;
820         }
821
822 out:
823         kfree(cmd);
824
825         return ret;
826 }
827
828 int wl1271_cmd_disconnect(struct wl1271 *wl)
829 {
830         struct wl1271_cmd_disconnect *cmd;
831         int ret = 0;
832
833         wl1271_debug(DEBUG_CMD, "cmd disconnect");
834
835         cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
836         if (!cmd) {
837                 ret = -ENOMEM;
838                 goto out;
839         }
840
841         cmd->rx_config_options = wl->rx_config;
842         cmd->rx_filter_options = wl->rx_filter;
843         /* disconnect reason is not used in immediate disconnections */
844         cmd->type = DISCONNECT_IMMEDIATE;
845
846         ret = wl1271_cmd_send(wl, CMD_DISCONNECT, cmd, sizeof(*cmd));
847         if (ret < 0) {
848                 wl1271_error("failed to send disconnect command");
849                 goto out_free;
850         }
851
852 out_free:
853         kfree(cmd);
854
855 out:
856         return ret;
857 }