1// SPDX-License-Identifier: GPL-2.0-only
2/*
3 * This file contains the handling of command.
4 * It prepares command and sends it to firmware when it is ready.
5 */
6
7#include <linux/hardirq.h>
8#include <linux/kfifo.h>
9#include <linux/sched.h>
10#include <linux/slab.h>
11#include <linux/if_arp.h>
12#include <linux/export.h>
13
14#include "decl.h"
15#include "cfg.h"
16#include "cmd.h"
17
18#define CAL_NF(nf)		((s32)(-(s32)(nf)))
19#define CAL_RSSI(snr, nf)	((s32)((s32)(snr) + CAL_NF(nf)))
20
21/**
22 * lbs_cmd_copyback - Simple callback that copies response back into command
23 *
24 * @priv:	A pointer to &struct lbs_private structure
25 * @extra:	A pointer to the original command structure for which
26 *		'resp' is a response
27 * @resp:	A pointer to the command response
28 *
29 * returns:	0 on success, error on failure
30 */
31int lbs_cmd_copyback(struct lbs_private *priv, unsigned long extra,
32		     struct cmd_header *resp)
33{
34	struct cmd_header *buf = (void *)extra;
35	uint16_t copy_len;
36
37	copy_len = min(le16_to_cpu(buf->size), le16_to_cpu(resp->size));
38	memcpy(buf, resp, copy_len);
39	return 0;
40}
41EXPORT_SYMBOL_GPL(lbs_cmd_copyback);
42
43/**
44 *  lbs_cmd_async_callback - Simple callback that ignores the result.
45 *  Use this if you just want to send a command to the hardware, but don't
46 *  care for the result.
47 *
48 *  @priv:	ignored
49 *  @extra:	ignored
50 *  @resp:	ignored
51 *
52 *  returns:	0 for success
53 */
54static int lbs_cmd_async_callback(struct lbs_private *priv, unsigned long extra,
55		     struct cmd_header *resp)
56{
57	return 0;
58}
59
60
61/**
62 *  is_command_allowed_in_ps - tests if a command is allowed in Power Save mode
63 *
64 *  @cmd:	the command ID
65 *
66 *  returns:	1 if allowed, 0 if not allowed
67 */
68static u8 is_command_allowed_in_ps(u16 cmd)
69{
70	switch (cmd) {
71	case CMD_802_11_RSSI:
72		return 1;
73	case CMD_802_11_HOST_SLEEP_CFG:
74		return 1;
75	default:
76		break;
77	}
78	return 0;
79}
80
81/**
82 *  lbs_update_hw_spec - Updates the hardware details like MAC address
83 *  and regulatory region
84 *
85 *  @priv:	A pointer to &struct lbs_private structure
86 *
87 *  returns:	0 on success, error on failure
88 */
89int lbs_update_hw_spec(struct lbs_private *priv)
90{
91	struct cmd_ds_get_hw_spec cmd;
92	int ret = -1;
93	u32 i;
94
95	memset(&cmd, 0, sizeof(cmd));
96	cmd.hdr.size = cpu_to_le16(sizeof(cmd));
97	memcpy(cmd.permanentaddr, priv->current_addr, ETH_ALEN);
98	ret = lbs_cmd_with_response(priv, CMD_GET_HW_SPEC, &cmd);
99	if (ret)
100		goto out;
101
102	priv->fwcapinfo = le32_to_cpu(cmd.fwcapinfo);
103
104	/* The firmware release is in an interesting format: the patch
105	 * level is in the most significant nibble ... so fix that: */
106	priv->fwrelease = le32_to_cpu(cmd.fwrelease);
107	priv->fwrelease = (priv->fwrelease << 8) |
108		(priv->fwrelease >> 24 & 0xff);
109
110	/* Some firmware capabilities:
111	 * CF card    firmware 5.0.16p0:   cap 0x00000303
112	 * USB dongle firmware 5.110.17p2: cap 0x00000303
113	 */
114	netdev_info(priv->dev, "%pM, fw %u.%u.%up%u, cap 0x%08x\n",
115		cmd.permanentaddr,
116		priv->fwrelease >> 24 & 0xff,
117		priv->fwrelease >> 16 & 0xff,
118		priv->fwrelease >>  8 & 0xff,
119		priv->fwrelease       & 0xff,
120		priv->fwcapinfo);
121	lbs_deb_cmd("GET_HW_SPEC: hardware interface 0x%x, hardware spec 0x%04x\n",
122		    cmd.hwifversion, cmd.version);
123
124	/* Clamp region code to 8-bit since FW spec indicates that it should
125	 * only ever be 8-bit, even though the field size is 16-bit.  Some firmware
126	 * returns non-zero high 8 bits here.
127	 *
128	 * Firmware version 4.0.102 used in CF8381 has region code shifted.  We
129	 * need to check for this problem and handle it properly.
130	 */
131	if (MRVL_FW_MAJOR_REV(priv->fwrelease) == MRVL_FW_V4)
132		priv->regioncode = (le16_to_cpu(cmd.regioncode) >> 8) & 0xFF;
133	else
134		priv->regioncode = le16_to_cpu(cmd.regioncode) & 0xFF;
135
136	for (i = 0; i < MRVDRV_MAX_REGION_CODE; i++) {
137		/* use the region code to search for the index */
138		if (priv->regioncode == lbs_region_code_to_index[i])
139			break;
140	}
141
142	/* if it's unidentified region code, use the default (USA) */
143	if (i >= MRVDRV_MAX_REGION_CODE) {
144		priv->regioncode = 0x10;
145		netdev_info(priv->dev,
146			    "unidentified region code; using the default (USA)\n");
147	}
148
149	if (priv->current_addr[0] == 0xff)
150		memmove(priv->current_addr, cmd.permanentaddr, ETH_ALEN);
151
152	if (!priv->copied_hwaddr) {
153		eth_hw_addr_set(priv->dev, priv->current_addr);
154		if (priv->mesh_dev)
155			eth_hw_addr_set(priv->mesh_dev, priv->current_addr);
156		priv->copied_hwaddr = 1;
157	}
158
159out:
160	return ret;
161}
162
163static int lbs_ret_host_sleep_cfg(struct lbs_private *priv, unsigned long dummy,
164			struct cmd_header *resp)
165{
166	if (priv->is_host_sleep_activated) {
167		priv->is_host_sleep_configured = 0;
168		if (priv->psstate == PS_STATE_FULL_POWER) {
169			priv->is_host_sleep_activated = 0;
170			wake_up_interruptible(&priv->host_sleep_q);
171		}
172	} else {
173		priv->is_host_sleep_configured = 1;
174	}
175
176	return 0;
177}
178
179int lbs_host_sleep_cfg(struct lbs_private *priv, uint32_t criteria,
180		struct wol_config *p_wol_config)
181{
182	struct cmd_ds_host_sleep cmd_config;
183	int ret;
184
185	/*
186	 * Certain firmware versions do not support EHS_REMOVE_WAKEUP command
187	 * and the card will return a failure.  Since we need to be
188	 * able to reset the mask, in those cases we set a 0 mask instead.
189	 */
190	if (criteria == EHS_REMOVE_WAKEUP && !priv->ehs_remove_supported)
191		criteria = 0;
192
193	cmd_config.hdr.size = cpu_to_le16(sizeof(cmd_config));
194	cmd_config.criteria = cpu_to_le32(criteria);
195	cmd_config.gpio = priv->wol_gpio;
196	cmd_config.gap = priv->wol_gap;
197
198	if (p_wol_config != NULL)
199		memcpy((uint8_t *)&cmd_config.wol_conf, (uint8_t *)p_wol_config,
200				sizeof(struct wol_config));
201	else
202		cmd_config.wol_conf.action = CMD_ACT_ACTION_NONE;
203
204	ret = __lbs_cmd(priv, CMD_802_11_HOST_SLEEP_CFG, &cmd_config.hdr,
205			le16_to_cpu(cmd_config.hdr.size),
206			lbs_ret_host_sleep_cfg, 0);
207	if (!ret) {
208		if (p_wol_config)
209			memcpy((uint8_t *) p_wol_config,
210					(uint8_t *)&cmd_config.wol_conf,
211					sizeof(struct wol_config));
212	} else {
213		netdev_info(priv->dev, "HOST_SLEEP_CFG failed %d\n", ret);
214	}
215
216	return ret;
217}
218EXPORT_SYMBOL_GPL(lbs_host_sleep_cfg);
219
220/**
221 *  lbs_set_ps_mode - Sets the Power Save mode
222 *
223 *  @priv:	A pointer to &struct lbs_private structure
224 *  @cmd_action: The Power Save operation (PS_MODE_ACTION_ENTER_PS or
225 *                         PS_MODE_ACTION_EXIT_PS)
226 *  @block:	Whether to block on a response or not
227 *
228 *  returns:	0 on success, error on failure
229 */
230int lbs_set_ps_mode(struct lbs_private *priv, u16 cmd_action, bool block)
231{
232	struct cmd_ds_802_11_ps_mode cmd;
233	int ret = 0;
234
235	memset(&cmd, 0, sizeof(cmd));
236	cmd.hdr.size = cpu_to_le16(sizeof(cmd));
237	cmd.action = cpu_to_le16(cmd_action);
238
239	if (cmd_action == PS_MODE_ACTION_ENTER_PS) {
240		lbs_deb_cmd("PS_MODE: action ENTER_PS\n");
241		cmd.multipledtim = cpu_to_le16(1);  /* Default DTIM multiple */
242	} else if (cmd_action == PS_MODE_ACTION_EXIT_PS) {
243		lbs_deb_cmd("PS_MODE: action EXIT_PS\n");
244	} else {
245		/* We don't handle CONFIRM_SLEEP here because it needs to
246		 * be fastpathed to the firmware.
247		 */
248		lbs_deb_cmd("PS_MODE: unknown action 0x%X\n", cmd_action);
249		ret = -EOPNOTSUPP;
250		goto out;
251	}
252
253	if (block)
254		ret = lbs_cmd_with_response(priv, CMD_802_11_PS_MODE, &cmd);
255	else
256		lbs_cmd_async(priv, CMD_802_11_PS_MODE, &cmd.hdr, sizeof (cmd));
257
258out:
259	return ret;
260}
261
262int lbs_cmd_802_11_sleep_params(struct lbs_private *priv, uint16_t cmd_action,
263				struct sleep_params *sp)
264{
265	struct cmd_ds_802_11_sleep_params cmd;
266	int ret;
267
268	if (cmd_action == CMD_ACT_GET) {
269		memset(&cmd, 0, sizeof(cmd));
270	} else {
271		cmd.error = cpu_to_le16(sp->sp_error);
272		cmd.offset = cpu_to_le16(sp->sp_offset);
273		cmd.stabletime = cpu_to_le16(sp->sp_stabletime);
274		cmd.calcontrol = sp->sp_calcontrol;
275		cmd.externalsleepclk = sp->sp_extsleepclk;
276		cmd.reserved = cpu_to_le16(sp->sp_reserved);
277	}
278	cmd.hdr.size = cpu_to_le16(sizeof(cmd));
279	cmd.action = cpu_to_le16(cmd_action);
280
281	ret = lbs_cmd_with_response(priv, CMD_802_11_SLEEP_PARAMS, &cmd);
282
283	if (!ret) {
284		lbs_deb_cmd("error 0x%x, offset 0x%x, stabletime 0x%x, "
285			    "calcontrol 0x%x extsleepclk 0x%x\n",
286			    le16_to_cpu(cmd.error), le16_to_cpu(cmd.offset),
287			    le16_to_cpu(cmd.stabletime), cmd.calcontrol,
288			    cmd.externalsleepclk);
289
290		sp->sp_error = le16_to_cpu(cmd.error);
291		sp->sp_offset = le16_to_cpu(cmd.offset);
292		sp->sp_stabletime = le16_to_cpu(cmd.stabletime);
293		sp->sp_calcontrol = cmd.calcontrol;
294		sp->sp_extsleepclk = cmd.externalsleepclk;
295		sp->sp_reserved = le16_to_cpu(cmd.reserved);
296	}
297
298	return ret;
299}
300
301static int lbs_wait_for_ds_awake(struct lbs_private *priv)
302{
303	int ret = 0;
304
305	if (priv->is_deep_sleep) {
306		if (!wait_event_interruptible_timeout(priv->ds_awake_q,
307					!priv->is_deep_sleep, (10 * HZ))) {
308			netdev_err(priv->dev, "ds_awake_q: timer expired\n");
309			ret = -1;
310		}
311	}
312
313	return ret;
314}
315
316int lbs_set_deep_sleep(struct lbs_private *priv, int deep_sleep)
317{
318	int ret =  0;
319
320	if (deep_sleep) {
321		if (priv->is_deep_sleep != 1) {
322			lbs_deb_cmd("deep sleep: sleep\n");
323			BUG_ON(!priv->enter_deep_sleep);
324			ret = priv->enter_deep_sleep(priv);
325			if (!ret) {
326				netif_stop_queue(priv->dev);
327				netif_carrier_off(priv->dev);
328			}
329		} else {
330			netdev_err(priv->dev, "deep sleep: already enabled\n");
331		}
332	} else {
333		if (priv->is_deep_sleep) {
334			lbs_deb_cmd("deep sleep: wakeup\n");
335			BUG_ON(!priv->exit_deep_sleep);
336			ret = priv->exit_deep_sleep(priv);
337			if (!ret) {
338				ret = lbs_wait_for_ds_awake(priv);
339				if (ret)
340					netdev_err(priv->dev,
341						   "deep sleep: wakeup failed\n");
342			}
343		}
344	}
345
346	return ret;
347}
348
349static int lbs_ret_host_sleep_activate(struct lbs_private *priv,
350		unsigned long dummy,
351		struct cmd_header *cmd)
352{
353	priv->is_host_sleep_activated = 1;
354	wake_up_interruptible(&priv->host_sleep_q);
355
356	return 0;
357}
358
359int lbs_set_host_sleep(struct lbs_private *priv, int host_sleep)
360{
361	struct cmd_header cmd;
362	int ret = 0;
363	uint32_t criteria = EHS_REMOVE_WAKEUP;
364
365	if (host_sleep) {
366		if (priv->is_host_sleep_activated != 1) {
367			memset(&cmd, 0, sizeof(cmd));
368			ret = lbs_host_sleep_cfg(priv, priv->wol_criteria,
369					(struct wol_config *)NULL);
370			if (ret) {
371				netdev_info(priv->dev,
372					    "Host sleep configuration failed: %d\n",
373					    ret);
374				return ret;
375			}
376			if (priv->psstate == PS_STATE_FULL_POWER) {
377				ret = __lbs_cmd(priv,
378						CMD_802_11_HOST_SLEEP_ACTIVATE,
379						&cmd,
380						sizeof(cmd),
381						lbs_ret_host_sleep_activate, 0);
382				if (ret)
383					netdev_info(priv->dev,
384						    "HOST_SLEEP_ACTIVATE failed: %d\n",
385						    ret);
386			}
387
388			if (!wait_event_interruptible_timeout(
389						priv->host_sleep_q,
390						priv->is_host_sleep_activated,
391						(10 * HZ))) {
392				netdev_err(priv->dev,
393					   "host_sleep_q: timer expired\n");
394				ret = -1;
395			}
396		} else {
397			netdev_err(priv->dev, "host sleep: already enabled\n");
398		}
399	} else {
400		if (priv->is_host_sleep_activated)
401			ret = lbs_host_sleep_cfg(priv, criteria,
402					(struct wol_config *)NULL);
403	}
404
405	return ret;
406}
407
408/**
409 *  lbs_set_snmp_mib - Set an SNMP MIB value
410 *
411 *  @priv:	A pointer to &struct lbs_private structure
412 *  @oid:	The OID to set in the firmware
413 *  @val:	Value to set the OID to
414 *
415 *  returns: 	   	0 on success, error on failure
416 */
417int lbs_set_snmp_mib(struct lbs_private *priv, u32 oid, u16 val)
418{
419	struct cmd_ds_802_11_snmp_mib cmd;
420	int ret;
421
422	memset(&cmd, 0, sizeof (cmd));
423	cmd.hdr.size = cpu_to_le16(sizeof(cmd));
424	cmd.action = cpu_to_le16(CMD_ACT_SET);
425	cmd.oid = cpu_to_le16((u16) oid);
426
427	switch (oid) {
428	case SNMP_MIB_OID_BSS_TYPE:
429		cmd.bufsize = cpu_to_le16(sizeof(u8));
430		cmd.value[0] = val;
431		break;
432	case SNMP_MIB_OID_11D_ENABLE:
433	case SNMP_MIB_OID_FRAG_THRESHOLD:
434	case SNMP_MIB_OID_RTS_THRESHOLD:
435	case SNMP_MIB_OID_SHORT_RETRY_LIMIT:
436	case SNMP_MIB_OID_LONG_RETRY_LIMIT:
437		cmd.bufsize = cpu_to_le16(sizeof(u16));
438		*((__le16 *)(&cmd.value)) = cpu_to_le16(val);
439		break;
440	default:
441		lbs_deb_cmd("SNMP_CMD: (set) unhandled OID 0x%x\n", oid);
442		ret = -EINVAL;
443		goto out;
444	}
445
446	lbs_deb_cmd("SNMP_CMD: (set) oid 0x%x, oid size 0x%x, value 0x%x\n",
447		    le16_to_cpu(cmd.oid), le16_to_cpu(cmd.bufsize), val);
448
449	ret = lbs_cmd_with_response(priv, CMD_802_11_SNMP_MIB, &cmd);
450
451out:
452	return ret;
453}
454
455/**
456 *  lbs_get_snmp_mib - Get an SNMP MIB value
457 *
458 *  @priv:	A pointer to &struct lbs_private structure
459 *  @oid:	The OID to retrieve from the firmware
460 *  @out_val:	Location for the returned value
461 *
462 *  returns:	0 on success, error on failure
463 */
464int lbs_get_snmp_mib(struct lbs_private *priv, u32 oid, u16 *out_val)
465{
466	struct cmd_ds_802_11_snmp_mib cmd;
467	int ret;
468
469	memset(&cmd, 0, sizeof (cmd));
470	cmd.hdr.size = cpu_to_le16(sizeof(cmd));
471	cmd.action = cpu_to_le16(CMD_ACT_GET);
472	cmd.oid = cpu_to_le16(oid);
473
474	ret = lbs_cmd_with_response(priv, CMD_802_11_SNMP_MIB, &cmd);
475	if (ret)
476		goto out;
477
478	switch (le16_to_cpu(cmd.bufsize)) {
479	case sizeof(u8):
480		*out_val = cmd.value[0];
481		break;
482	case sizeof(u16):
483		*out_val = le16_to_cpu(*((__le16 *)(&cmd.value)));
484		break;
485	default:
486		lbs_deb_cmd("SNMP_CMD: (get) unhandled OID 0x%x size %d\n",
487		            oid, le16_to_cpu(cmd.bufsize));
488		break;
489	}
490
491out:
492	return ret;
493}
494
495/**
496 *  lbs_get_tx_power - Get the min, max, and current TX power
497 *
498 *  @priv:	A pointer to &struct lbs_private structure
499 *  @curlevel:	Current power level in dBm
500 *  @minlevel:	Minimum supported power level in dBm (optional)
501 *  @maxlevel:	Maximum supported power level in dBm (optional)
502 *
503 *  returns:	0 on success, error on failure
504 */
505int lbs_get_tx_power(struct lbs_private *priv, s16 *curlevel, s16 *minlevel,
506		     s16 *maxlevel)
507{
508	struct cmd_ds_802_11_rf_tx_power cmd;
509	int ret;
510
511	memset(&cmd, 0, sizeof(cmd));
512	cmd.hdr.size = cpu_to_le16(sizeof(cmd));
513	cmd.action = cpu_to_le16(CMD_ACT_GET);
514
515	ret = lbs_cmd_with_response(priv, CMD_802_11_RF_TX_POWER, &cmd);
516	if (ret == 0) {
517		*curlevel = le16_to_cpu(cmd.curlevel);
518		if (minlevel)
519			*minlevel = cmd.minlevel;
520		if (maxlevel)
521			*maxlevel = cmd.maxlevel;
522	}
523
524	return ret;
525}
526
527/**
528 *  lbs_set_tx_power - Set the TX power
529 *
530 *  @priv:	A pointer to &struct lbs_private structure
531 *  @dbm:	The desired power level in dBm
532 *
533 *  returns: 	   	0 on success, error on failure
534 */
535int lbs_set_tx_power(struct lbs_private *priv, s16 dbm)
536{
537	struct cmd_ds_802_11_rf_tx_power cmd;
538	int ret;
539
540	memset(&cmd, 0, sizeof(cmd));
541	cmd.hdr.size = cpu_to_le16(sizeof(cmd));
542	cmd.action = cpu_to_le16(CMD_ACT_SET);
543	cmd.curlevel = cpu_to_le16(dbm);
544
545	lbs_deb_cmd("SET_RF_TX_POWER: %d dBm\n", dbm);
546
547	ret = lbs_cmd_with_response(priv, CMD_802_11_RF_TX_POWER, &cmd);
548
549	return ret;
550}
551
552/**
553 *  lbs_set_monitor_mode - Enable or disable monitor mode
554 *  (only implemented on OLPC usb8388 FW)
555 *
556 *  @priv:	A pointer to &struct lbs_private structure
557 *  @enable:	1 to enable monitor mode, 0 to disable
558 *
559 *  returns:	0 on success, error on failure
560 */
561int lbs_set_monitor_mode(struct lbs_private *priv, int enable)
562{
563	struct cmd_ds_802_11_monitor_mode cmd;
564	int ret;
565
566	memset(&cmd, 0, sizeof(cmd));
567	cmd.hdr.size = cpu_to_le16(sizeof(cmd));
568	cmd.action = cpu_to_le16(CMD_ACT_SET);
569	if (enable)
570		cmd.mode = cpu_to_le16(0x1);
571
572	lbs_deb_cmd("SET_MONITOR_MODE: %d\n", enable);
573
574	ret = lbs_cmd_with_response(priv, CMD_802_11_MONITOR_MODE, &cmd);
575	if (ret == 0) {
576		priv->dev->type = enable ? ARPHRD_IEEE80211_RADIOTAP :
577						ARPHRD_ETHER;
578	}
579
580	return ret;
581}
582
583/**
584 *  lbs_get_channel - Get the radio channel
585 *
586 *  @priv:	A pointer to &struct lbs_private structure
587 *
588 *  returns:	The channel on success, error on failure
589 */
590static int lbs_get_channel(struct lbs_private *priv)
591{
592	struct cmd_ds_802_11_rf_channel cmd;
593	int ret = 0;
594
595	memset(&cmd, 0, sizeof(cmd));
596	cmd.hdr.size = cpu_to_le16(sizeof(cmd));
597	cmd.action = cpu_to_le16(CMD_OPT_802_11_RF_CHANNEL_GET);
598
599	ret = lbs_cmd_with_response(priv, CMD_802_11_RF_CHANNEL, &cmd);
600	if (ret)
601		goto out;
602
603	ret = le16_to_cpu(cmd.channel);
604	lbs_deb_cmd("current radio channel is %d\n", ret);
605
606out:
607	return ret;
608}
609
610int lbs_update_channel(struct lbs_private *priv)
611{
612	int ret;
613
614	/* the channel in f/w could be out of sync; get the current channel */
615	ret = lbs_get_channel(priv);
616	if (ret > 0) {
617		priv->channel = ret;
618		ret = 0;
619	}
620
621	return ret;
622}
623
624/**
625 *  lbs_set_channel - Set the radio channel
626 *
627 *  @priv:	A pointer to &struct lbs_private structure
628 *  @channel:	The desired channel, or 0 to clear a locked channel
629 *
630 *  returns:	0 on success, error on failure
631 */
632int lbs_set_channel(struct lbs_private *priv, u8 channel)
633{
634	struct cmd_ds_802_11_rf_channel cmd;
635#ifdef DEBUG
636	u8 old_channel = priv->channel;
637#endif
638	int ret = 0;
639
640	memset(&cmd, 0, sizeof(cmd));
641	cmd.hdr.size = cpu_to_le16(sizeof(cmd));
642	cmd.action = cpu_to_le16(CMD_OPT_802_11_RF_CHANNEL_SET);
643	cmd.channel = cpu_to_le16(channel);
644
645	ret = lbs_cmd_with_response(priv, CMD_802_11_RF_CHANNEL, &cmd);
646	if (ret)
647		goto out;
648
649	priv->channel = (uint8_t) le16_to_cpu(cmd.channel);
650	lbs_deb_cmd("channel switch from %d to %d\n", old_channel,
651		priv->channel);
652
653out:
654	return ret;
655}
656
657/**
658 * lbs_get_rssi - Get current RSSI and noise floor
659 *
660 * @priv:	A pointer to &struct lbs_private structure
661 * @rssi:	On successful return, signal level in mBm
662 * @nf:		On successful return, Noise floor
663 *
664 * returns:	The channel on success, error on failure
665 */
666int lbs_get_rssi(struct lbs_private *priv, s8 *rssi, s8 *nf)
667{
668	struct cmd_ds_802_11_rssi cmd;
669	int ret = 0;
670
671	BUG_ON(rssi == NULL);
672	BUG_ON(nf == NULL);
673
674	memset(&cmd, 0, sizeof(cmd));
675	cmd.hdr.size = cpu_to_le16(sizeof(cmd));
676	/* Average SNR over last 8 beacons */
677	cmd.n_or_snr = cpu_to_le16(8);
678
679	ret = lbs_cmd_with_response(priv, CMD_802_11_RSSI, &cmd);
680	if (ret == 0) {
681		*nf = CAL_NF(le16_to_cpu(cmd.nf));
682		*rssi = CAL_RSSI(le16_to_cpu(cmd.n_or_snr), le16_to_cpu(cmd.nf));
683	}
684
685	return ret;
686}
687
688/**
689 *  lbs_set_11d_domain_info - Send regulatory and 802.11d domain information
690 *  to the firmware
691 *
692 *  @priv:	pointer to &struct lbs_private
693 *
694 *  returns:	0 on success, error code on failure
695*/
696int lbs_set_11d_domain_info(struct lbs_private *priv)
697{
698	struct wiphy *wiphy = priv->wdev->wiphy;
699	struct ieee80211_supported_band **bands = wiphy->bands;
700	struct cmd_ds_802_11d_domain_info cmd;
701	struct mrvl_ie_domain_param_set *domain = &cmd.domain;
702	struct ieee80211_country_ie_triplet *t;
703	enum nl80211_band band;
704	struct ieee80211_channel *ch;
705	u8 num_triplet = 0;
706	u8 num_parsed_chan = 0;
707	u8 first_channel = 0, next_chan = 0, max_pwr = 0;
708	u8 i, flag = 0;
709	size_t triplet_size;
710	int ret = 0;
711
712	if (!priv->country_code[0])
713		goto out;
714
715	memset(&cmd, 0, sizeof(cmd));
716	cmd.action = cpu_to_le16(CMD_ACT_SET);
717
718	lbs_deb_11d("Setting country code '%c%c'\n",
719		    priv->country_code[0], priv->country_code[1]);
720
721	domain->header.type = cpu_to_le16(TLV_TYPE_DOMAIN);
722
723	/* Set country code */
724	domain->country_code[0] = priv->country_code[0];
725	domain->country_code[1] = priv->country_code[1];
726	domain->country_code[2] = ' ';
727
728	/* Now set up the channel triplets; firmware is somewhat picky here
729	 * and doesn't validate channel numbers and spans; hence it would
730	 * interpret a triplet of (36, 4, 20) as channels 36, 37, 38, 39.  Since
731	 * the last 3 aren't valid channels, the driver is responsible for
732	 * splitting that up into 4 triplet pairs of (36, 1, 20) + (40, 1, 20)
733	 * etc.
734	 */
735	for (band = 0;
736	     (band < NUM_NL80211_BANDS) && (num_triplet < MAX_11D_TRIPLETS);
737	     band++) {
738
739		if (!bands[band])
740			continue;
741
742		for (i = 0;
743		     (i < bands[band]->n_channels) && (num_triplet < MAX_11D_TRIPLETS);
744		     i++) {
745			ch = &bands[band]->channels[i];
746			if (ch->flags & IEEE80211_CHAN_DISABLED)
747				continue;
748
749			if (!flag) {
750				flag = 1;
751				next_chan = first_channel = (u32) ch->hw_value;
752				max_pwr = ch->max_power;
753				num_parsed_chan = 1;
754				continue;
755			}
756
757			if ((ch->hw_value == next_chan + 1) &&
758					(ch->max_power == max_pwr)) {
759				/* Consolidate adjacent channels */
760				next_chan++;
761				num_parsed_chan++;
762			} else {
763				/* Add this triplet */
764				lbs_deb_11d("11D triplet (%d, %d, %d)\n",
765					first_channel, num_parsed_chan,
766					max_pwr);
767				t = &domain->triplet[num_triplet];
768				t->chans.first_channel = first_channel;
769				t->chans.num_channels = num_parsed_chan;
770				t->chans.max_power = max_pwr;
771				num_triplet++;
772				flag = 0;
773			}
774		}
775
776		if (flag) {
777			/* Add last triplet */
778			lbs_deb_11d("11D triplet (%d, %d, %d)\n", first_channel,
779				num_parsed_chan, max_pwr);
780			t = &domain->triplet[num_triplet];
781			t->chans.first_channel = first_channel;
782			t->chans.num_channels = num_parsed_chan;
783			t->chans.max_power = max_pwr;
784			num_triplet++;
785		}
786	}
787
788	lbs_deb_11d("# triplets %d\n", num_triplet);
789
790	/* Set command header sizes */
791	triplet_size = num_triplet * sizeof(struct ieee80211_country_ie_triplet);
792	domain->header.len = cpu_to_le16(sizeof(domain->country_code) +
793					triplet_size);
794
795	lbs_deb_hex(LBS_DEB_11D, "802.11D domain param set",
796			(u8 *) &cmd.domain.country_code,
797			le16_to_cpu(domain->header.len));
798
799	cmd.hdr.size = cpu_to_le16(sizeof(cmd.hdr) +
800				   sizeof(cmd.action) +
801				   sizeof(cmd.domain.header) +
802				   sizeof(cmd.domain.country_code) +
803				   triplet_size);
804
805	ret = lbs_cmd_with_response(priv, CMD_802_11D_DOMAIN_INFO, &cmd);
806
807out:
808	return ret;
809}
810
811/**
812 *  lbs_get_reg - Read a MAC, Baseband, or RF register
813 *
814 *  @priv:	pointer to &struct lbs_private
815 *  @reg:	register command, one of CMD_MAC_REG_ACCESS,
816 *		CMD_BBP_REG_ACCESS, or CMD_RF_REG_ACCESS
817 *  @offset:	byte offset of the register to get
818 *  @value:	on success, the value of the register at 'offset'
819 *
820 *  returns:	0 on success, error code on failure
821*/
822int lbs_get_reg(struct lbs_private *priv, u16 reg, u16 offset, u32 *value)
823{
824	struct cmd_ds_reg_access cmd;
825	int ret = 0;
826
827	BUG_ON(value == NULL);
828
829	memset(&cmd, 0, sizeof(cmd));
830	cmd.hdr.size = cpu_to_le16(sizeof(cmd));
831	cmd.action = cpu_to_le16(CMD_ACT_GET);
832	cmd.offset = cpu_to_le16(offset);
833
834	if (reg != CMD_MAC_REG_ACCESS &&
835	    reg != CMD_BBP_REG_ACCESS &&
836	    reg != CMD_RF_REG_ACCESS) {
837		ret = -EINVAL;
838		goto out;
839	}
840
841	ret = lbs_cmd_with_response(priv, reg, &cmd);
842	if (!ret) {
843		if (reg == CMD_BBP_REG_ACCESS || reg == CMD_RF_REG_ACCESS)
844			*value = cmd.value.bbp_rf;
845		else if (reg == CMD_MAC_REG_ACCESS)
846			*value = le32_to_cpu(cmd.value.mac);
847	}
848
849out:
850	return ret;
851}
852
853/**
854 *  lbs_set_reg - Write a MAC, Baseband, or RF register
855 *
856 *  @priv:	pointer to &struct lbs_private
857 *  @reg:	register command, one of CMD_MAC_REG_ACCESS,
858 *		CMD_BBP_REG_ACCESS, or CMD_RF_REG_ACCESS
859 *  @offset:	byte offset of the register to set
860 *  @value:	the value to write to the register at 'offset'
861 *
862 *  returns:	0 on success, error code on failure
863*/
864int lbs_set_reg(struct lbs_private *priv, u16 reg, u16 offset, u32 value)
865{
866	struct cmd_ds_reg_access cmd;
867	int ret = 0;
868
869	memset(&cmd, 0, sizeof(cmd));
870	cmd.hdr.size = cpu_to_le16(sizeof(cmd));
871	cmd.action = cpu_to_le16(CMD_ACT_SET);
872	cmd.offset = cpu_to_le16(offset);
873
874	if (reg == CMD_BBP_REG_ACCESS || reg == CMD_RF_REG_ACCESS)
875		cmd.value.bbp_rf = (u8) (value & 0xFF);
876	else if (reg == CMD_MAC_REG_ACCESS)
877		cmd.value.mac = cpu_to_le32(value);
878	else {
879		ret = -EINVAL;
880		goto out;
881	}
882
883	ret = lbs_cmd_with_response(priv, reg, &cmd);
884
885out:
886	return ret;
887}
888
889static void lbs_queue_cmd(struct lbs_private *priv,
890			  struct cmd_ctrl_node *cmdnode)
891{
892	unsigned long flags;
893	int addtail = 1;
894
895	if (!cmdnode) {
896		lbs_deb_host("QUEUE_CMD: cmdnode is NULL\n");
897		return;
898	}
899	if (!cmdnode->cmdbuf->size) {
900		lbs_deb_host("DNLD_CMD: cmd size is zero\n");
901		return;
902	}
903	cmdnode->result = 0;
904
905	/* Exit_PS command needs to be queued in the header always. */
906	if (le16_to_cpu(cmdnode->cmdbuf->command) == CMD_802_11_PS_MODE) {
907		struct cmd_ds_802_11_ps_mode *psm = (void *)cmdnode->cmdbuf;
908
909		if (psm->action == cpu_to_le16(PS_MODE_ACTION_EXIT_PS)) {
910			if (priv->psstate != PS_STATE_FULL_POWER)
911				addtail = 0;
912		}
913	}
914
915	if (le16_to_cpu(cmdnode->cmdbuf->command) == CMD_802_11_WAKEUP_CONFIRM)
916		addtail = 0;
917
918	spin_lock_irqsave(&priv->driver_lock, flags);
919
920	if (addtail)
921		list_add_tail(&cmdnode->list, &priv->cmdpendingq);
922	else
923		list_add(&cmdnode->list, &priv->cmdpendingq);
924
925	spin_unlock_irqrestore(&priv->driver_lock, flags);
926
927	lbs_deb_host("QUEUE_CMD: inserted command 0x%04x into cmdpendingq\n",
928		     le16_to_cpu(cmdnode->cmdbuf->command));
929}
930
931static void lbs_submit_command(struct lbs_private *priv,
932			       struct cmd_ctrl_node *cmdnode)
933{
934	unsigned long flags;
935	struct cmd_header *cmd;
936	uint16_t cmdsize;
937	uint16_t command;
938	int timeo = 3 * HZ;
939	int ret;
940
941	cmd = cmdnode->cmdbuf;
942
943	spin_lock_irqsave(&priv->driver_lock, flags);
944	priv->seqnum++;
945	cmd->seqnum = cpu_to_le16(priv->seqnum);
946	priv->cur_cmd = cmdnode;
947	spin_unlock_irqrestore(&priv->driver_lock, flags);
948
949	cmdsize = le16_to_cpu(cmd->size);
950	command = le16_to_cpu(cmd->command);
951
952	/* These commands take longer */
953	if (command == CMD_802_11_SCAN || command == CMD_802_11_ASSOCIATE)
954		timeo = 5 * HZ;
955
956	lbs_deb_cmd("DNLD_CMD: command 0x%04x, seq %d, size %d\n",
957		     command, le16_to_cpu(cmd->seqnum), cmdsize);
958	lbs_deb_hex(LBS_DEB_CMD, "DNLD_CMD", (void *) cmdnode->cmdbuf, cmdsize);
959
960	ret = priv->hw_host_to_card(priv, MVMS_CMD, (u8 *) cmd, cmdsize);
961
962	if (ret) {
963		netdev_info(priv->dev, "DNLD_CMD: hw_host_to_card failed: %d\n",
964			    ret);
965		/* Reset dnld state machine, report failure */
966		priv->dnld_sent = DNLD_RES_RECEIVED;
967		lbs_complete_command(priv, cmdnode, ret);
968	}
969
970	if (command == CMD_802_11_DEEP_SLEEP) {
971		if (priv->is_auto_deep_sleep_enabled) {
972			priv->wakeup_dev_required = 1;
973			priv->dnld_sent = 0;
974		}
975		priv->is_deep_sleep = 1;
976		lbs_complete_command(priv, cmdnode, 0);
977	} else {
978		/* Setup the timer after transmit command */
979		mod_timer(&priv->command_timer, jiffies + timeo);
980	}
981}
982
983/*
984 *  This function inserts command node to cmdfreeq
985 *  after cleans it. Requires priv->driver_lock held.
986 */
987static void __lbs_cleanup_and_insert_cmd(struct lbs_private *priv,
988					 struct cmd_ctrl_node *cmdnode)
989{
990	if (!cmdnode)
991		return;
992
993	cmdnode->callback = NULL;
994	cmdnode->callback_arg = 0;
995
996	memset(cmdnode->cmdbuf, 0, LBS_CMD_BUFFER_SIZE);
997
998	list_add_tail(&cmdnode->list, &priv->cmdfreeq);
999}
1000
1001static void lbs_cleanup_and_insert_cmd(struct lbs_private *priv,
1002	struct cmd_ctrl_node *ptempcmd)
1003{
1004	unsigned long flags;
1005
1006	spin_lock_irqsave(&priv->driver_lock, flags);
1007	__lbs_cleanup_and_insert_cmd(priv, ptempcmd);
1008	spin_unlock_irqrestore(&priv->driver_lock, flags);
1009}
1010
1011void __lbs_complete_command(struct lbs_private *priv, struct cmd_ctrl_node *cmd,
1012			    int result)
1013{
1014	/*
1015	 * Normally, commands are removed from cmdpendingq before being
1016	 * submitted. However, we can arrive here on alternative codepaths
1017	 * where the command is still pending. Make sure the command really
1018	 * isn't part of a list at this point.
1019	 */
1020	list_del_init(&cmd->list);
1021
1022	cmd->result = result;
1023	cmd->cmdwaitqwoken = 1;
1024	wake_up(&cmd->cmdwait_q);
1025
1026	if (!cmd->callback || cmd->callback == lbs_cmd_async_callback)
1027		__lbs_cleanup_and_insert_cmd(priv, cmd);
1028	priv->cur_cmd = NULL;
1029	wake_up(&priv->waitq);
1030}
1031
1032void lbs_complete_command(struct lbs_private *priv, struct cmd_ctrl_node *cmd,
1033			  int result)
1034{
1035	unsigned long flags;
1036	spin_lock_irqsave(&priv->driver_lock, flags);
1037	__lbs_complete_command(priv, cmd, result);
1038	spin_unlock_irqrestore(&priv->driver_lock, flags);
1039}
1040
1041int lbs_set_radio(struct lbs_private *priv, u8 preamble, u8 radio_on)
1042{
1043	struct cmd_ds_802_11_radio_control cmd;
1044	int ret = -EINVAL;
1045
1046	cmd.hdr.size = cpu_to_le16(sizeof(cmd));
1047	cmd.action = cpu_to_le16(CMD_ACT_SET);
1048	cmd.control = 0;
1049
1050	/* Only v8 and below support setting the preamble */
1051	if (priv->fwrelease < 0x09000000) {
1052		switch (preamble) {
1053		case RADIO_PREAMBLE_SHORT:
1054		case RADIO_PREAMBLE_AUTO:
1055		case RADIO_PREAMBLE_LONG:
1056			cmd.control = cpu_to_le16(preamble);
1057			break;
1058		default:
1059			goto out;
1060		}
1061	}
1062
1063	if (radio_on)
1064		cmd.control |= cpu_to_le16(0x1);
1065	else {
1066		cmd.control &= cpu_to_le16(~0x1);
1067		priv->txpower_cur = 0;
1068	}
1069
1070	lbs_deb_cmd("RADIO_CONTROL: radio %s, preamble %d\n",
1071		    radio_on ? "ON" : "OFF", preamble);
1072
1073	priv->radio_on = radio_on;
1074
1075	ret = lbs_cmd_with_response(priv, CMD_802_11_RADIO_CONTROL, &cmd);
1076
1077out:
1078	return ret;
1079}
1080
1081void lbs_set_mac_control(struct lbs_private *priv)
1082{
1083	struct cmd_ds_mac_control cmd;
1084
1085	cmd.hdr.size = cpu_to_le16(sizeof(cmd));
1086	cmd.action = cpu_to_le16(priv->mac_control);
1087	cmd.reserved = 0;
1088
1089	lbs_cmd_async(priv, CMD_MAC_CONTROL, &cmd.hdr, sizeof(cmd));
1090}
1091
1092int lbs_set_mac_control_sync(struct lbs_private *priv)
1093{
1094	struct cmd_ds_mac_control cmd;
1095	int ret = 0;
1096
1097	cmd.hdr.size = cpu_to_le16(sizeof(cmd));
1098	cmd.action = cpu_to_le16(priv->mac_control);
1099	cmd.reserved = 0;
1100	ret = lbs_cmd_with_response(priv, CMD_MAC_CONTROL, &cmd);
1101
1102	return ret;
1103}
1104
1105/**
1106 *  lbs_allocate_cmd_buffer - allocates the command buffer and links
1107 *  it to command free queue
1108 *
1109 *  @priv:	A pointer to &struct lbs_private structure
1110 *
1111 *  returns:	0 for success or -1 on error
1112 */
1113int lbs_allocate_cmd_buffer(struct lbs_private *priv)
1114{
1115	int ret = 0;
1116	u32 bufsize;
1117	u32 i;
1118	struct cmd_ctrl_node *cmdarray;
1119
1120	/* Allocate and initialize the command array */
1121	bufsize = sizeof(struct cmd_ctrl_node) * LBS_NUM_CMD_BUFFERS;
1122	if (!(cmdarray = kzalloc(bufsize, GFP_KERNEL))) {
1123		lbs_deb_host("ALLOC_CMD_BUF: tempcmd_array is NULL\n");
1124		ret = -1;
1125		goto done;
1126	}
1127	priv->cmd_array = cmdarray;
1128
1129	/* Allocate and initialize each command buffer in the command array */
1130	for (i = 0; i < LBS_NUM_CMD_BUFFERS; i++) {
1131		cmdarray[i].cmdbuf = kzalloc(LBS_CMD_BUFFER_SIZE, GFP_KERNEL);
1132		if (!cmdarray[i].cmdbuf) {
1133			lbs_deb_host("ALLOC_CMD_BUF: ptempvirtualaddr is NULL\n");
1134			ret = -1;
1135			goto free_cmd_array;
1136		}
1137	}
1138
1139	for (i = 0; i < LBS_NUM_CMD_BUFFERS; i++) {
1140		init_waitqueue_head(&cmdarray[i].cmdwait_q);
1141		lbs_cleanup_and_insert_cmd(priv, &cmdarray[i]);
1142	}
1143	return 0;
1144
1145free_cmd_array:
1146	for (i = 0; i < LBS_NUM_CMD_BUFFERS; i++) {
1147		if (cmdarray[i].cmdbuf) {
1148			kfree(cmdarray[i].cmdbuf);
1149			cmdarray[i].cmdbuf = NULL;
1150		}
1151	}
1152	kfree(priv->cmd_array);
1153	priv->cmd_array = NULL;
1154done:
1155	return ret;
1156}
1157
1158/**
1159 *  lbs_free_cmd_buffer - free the command buffer
1160 *
1161 *  @priv:	A pointer to &struct lbs_private structure
1162 *
1163 *  returns:	0 for success
1164 */
1165int lbs_free_cmd_buffer(struct lbs_private *priv)
1166{
1167	struct cmd_ctrl_node *cmdarray;
1168	unsigned int i;
1169
1170	/* need to check if cmd array is allocated or not */
1171	if (priv->cmd_array == NULL) {
1172		lbs_deb_host("FREE_CMD_BUF: cmd_array is NULL\n");
1173		goto done;
1174	}
1175
1176	cmdarray = priv->cmd_array;
1177
1178	/* Release shared memory buffers */
1179	for (i = 0; i < LBS_NUM_CMD_BUFFERS; i++) {
1180		if (cmdarray[i].cmdbuf) {
1181			kfree(cmdarray[i].cmdbuf);
1182			cmdarray[i].cmdbuf = NULL;
1183		}
1184	}
1185
1186	/* Release cmd_ctrl_node */
1187	if (priv->cmd_array) {
1188		kfree(priv->cmd_array);
1189		priv->cmd_array = NULL;
1190	}
1191
1192done:
1193	return 0;
1194}
1195
1196/**
1197 *  lbs_get_free_cmd_node - gets a free command node if available in
1198 *  command free queue
1199 *
1200 *  @priv:	A pointer to &struct lbs_private structure
1201 *
1202 *  returns:	A pointer to &cmd_ctrl_node structure on success
1203 *		or %NULL on error
1204 */
1205static struct cmd_ctrl_node *lbs_get_free_cmd_node(struct lbs_private *priv)
1206{
1207	struct cmd_ctrl_node *tempnode;
1208	unsigned long flags;
1209
1210	if (!priv)
1211		return NULL;
1212
1213	spin_lock_irqsave(&priv->driver_lock, flags);
1214
1215	if (!list_empty(&priv->cmdfreeq)) {
1216		tempnode = list_first_entry(&priv->cmdfreeq,
1217					    struct cmd_ctrl_node, list);
1218		list_del_init(&tempnode->list);
1219	} else {
1220		lbs_deb_host("GET_CMD_NODE: cmd_ctrl_node is not available\n");
1221		tempnode = NULL;
1222	}
1223
1224	spin_unlock_irqrestore(&priv->driver_lock, flags);
1225
1226	return tempnode;
1227}
1228
1229/**
1230 *  lbs_execute_next_command - execute next command in command
1231 *  pending queue. Will put firmware back to PS mode if applicable.
1232 *
1233 *  @priv:	A pointer to &struct lbs_private structure
1234 *
1235 *  returns:	0 on success or -1 on error
1236 */
1237int lbs_execute_next_command(struct lbs_private *priv)
1238{
1239	struct cmd_ctrl_node *cmdnode = NULL;
1240	struct cmd_header *cmd;
1241	unsigned long flags;
1242	int ret = 0;
1243
1244	/* Debug group is LBS_DEB_THREAD and not LBS_DEB_HOST, because the
1245	 * only caller to us is lbs_thread() and we get even when a
1246	 * data packet is received */
1247	spin_lock_irqsave(&priv->driver_lock, flags);
1248
1249	if (priv->cur_cmd) {
1250		netdev_alert(priv->dev,
1251			     "EXEC_NEXT_CMD: already processing command!\n");
1252		spin_unlock_irqrestore(&priv->driver_lock, flags);
1253		ret = -1;
1254		goto done;
1255	}
1256
1257	if (!list_empty(&priv->cmdpendingq)) {
1258		cmdnode = list_first_entry(&priv->cmdpendingq,
1259					   struct cmd_ctrl_node, list);
1260	}
1261
1262	spin_unlock_irqrestore(&priv->driver_lock, flags);
1263
1264	if (cmdnode) {
1265		cmd = cmdnode->cmdbuf;
1266
1267		if (is_command_allowed_in_ps(le16_to_cpu(cmd->command))) {
1268			if ((priv->psstate == PS_STATE_SLEEP) ||
1269			    (priv->psstate == PS_STATE_PRE_SLEEP)) {
1270				lbs_deb_host(
1271				       "EXEC_NEXT_CMD: cannot send cmd 0x%04x in psstate %d\n",
1272				       le16_to_cpu(cmd->command),
1273				       priv->psstate);
1274				ret = -1;
1275				goto done;
1276			}
1277			lbs_deb_host("EXEC_NEXT_CMD: OK to send command "
1278				     "0x%04x in psstate %d\n",
1279				     le16_to_cpu(cmd->command), priv->psstate);
1280		} else if (priv->psstate != PS_STATE_FULL_POWER) {
1281			/*
1282			 * 1. Non-PS command:
1283			 * Queue it. set needtowakeup to TRUE if current state
1284			 * is SLEEP, otherwise call send EXIT_PS.
1285			 * 2. PS command but not EXIT_PS:
1286			 * Ignore it.
1287			 * 3. PS command EXIT_PS:
1288			 * Set needtowakeup to TRUE if current state is SLEEP,
1289			 * otherwise send this command down to firmware
1290			 * immediately.
1291			 */
1292			if (cmd->command != cpu_to_le16(CMD_802_11_PS_MODE)) {
1293				/*  Prepare to send Exit PS,
1294				 *  this non PS command will be sent later */
1295				if ((priv->psstate == PS_STATE_SLEEP)
1296				    || (priv->psstate == PS_STATE_PRE_SLEEP)
1297				    ) {
1298					/* w/ new scheme, it will not reach here.
1299					   since it is blocked in main_thread. */
1300					priv->needtowakeup = 1;
1301				} else {
1302					lbs_set_ps_mode(priv,
1303							PS_MODE_ACTION_EXIT_PS,
1304							false);
1305				}
1306
1307				ret = 0;
1308				goto done;
1309			} else {
1310				/*
1311				 * PS command. Ignore it if it is not Exit_PS.
1312				 * otherwise send it down immediately.
1313				 */
1314				struct cmd_ds_802_11_ps_mode *psm = (void *)cmd;
1315
1316				lbs_deb_host(
1317				       "EXEC_NEXT_CMD: PS cmd, action 0x%02x\n",
1318				       psm->action);
1319				if (psm->action !=
1320				    cpu_to_le16(PS_MODE_ACTION_EXIT_PS)) {
1321					lbs_deb_host(
1322					       "EXEC_NEXT_CMD: ignore ENTER_PS cmd\n");
1323					lbs_complete_command(priv, cmdnode, 0);
1324
1325					ret = 0;
1326					goto done;
1327				}
1328
1329				if ((priv->psstate == PS_STATE_SLEEP) ||
1330				    (priv->psstate == PS_STATE_PRE_SLEEP)) {
1331					lbs_deb_host(
1332					       "EXEC_NEXT_CMD: ignore EXIT_PS cmd in sleep\n");
1333					lbs_complete_command(priv, cmdnode, 0);
1334					priv->needtowakeup = 1;
1335
1336					ret = 0;
1337					goto done;
1338				}
1339
1340				lbs_deb_host(
1341				       "EXEC_NEXT_CMD: sending EXIT_PS\n");
1342			}
1343		}
1344		spin_lock_irqsave(&priv->driver_lock, flags);
1345		list_del_init(&cmdnode->list);
1346		spin_unlock_irqrestore(&priv->driver_lock, flags);
1347		lbs_deb_host("EXEC_NEXT_CMD: sending command 0x%04x\n",
1348			    le16_to_cpu(cmd->command));
1349		lbs_submit_command(priv, cmdnode);
1350	} else {
1351		/*
1352		 * check if in power save mode, if yes, put the device back
1353		 * to PS mode
1354		 */
1355		if ((priv->psmode != LBS802_11POWERMODECAM) &&
1356		    (priv->psstate == PS_STATE_FULL_POWER) &&
1357		    (priv->connect_status == LBS_CONNECTED)) {
1358			lbs_deb_host(
1359				"EXEC_NEXT_CMD: cmdpendingq empty, go back to PS_SLEEP");
1360			lbs_set_ps_mode(priv, PS_MODE_ACTION_ENTER_PS,
1361					false);
1362		}
1363	}
1364
1365	ret = 0;
1366done:
1367	return ret;
1368}
1369
1370static void lbs_send_confirmsleep(struct lbs_private *priv)
1371{
1372	unsigned long flags;
1373	int ret;
1374
1375	lbs_deb_hex(LBS_DEB_HOST, "sleep confirm", (u8 *) &confirm_sleep,
1376		sizeof(confirm_sleep));
1377
1378	ret = priv->hw_host_to_card(priv, MVMS_CMD, (u8 *) &confirm_sleep,
1379		sizeof(confirm_sleep));
1380	if (ret) {
1381		netdev_alert(priv->dev, "confirm_sleep failed\n");
1382		return;
1383	}
1384
1385	spin_lock_irqsave(&priv->driver_lock, flags);
1386
1387	/* We don't get a response on the sleep-confirmation */
1388	priv->dnld_sent = DNLD_RES_RECEIVED;
1389
1390	if (priv->is_host_sleep_configured) {
1391		priv->is_host_sleep_activated = 1;
1392		wake_up_interruptible(&priv->host_sleep_q);
1393	}
1394
1395	/* If nothing to do, go back to sleep (?) */
1396	if (!kfifo_len(&priv->event_fifo) && !priv->resp_len[priv->resp_idx])
1397		priv->psstate = PS_STATE_SLEEP;
1398
1399	spin_unlock_irqrestore(&priv->driver_lock, flags);
1400}
1401
1402/**
1403 * lbs_ps_confirm_sleep - checks condition and prepares to
1404 * send sleep confirm command to firmware if ok
1405 *
1406 * @priv:	A pointer to &struct lbs_private structure
1407 *
1408 * returns:	n/a
1409 */
1410void lbs_ps_confirm_sleep(struct lbs_private *priv)
1411{
1412	unsigned long flags =0;
1413	int allowed = 1;
1414
1415	spin_lock_irqsave(&priv->driver_lock, flags);
1416	if (priv->dnld_sent) {
1417		allowed = 0;
1418		lbs_deb_host("dnld_sent was set\n");
1419	}
1420
1421	/* In-progress command? */
1422	if (priv->cur_cmd) {
1423		allowed = 0;
1424		lbs_deb_host("cur_cmd was set\n");
1425	}
1426
1427	/* Pending events or command responses? */
1428	if (kfifo_len(&priv->event_fifo) || priv->resp_len[priv->resp_idx]) {
1429		allowed = 0;
1430		lbs_deb_host("pending events or command responses\n");
1431	}
1432	spin_unlock_irqrestore(&priv->driver_lock, flags);
1433
1434	if (allowed) {
1435		lbs_deb_host("sending lbs_ps_confirm_sleep\n");
1436		lbs_send_confirmsleep(priv);
1437	} else {
1438		lbs_deb_host("sleep confirm has been delayed\n");
1439	}
1440}
1441
1442
1443/**
1444 * lbs_set_tpc_cfg - Configures the transmission power control functionality
1445 *
1446 * @priv:	A pointer to &struct lbs_private structure
1447 * @enable:	Transmission power control enable
1448 * @p0:		Power level when link quality is good (dBm).
1449 * @p1:		Power level when link quality is fair (dBm).
1450 * @p2:		Power level when link quality is poor (dBm).
1451 * @usesnr:	Use Signal to Noise Ratio in TPC
1452 *
1453 * returns:	0 on success
1454 */
1455int lbs_set_tpc_cfg(struct lbs_private *priv, int enable, int8_t p0, int8_t p1,
1456		int8_t p2, int usesnr)
1457{
1458	struct cmd_ds_802_11_tpc_cfg cmd;
1459	int ret;
1460
1461	memset(&cmd, 0, sizeof(cmd));
1462	cmd.hdr.size = cpu_to_le16(sizeof(cmd));
1463	cmd.action = cpu_to_le16(CMD_ACT_SET);
1464	cmd.enable = !!enable;
1465	cmd.usesnr = !!usesnr;
1466	cmd.P0 = p0;
1467	cmd.P1 = p1;
1468	cmd.P2 = p2;
1469
1470	ret = lbs_cmd_with_response(priv, CMD_802_11_TPC_CFG, &cmd);
1471
1472	return ret;
1473}
1474
1475/**
1476 * lbs_set_power_adapt_cfg - Configures the power adaptation settings
1477 *
1478 * @priv:	A pointer to &struct lbs_private structure
1479 * @enable:	Power adaptation enable
1480 * @p0:		Power level for 1, 2, 5.5 and 11 Mbps (dBm).
1481 * @p1:		Power level for 6, 9, 12, 18, 22, 24 and 36 Mbps (dBm).
1482 * @p2:		Power level for 48 and 54 Mbps (dBm).
1483 *
1484 * returns:	0 on Success
1485 */
1486
1487int lbs_set_power_adapt_cfg(struct lbs_private *priv, int enable, int8_t p0,
1488		int8_t p1, int8_t p2)
1489{
1490	struct cmd_ds_802_11_pa_cfg cmd;
1491	int ret;
1492
1493	memset(&cmd, 0, sizeof(cmd));
1494	cmd.hdr.size = cpu_to_le16(sizeof(cmd));
1495	cmd.action = cpu_to_le16(CMD_ACT_SET);
1496	cmd.enable = !!enable;
1497	cmd.P0 = p0;
1498	cmd.P1 = p1;
1499	cmd.P2 = p2;
1500
1501	ret = lbs_cmd_with_response(priv, CMD_802_11_PA_CFG , &cmd);
1502
1503	return ret;
1504}
1505
1506
1507struct cmd_ctrl_node *__lbs_cmd_async(struct lbs_private *priv,
1508	uint16_t command, struct cmd_header *in_cmd, int in_cmd_size,
1509	int (*callback)(struct lbs_private *, unsigned long, struct cmd_header *),
1510	unsigned long callback_arg)
1511{
1512	struct cmd_ctrl_node *cmdnode;
1513
1514	if (priv->surpriseremoved) {
1515		lbs_deb_host("PREP_CMD: card removed\n");
1516		cmdnode = ERR_PTR(-ENOENT);
1517		goto done;
1518	}
1519
1520	/* No commands are allowed in Deep Sleep until we toggle the GPIO
1521	 * to wake up the card and it has signaled that it's ready.
1522	 */
1523	if (!priv->is_auto_deep_sleep_enabled) {
1524		if (priv->is_deep_sleep) {
1525			lbs_deb_cmd("command not allowed in deep sleep\n");
1526			cmdnode = ERR_PTR(-EBUSY);
1527			goto done;
1528		}
1529	}
1530
1531	cmdnode = lbs_get_free_cmd_node(priv);
1532	if (cmdnode == NULL) {
1533		lbs_deb_host("PREP_CMD: cmdnode is NULL\n");
1534
1535		/* Wake up main thread to execute next command */
1536		wake_up(&priv->waitq);
1537		cmdnode = ERR_PTR(-ENOBUFS);
1538		goto done;
1539	}
1540
1541	cmdnode->callback = callback;
1542	cmdnode->callback_arg = callback_arg;
1543
1544	/* Copy the incoming command to the buffer */
1545	memcpy(cmdnode->cmdbuf, in_cmd, in_cmd_size);
1546
1547	/* Set command, clean result, move to buffer */
1548	cmdnode->cmdbuf->command = cpu_to_le16(command);
1549	cmdnode->cmdbuf->size    = cpu_to_le16(in_cmd_size);
1550	cmdnode->cmdbuf->result  = 0;
1551
1552	lbs_deb_host("PREP_CMD: command 0x%04x\n", command);
1553
1554	cmdnode->cmdwaitqwoken = 0;
1555	lbs_queue_cmd(priv, cmdnode);
1556	wake_up(&priv->waitq);
1557
1558 done:
1559	return cmdnode;
1560}
1561
1562void lbs_cmd_async(struct lbs_private *priv, uint16_t command,
1563	struct cmd_header *in_cmd, int in_cmd_size)
1564{
1565	__lbs_cmd_async(priv, command, in_cmd, in_cmd_size,
1566		lbs_cmd_async_callback, 0);
1567}
1568
1569int __lbs_cmd(struct lbs_private *priv, uint16_t command,
1570	      struct cmd_header *in_cmd, int in_cmd_size,
1571	      int (*callback)(struct lbs_private *, unsigned long, struct cmd_header *),
1572	      unsigned long callback_arg)
1573{
1574	struct cmd_ctrl_node *cmdnode;
1575	unsigned long flags;
1576	int ret = 0;
1577
1578	cmdnode = __lbs_cmd_async(priv, command, in_cmd, in_cmd_size,
1579				  callback, callback_arg);
1580	if (IS_ERR(cmdnode)) {
1581		ret = PTR_ERR(cmdnode);
1582		goto done;
1583	}
1584
1585	might_sleep();
1586
1587	/*
1588	 * Be careful with signals here. A signal may be received as the system
1589	 * goes into suspend or resume. We do not want this to interrupt the
1590	 * command, so we perform an uninterruptible sleep.
1591	 */
1592	wait_event(cmdnode->cmdwait_q, cmdnode->cmdwaitqwoken);
1593
1594	spin_lock_irqsave(&priv->driver_lock, flags);
1595	ret = cmdnode->result;
1596	if (ret)
1597		netdev_info(priv->dev, "PREP_CMD: command 0x%04x failed: %d\n",
1598			    command, ret);
1599
1600	__lbs_cleanup_and_insert_cmd(priv, cmdnode);
1601	spin_unlock_irqrestore(&priv->driver_lock, flags);
1602
1603done:
1604	return ret;
1605}
1606EXPORT_SYMBOL_GPL(__lbs_cmd);
1607