cmd.c revision 045b9b5f4172b2b21af0b9bf5e6dda51146d51a4
1/*
2 * This file is part of wl1271
3 *
4 * Copyright (C) 2009-2010 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/spi/spi.h>
27#include <linux/etherdevice.h>
28#include <linux/ieee80211.h>
29#include <linux/slab.h>
30
31#include "wlcore.h"
32#include "debug.h"
33#include "io.h"
34#include "acx.h"
35#include "wl12xx_80211.h"
36#include "cmd.h"
37#include "event.h"
38#include "tx.h"
39#include "hw_ops.h"
40
41#define WL1271_CMD_FAST_POLL_COUNT       50
42
43/*
44 * send command to firmware
45 *
46 * @wl: wl struct
47 * @id: command id
48 * @buf: buffer containing the command, must work with dma
49 * @len: length of the buffer
50 */
51int wl1271_cmd_send(struct wl1271 *wl, u16 id, void *buf, size_t len,
52		    size_t res_len)
53{
54	struct wl1271_cmd_header *cmd;
55	unsigned long timeout;
56	u32 intr;
57	int ret = 0;
58	u16 status;
59	u16 poll_count = 0;
60
61	cmd = buf;
62	cmd->id = cpu_to_le16(id);
63	cmd->status = 0;
64
65	WARN_ON(len % 4 != 0);
66	WARN_ON(test_bit(WL1271_FLAG_IN_ELP, &wl->flags));
67
68	wl1271_write(wl, wl->cmd_box_addr, buf, len, false);
69
70	/*
71	 * TODO: we just need this because one bit is in a different
72	 * place.  Is there any better way?
73	 */
74	wl->ops->trigger_cmd(wl, wl->cmd_box_addr, buf, len);
75
76	timeout = jiffies + msecs_to_jiffies(WL1271_COMMAND_TIMEOUT);
77
78	intr = wlcore_read_reg(wl, REG_INTERRUPT_NO_CLEAR);
79	while (!(intr & WL1271_ACX_INTR_CMD_COMPLETE)) {
80		if (time_after(jiffies, timeout)) {
81			wl1271_error("command complete timeout");
82			ret = -ETIMEDOUT;
83			goto fail;
84		}
85
86		poll_count++;
87		if (poll_count < WL1271_CMD_FAST_POLL_COUNT)
88			udelay(10);
89		else
90			msleep(1);
91
92		intr = wlcore_read_reg(wl, REG_INTERRUPT_NO_CLEAR);
93	}
94
95	/* read back the status code of the command */
96	if (res_len == 0)
97		res_len = sizeof(struct wl1271_cmd_header);
98
99	ret = wlcore_read(wl, wl->cmd_box_addr, cmd, res_len, false);
100	if (ret < 0)
101		goto fail;
102
103	status = le16_to_cpu(cmd->status);
104	if (status != CMD_STATUS_SUCCESS) {
105		wl1271_error("command execute failure %d", status);
106		ret = -EIO;
107		goto fail;
108	}
109
110	wlcore_write_reg(wl, REG_INTERRUPT_ACK, WL1271_ACX_INTR_CMD_COMPLETE);
111	return 0;
112
113fail:
114	WARN_ON(1);
115	wl12xx_queue_recovery_work(wl);
116	return ret;
117}
118
119/*
120 * Poll the mailbox event field until any of the bits in the mask is set or a
121 * timeout occurs (WL1271_EVENT_TIMEOUT in msecs)
122 */
123static int wl1271_cmd_wait_for_event_or_timeout(struct wl1271 *wl, u32 mask)
124{
125	u32 *events_vector;
126	u32 event;
127	unsigned long timeout;
128	int ret = 0;
129
130	events_vector = kmalloc(sizeof(*events_vector), GFP_KERNEL | GFP_DMA);
131	if (!events_vector)
132		return -ENOMEM;
133
134	timeout = jiffies + msecs_to_jiffies(WL1271_EVENT_TIMEOUT);
135
136	do {
137		if (time_after(jiffies, timeout)) {
138			wl1271_debug(DEBUG_CMD, "timeout waiting for event %d",
139				     (int)mask);
140			ret = -ETIMEDOUT;
141			goto out;
142		}
143
144		msleep(1);
145
146		/* read from both event fields */
147		ret = wlcore_read(wl, wl->mbox_ptr[0], events_vector,
148				  sizeof(*events_vector), false);
149		if (ret < 0)
150			goto out;
151
152		event = *events_vector & mask;
153
154		ret = wlcore_read(wl, wl->mbox_ptr[1], events_vector,
155				  sizeof(*events_vector), false);
156		if (ret < 0)
157			goto out;
158
159		event |= *events_vector & mask;
160	} while (!event);
161
162out:
163	kfree(events_vector);
164	return ret;
165}
166
167static int wl1271_cmd_wait_for_event(struct wl1271 *wl, u32 mask)
168{
169	int ret;
170
171	ret = wl1271_cmd_wait_for_event_or_timeout(wl, mask);
172	if (ret != 0) {
173		wl12xx_queue_recovery_work(wl);
174		return ret;
175	}
176
177	return 0;
178}
179
180int wl12xx_cmd_role_enable(struct wl1271 *wl, u8 *addr, u8 role_type,
181			   u8 *role_id)
182{
183	struct wl12xx_cmd_role_enable *cmd;
184	int ret;
185
186	wl1271_debug(DEBUG_CMD, "cmd role enable");
187
188	if (WARN_ON(*role_id != WL12XX_INVALID_ROLE_ID))
189		return -EBUSY;
190
191	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
192	if (!cmd) {
193		ret = -ENOMEM;
194		goto out;
195	}
196
197	/* get role id */
198	cmd->role_id = find_first_zero_bit(wl->roles_map, WL12XX_MAX_ROLES);
199	if (cmd->role_id >= WL12XX_MAX_ROLES) {
200		ret = -EBUSY;
201		goto out_free;
202	}
203
204	memcpy(cmd->mac_address, addr, ETH_ALEN);
205	cmd->role_type = role_type;
206
207	ret = wl1271_cmd_send(wl, CMD_ROLE_ENABLE, cmd, sizeof(*cmd), 0);
208	if (ret < 0) {
209		wl1271_error("failed to initiate cmd role enable");
210		goto out_free;
211	}
212
213	__set_bit(cmd->role_id, wl->roles_map);
214	*role_id = cmd->role_id;
215
216out_free:
217	kfree(cmd);
218
219out:
220	return ret;
221}
222
223int wl12xx_cmd_role_disable(struct wl1271 *wl, u8 *role_id)
224{
225	struct wl12xx_cmd_role_disable *cmd;
226	int ret;
227
228	wl1271_debug(DEBUG_CMD, "cmd role disable");
229
230	if (WARN_ON(*role_id == WL12XX_INVALID_ROLE_ID))
231		return -ENOENT;
232
233	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
234	if (!cmd) {
235		ret = -ENOMEM;
236		goto out;
237	}
238	cmd->role_id = *role_id;
239
240	ret = wl1271_cmd_send(wl, CMD_ROLE_DISABLE, cmd, sizeof(*cmd), 0);
241	if (ret < 0) {
242		wl1271_error("failed to initiate cmd role disable");
243		goto out_free;
244	}
245
246	__clear_bit(*role_id, wl->roles_map);
247	*role_id = WL12XX_INVALID_ROLE_ID;
248
249out_free:
250	kfree(cmd);
251
252out:
253	return ret;
254}
255
256int wl12xx_allocate_link(struct wl1271 *wl, struct wl12xx_vif *wlvif, u8 *hlid)
257{
258	unsigned long flags;
259	u8 link = find_first_zero_bit(wl->links_map, WL12XX_MAX_LINKS);
260	if (link >= WL12XX_MAX_LINKS)
261		return -EBUSY;
262
263	/* these bits are used by op_tx */
264	spin_lock_irqsave(&wl->wl_lock, flags);
265	__set_bit(link, wl->links_map);
266	__set_bit(link, wlvif->links_map);
267	spin_unlock_irqrestore(&wl->wl_lock, flags);
268	*hlid = link;
269	return 0;
270}
271
272void wl12xx_free_link(struct wl1271 *wl, struct wl12xx_vif *wlvif, u8 *hlid)
273{
274	unsigned long flags;
275
276	if (*hlid == WL12XX_INVALID_LINK_ID)
277		return;
278
279	/* these bits are used by op_tx */
280	spin_lock_irqsave(&wl->wl_lock, flags);
281	__clear_bit(*hlid, wl->links_map);
282	__clear_bit(*hlid, wlvif->links_map);
283	spin_unlock_irqrestore(&wl->wl_lock, flags);
284
285	/*
286	 * At this point op_tx() will not add more packets to the queues. We
287	 * can purge them.
288	 */
289	wl1271_tx_reset_link_queues(wl, *hlid);
290
291	*hlid = WL12XX_INVALID_LINK_ID;
292}
293
294static int wl12xx_get_new_session_id(struct wl1271 *wl,
295				     struct wl12xx_vif *wlvif)
296{
297	if (wlvif->session_counter >= SESSION_COUNTER_MAX)
298		wlvif->session_counter = 0;
299
300	wlvif->session_counter++;
301
302	return wlvif->session_counter;
303}
304
305static u8 wlcore_get_native_channel_type(u8 nl_channel_type)
306{
307	switch (nl_channel_type) {
308	case NL80211_CHAN_NO_HT:
309		return WLCORE_CHAN_NO_HT;
310	case NL80211_CHAN_HT20:
311		return WLCORE_CHAN_HT20;
312	case NL80211_CHAN_HT40MINUS:
313		return WLCORE_CHAN_HT40MINUS;
314	case NL80211_CHAN_HT40PLUS:
315		return WLCORE_CHAN_HT40PLUS;
316	default:
317		WARN_ON(1);
318		return WLCORE_CHAN_NO_HT;
319	}
320}
321
322static int wl12xx_cmd_role_start_dev(struct wl1271 *wl,
323				     struct wl12xx_vif *wlvif)
324{
325	struct wl12xx_cmd_role_start *cmd;
326	int ret;
327
328	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
329	if (!cmd) {
330		ret = -ENOMEM;
331		goto out;
332	}
333
334	wl1271_debug(DEBUG_CMD, "cmd role start dev %d", wlvif->dev_role_id);
335
336	cmd->role_id = wlvif->dev_role_id;
337	if (wlvif->band == IEEE80211_BAND_5GHZ)
338		cmd->band = WLCORE_BAND_5GHZ;
339	cmd->channel = wlvif->channel;
340
341	if (wlvif->dev_hlid == WL12XX_INVALID_LINK_ID) {
342		ret = wl12xx_allocate_link(wl, wlvif, &wlvif->dev_hlid);
343		if (ret)
344			goto out_free;
345	}
346	cmd->device.hlid = wlvif->dev_hlid;
347	cmd->device.session = wl12xx_get_new_session_id(wl, wlvif);
348
349	wl1271_debug(DEBUG_CMD, "role start: roleid=%d, hlid=%d, session=%d",
350		     cmd->role_id, cmd->device.hlid, cmd->device.session);
351
352	ret = wl1271_cmd_send(wl, CMD_ROLE_START, cmd, sizeof(*cmd), 0);
353	if (ret < 0) {
354		wl1271_error("failed to initiate cmd role enable");
355		goto err_hlid;
356	}
357
358	goto out_free;
359
360err_hlid:
361	/* clear links on error */
362	wl12xx_free_link(wl, wlvif, &wlvif->dev_hlid);
363
364out_free:
365	kfree(cmd);
366
367out:
368	return ret;
369}
370
371static int wl12xx_cmd_role_stop_dev(struct wl1271 *wl,
372				    struct wl12xx_vif *wlvif)
373{
374	struct wl12xx_cmd_role_stop *cmd;
375	int ret;
376
377	if (WARN_ON(wlvif->dev_hlid == WL12XX_INVALID_LINK_ID))
378		return -EINVAL;
379
380	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
381	if (!cmd) {
382		ret = -ENOMEM;
383		goto out;
384	}
385
386	wl1271_debug(DEBUG_CMD, "cmd role stop dev");
387
388	cmd->role_id = wlvif->dev_role_id;
389	cmd->disc_type = DISCONNECT_IMMEDIATE;
390	cmd->reason = cpu_to_le16(WLAN_REASON_UNSPECIFIED);
391
392	ret = wl1271_cmd_send(wl, CMD_ROLE_STOP, cmd, sizeof(*cmd), 0);
393	if (ret < 0) {
394		wl1271_error("failed to initiate cmd role stop");
395		goto out_free;
396	}
397
398	ret = wl1271_cmd_wait_for_event(wl, ROLE_STOP_COMPLETE_EVENT_ID);
399	if (ret < 0) {
400		wl1271_error("cmd role stop dev event completion error");
401		goto out_free;
402	}
403
404	wl12xx_free_link(wl, wlvif, &wlvif->dev_hlid);
405
406out_free:
407	kfree(cmd);
408
409out:
410	return ret;
411}
412
413int wl12xx_cmd_role_start_sta(struct wl1271 *wl, struct wl12xx_vif *wlvif)
414{
415	struct ieee80211_vif *vif = wl12xx_wlvif_to_vif(wlvif);
416	struct wl12xx_cmd_role_start *cmd;
417	int ret;
418
419	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
420	if (!cmd) {
421		ret = -ENOMEM;
422		goto out;
423	}
424
425	wl1271_debug(DEBUG_CMD, "cmd role start sta %d", wlvif->role_id);
426
427	cmd->role_id = wlvif->role_id;
428	if (wlvif->band == IEEE80211_BAND_5GHZ)
429		cmd->band = WLCORE_BAND_5GHZ;
430	cmd->channel = wlvif->channel;
431	cmd->sta.basic_rate_set = cpu_to_le32(wlvif->basic_rate_set);
432	cmd->sta.beacon_interval = cpu_to_le16(wlvif->beacon_int);
433	cmd->sta.ssid_type = WL12XX_SSID_TYPE_ANY;
434	cmd->sta.ssid_len = wlvif->ssid_len;
435	memcpy(cmd->sta.ssid, wlvif->ssid, wlvif->ssid_len);
436	memcpy(cmd->sta.bssid, vif->bss_conf.bssid, ETH_ALEN);
437	cmd->sta.local_rates = cpu_to_le32(wlvif->rate_set);
438	cmd->channel_type = wlcore_get_native_channel_type(wlvif->channel_type);
439
440	if (wlvif->sta.hlid == WL12XX_INVALID_LINK_ID) {
441		ret = wl12xx_allocate_link(wl, wlvif, &wlvif->sta.hlid);
442		if (ret)
443			goto out_free;
444	}
445	cmd->sta.hlid = wlvif->sta.hlid;
446	cmd->sta.session = wl12xx_get_new_session_id(wl, wlvif);
447	cmd->sta.remote_rates = cpu_to_le32(wlvif->rate_set);
448
449	wl1271_debug(DEBUG_CMD, "role start: roleid=%d, hlid=%d, session=%d "
450		     "basic_rate_set: 0x%x, remote_rates: 0x%x",
451		     wlvif->role_id, cmd->sta.hlid, cmd->sta.session,
452		     wlvif->basic_rate_set, wlvif->rate_set);
453
454	ret = wl1271_cmd_send(wl, CMD_ROLE_START, cmd, sizeof(*cmd), 0);
455	if (ret < 0) {
456		wl1271_error("failed to initiate cmd role start sta");
457		goto err_hlid;
458	}
459
460	goto out_free;
461
462err_hlid:
463	/* clear links on error. */
464	wl12xx_free_link(wl, wlvif, &wlvif->sta.hlid);
465
466out_free:
467	kfree(cmd);
468
469out:
470	return ret;
471}
472
473/* use this function to stop ibss as well */
474int wl12xx_cmd_role_stop_sta(struct wl1271 *wl, struct wl12xx_vif *wlvif)
475{
476	struct wl12xx_cmd_role_stop *cmd;
477	int ret;
478
479	if (WARN_ON(wlvif->sta.hlid == WL12XX_INVALID_LINK_ID))
480		return -EINVAL;
481
482	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
483	if (!cmd) {
484		ret = -ENOMEM;
485		goto out;
486	}
487
488	wl1271_debug(DEBUG_CMD, "cmd role stop sta %d", wlvif->role_id);
489
490	cmd->role_id = wlvif->role_id;
491	cmd->disc_type = DISCONNECT_IMMEDIATE;
492	cmd->reason = cpu_to_le16(WLAN_REASON_UNSPECIFIED);
493
494	ret = wl1271_cmd_send(wl, CMD_ROLE_STOP, cmd, sizeof(*cmd), 0);
495	if (ret < 0) {
496		wl1271_error("failed to initiate cmd role stop sta");
497		goto out_free;
498	}
499
500	wl12xx_free_link(wl, wlvif, &wlvif->sta.hlid);
501
502out_free:
503	kfree(cmd);
504
505out:
506	return ret;
507}
508
509int wl12xx_cmd_role_start_ap(struct wl1271 *wl, struct wl12xx_vif *wlvif)
510{
511	struct wl12xx_cmd_role_start *cmd;
512	struct ieee80211_vif *vif = wl12xx_wlvif_to_vif(wlvif);
513	struct ieee80211_bss_conf *bss_conf = &vif->bss_conf;
514	u32 supported_rates;
515	int ret;
516
517	wl1271_debug(DEBUG_CMD, "cmd role start ap %d", wlvif->role_id);
518
519	/* trying to use hidden SSID with an old hostapd version */
520	if (wlvif->ssid_len == 0 && !bss_conf->hidden_ssid) {
521		wl1271_error("got a null SSID from beacon/bss");
522		ret = -EINVAL;
523		goto out;
524	}
525
526	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
527	if (!cmd) {
528		ret = -ENOMEM;
529		goto out;
530	}
531
532	ret = wl12xx_allocate_link(wl, wlvif, &wlvif->ap.global_hlid);
533	if (ret < 0)
534		goto out_free;
535
536	ret = wl12xx_allocate_link(wl, wlvif, &wlvif->ap.bcast_hlid);
537	if (ret < 0)
538		goto out_free_global;
539
540	cmd->role_id = wlvif->role_id;
541	cmd->ap.aging_period = cpu_to_le16(wl->conf.tx.ap_aging_period);
542	cmd->ap.bss_index = WL1271_AP_BSS_INDEX;
543	cmd->ap.global_hlid = wlvif->ap.global_hlid;
544	cmd->ap.broadcast_hlid = wlvif->ap.bcast_hlid;
545	cmd->ap.basic_rate_set = cpu_to_le32(wlvif->basic_rate_set);
546	cmd->ap.beacon_interval = cpu_to_le16(wlvif->beacon_int);
547	cmd->ap.dtim_interval = bss_conf->dtim_period;
548	cmd->ap.beacon_expiry = WL1271_AP_DEF_BEACON_EXP;
549	/* FIXME: Change when adding DFS */
550	cmd->ap.reset_tsf = 1;  /* By default reset AP TSF */
551	cmd->channel = wlvif->channel;
552	cmd->channel_type = wlcore_get_native_channel_type(wlvif->channel_type);
553
554	if (!bss_conf->hidden_ssid) {
555		/* take the SSID from the beacon for backward compatibility */
556		cmd->ap.ssid_type = WL12XX_SSID_TYPE_PUBLIC;
557		cmd->ap.ssid_len = wlvif->ssid_len;
558		memcpy(cmd->ap.ssid, wlvif->ssid, wlvif->ssid_len);
559	} else {
560		cmd->ap.ssid_type = WL12XX_SSID_TYPE_HIDDEN;
561		cmd->ap.ssid_len = bss_conf->ssid_len;
562		memcpy(cmd->ap.ssid, bss_conf->ssid, bss_conf->ssid_len);
563	}
564
565	supported_rates = CONF_TX_AP_ENABLED_RATES | CONF_TX_MCS_RATES |
566		wlcore_hw_ap_get_mimo_wide_rate_mask(wl, wlvif);
567
568	wl1271_debug(DEBUG_CMD, "cmd role start ap with supported_rates 0x%08x",
569		     supported_rates);
570
571	cmd->ap.local_rates = cpu_to_le32(supported_rates);
572
573	switch (wlvif->band) {
574	case IEEE80211_BAND_2GHZ:
575		cmd->band = WLCORE_BAND_2_4GHZ;
576		break;
577	case IEEE80211_BAND_5GHZ:
578		cmd->band = WLCORE_BAND_5GHZ;
579		break;
580	default:
581		wl1271_warning("ap start - unknown band: %d", (int)wlvif->band);
582		cmd->band = WLCORE_BAND_2_4GHZ;
583		break;
584	}
585
586	ret = wl1271_cmd_send(wl, CMD_ROLE_START, cmd, sizeof(*cmd), 0);
587	if (ret < 0) {
588		wl1271_error("failed to initiate cmd role start ap");
589		goto out_free_bcast;
590	}
591
592	goto out_free;
593
594out_free_bcast:
595	wl12xx_free_link(wl, wlvif, &wlvif->ap.bcast_hlid);
596
597out_free_global:
598	wl12xx_free_link(wl, wlvif, &wlvif->ap.global_hlid);
599
600out_free:
601	kfree(cmd);
602
603out:
604	return ret;
605}
606
607int wl12xx_cmd_role_stop_ap(struct wl1271 *wl, struct wl12xx_vif *wlvif)
608{
609	struct wl12xx_cmd_role_stop *cmd;
610	int ret;
611
612	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
613	if (!cmd) {
614		ret = -ENOMEM;
615		goto out;
616	}
617
618	wl1271_debug(DEBUG_CMD, "cmd role stop ap %d", wlvif->role_id);
619
620	cmd->role_id = wlvif->role_id;
621
622	ret = wl1271_cmd_send(wl, CMD_ROLE_STOP, cmd, sizeof(*cmd), 0);
623	if (ret < 0) {
624		wl1271_error("failed to initiate cmd role stop ap");
625		goto out_free;
626	}
627
628	wl12xx_free_link(wl, wlvif, &wlvif->ap.bcast_hlid);
629	wl12xx_free_link(wl, wlvif, &wlvif->ap.global_hlid);
630
631out_free:
632	kfree(cmd);
633
634out:
635	return ret;
636}
637
638int wl12xx_cmd_role_start_ibss(struct wl1271 *wl, struct wl12xx_vif *wlvif)
639{
640	struct ieee80211_vif *vif = wl12xx_wlvif_to_vif(wlvif);
641	struct wl12xx_cmd_role_start *cmd;
642	struct ieee80211_bss_conf *bss_conf = &vif->bss_conf;
643	int ret;
644
645	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
646	if (!cmd) {
647		ret = -ENOMEM;
648		goto out;
649	}
650
651	wl1271_debug(DEBUG_CMD, "cmd role start ibss %d", wlvif->role_id);
652
653	cmd->role_id = wlvif->role_id;
654	if (wlvif->band == IEEE80211_BAND_5GHZ)
655		cmd->band = WLCORE_BAND_5GHZ;
656	cmd->channel = wlvif->channel;
657	cmd->ibss.basic_rate_set = cpu_to_le32(wlvif->basic_rate_set);
658	cmd->ibss.beacon_interval = cpu_to_le16(wlvif->beacon_int);
659	cmd->ibss.dtim_interval = bss_conf->dtim_period;
660	cmd->ibss.ssid_type = WL12XX_SSID_TYPE_ANY;
661	cmd->ibss.ssid_len = wlvif->ssid_len;
662	memcpy(cmd->ibss.ssid, wlvif->ssid, wlvif->ssid_len);
663	memcpy(cmd->ibss.bssid, vif->bss_conf.bssid, ETH_ALEN);
664	cmd->sta.local_rates = cpu_to_le32(wlvif->rate_set);
665
666	if (wlvif->sta.hlid == WL12XX_INVALID_LINK_ID) {
667		ret = wl12xx_allocate_link(wl, wlvif, &wlvif->sta.hlid);
668		if (ret)
669			goto out_free;
670	}
671	cmd->ibss.hlid = wlvif->sta.hlid;
672	cmd->ibss.remote_rates = cpu_to_le32(wlvif->rate_set);
673
674	wl1271_debug(DEBUG_CMD, "role start: roleid=%d, hlid=%d, session=%d "
675		     "basic_rate_set: 0x%x, remote_rates: 0x%x",
676		     wlvif->role_id, cmd->sta.hlid, cmd->sta.session,
677		     wlvif->basic_rate_set, wlvif->rate_set);
678
679	wl1271_debug(DEBUG_CMD, "vif->bss_conf.bssid = %pM",
680		     vif->bss_conf.bssid);
681
682	ret = wl1271_cmd_send(wl, CMD_ROLE_START, cmd, sizeof(*cmd), 0);
683	if (ret < 0) {
684		wl1271_error("failed to initiate cmd role enable");
685		goto err_hlid;
686	}
687
688	goto out_free;
689
690err_hlid:
691	/* clear links on error. */
692	wl12xx_free_link(wl, wlvif, &wlvif->sta.hlid);
693
694out_free:
695	kfree(cmd);
696
697out:
698	return ret;
699}
700
701
702/**
703 * send test command to firmware
704 *
705 * @wl: wl struct
706 * @buf: buffer containing the command, with all headers, must work with dma
707 * @len: length of the buffer
708 * @answer: is answer needed
709 */
710int wl1271_cmd_test(struct wl1271 *wl, void *buf, size_t buf_len, u8 answer)
711{
712	int ret;
713	size_t res_len = 0;
714
715	wl1271_debug(DEBUG_CMD, "cmd test");
716
717	if (answer)
718		res_len = buf_len;
719
720	ret = wl1271_cmd_send(wl, CMD_TEST, buf, buf_len, res_len);
721
722	if (ret < 0) {
723		wl1271_warning("TEST command failed");
724		return ret;
725	}
726
727	return ret;
728}
729EXPORT_SYMBOL_GPL(wl1271_cmd_test);
730
731/**
732 * read acx from firmware
733 *
734 * @wl: wl struct
735 * @id: acx id
736 * @buf: buffer for the response, including all headers, must work with dma
737 * @len: length of buf
738 */
739int wl1271_cmd_interrogate(struct wl1271 *wl, u16 id, void *buf, size_t len)
740{
741	struct acx_header *acx = buf;
742	int ret;
743
744	wl1271_debug(DEBUG_CMD, "cmd interrogate");
745
746	acx->id = cpu_to_le16(id);
747
748	/* payload length, does not include any headers */
749	acx->len = cpu_to_le16(len - sizeof(*acx));
750
751	ret = wl1271_cmd_send(wl, CMD_INTERROGATE, acx, sizeof(*acx), len);
752	if (ret < 0)
753		wl1271_error("INTERROGATE command failed");
754
755	return ret;
756}
757
758/**
759 * write acx value to firmware
760 *
761 * @wl: wl struct
762 * @id: acx id
763 * @buf: buffer containing acx, including all headers, must work with dma
764 * @len: length of buf
765 */
766int wl1271_cmd_configure(struct wl1271 *wl, u16 id, void *buf, size_t len)
767{
768	struct acx_header *acx = buf;
769	int ret;
770
771	wl1271_debug(DEBUG_CMD, "cmd configure (%d)", id);
772
773	acx->id = cpu_to_le16(id);
774
775	/* payload length, does not include any headers */
776	acx->len = cpu_to_le16(len - sizeof(*acx));
777
778	ret = wl1271_cmd_send(wl, CMD_CONFIGURE, acx, len, 0);
779	if (ret < 0) {
780		wl1271_warning("CONFIGURE command NOK");
781		return ret;
782	}
783
784	return 0;
785}
786EXPORT_SYMBOL_GPL(wl1271_cmd_configure);
787
788int wl1271_cmd_data_path(struct wl1271 *wl, bool enable)
789{
790	struct cmd_enabledisable_path *cmd;
791	int ret;
792	u16 cmd_rx, cmd_tx;
793
794	wl1271_debug(DEBUG_CMD, "cmd data path");
795
796	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
797	if (!cmd) {
798		ret = -ENOMEM;
799		goto out;
800	}
801
802	/* the channel here is only used for calibration, so hardcoded to 1 */
803	cmd->channel = 1;
804
805	if (enable) {
806		cmd_rx = CMD_ENABLE_RX;
807		cmd_tx = CMD_ENABLE_TX;
808	} else {
809		cmd_rx = CMD_DISABLE_RX;
810		cmd_tx = CMD_DISABLE_TX;
811	}
812
813	ret = wl1271_cmd_send(wl, cmd_rx, cmd, sizeof(*cmd), 0);
814	if (ret < 0) {
815		wl1271_error("rx %s cmd for channel %d failed",
816			     enable ? "start" : "stop", cmd->channel);
817		goto out;
818	}
819
820	wl1271_debug(DEBUG_BOOT, "rx %s cmd channel %d",
821		     enable ? "start" : "stop", cmd->channel);
822
823	ret = wl1271_cmd_send(wl, cmd_tx, cmd, sizeof(*cmd), 0);
824	if (ret < 0) {
825		wl1271_error("tx %s cmd for channel %d failed",
826			     enable ? "start" : "stop", cmd->channel);
827		goto out;
828	}
829
830	wl1271_debug(DEBUG_BOOT, "tx %s cmd channel %d",
831		     enable ? "start" : "stop", cmd->channel);
832
833out:
834	kfree(cmd);
835	return ret;
836}
837EXPORT_SYMBOL_GPL(wl1271_cmd_data_path);
838
839int wl1271_cmd_ps_mode(struct wl1271 *wl, struct wl12xx_vif *wlvif,
840		       u8 ps_mode, u16 auto_ps_timeout)
841{
842	struct wl1271_cmd_ps_params *ps_params = NULL;
843	int ret = 0;
844
845	wl1271_debug(DEBUG_CMD, "cmd set ps mode");
846
847	ps_params = kzalloc(sizeof(*ps_params), GFP_KERNEL);
848	if (!ps_params) {
849		ret = -ENOMEM;
850		goto out;
851	}
852
853	ps_params->role_id = wlvif->role_id;
854	ps_params->ps_mode = ps_mode;
855	ps_params->auto_ps_timeout = auto_ps_timeout;
856
857	ret = wl1271_cmd_send(wl, CMD_SET_PS_MODE, ps_params,
858			      sizeof(*ps_params), 0);
859	if (ret < 0) {
860		wl1271_error("cmd set_ps_mode failed");
861		goto out;
862	}
863
864out:
865	kfree(ps_params);
866	return ret;
867}
868
869int wl1271_cmd_template_set(struct wl1271 *wl, u8 role_id,
870			    u16 template_id, void *buf, size_t buf_len,
871			    int index, u32 rates)
872{
873	struct wl1271_cmd_template_set *cmd;
874	int ret = 0;
875
876	wl1271_debug(DEBUG_CMD, "cmd template_set %d (role %d)",
877		     template_id, role_id);
878
879	WARN_ON(buf_len > WL1271_CMD_TEMPL_MAX_SIZE);
880	buf_len = min_t(size_t, buf_len, WL1271_CMD_TEMPL_MAX_SIZE);
881
882	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
883	if (!cmd) {
884		ret = -ENOMEM;
885		goto out;
886	}
887
888	/* during initialization wlvif is NULL */
889	cmd->role_id = role_id;
890	cmd->len = cpu_to_le16(buf_len);
891	cmd->template_type = template_id;
892	cmd->enabled_rates = cpu_to_le32(rates);
893	cmd->short_retry_limit = wl->conf.tx.tmpl_short_retry_limit;
894	cmd->long_retry_limit = wl->conf.tx.tmpl_long_retry_limit;
895	cmd->index = index;
896
897	if (buf)
898		memcpy(cmd->template_data, buf, buf_len);
899
900	ret = wl1271_cmd_send(wl, CMD_SET_TEMPLATE, cmd, sizeof(*cmd), 0);
901	if (ret < 0) {
902		wl1271_warning("cmd set_template failed: %d", ret);
903		goto out_free;
904	}
905
906out_free:
907	kfree(cmd);
908
909out:
910	return ret;
911}
912
913int wl12xx_cmd_build_null_data(struct wl1271 *wl, struct wl12xx_vif *wlvif)
914{
915	struct sk_buff *skb = NULL;
916	int size;
917	void *ptr;
918	int ret = -ENOMEM;
919
920
921	if (wlvif->bss_type == BSS_TYPE_IBSS) {
922		size = sizeof(struct wl12xx_null_data_template);
923		ptr = NULL;
924	} else {
925		skb = ieee80211_nullfunc_get(wl->hw,
926					     wl12xx_wlvif_to_vif(wlvif));
927		if (!skb)
928			goto out;
929		size = skb->len;
930		ptr = skb->data;
931	}
932
933	ret = wl1271_cmd_template_set(wl, wlvif->role_id,
934				      CMD_TEMPL_NULL_DATA, ptr, size, 0,
935				      wlvif->basic_rate);
936
937out:
938	dev_kfree_skb(skb);
939	if (ret)
940		wl1271_warning("cmd buld null data failed %d", ret);
941
942	return ret;
943
944}
945
946int wl12xx_cmd_build_klv_null_data(struct wl1271 *wl,
947				   struct wl12xx_vif *wlvif)
948{
949	struct ieee80211_vif *vif = wl12xx_wlvif_to_vif(wlvif);
950	struct sk_buff *skb = NULL;
951	int ret = -ENOMEM;
952
953	skb = ieee80211_nullfunc_get(wl->hw, vif);
954	if (!skb)
955		goto out;
956
957	ret = wl1271_cmd_template_set(wl, wlvif->role_id, CMD_TEMPL_KLV,
958				      skb->data, skb->len,
959				      CMD_TEMPL_KLV_IDX_NULL_DATA,
960				      wlvif->basic_rate);
961
962out:
963	dev_kfree_skb(skb);
964	if (ret)
965		wl1271_warning("cmd build klv null data failed %d", ret);
966
967	return ret;
968
969}
970
971int wl1271_cmd_build_ps_poll(struct wl1271 *wl, struct wl12xx_vif *wlvif,
972			     u16 aid)
973{
974	struct ieee80211_vif *vif = wl12xx_wlvif_to_vif(wlvif);
975	struct sk_buff *skb;
976	int ret = 0;
977
978	skb = ieee80211_pspoll_get(wl->hw, vif);
979	if (!skb)
980		goto out;
981
982	ret = wl1271_cmd_template_set(wl, wlvif->role_id,
983				      CMD_TEMPL_PS_POLL, skb->data,
984				      skb->len, 0, wlvif->basic_rate_set);
985
986out:
987	dev_kfree_skb(skb);
988	return ret;
989}
990
991int wl12xx_cmd_build_probe_req(struct wl1271 *wl, struct wl12xx_vif *wlvif,
992			       u8 role_id, u8 band,
993			       const u8 *ssid, size_t ssid_len,
994			       const u8 *ie, size_t ie_len)
995{
996	struct ieee80211_vif *vif = wl12xx_wlvif_to_vif(wlvif);
997	struct sk_buff *skb;
998	int ret;
999	u32 rate;
1000
1001	skb = ieee80211_probereq_get(wl->hw, vif, ssid, ssid_len,
1002				     ie, ie_len);
1003	if (!skb) {
1004		ret = -ENOMEM;
1005		goto out;
1006	}
1007
1008	wl1271_dump(DEBUG_SCAN, "PROBE REQ: ", skb->data, skb->len);
1009
1010	rate = wl1271_tx_min_rate_get(wl, wlvif->bitrate_masks[band]);
1011	if (band == IEEE80211_BAND_2GHZ)
1012		ret = wl1271_cmd_template_set(wl, role_id,
1013					      CMD_TEMPL_CFG_PROBE_REQ_2_4,
1014					      skb->data, skb->len, 0, rate);
1015	else
1016		ret = wl1271_cmd_template_set(wl, role_id,
1017					      CMD_TEMPL_CFG_PROBE_REQ_5,
1018					      skb->data, skb->len, 0, rate);
1019
1020out:
1021	dev_kfree_skb(skb);
1022	return ret;
1023}
1024
1025struct sk_buff *wl1271_cmd_build_ap_probe_req(struct wl1271 *wl,
1026					      struct wl12xx_vif *wlvif,
1027					      struct sk_buff *skb)
1028{
1029	struct ieee80211_vif *vif = wl12xx_wlvif_to_vif(wlvif);
1030	int ret;
1031	u32 rate;
1032
1033	if (!skb)
1034		skb = ieee80211_ap_probereq_get(wl->hw, vif);
1035	if (!skb)
1036		goto out;
1037
1038	wl1271_dump(DEBUG_SCAN, "AP PROBE REQ: ", skb->data, skb->len);
1039
1040	rate = wl1271_tx_min_rate_get(wl, wlvif->bitrate_masks[wlvif->band]);
1041	if (wlvif->band == IEEE80211_BAND_2GHZ)
1042		ret = wl1271_cmd_template_set(wl, wlvif->role_id,
1043					      CMD_TEMPL_CFG_PROBE_REQ_2_4,
1044					      skb->data, skb->len, 0, rate);
1045	else
1046		ret = wl1271_cmd_template_set(wl, wlvif->role_id,
1047					      CMD_TEMPL_CFG_PROBE_REQ_5,
1048					      skb->data, skb->len, 0, rate);
1049
1050	if (ret < 0)
1051		wl1271_error("Unable to set ap probe request template.");
1052
1053out:
1054	return skb;
1055}
1056
1057int wl1271_cmd_build_arp_rsp(struct wl1271 *wl, struct wl12xx_vif *wlvif)
1058{
1059	int ret, extra = 0;
1060	u16 fc;
1061	struct ieee80211_vif *vif = wl12xx_wlvif_to_vif(wlvif);
1062	struct sk_buff *skb;
1063	struct wl12xx_arp_rsp_template *tmpl;
1064	struct ieee80211_hdr_3addr *hdr;
1065	struct arphdr *arp_hdr;
1066
1067	skb = dev_alloc_skb(sizeof(*hdr) + sizeof(__le16) + sizeof(*tmpl) +
1068			    WL1271_EXTRA_SPACE_MAX);
1069	if (!skb) {
1070		wl1271_error("failed to allocate buffer for arp rsp template");
1071		return -ENOMEM;
1072	}
1073
1074	skb_reserve(skb, sizeof(*hdr) + WL1271_EXTRA_SPACE_MAX);
1075
1076	tmpl = (struct wl12xx_arp_rsp_template *)skb_put(skb, sizeof(*tmpl));
1077	memset(tmpl, 0, sizeof(*tmpl));
1078
1079	/* llc layer */
1080	memcpy(tmpl->llc_hdr, rfc1042_header, sizeof(rfc1042_header));
1081	tmpl->llc_type = cpu_to_be16(ETH_P_ARP);
1082
1083	/* arp header */
1084	arp_hdr = &tmpl->arp_hdr;
1085	arp_hdr->ar_hrd = cpu_to_be16(ARPHRD_ETHER);
1086	arp_hdr->ar_pro = cpu_to_be16(ETH_P_IP);
1087	arp_hdr->ar_hln = ETH_ALEN;
1088	arp_hdr->ar_pln = 4;
1089	arp_hdr->ar_op = cpu_to_be16(ARPOP_REPLY);
1090
1091	/* arp payload */
1092	memcpy(tmpl->sender_hw, vif->addr, ETH_ALEN);
1093	tmpl->sender_ip = wlvif->ip_addr;
1094
1095	/* encryption space */
1096	switch (wlvif->encryption_type) {
1097	case KEY_TKIP:
1098		if (wl->quirks & WLCORE_QUIRK_TKIP_HEADER_SPACE)
1099			extra = WL1271_EXTRA_SPACE_TKIP;
1100		break;
1101	case KEY_AES:
1102		extra = WL1271_EXTRA_SPACE_AES;
1103		break;
1104	case KEY_NONE:
1105	case KEY_WEP:
1106	case KEY_GEM:
1107		extra = 0;
1108		break;
1109	default:
1110		wl1271_warning("Unknown encryption type: %d",
1111			       wlvif->encryption_type);
1112		ret = -EINVAL;
1113		goto out;
1114	}
1115
1116	if (extra) {
1117		u8 *space = skb_push(skb, extra);
1118		memset(space, 0, extra);
1119	}
1120
1121	/* QoS header - BE */
1122	if (wlvif->sta.qos)
1123		memset(skb_push(skb, sizeof(__le16)), 0, sizeof(__le16));
1124
1125	/* mac80211 header */
1126	hdr = (struct ieee80211_hdr_3addr *)skb_push(skb, sizeof(*hdr));
1127	memset(hdr, 0, sizeof(*hdr));
1128	fc = IEEE80211_FTYPE_DATA | IEEE80211_FCTL_TODS;
1129	if (wlvif->sta.qos)
1130		fc |= IEEE80211_STYPE_QOS_DATA;
1131	else
1132		fc |= IEEE80211_STYPE_DATA;
1133	if (wlvif->encryption_type != KEY_NONE)
1134		fc |= IEEE80211_FCTL_PROTECTED;
1135
1136	hdr->frame_control = cpu_to_le16(fc);
1137	memcpy(hdr->addr1, vif->bss_conf.bssid, ETH_ALEN);
1138	memcpy(hdr->addr2, vif->addr, ETH_ALEN);
1139	memset(hdr->addr3, 0xff, ETH_ALEN);
1140
1141	ret = wl1271_cmd_template_set(wl, wlvif->role_id, CMD_TEMPL_ARP_RSP,
1142				      skb->data, skb->len, 0,
1143				      wlvif->basic_rate);
1144out:
1145	dev_kfree_skb(skb);
1146	return ret;
1147}
1148
1149int wl1271_build_qos_null_data(struct wl1271 *wl, struct ieee80211_vif *vif)
1150{
1151	struct wl12xx_vif *wlvif = wl12xx_vif_to_data(vif);
1152	struct ieee80211_qos_hdr template;
1153
1154	memset(&template, 0, sizeof(template));
1155
1156	memcpy(template.addr1, vif->bss_conf.bssid, ETH_ALEN);
1157	memcpy(template.addr2, vif->addr, ETH_ALEN);
1158	memcpy(template.addr3, vif->bss_conf.bssid, ETH_ALEN);
1159
1160	template.frame_control = cpu_to_le16(IEEE80211_FTYPE_DATA |
1161					     IEEE80211_STYPE_QOS_NULLFUNC |
1162					     IEEE80211_FCTL_TODS);
1163
1164	/* FIXME: not sure what priority to use here */
1165	template.qos_ctrl = cpu_to_le16(0);
1166
1167	return wl1271_cmd_template_set(wl, wlvif->role_id,
1168				       CMD_TEMPL_QOS_NULL_DATA, &template,
1169				       sizeof(template), 0,
1170				       wlvif->basic_rate);
1171}
1172
1173int wl12xx_cmd_set_default_wep_key(struct wl1271 *wl, u8 id, u8 hlid)
1174{
1175	struct wl1271_cmd_set_keys *cmd;
1176	int ret = 0;
1177
1178	wl1271_debug(DEBUG_CMD, "cmd set_default_wep_key %d", id);
1179
1180	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
1181	if (!cmd) {
1182		ret = -ENOMEM;
1183		goto out;
1184	}
1185
1186	cmd->hlid = hlid;
1187	cmd->key_id = id;
1188	cmd->lid_key_type = WEP_DEFAULT_LID_TYPE;
1189	cmd->key_action = cpu_to_le16(KEY_SET_ID);
1190	cmd->key_type = KEY_WEP;
1191
1192	ret = wl1271_cmd_send(wl, CMD_SET_KEYS, cmd, sizeof(*cmd), 0);
1193	if (ret < 0) {
1194		wl1271_warning("cmd set_default_wep_key failed: %d", ret);
1195		goto out;
1196	}
1197
1198out:
1199	kfree(cmd);
1200
1201	return ret;
1202}
1203
1204int wl1271_cmd_set_sta_key(struct wl1271 *wl, struct wl12xx_vif *wlvif,
1205		       u16 action, u8 id, u8 key_type,
1206		       u8 key_size, const u8 *key, const u8 *addr,
1207		       u32 tx_seq_32, u16 tx_seq_16)
1208{
1209	struct wl1271_cmd_set_keys *cmd;
1210	int ret = 0;
1211
1212	/* hlid might have already been deleted */
1213	if (wlvif->sta.hlid == WL12XX_INVALID_LINK_ID)
1214		return 0;
1215
1216	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
1217	if (!cmd) {
1218		ret = -ENOMEM;
1219		goto out;
1220	}
1221
1222	cmd->hlid = wlvif->sta.hlid;
1223
1224	if (key_type == KEY_WEP)
1225		cmd->lid_key_type = WEP_DEFAULT_LID_TYPE;
1226	else if (is_broadcast_ether_addr(addr))
1227		cmd->lid_key_type = BROADCAST_LID_TYPE;
1228	else
1229		cmd->lid_key_type = UNICAST_LID_TYPE;
1230
1231	cmd->key_action = cpu_to_le16(action);
1232	cmd->key_size = key_size;
1233	cmd->key_type = key_type;
1234
1235	cmd->ac_seq_num16[0] = cpu_to_le16(tx_seq_16);
1236	cmd->ac_seq_num32[0] = cpu_to_le32(tx_seq_32);
1237
1238	cmd->key_id = id;
1239
1240	if (key_type == KEY_TKIP) {
1241		/*
1242		 * We get the key in the following form:
1243		 * TKIP (16 bytes) - TX MIC (8 bytes) - RX MIC (8 bytes)
1244		 * but the target is expecting:
1245		 * TKIP - RX MIC - TX MIC
1246		 */
1247		memcpy(cmd->key, key, 16);
1248		memcpy(cmd->key + 16, key + 24, 8);
1249		memcpy(cmd->key + 24, key + 16, 8);
1250
1251	} else {
1252		memcpy(cmd->key, key, key_size);
1253	}
1254
1255	wl1271_dump(DEBUG_CRYPT, "TARGET KEY: ", cmd, sizeof(*cmd));
1256
1257	ret = wl1271_cmd_send(wl, CMD_SET_KEYS, cmd, sizeof(*cmd), 0);
1258	if (ret < 0) {
1259		wl1271_warning("could not set keys");
1260	goto out;
1261	}
1262
1263out:
1264	kfree(cmd);
1265
1266	return ret;
1267}
1268
1269/*
1270 * TODO: merge with sta/ibss into 1 set_key function.
1271 * note there are slight diffs
1272 */
1273int wl1271_cmd_set_ap_key(struct wl1271 *wl, struct wl12xx_vif *wlvif,
1274			  u16 action, u8 id, u8 key_type,
1275			  u8 key_size, const u8 *key, u8 hlid, u32 tx_seq_32,
1276			  u16 tx_seq_16)
1277{
1278	struct wl1271_cmd_set_keys *cmd;
1279	int ret = 0;
1280	u8 lid_type;
1281
1282	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
1283	if (!cmd)
1284		return -ENOMEM;
1285
1286	if (hlid == wlvif->ap.bcast_hlid) {
1287		if (key_type == KEY_WEP)
1288			lid_type = WEP_DEFAULT_LID_TYPE;
1289		else
1290			lid_type = BROADCAST_LID_TYPE;
1291	} else {
1292		lid_type = UNICAST_LID_TYPE;
1293	}
1294
1295	wl1271_debug(DEBUG_CRYPT, "ap key action: %d id: %d lid: %d type: %d"
1296		     " hlid: %d", (int)action, (int)id, (int)lid_type,
1297		     (int)key_type, (int)hlid);
1298
1299	cmd->lid_key_type = lid_type;
1300	cmd->hlid = hlid;
1301	cmd->key_action = cpu_to_le16(action);
1302	cmd->key_size = key_size;
1303	cmd->key_type = key_type;
1304	cmd->key_id = id;
1305	cmd->ac_seq_num16[0] = cpu_to_le16(tx_seq_16);
1306	cmd->ac_seq_num32[0] = cpu_to_le32(tx_seq_32);
1307
1308	if (key_type == KEY_TKIP) {
1309		/*
1310		 * We get the key in the following form:
1311		 * TKIP (16 bytes) - TX MIC (8 bytes) - RX MIC (8 bytes)
1312		 * but the target is expecting:
1313		 * TKIP - RX MIC - TX MIC
1314		 */
1315		memcpy(cmd->key, key, 16);
1316		memcpy(cmd->key + 16, key + 24, 8);
1317		memcpy(cmd->key + 24, key + 16, 8);
1318	} else {
1319		memcpy(cmd->key, key, key_size);
1320	}
1321
1322	wl1271_dump(DEBUG_CRYPT, "TARGET AP KEY: ", cmd, sizeof(*cmd));
1323
1324	ret = wl1271_cmd_send(wl, CMD_SET_KEYS, cmd, sizeof(*cmd), 0);
1325	if (ret < 0) {
1326		wl1271_warning("could not set ap keys");
1327		goto out;
1328	}
1329
1330out:
1331	kfree(cmd);
1332	return ret;
1333}
1334
1335int wl12xx_cmd_set_peer_state(struct wl1271 *wl, u8 hlid)
1336{
1337	struct wl12xx_cmd_set_peer_state *cmd;
1338	int ret = 0;
1339
1340	wl1271_debug(DEBUG_CMD, "cmd set peer state (hlid=%d)", hlid);
1341
1342	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
1343	if (!cmd) {
1344		ret = -ENOMEM;
1345		goto out;
1346	}
1347
1348	cmd->hlid = hlid;
1349	cmd->state = WL1271_CMD_STA_STATE_CONNECTED;
1350
1351	ret = wl1271_cmd_send(wl, CMD_SET_PEER_STATE, cmd, sizeof(*cmd), 0);
1352	if (ret < 0) {
1353		wl1271_error("failed to send set peer state command");
1354		goto out_free;
1355	}
1356
1357out_free:
1358	kfree(cmd);
1359
1360out:
1361	return ret;
1362}
1363
1364int wl12xx_cmd_add_peer(struct wl1271 *wl, struct wl12xx_vif *wlvif,
1365			struct ieee80211_sta *sta, u8 hlid)
1366{
1367	struct wl12xx_cmd_add_peer *cmd;
1368	int i, ret;
1369	u32 sta_rates;
1370
1371	wl1271_debug(DEBUG_CMD, "cmd add peer %d", (int)hlid);
1372
1373	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
1374	if (!cmd) {
1375		ret = -ENOMEM;
1376		goto out;
1377	}
1378
1379	memcpy(cmd->addr, sta->addr, ETH_ALEN);
1380	cmd->bss_index = WL1271_AP_BSS_INDEX;
1381	cmd->aid = sta->aid;
1382	cmd->hlid = hlid;
1383	cmd->sp_len = sta->max_sp;
1384	cmd->wmm = sta->wme ? 1 : 0;
1385
1386	for (i = 0; i < NUM_ACCESS_CATEGORIES_COPY; i++)
1387		if (sta->wme && (sta->uapsd_queues & BIT(i)))
1388			cmd->psd_type[NUM_ACCESS_CATEGORIES_COPY-1-i] =
1389					WL1271_PSD_UPSD_TRIGGER;
1390		else
1391			cmd->psd_type[NUM_ACCESS_CATEGORIES_COPY-1-i] =
1392					WL1271_PSD_LEGACY;
1393
1394
1395	sta_rates = sta->supp_rates[wlvif->band];
1396	if (sta->ht_cap.ht_supported)
1397		sta_rates |=
1398			(sta->ht_cap.mcs.rx_mask[0] << HW_HT_RATES_OFFSET) |
1399			(sta->ht_cap.mcs.rx_mask[1] << HW_MIMO_RATES_OFFSET);
1400
1401	cmd->supported_rates =
1402		cpu_to_le32(wl1271_tx_enabled_rates_get(wl, sta_rates,
1403							wlvif->band));
1404
1405	wl1271_debug(DEBUG_CMD, "new peer rates=0x%x queues=0x%x",
1406		     cmd->supported_rates, sta->uapsd_queues);
1407
1408	ret = wl1271_cmd_send(wl, CMD_ADD_PEER, cmd, sizeof(*cmd), 0);
1409	if (ret < 0) {
1410		wl1271_error("failed to initiate cmd add peer");
1411		goto out_free;
1412	}
1413
1414out_free:
1415	kfree(cmd);
1416
1417out:
1418	return ret;
1419}
1420
1421int wl12xx_cmd_remove_peer(struct wl1271 *wl, u8 hlid)
1422{
1423	struct wl12xx_cmd_remove_peer *cmd;
1424	int ret;
1425
1426	wl1271_debug(DEBUG_CMD, "cmd remove peer %d", (int)hlid);
1427
1428	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
1429	if (!cmd) {
1430		ret = -ENOMEM;
1431		goto out;
1432	}
1433
1434	cmd->hlid = hlid;
1435	/* We never send a deauth, mac80211 is in charge of this */
1436	cmd->reason_opcode = 0;
1437	cmd->send_deauth_flag = 0;
1438
1439	ret = wl1271_cmd_send(wl, CMD_REMOVE_PEER, cmd, sizeof(*cmd), 0);
1440	if (ret < 0) {
1441		wl1271_error("failed to initiate cmd remove peer");
1442		goto out_free;
1443	}
1444
1445	/*
1446	 * We are ok with a timeout here. The event is sometimes not sent
1447	 * due to a firmware bug.
1448	 */
1449	wl1271_cmd_wait_for_event_or_timeout(wl,
1450					     PEER_REMOVE_COMPLETE_EVENT_ID);
1451
1452out_free:
1453	kfree(cmd);
1454
1455out:
1456	return ret;
1457}
1458
1459int wl12xx_cmd_config_fwlog(struct wl1271 *wl)
1460{
1461	struct wl12xx_cmd_config_fwlog *cmd;
1462	int ret = 0;
1463
1464	wl1271_debug(DEBUG_CMD, "cmd config firmware logger");
1465
1466	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
1467	if (!cmd) {
1468		ret = -ENOMEM;
1469		goto out;
1470	}
1471
1472	cmd->logger_mode = wl->conf.fwlog.mode;
1473	cmd->log_severity = wl->conf.fwlog.severity;
1474	cmd->timestamp = wl->conf.fwlog.timestamp;
1475	cmd->output = wl->conf.fwlog.output;
1476	cmd->threshold = wl->conf.fwlog.threshold;
1477
1478	ret = wl1271_cmd_send(wl, CMD_CONFIG_FWLOGGER, cmd, sizeof(*cmd), 0);
1479	if (ret < 0) {
1480		wl1271_error("failed to send config firmware logger command");
1481		goto out_free;
1482	}
1483
1484out_free:
1485	kfree(cmd);
1486
1487out:
1488	return ret;
1489}
1490
1491int wl12xx_cmd_start_fwlog(struct wl1271 *wl)
1492{
1493	struct wl12xx_cmd_start_fwlog *cmd;
1494	int ret = 0;
1495
1496	wl1271_debug(DEBUG_CMD, "cmd start firmware logger");
1497
1498	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
1499	if (!cmd) {
1500		ret = -ENOMEM;
1501		goto out;
1502	}
1503
1504	ret = wl1271_cmd_send(wl, CMD_START_FWLOGGER, cmd, sizeof(*cmd), 0);
1505	if (ret < 0) {
1506		wl1271_error("failed to send start firmware logger command");
1507		goto out_free;
1508	}
1509
1510out_free:
1511	kfree(cmd);
1512
1513out:
1514	return ret;
1515}
1516
1517int wl12xx_cmd_stop_fwlog(struct wl1271 *wl)
1518{
1519	struct wl12xx_cmd_stop_fwlog *cmd;
1520	int ret = 0;
1521
1522	wl1271_debug(DEBUG_CMD, "cmd stop firmware logger");
1523
1524	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
1525	if (!cmd) {
1526		ret = -ENOMEM;
1527		goto out;
1528	}
1529
1530	ret = wl1271_cmd_send(wl, CMD_STOP_FWLOGGER, cmd, sizeof(*cmd), 0);
1531	if (ret < 0) {
1532		wl1271_error("failed to send stop firmware logger command");
1533		goto out_free;
1534	}
1535
1536out_free:
1537	kfree(cmd);
1538
1539out:
1540	return ret;
1541}
1542
1543static int wl12xx_cmd_roc(struct wl1271 *wl, struct wl12xx_vif *wlvif,
1544			  u8 role_id)
1545{
1546	struct wl12xx_cmd_roc *cmd;
1547	int ret = 0;
1548
1549	wl1271_debug(DEBUG_CMD, "cmd roc %d (%d)", wlvif->channel, role_id);
1550
1551	if (WARN_ON(role_id == WL12XX_INVALID_ROLE_ID))
1552		return -EINVAL;
1553
1554	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
1555	if (!cmd) {
1556		ret = -ENOMEM;
1557		goto out;
1558	}
1559
1560	cmd->role_id = role_id;
1561	cmd->channel = wlvif->channel;
1562	switch (wlvif->band) {
1563	case IEEE80211_BAND_2GHZ:
1564		cmd->band = WLCORE_BAND_2_4GHZ;
1565		break;
1566	case IEEE80211_BAND_5GHZ:
1567		cmd->band = WLCORE_BAND_5GHZ;
1568		break;
1569	default:
1570		wl1271_error("roc - unknown band: %d", (int)wlvif->band);
1571		ret = -EINVAL;
1572		goto out_free;
1573	}
1574
1575
1576	ret = wl1271_cmd_send(wl, CMD_REMAIN_ON_CHANNEL, cmd, sizeof(*cmd), 0);
1577	if (ret < 0) {
1578		wl1271_error("failed to send ROC command");
1579		goto out_free;
1580	}
1581
1582out_free:
1583	kfree(cmd);
1584
1585out:
1586	return ret;
1587}
1588
1589static int wl12xx_cmd_croc(struct wl1271 *wl, u8 role_id)
1590{
1591	struct wl12xx_cmd_croc *cmd;
1592	int ret = 0;
1593
1594	wl1271_debug(DEBUG_CMD, "cmd croc (%d)", role_id);
1595
1596	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
1597	if (!cmd) {
1598		ret = -ENOMEM;
1599		goto out;
1600	}
1601	cmd->role_id = role_id;
1602
1603	ret = wl1271_cmd_send(wl, CMD_CANCEL_REMAIN_ON_CHANNEL, cmd,
1604			      sizeof(*cmd), 0);
1605	if (ret < 0) {
1606		wl1271_error("failed to send ROC command");
1607		goto out_free;
1608	}
1609
1610out_free:
1611	kfree(cmd);
1612
1613out:
1614	return ret;
1615}
1616
1617int wl12xx_roc(struct wl1271 *wl, struct wl12xx_vif *wlvif, u8 role_id)
1618{
1619	int ret = 0;
1620	bool is_first_roc;
1621
1622	if (WARN_ON(test_bit(role_id, wl->roc_map)))
1623		return 0;
1624
1625	is_first_roc = (find_first_bit(wl->roc_map, WL12XX_MAX_ROLES) >=
1626			WL12XX_MAX_ROLES);
1627
1628	ret = wl12xx_cmd_roc(wl, wlvif, role_id);
1629	if (ret < 0)
1630		goto out;
1631
1632	if (is_first_roc) {
1633		ret = wl1271_cmd_wait_for_event(wl,
1634					   REMAIN_ON_CHANNEL_COMPLETE_EVENT_ID);
1635		if (ret < 0) {
1636			wl1271_error("cmd roc event completion error");
1637			goto out;
1638		}
1639	}
1640
1641	__set_bit(role_id, wl->roc_map);
1642out:
1643	return ret;
1644}
1645
1646int wl12xx_croc(struct wl1271 *wl, u8 role_id)
1647{
1648	int ret = 0;
1649
1650	if (WARN_ON(!test_bit(role_id, wl->roc_map)))
1651		return 0;
1652
1653	ret = wl12xx_cmd_croc(wl, role_id);
1654	if (ret < 0)
1655		goto out;
1656
1657	__clear_bit(role_id, wl->roc_map);
1658
1659	/*
1660	 * Rearm the tx watchdog when removing the last ROC. This prevents
1661	 * recoveries due to just finished ROCs - when Tx hasn't yet had
1662	 * a chance to get out.
1663	 */
1664	if (find_first_bit(wl->roc_map, WL12XX_MAX_ROLES) >= WL12XX_MAX_ROLES)
1665		wl12xx_rearm_tx_watchdog_locked(wl);
1666out:
1667	return ret;
1668}
1669
1670int wl12xx_cmd_channel_switch(struct wl1271 *wl,
1671			      struct wl12xx_vif *wlvif,
1672			      struct ieee80211_channel_switch *ch_switch)
1673{
1674	struct wl12xx_cmd_channel_switch *cmd;
1675	int ret;
1676
1677	wl1271_debug(DEBUG_ACX, "cmd channel switch");
1678
1679	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
1680	if (!cmd) {
1681		ret = -ENOMEM;
1682		goto out;
1683	}
1684
1685	cmd->role_id = wlvif->role_id;
1686	cmd->channel = ch_switch->channel->hw_value;
1687	cmd->switch_time = ch_switch->count;
1688	cmd->stop_tx = ch_switch->block_tx;
1689
1690	/* FIXME: control from mac80211 in the future */
1691	cmd->post_switch_tx_disable = 0;  /* Enable TX on the target channel */
1692
1693	ret = wl1271_cmd_send(wl, CMD_CHANNEL_SWITCH, cmd, sizeof(*cmd), 0);
1694	if (ret < 0) {
1695		wl1271_error("failed to send channel switch command");
1696		goto out_free;
1697	}
1698
1699out_free:
1700	kfree(cmd);
1701
1702out:
1703	return ret;
1704}
1705
1706int wl12xx_cmd_stop_channel_switch(struct wl1271 *wl)
1707{
1708	struct wl12xx_cmd_stop_channel_switch *cmd;
1709	int ret;
1710
1711	wl1271_debug(DEBUG_ACX, "cmd stop channel switch");
1712
1713	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
1714	if (!cmd) {
1715		ret = -ENOMEM;
1716		goto out;
1717	}
1718
1719	ret = wl1271_cmd_send(wl, CMD_STOP_CHANNEL_SWICTH, cmd, sizeof(*cmd), 0);
1720	if (ret < 0) {
1721		wl1271_error("failed to stop channel switch command");
1722		goto out_free;
1723	}
1724
1725out_free:
1726	kfree(cmd);
1727
1728out:
1729	return ret;
1730}
1731
1732/* start dev role and roc on its channel */
1733int wl12xx_start_dev(struct wl1271 *wl, struct wl12xx_vif *wlvif)
1734{
1735	int ret;
1736
1737	if (WARN_ON(!(wlvif->bss_type == BSS_TYPE_STA_BSS ||
1738		      wlvif->bss_type == BSS_TYPE_IBSS)))
1739		return -EINVAL;
1740
1741	ret = wl12xx_cmd_role_start_dev(wl, wlvif);
1742	if (ret < 0)
1743		goto out;
1744
1745	ret = wl12xx_roc(wl, wlvif, wlvif->dev_role_id);
1746	if (ret < 0)
1747		goto out_stop;
1748
1749	return 0;
1750
1751out_stop:
1752	wl12xx_cmd_role_stop_dev(wl, wlvif);
1753out:
1754	return ret;
1755}
1756
1757/* croc dev hlid, and stop the role */
1758int wl12xx_stop_dev(struct wl1271 *wl, struct wl12xx_vif *wlvif)
1759{
1760	int ret;
1761
1762	if (WARN_ON(!(wlvif->bss_type == BSS_TYPE_STA_BSS ||
1763		      wlvif->bss_type == BSS_TYPE_IBSS)))
1764		return -EINVAL;
1765
1766	/* flush all pending packets */
1767	wl1271_tx_work_locked(wl);
1768
1769	if (test_bit(wlvif->dev_role_id, wl->roc_map)) {
1770		ret = wl12xx_croc(wl, wlvif->dev_role_id);
1771		if (ret < 0)
1772			goto out;
1773	}
1774
1775	ret = wl12xx_cmd_role_stop_dev(wl, wlvif);
1776	if (ret < 0)
1777		goto out;
1778out:
1779	return ret;
1780}
1781