cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

wsm.c (44154B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/*
      3 * WSM host interface (HI) implementation for
      4 * ST-Ericsson CW1200 mac80211 drivers.
      5 *
      6 * Copyright (c) 2010, ST-Ericsson
      7 * Author: Dmitry Tarnyagin <dmitry.tarnyagin@lockless.no>
      8 */
      9
     10#include <linux/skbuff.h>
     11#include <linux/wait.h>
     12#include <linux/delay.h>
     13#include <linux/sched.h>
     14#include <linux/random.h>
     15
     16#include "cw1200.h"
     17#include "wsm.h"
     18#include "bh.h"
     19#include "sta.h"
     20#include "debug.h"
     21
     22#define WSM_CMD_TIMEOUT		(2 * HZ) /* With respect to interrupt loss */
     23#define WSM_CMD_START_TIMEOUT	(7 * HZ)
     24#define WSM_CMD_RESET_TIMEOUT	(3 * HZ) /* 2 sec. timeout was observed.   */
     25#define WSM_CMD_MAX_TIMEOUT	(3 * HZ)
     26
     27#define WSM_SKIP(buf, size)						\
     28	do {								\
     29		if ((buf)->data + size > (buf)->end)			\
     30			goto underflow;					\
     31		(buf)->data += size;					\
     32	} while (0)
     33
     34#define WSM_GET(buf, ptr, size)						\
     35	do {								\
     36		if ((buf)->data + size > (buf)->end)			\
     37			goto underflow;					\
     38		memcpy(ptr, (buf)->data, size);				\
     39		(buf)->data += size;					\
     40	} while (0)
     41
     42#define __WSM_GET(buf, type, type2, cvt)				\
     43	({								\
     44		type val;						\
     45		if ((buf)->data + sizeof(type) > (buf)->end)		\
     46			goto underflow;					\
     47		val = cvt(*(type2 *)(buf)->data);			\
     48		(buf)->data += sizeof(type);				\
     49		val;							\
     50	})
     51
     52#define WSM_GET8(buf)  __WSM_GET(buf, u8, u8, (u8))
     53#define WSM_GET16(buf) __WSM_GET(buf, u16, __le16, __le16_to_cpu)
     54#define WSM_GET32(buf) __WSM_GET(buf, u32, __le32, __le32_to_cpu)
     55
     56#define WSM_PUT(buf, ptr, size)						\
     57	do {								\
     58		if ((buf)->data + size > (buf)->end)		\
     59			if (wsm_buf_reserve((buf), size))	\
     60				goto nomem;				\
     61		memcpy((buf)->data, ptr, size);				\
     62		(buf)->data += size;					\
     63	} while (0)
     64
     65#define __WSM_PUT(buf, val, type, type2, cvt)				\
     66	do {								\
     67		if ((buf)->data + sizeof(type) > (buf)->end)		\
     68			if (wsm_buf_reserve((buf), sizeof(type))) \
     69				goto nomem;				\
     70		*(type2 *)(buf)->data = cvt(val);			\
     71		(buf)->data += sizeof(type);				\
     72	} while (0)
     73
     74#define WSM_PUT8(buf, val)  __WSM_PUT(buf, val, u8, u8, (u8))
     75#define WSM_PUT16(buf, val) __WSM_PUT(buf, val, u16, __le16, __cpu_to_le16)
     76#define WSM_PUT32(buf, val) __WSM_PUT(buf, val, u32, __le32, __cpu_to_le32)
     77
     78static void wsm_buf_reset(struct wsm_buf *buf);
     79static int wsm_buf_reserve(struct wsm_buf *buf, size_t extra_size);
     80
     81static int wsm_cmd_send(struct cw1200_common *priv,
     82			struct wsm_buf *buf,
     83			void *arg, u16 cmd, long tmo);
     84
     85#define wsm_cmd_lock(__priv) mutex_lock(&((__priv)->wsm_cmd_mux))
     86#define wsm_cmd_unlock(__priv) mutex_unlock(&((__priv)->wsm_cmd_mux))
     87
     88/* ******************************************************************** */
     89/* WSM API implementation						*/
     90
     91static int wsm_generic_confirm(struct cw1200_common *priv,
     92			     void *arg,
     93			     struct wsm_buf *buf)
     94{
     95	u32 status = WSM_GET32(buf);
     96	if (status != WSM_STATUS_SUCCESS)
     97		return -EINVAL;
     98	return 0;
     99
    100underflow:
    101	WARN_ON(1);
    102	return -EINVAL;
    103}
    104
    105int wsm_configuration(struct cw1200_common *priv, struct wsm_configuration *arg)
    106{
    107	int ret;
    108	struct wsm_buf *buf = &priv->wsm_cmd_buf;
    109
    110	wsm_cmd_lock(priv);
    111
    112	WSM_PUT32(buf, arg->dot11MaxTransmitMsduLifeTime);
    113	WSM_PUT32(buf, arg->dot11MaxReceiveLifeTime);
    114	WSM_PUT32(buf, arg->dot11RtsThreshold);
    115
    116	/* DPD block. */
    117	WSM_PUT16(buf, arg->dpdData_size + 12);
    118	WSM_PUT16(buf, 1); /* DPD version */
    119	WSM_PUT(buf, arg->dot11StationId, ETH_ALEN);
    120	WSM_PUT16(buf, 5); /* DPD flags */
    121	WSM_PUT(buf, arg->dpdData, arg->dpdData_size);
    122
    123	ret = wsm_cmd_send(priv, buf, arg,
    124			   WSM_CONFIGURATION_REQ_ID, WSM_CMD_TIMEOUT);
    125
    126	wsm_cmd_unlock(priv);
    127	return ret;
    128
    129nomem:
    130	wsm_cmd_unlock(priv);
    131	return -ENOMEM;
    132}
    133
    134static int wsm_configuration_confirm(struct cw1200_common *priv,
    135				     struct wsm_configuration *arg,
    136				     struct wsm_buf *buf)
    137{
    138	int i;
    139	int status;
    140
    141	status = WSM_GET32(buf);
    142	if (WARN_ON(status != WSM_STATUS_SUCCESS))
    143		return -EINVAL;
    144
    145	WSM_GET(buf, arg->dot11StationId, ETH_ALEN);
    146	arg->dot11FrequencyBandsSupported = WSM_GET8(buf);
    147	WSM_SKIP(buf, 1);
    148	arg->supportedRateMask = WSM_GET32(buf);
    149	for (i = 0; i < 2; ++i) {
    150		arg->txPowerRange[i].min_power_level = WSM_GET32(buf);
    151		arg->txPowerRange[i].max_power_level = WSM_GET32(buf);
    152		arg->txPowerRange[i].stepping = WSM_GET32(buf);
    153	}
    154	return 0;
    155
    156underflow:
    157	WARN_ON(1);
    158	return -EINVAL;
    159}
    160
    161/* ******************************************************************** */
    162
    163int wsm_reset(struct cw1200_common *priv, const struct wsm_reset *arg)
    164{
    165	int ret;
    166	struct wsm_buf *buf = &priv->wsm_cmd_buf;
    167	u16 cmd = WSM_RESET_REQ_ID | WSM_TX_LINK_ID(arg->link_id);
    168
    169	wsm_cmd_lock(priv);
    170
    171	WSM_PUT32(buf, arg->reset_statistics ? 0 : 1);
    172	ret = wsm_cmd_send(priv, buf, NULL, cmd, WSM_CMD_RESET_TIMEOUT);
    173	wsm_cmd_unlock(priv);
    174	return ret;
    175
    176nomem:
    177	wsm_cmd_unlock(priv);
    178	return -ENOMEM;
    179}
    180
    181/* ******************************************************************** */
    182
    183struct wsm_mib {
    184	u16 mib_id;
    185	void *buf;
    186	size_t buf_size;
    187};
    188
    189int wsm_read_mib(struct cw1200_common *priv, u16 mib_id, void *_buf,
    190			size_t buf_size)
    191{
    192	int ret;
    193	struct wsm_buf *buf = &priv->wsm_cmd_buf;
    194	struct wsm_mib mib_buf = {
    195		.mib_id = mib_id,
    196		.buf = _buf,
    197		.buf_size = buf_size,
    198	};
    199	wsm_cmd_lock(priv);
    200
    201	WSM_PUT16(buf, mib_id);
    202	WSM_PUT16(buf, 0);
    203
    204	ret = wsm_cmd_send(priv, buf, &mib_buf,
    205			   WSM_READ_MIB_REQ_ID, WSM_CMD_TIMEOUT);
    206	wsm_cmd_unlock(priv);
    207	return ret;
    208
    209nomem:
    210	wsm_cmd_unlock(priv);
    211	return -ENOMEM;
    212}
    213
    214static int wsm_read_mib_confirm(struct cw1200_common *priv,
    215				struct wsm_mib *arg,
    216				struct wsm_buf *buf)
    217{
    218	u16 size;
    219	if (WARN_ON(WSM_GET32(buf) != WSM_STATUS_SUCCESS))
    220		return -EINVAL;
    221
    222	if (WARN_ON(WSM_GET16(buf) != arg->mib_id))
    223		return -EINVAL;
    224
    225	size = WSM_GET16(buf);
    226	if (size > arg->buf_size)
    227		size = arg->buf_size;
    228
    229	WSM_GET(buf, arg->buf, size);
    230	arg->buf_size = size;
    231	return 0;
    232
    233underflow:
    234	WARN_ON(1);
    235	return -EINVAL;
    236}
    237
    238/* ******************************************************************** */
    239
    240int wsm_write_mib(struct cw1200_common *priv, u16 mib_id, void *_buf,
    241			size_t buf_size)
    242{
    243	int ret;
    244	struct wsm_buf *buf = &priv->wsm_cmd_buf;
    245	struct wsm_mib mib_buf = {
    246		.mib_id = mib_id,
    247		.buf = _buf,
    248		.buf_size = buf_size,
    249	};
    250
    251	wsm_cmd_lock(priv);
    252
    253	WSM_PUT16(buf, mib_id);
    254	WSM_PUT16(buf, buf_size);
    255	WSM_PUT(buf, _buf, buf_size);
    256
    257	ret = wsm_cmd_send(priv, buf, &mib_buf,
    258			   WSM_WRITE_MIB_REQ_ID, WSM_CMD_TIMEOUT);
    259	wsm_cmd_unlock(priv);
    260	return ret;
    261
    262nomem:
    263	wsm_cmd_unlock(priv);
    264	return -ENOMEM;
    265}
    266
    267static int wsm_write_mib_confirm(struct cw1200_common *priv,
    268				struct wsm_mib *arg,
    269				struct wsm_buf *buf)
    270{
    271	int ret;
    272
    273	ret = wsm_generic_confirm(priv, arg, buf);
    274	if (ret)
    275		return ret;
    276
    277	if (arg->mib_id == WSM_MIB_ID_OPERATIONAL_POWER_MODE) {
    278		/* OperationalMode: update PM status. */
    279		const char *p = arg->buf;
    280		cw1200_enable_powersave(priv, (p[0] & 0x0F) ? true : false);
    281	}
    282	return 0;
    283}
    284
    285/* ******************************************************************** */
    286
    287int wsm_scan(struct cw1200_common *priv, const struct wsm_scan *arg)
    288{
    289	int i;
    290	int ret;
    291	struct wsm_buf *buf = &priv->wsm_cmd_buf;
    292
    293	if (arg->num_channels > 48)
    294		return -EINVAL;
    295
    296	if (arg->num_ssids > 2)
    297		return -EINVAL;
    298
    299	if (arg->band > 1)
    300		return -EINVAL;
    301
    302	wsm_cmd_lock(priv);
    303
    304	WSM_PUT8(buf, arg->band);
    305	WSM_PUT8(buf, arg->type);
    306	WSM_PUT8(buf, arg->flags);
    307	WSM_PUT8(buf, arg->max_tx_rate);
    308	WSM_PUT32(buf, arg->auto_scan_interval);
    309	WSM_PUT8(buf, arg->num_probes);
    310	WSM_PUT8(buf, arg->num_channels);
    311	WSM_PUT8(buf, arg->num_ssids);
    312	WSM_PUT8(buf, arg->probe_delay);
    313
    314	for (i = 0; i < arg->num_channels; ++i) {
    315		WSM_PUT16(buf, arg->ch[i].number);
    316		WSM_PUT16(buf, 0);
    317		WSM_PUT32(buf, arg->ch[i].min_chan_time);
    318		WSM_PUT32(buf, arg->ch[i].max_chan_time);
    319		WSM_PUT32(buf, 0);
    320	}
    321
    322	for (i = 0; i < arg->num_ssids; ++i) {
    323		WSM_PUT32(buf, arg->ssids[i].length);
    324		WSM_PUT(buf, &arg->ssids[i].ssid[0],
    325			sizeof(arg->ssids[i].ssid));
    326	}
    327
    328	ret = wsm_cmd_send(priv, buf, NULL,
    329			   WSM_START_SCAN_REQ_ID, WSM_CMD_TIMEOUT);
    330	wsm_cmd_unlock(priv);
    331	return ret;
    332
    333nomem:
    334	wsm_cmd_unlock(priv);
    335	return -ENOMEM;
    336}
    337
    338/* ******************************************************************** */
    339
    340int wsm_stop_scan(struct cw1200_common *priv)
    341{
    342	int ret;
    343	struct wsm_buf *buf = &priv->wsm_cmd_buf;
    344	wsm_cmd_lock(priv);
    345	ret = wsm_cmd_send(priv, buf, NULL,
    346			   WSM_STOP_SCAN_REQ_ID, WSM_CMD_TIMEOUT);
    347	wsm_cmd_unlock(priv);
    348	return ret;
    349}
    350
    351
    352static int wsm_tx_confirm(struct cw1200_common *priv,
    353			  struct wsm_buf *buf,
    354			  int link_id)
    355{
    356	struct wsm_tx_confirm tx_confirm;
    357
    358	tx_confirm.packet_id = WSM_GET32(buf);
    359	tx_confirm.status = WSM_GET32(buf);
    360	tx_confirm.tx_rate = WSM_GET8(buf);
    361	tx_confirm.ack_failures = WSM_GET8(buf);
    362	tx_confirm.flags = WSM_GET16(buf);
    363	tx_confirm.media_delay = WSM_GET32(buf);
    364	tx_confirm.tx_queue_delay = WSM_GET32(buf);
    365
    366	cw1200_tx_confirm_cb(priv, link_id, &tx_confirm);
    367	return 0;
    368
    369underflow:
    370	WARN_ON(1);
    371	return -EINVAL;
    372}
    373
    374static int wsm_multi_tx_confirm(struct cw1200_common *priv,
    375				struct wsm_buf *buf, int link_id)
    376{
    377	int ret;
    378	int count;
    379
    380	count = WSM_GET32(buf);
    381	if (WARN_ON(count <= 0))
    382		return -EINVAL;
    383
    384	if (count > 1) {
    385		/* We already released one buffer, now for the rest */
    386		ret = wsm_release_tx_buffer(priv, count - 1);
    387		if (ret < 0)
    388			return ret;
    389		else if (ret > 0)
    390			cw1200_bh_wakeup(priv);
    391	}
    392
    393	cw1200_debug_txed_multi(priv, count);
    394	do {
    395		ret = wsm_tx_confirm(priv, buf, link_id);
    396	} while (!ret && --count);
    397
    398	return ret;
    399
    400underflow:
    401	WARN_ON(1);
    402	return -EINVAL;
    403}
    404
    405/* ******************************************************************** */
    406
    407static int wsm_join_confirm(struct cw1200_common *priv,
    408			    struct wsm_join_cnf *arg,
    409			    struct wsm_buf *buf)
    410{
    411	arg->status = WSM_GET32(buf);
    412	if (WARN_ON(arg->status) != WSM_STATUS_SUCCESS)
    413		return -EINVAL;
    414
    415	arg->min_power_level = WSM_GET32(buf);
    416	arg->max_power_level = WSM_GET32(buf);
    417
    418	return 0;
    419
    420underflow:
    421	WARN_ON(1);
    422	return -EINVAL;
    423}
    424
    425int wsm_join(struct cw1200_common *priv, struct wsm_join *arg)
    426{
    427	int ret;
    428	struct wsm_buf *buf = &priv->wsm_cmd_buf;
    429	struct wsm_join_cnf resp;
    430	wsm_cmd_lock(priv);
    431
    432	WSM_PUT8(buf, arg->mode);
    433	WSM_PUT8(buf, arg->band);
    434	WSM_PUT16(buf, arg->channel_number);
    435	WSM_PUT(buf, &arg->bssid[0], sizeof(arg->bssid));
    436	WSM_PUT16(buf, arg->atim_window);
    437	WSM_PUT8(buf, arg->preamble_type);
    438	WSM_PUT8(buf, arg->probe_for_join);
    439	WSM_PUT8(buf, arg->dtim_period);
    440	WSM_PUT8(buf, arg->flags);
    441	WSM_PUT32(buf, arg->ssid_len);
    442	WSM_PUT(buf, &arg->ssid[0], sizeof(arg->ssid));
    443	WSM_PUT32(buf, arg->beacon_interval);
    444	WSM_PUT32(buf, arg->basic_rate_set);
    445
    446	priv->tx_burst_idx = -1;
    447	ret = wsm_cmd_send(priv, buf, &resp,
    448			   WSM_JOIN_REQ_ID, WSM_CMD_TIMEOUT);
    449	/* TODO:  Update state based on resp.min|max_power_level */
    450
    451	priv->join_complete_status = resp.status;
    452
    453	wsm_cmd_unlock(priv);
    454	return ret;
    455
    456nomem:
    457	wsm_cmd_unlock(priv);
    458	return -ENOMEM;
    459}
    460
    461/* ******************************************************************** */
    462
    463int wsm_set_bss_params(struct cw1200_common *priv,
    464		       const struct wsm_set_bss_params *arg)
    465{
    466	int ret;
    467	struct wsm_buf *buf = &priv->wsm_cmd_buf;
    468
    469	wsm_cmd_lock(priv);
    470
    471	WSM_PUT8(buf, (arg->reset_beacon_loss ?  0x1 : 0));
    472	WSM_PUT8(buf, arg->beacon_lost_count);
    473	WSM_PUT16(buf, arg->aid);
    474	WSM_PUT32(buf, arg->operational_rate_set);
    475
    476	ret = wsm_cmd_send(priv, buf, NULL,
    477			   WSM_SET_BSS_PARAMS_REQ_ID, WSM_CMD_TIMEOUT);
    478
    479	wsm_cmd_unlock(priv);
    480	return ret;
    481
    482nomem:
    483	wsm_cmd_unlock(priv);
    484	return -ENOMEM;
    485}
    486
    487/* ******************************************************************** */
    488
    489int wsm_add_key(struct cw1200_common *priv, const struct wsm_add_key *arg)
    490{
    491	int ret;
    492	struct wsm_buf *buf = &priv->wsm_cmd_buf;
    493
    494	wsm_cmd_lock(priv);
    495
    496	WSM_PUT(buf, arg, sizeof(*arg));
    497
    498	ret = wsm_cmd_send(priv, buf, NULL,
    499			   WSM_ADD_KEY_REQ_ID, WSM_CMD_TIMEOUT);
    500
    501	wsm_cmd_unlock(priv);
    502	return ret;
    503
    504nomem:
    505	wsm_cmd_unlock(priv);
    506	return -ENOMEM;
    507}
    508
    509/* ******************************************************************** */
    510
    511int wsm_remove_key(struct cw1200_common *priv, const struct wsm_remove_key *arg)
    512{
    513	int ret;
    514	struct wsm_buf *buf = &priv->wsm_cmd_buf;
    515
    516	wsm_cmd_lock(priv);
    517
    518	WSM_PUT8(buf, arg->index);
    519	WSM_PUT8(buf, 0);
    520	WSM_PUT16(buf, 0);
    521
    522	ret = wsm_cmd_send(priv, buf, NULL,
    523			   WSM_REMOVE_KEY_REQ_ID, WSM_CMD_TIMEOUT);
    524
    525	wsm_cmd_unlock(priv);
    526	return ret;
    527
    528nomem:
    529	wsm_cmd_unlock(priv);
    530	return -ENOMEM;
    531}
    532
    533/* ******************************************************************** */
    534
    535int wsm_set_tx_queue_params(struct cw1200_common *priv,
    536		const struct wsm_set_tx_queue_params *arg, u8 id)
    537{
    538	int ret;
    539	struct wsm_buf *buf = &priv->wsm_cmd_buf;
    540	static const u8 queue_id_to_wmm_aci[] = { 3, 2, 0, 1 };
    541
    542	wsm_cmd_lock(priv);
    543
    544	WSM_PUT8(buf, queue_id_to_wmm_aci[id]);
    545	WSM_PUT8(buf, 0);
    546	WSM_PUT8(buf, arg->ackPolicy);
    547	WSM_PUT8(buf, 0);
    548	WSM_PUT32(buf, arg->maxTransmitLifetime);
    549	WSM_PUT16(buf, arg->allowedMediumTime);
    550	WSM_PUT16(buf, 0);
    551
    552	ret = wsm_cmd_send(priv, buf, NULL, 0x0012, WSM_CMD_TIMEOUT);
    553
    554	wsm_cmd_unlock(priv);
    555	return ret;
    556
    557nomem:
    558	wsm_cmd_unlock(priv);
    559	return -ENOMEM;
    560}
    561
    562/* ******************************************************************** */
    563
    564int wsm_set_edca_params(struct cw1200_common *priv,
    565				const struct wsm_edca_params *arg)
    566{
    567	int ret;
    568	struct wsm_buf *buf = &priv->wsm_cmd_buf;
    569
    570	wsm_cmd_lock(priv);
    571
    572	/* Implemented according to specification. */
    573
    574	WSM_PUT16(buf, arg->params[3].cwmin);
    575	WSM_PUT16(buf, arg->params[2].cwmin);
    576	WSM_PUT16(buf, arg->params[1].cwmin);
    577	WSM_PUT16(buf, arg->params[0].cwmin);
    578
    579	WSM_PUT16(buf, arg->params[3].cwmax);
    580	WSM_PUT16(buf, arg->params[2].cwmax);
    581	WSM_PUT16(buf, arg->params[1].cwmax);
    582	WSM_PUT16(buf, arg->params[0].cwmax);
    583
    584	WSM_PUT8(buf, arg->params[3].aifns);
    585	WSM_PUT8(buf, arg->params[2].aifns);
    586	WSM_PUT8(buf, arg->params[1].aifns);
    587	WSM_PUT8(buf, arg->params[0].aifns);
    588
    589	WSM_PUT16(buf, arg->params[3].txop_limit);
    590	WSM_PUT16(buf, arg->params[2].txop_limit);
    591	WSM_PUT16(buf, arg->params[1].txop_limit);
    592	WSM_PUT16(buf, arg->params[0].txop_limit);
    593
    594	WSM_PUT32(buf, arg->params[3].max_rx_lifetime);
    595	WSM_PUT32(buf, arg->params[2].max_rx_lifetime);
    596	WSM_PUT32(buf, arg->params[1].max_rx_lifetime);
    597	WSM_PUT32(buf, arg->params[0].max_rx_lifetime);
    598
    599	ret = wsm_cmd_send(priv, buf, NULL,
    600			   WSM_EDCA_PARAMS_REQ_ID, WSM_CMD_TIMEOUT);
    601	wsm_cmd_unlock(priv);
    602	return ret;
    603
    604nomem:
    605	wsm_cmd_unlock(priv);
    606	return -ENOMEM;
    607}
    608
    609/* ******************************************************************** */
    610
    611int wsm_switch_channel(struct cw1200_common *priv,
    612			const struct wsm_switch_channel *arg)
    613{
    614	int ret;
    615	struct wsm_buf *buf = &priv->wsm_cmd_buf;
    616
    617	wsm_cmd_lock(priv);
    618
    619	WSM_PUT8(buf, arg->mode);
    620	WSM_PUT8(buf, arg->switch_count);
    621	WSM_PUT16(buf, arg->channel_number);
    622
    623	priv->channel_switch_in_progress = 1;
    624
    625	ret = wsm_cmd_send(priv, buf, NULL,
    626			   WSM_SWITCH_CHANNEL_REQ_ID, WSM_CMD_TIMEOUT);
    627	if (ret)
    628		priv->channel_switch_in_progress = 0;
    629
    630	wsm_cmd_unlock(priv);
    631	return ret;
    632
    633nomem:
    634	wsm_cmd_unlock(priv);
    635	return -ENOMEM;
    636}
    637
    638/* ******************************************************************** */
    639
    640int wsm_set_pm(struct cw1200_common *priv, const struct wsm_set_pm *arg)
    641{
    642	int ret;
    643	struct wsm_buf *buf = &priv->wsm_cmd_buf;
    644	priv->ps_mode_switch_in_progress = 1;
    645
    646	wsm_cmd_lock(priv);
    647
    648	WSM_PUT8(buf, arg->mode);
    649	WSM_PUT8(buf, arg->fast_psm_idle_period);
    650	WSM_PUT8(buf, arg->ap_psm_change_period);
    651	WSM_PUT8(buf, arg->min_auto_pspoll_period);
    652
    653	ret = wsm_cmd_send(priv, buf, NULL,
    654			   WSM_SET_PM_REQ_ID, WSM_CMD_TIMEOUT);
    655
    656	wsm_cmd_unlock(priv);
    657	return ret;
    658
    659nomem:
    660	wsm_cmd_unlock(priv);
    661	return -ENOMEM;
    662}
    663
    664/* ******************************************************************** */
    665
    666int wsm_start(struct cw1200_common *priv, const struct wsm_start *arg)
    667{
    668	int ret;
    669	struct wsm_buf *buf = &priv->wsm_cmd_buf;
    670
    671	wsm_cmd_lock(priv);
    672
    673	WSM_PUT8(buf, arg->mode);
    674	WSM_PUT8(buf, arg->band);
    675	WSM_PUT16(buf, arg->channel_number);
    676	WSM_PUT32(buf, arg->ct_window);
    677	WSM_PUT32(buf, arg->beacon_interval);
    678	WSM_PUT8(buf, arg->dtim_period);
    679	WSM_PUT8(buf, arg->preamble);
    680	WSM_PUT8(buf, arg->probe_delay);
    681	WSM_PUT8(buf, arg->ssid_len);
    682	WSM_PUT(buf, arg->ssid, sizeof(arg->ssid));
    683	WSM_PUT32(buf, arg->basic_rate_set);
    684
    685	priv->tx_burst_idx = -1;
    686	ret = wsm_cmd_send(priv, buf, NULL,
    687			   WSM_START_REQ_ID, WSM_CMD_START_TIMEOUT);
    688
    689	wsm_cmd_unlock(priv);
    690	return ret;
    691
    692nomem:
    693	wsm_cmd_unlock(priv);
    694	return -ENOMEM;
    695}
    696
    697/* ******************************************************************** */
    698
    699int wsm_beacon_transmit(struct cw1200_common *priv,
    700			const struct wsm_beacon_transmit *arg)
    701{
    702	int ret;
    703	struct wsm_buf *buf = &priv->wsm_cmd_buf;
    704
    705	wsm_cmd_lock(priv);
    706
    707	WSM_PUT32(buf, arg->enable_beaconing ? 1 : 0);
    708
    709	ret = wsm_cmd_send(priv, buf, NULL,
    710			   WSM_BEACON_TRANSMIT_REQ_ID, WSM_CMD_TIMEOUT);
    711
    712	wsm_cmd_unlock(priv);
    713	return ret;
    714
    715nomem:
    716	wsm_cmd_unlock(priv);
    717	return -ENOMEM;
    718}
    719
    720/* ******************************************************************** */
    721
    722int wsm_start_find(struct cw1200_common *priv)
    723{
    724	int ret;
    725	struct wsm_buf *buf = &priv->wsm_cmd_buf;
    726
    727	wsm_cmd_lock(priv);
    728	ret = wsm_cmd_send(priv, buf, NULL, 0x0019, WSM_CMD_TIMEOUT);
    729	wsm_cmd_unlock(priv);
    730	return ret;
    731}
    732
    733/* ******************************************************************** */
    734
    735int wsm_stop_find(struct cw1200_common *priv)
    736{
    737	int ret;
    738	struct wsm_buf *buf = &priv->wsm_cmd_buf;
    739
    740	wsm_cmd_lock(priv);
    741	ret = wsm_cmd_send(priv, buf, NULL, 0x001A, WSM_CMD_TIMEOUT);
    742	wsm_cmd_unlock(priv);
    743	return ret;
    744}
    745
    746/* ******************************************************************** */
    747
    748int wsm_map_link(struct cw1200_common *priv, const struct wsm_map_link *arg)
    749{
    750	int ret;
    751	struct wsm_buf *buf = &priv->wsm_cmd_buf;
    752	u16 cmd = 0x001C | WSM_TX_LINK_ID(arg->link_id);
    753
    754	wsm_cmd_lock(priv);
    755
    756	WSM_PUT(buf, &arg->mac_addr[0], sizeof(arg->mac_addr));
    757	WSM_PUT16(buf, 0);
    758
    759	ret = wsm_cmd_send(priv, buf, NULL, cmd, WSM_CMD_TIMEOUT);
    760
    761	wsm_cmd_unlock(priv);
    762	return ret;
    763
    764nomem:
    765	wsm_cmd_unlock(priv);
    766	return -ENOMEM;
    767}
    768
    769/* ******************************************************************** */
    770
    771int wsm_update_ie(struct cw1200_common *priv,
    772		  const struct wsm_update_ie *arg)
    773{
    774	int ret;
    775	struct wsm_buf *buf = &priv->wsm_cmd_buf;
    776
    777	wsm_cmd_lock(priv);
    778
    779	WSM_PUT16(buf, arg->what);
    780	WSM_PUT16(buf, arg->count);
    781	WSM_PUT(buf, arg->ies, arg->length);
    782
    783	ret = wsm_cmd_send(priv, buf, NULL, 0x001B, WSM_CMD_TIMEOUT);
    784
    785	wsm_cmd_unlock(priv);
    786	return ret;
    787
    788nomem:
    789	wsm_cmd_unlock(priv);
    790	return -ENOMEM;
    791}
    792
    793/* ******************************************************************** */
    794int wsm_set_probe_responder(struct cw1200_common *priv, bool enable)
    795{
    796	priv->rx_filter.probeResponder = enable;
    797	return wsm_set_rx_filter(priv, &priv->rx_filter);
    798}
    799
    800/* ******************************************************************** */
    801/* WSM indication events implementation					*/
    802const char * const cw1200_fw_types[] = {
    803	"ETF",
    804	"WFM",
    805	"WSM",
    806	"HI test",
    807	"Platform test"
    808};
    809
    810static int wsm_startup_indication(struct cw1200_common *priv,
    811					struct wsm_buf *buf)
    812{
    813	priv->wsm_caps.input_buffers     = WSM_GET16(buf);
    814	priv->wsm_caps.input_buffer_size = WSM_GET16(buf);
    815	priv->wsm_caps.hw_id	  = WSM_GET16(buf);
    816	priv->wsm_caps.hw_subid	  = WSM_GET16(buf);
    817	priv->wsm_caps.status	  = WSM_GET16(buf);
    818	priv->wsm_caps.fw_cap	  = WSM_GET16(buf);
    819	priv->wsm_caps.fw_type	  = WSM_GET16(buf);
    820	priv->wsm_caps.fw_api	  = WSM_GET16(buf);
    821	priv->wsm_caps.fw_build   = WSM_GET16(buf);
    822	priv->wsm_caps.fw_ver     = WSM_GET16(buf);
    823	WSM_GET(buf, priv->wsm_caps.fw_label, sizeof(priv->wsm_caps.fw_label));
    824	priv->wsm_caps.fw_label[sizeof(priv->wsm_caps.fw_label) - 1] = 0; /* Do not trust FW too much... */
    825
    826	if (WARN_ON(priv->wsm_caps.status))
    827		return -EINVAL;
    828
    829	if (WARN_ON(priv->wsm_caps.fw_type > 4))
    830		return -EINVAL;
    831
    832	pr_info("CW1200 WSM init done.\n"
    833		"   Input buffers: %d x %d bytes\n"
    834		"   Hardware: %d.%d\n"
    835		"   %s firmware [%s], ver: %d, build: %d,"
    836		"   api: %d, cap: 0x%.4X\n",
    837		priv->wsm_caps.input_buffers,
    838		priv->wsm_caps.input_buffer_size,
    839		priv->wsm_caps.hw_id, priv->wsm_caps.hw_subid,
    840		cw1200_fw_types[priv->wsm_caps.fw_type],
    841		priv->wsm_caps.fw_label, priv->wsm_caps.fw_ver,
    842		priv->wsm_caps.fw_build,
    843		priv->wsm_caps.fw_api, priv->wsm_caps.fw_cap);
    844
    845	/* Disable unsupported frequency bands */
    846	if (!(priv->wsm_caps.fw_cap & 0x1))
    847		priv->hw->wiphy->bands[NL80211_BAND_2GHZ] = NULL;
    848	if (!(priv->wsm_caps.fw_cap & 0x2))
    849		priv->hw->wiphy->bands[NL80211_BAND_5GHZ] = NULL;
    850
    851	priv->firmware_ready = 1;
    852	wake_up(&priv->wsm_startup_done);
    853	return 0;
    854
    855underflow:
    856	WARN_ON(1);
    857	return -EINVAL;
    858}
    859
    860static int wsm_receive_indication(struct cw1200_common *priv,
    861				  int link_id,
    862				  struct wsm_buf *buf,
    863				  struct sk_buff **skb_p)
    864{
    865	struct wsm_rx rx;
    866	struct ieee80211_hdr *hdr;
    867	size_t hdr_len;
    868	__le16 fctl;
    869
    870	rx.status = WSM_GET32(buf);
    871	rx.channel_number = WSM_GET16(buf);
    872	rx.rx_rate = WSM_GET8(buf);
    873	rx.rcpi_rssi = WSM_GET8(buf);
    874	rx.flags = WSM_GET32(buf);
    875
    876	/* FW Workaround: Drop probe resp or
    877	   beacon when RSSI is 0
    878	*/
    879	hdr = (struct ieee80211_hdr *)(*skb_p)->data;
    880
    881	if (!rx.rcpi_rssi &&
    882	    (ieee80211_is_probe_resp(hdr->frame_control) ||
    883	     ieee80211_is_beacon(hdr->frame_control)))
    884		return 0;
    885
    886	/* If no RSSI subscription has been made,
    887	 * convert RCPI to RSSI here
    888	 */
    889	if (!priv->cqm_use_rssi)
    890		rx.rcpi_rssi = rx.rcpi_rssi / 2 - 110;
    891
    892	fctl = *(__le16 *)buf->data;
    893	hdr_len = buf->data - buf->begin;
    894	skb_pull(*skb_p, hdr_len);
    895	if (!rx.status && ieee80211_is_deauth(fctl)) {
    896		if (priv->join_status == CW1200_JOIN_STATUS_STA) {
    897			/* Shedule unjoin work */
    898			pr_debug("[WSM] Issue unjoin command (RX).\n");
    899			wsm_lock_tx_async(priv);
    900			if (queue_work(priv->workqueue,
    901				       &priv->unjoin_work) <= 0)
    902				wsm_unlock_tx(priv);
    903		}
    904	}
    905	cw1200_rx_cb(priv, &rx, link_id, skb_p);
    906	if (*skb_p)
    907		skb_push(*skb_p, hdr_len);
    908
    909	return 0;
    910
    911underflow:
    912	return -EINVAL;
    913}
    914
    915static int wsm_event_indication(struct cw1200_common *priv, struct wsm_buf *buf)
    916{
    917	int first;
    918	struct cw1200_wsm_event *event;
    919
    920	if (priv->mode == NL80211_IFTYPE_UNSPECIFIED) {
    921		/* STA is stopped. */
    922		return 0;
    923	}
    924
    925	event = kzalloc(sizeof(struct cw1200_wsm_event), GFP_KERNEL);
    926	if (!event)
    927		return -ENOMEM;
    928
    929	event->evt.id = WSM_GET32(buf);
    930	event->evt.data = WSM_GET32(buf);
    931
    932	pr_debug("[WSM] Event: %d(%d)\n",
    933		 event->evt.id, event->evt.data);
    934
    935	spin_lock(&priv->event_queue_lock);
    936	first = list_empty(&priv->event_queue);
    937	list_add_tail(&event->link, &priv->event_queue);
    938	spin_unlock(&priv->event_queue_lock);
    939
    940	if (first)
    941		queue_work(priv->workqueue, &priv->event_handler);
    942
    943	return 0;
    944
    945underflow:
    946	kfree(event);
    947	return -EINVAL;
    948}
    949
    950static int wsm_channel_switch_indication(struct cw1200_common *priv,
    951					 struct wsm_buf *buf)
    952{
    953	WARN_ON(WSM_GET32(buf));
    954
    955	priv->channel_switch_in_progress = 0;
    956	wake_up(&priv->channel_switch_done);
    957
    958	wsm_unlock_tx(priv);
    959
    960	return 0;
    961
    962underflow:
    963	return -EINVAL;
    964}
    965
    966static int wsm_set_pm_indication(struct cw1200_common *priv,
    967				 struct wsm_buf *buf)
    968{
    969	/* TODO:  Check buf (struct wsm_set_pm_complete) for validity */
    970	if (priv->ps_mode_switch_in_progress) {
    971		priv->ps_mode_switch_in_progress = 0;
    972		wake_up(&priv->ps_mode_switch_done);
    973	}
    974	return 0;
    975}
    976
    977static int wsm_scan_started(struct cw1200_common *priv, void *arg,
    978			    struct wsm_buf *buf)
    979{
    980	u32 status = WSM_GET32(buf);
    981	if (status != WSM_STATUS_SUCCESS) {
    982		cw1200_scan_failed_cb(priv);
    983		return -EINVAL;
    984	}
    985	return 0;
    986
    987underflow:
    988	WARN_ON(1);
    989	return -EINVAL;
    990}
    991
    992static int wsm_scan_complete_indication(struct cw1200_common *priv,
    993					struct wsm_buf *buf)
    994{
    995	struct wsm_scan_complete arg;
    996	arg.status = WSM_GET32(buf);
    997	arg.psm = WSM_GET8(buf);
    998	arg.num_channels = WSM_GET8(buf);
    999	cw1200_scan_complete_cb(priv, &arg);
   1000
   1001	return 0;
   1002
   1003underflow:
   1004	return -EINVAL;
   1005}
   1006
   1007static int wsm_join_complete_indication(struct cw1200_common *priv,
   1008					struct wsm_buf *buf)
   1009{
   1010	struct wsm_join_complete arg;
   1011	arg.status = WSM_GET32(buf);
   1012	pr_debug("[WSM] Join complete indication, status: %d\n", arg.status);
   1013	cw1200_join_complete_cb(priv, &arg);
   1014
   1015	return 0;
   1016
   1017underflow:
   1018	return -EINVAL;
   1019}
   1020
   1021static int wsm_find_complete_indication(struct cw1200_common *priv,
   1022					struct wsm_buf *buf)
   1023{
   1024	pr_warn("Implement find_complete_indication\n");
   1025	return 0;
   1026}
   1027
   1028static int wsm_ba_timeout_indication(struct cw1200_common *priv,
   1029				     struct wsm_buf *buf)
   1030{
   1031	u8 tid;
   1032	u8 addr[ETH_ALEN];
   1033
   1034	WSM_GET32(buf);
   1035	tid = WSM_GET8(buf);
   1036	WSM_GET8(buf);
   1037	WSM_GET(buf, addr, ETH_ALEN);
   1038
   1039	pr_info("BlockACK timeout, tid %d, addr %pM\n",
   1040		tid, addr);
   1041
   1042	return 0;
   1043
   1044underflow:
   1045	return -EINVAL;
   1046}
   1047
   1048static int wsm_suspend_resume_indication(struct cw1200_common *priv,
   1049					 int link_id, struct wsm_buf *buf)
   1050{
   1051	u32 flags;
   1052	struct wsm_suspend_resume arg;
   1053
   1054	flags = WSM_GET32(buf);
   1055	arg.link_id = link_id;
   1056	arg.stop = !(flags & 1);
   1057	arg.multicast = !!(flags & 8);
   1058	arg.queue = (flags >> 1) & 3;
   1059
   1060	cw1200_suspend_resume(priv, &arg);
   1061
   1062	return 0;
   1063
   1064underflow:
   1065	return -EINVAL;
   1066}
   1067
   1068
   1069/* ******************************************************************** */
   1070/* WSM TX								*/
   1071
   1072static int wsm_cmd_send(struct cw1200_common *priv,
   1073			struct wsm_buf *buf,
   1074			void *arg, u16 cmd, long tmo)
   1075{
   1076	size_t buf_len = buf->data - buf->begin;
   1077	int ret;
   1078
   1079	/* Don't bother if we're dead. */
   1080	if (priv->bh_error) {
   1081		ret = 0;
   1082		goto done;
   1083	}
   1084
   1085	/* Block until the cmd buffer is completed.  Tortuous. */
   1086	spin_lock(&priv->wsm_cmd.lock);
   1087	while (!priv->wsm_cmd.done) {
   1088		spin_unlock(&priv->wsm_cmd.lock);
   1089		spin_lock(&priv->wsm_cmd.lock);
   1090	}
   1091	priv->wsm_cmd.done = 0;
   1092	spin_unlock(&priv->wsm_cmd.lock);
   1093
   1094	if (cmd == WSM_WRITE_MIB_REQ_ID ||
   1095	    cmd == WSM_READ_MIB_REQ_ID)
   1096		pr_debug("[WSM] >>> 0x%.4X [MIB: 0x%.4X] (%zu)\n",
   1097			 cmd, __le16_to_cpu(((__le16 *)buf->begin)[2]),
   1098			 buf_len);
   1099	else
   1100		pr_debug("[WSM] >>> 0x%.4X (%zu)\n", cmd, buf_len);
   1101
   1102	/* Due to buggy SPI on CW1200, we need to
   1103	 * pad the message by a few bytes to ensure
   1104	 * that it's completely received.
   1105	 */
   1106	buf_len += 4;
   1107
   1108	/* Fill HI message header */
   1109	/* BH will add sequence number */
   1110	((__le16 *)buf->begin)[0] = __cpu_to_le16(buf_len);
   1111	((__le16 *)buf->begin)[1] = __cpu_to_le16(cmd);
   1112
   1113	spin_lock(&priv->wsm_cmd.lock);
   1114	BUG_ON(priv->wsm_cmd.ptr);
   1115	priv->wsm_cmd.ptr = buf->begin;
   1116	priv->wsm_cmd.len = buf_len;
   1117	priv->wsm_cmd.arg = arg;
   1118	priv->wsm_cmd.cmd = cmd;
   1119	spin_unlock(&priv->wsm_cmd.lock);
   1120
   1121	cw1200_bh_wakeup(priv);
   1122
   1123	/* Wait for command completion */
   1124	ret = wait_event_timeout(priv->wsm_cmd_wq,
   1125				 priv->wsm_cmd.done, tmo);
   1126
   1127	if (!ret && !priv->wsm_cmd.done) {
   1128		spin_lock(&priv->wsm_cmd.lock);
   1129		priv->wsm_cmd.done = 1;
   1130		priv->wsm_cmd.ptr = NULL;
   1131		spin_unlock(&priv->wsm_cmd.lock);
   1132		if (priv->bh_error) {
   1133			/* Return ok to help system cleanup */
   1134			ret = 0;
   1135		} else {
   1136			pr_err("CMD req (0x%04x) stuck in firmware, killing BH\n", priv->wsm_cmd.cmd);
   1137			print_hex_dump_bytes("REQDUMP: ", DUMP_PREFIX_NONE,
   1138					     buf->begin, buf_len);
   1139			pr_err("Outstanding outgoing frames:  %d\n", priv->hw_bufs_used);
   1140
   1141			/* Kill BH thread to report the error to the top layer. */
   1142			atomic_inc(&priv->bh_term);
   1143			wake_up(&priv->bh_wq);
   1144			ret = -ETIMEDOUT;
   1145		}
   1146	} else {
   1147		spin_lock(&priv->wsm_cmd.lock);
   1148		BUG_ON(!priv->wsm_cmd.done);
   1149		ret = priv->wsm_cmd.ret;
   1150		spin_unlock(&priv->wsm_cmd.lock);
   1151	}
   1152done:
   1153	wsm_buf_reset(buf);
   1154	return ret;
   1155}
   1156
   1157/* ******************************************************************** */
   1158/* WSM TX port control							*/
   1159
   1160void wsm_lock_tx(struct cw1200_common *priv)
   1161{
   1162	wsm_cmd_lock(priv);
   1163	if (atomic_inc_return(&priv->tx_lock) == 1) {
   1164		if (wsm_flush_tx(priv))
   1165			pr_debug("[WSM] TX is locked.\n");
   1166	}
   1167	wsm_cmd_unlock(priv);
   1168}
   1169
   1170void wsm_lock_tx_async(struct cw1200_common *priv)
   1171{
   1172	if (atomic_inc_return(&priv->tx_lock) == 1)
   1173		pr_debug("[WSM] TX is locked (async).\n");
   1174}
   1175
   1176bool wsm_flush_tx(struct cw1200_common *priv)
   1177{
   1178	unsigned long timestamp = jiffies;
   1179	bool pending = false;
   1180	long timeout;
   1181	int i;
   1182
   1183	/* Flush must be called with TX lock held. */
   1184	BUG_ON(!atomic_read(&priv->tx_lock));
   1185
   1186	/* First check if we really need to do something.
   1187	 * It is safe to use unprotected access, as hw_bufs_used
   1188	 * can only decrements.
   1189	 */
   1190	if (!priv->hw_bufs_used)
   1191		return true;
   1192
   1193	if (priv->bh_error) {
   1194		/* In case of failure do not wait for magic. */
   1195		pr_err("[WSM] Fatal error occurred, will not flush TX.\n");
   1196		return false;
   1197	} else {
   1198		/* Get a timestamp of "oldest" frame */
   1199		for (i = 0; i < 4; ++i)
   1200			pending |= cw1200_queue_get_xmit_timestamp(
   1201					&priv->tx_queue[i],
   1202					&timestamp, 0xffffffff);
   1203		/* If there's nothing pending, we're good */
   1204		if (!pending)
   1205			return true;
   1206
   1207		timeout = timestamp + WSM_CMD_LAST_CHANCE_TIMEOUT - jiffies;
   1208		if (timeout < 0 || wait_event_timeout(priv->bh_evt_wq,
   1209						      !priv->hw_bufs_used,
   1210						      timeout) <= 0) {
   1211			/* Hmmm... Not good. Frame had stuck in firmware. */
   1212			priv->bh_error = 1;
   1213			wiphy_err(priv->hw->wiphy, "[WSM] TX Frames (%d) stuck in firmware, killing BH\n", priv->hw_bufs_used);
   1214			wake_up(&priv->bh_wq);
   1215			return false;
   1216		}
   1217
   1218		/* Ok, everything is flushed. */
   1219		return true;
   1220	}
   1221}
   1222
   1223void wsm_unlock_tx(struct cw1200_common *priv)
   1224{
   1225	int tx_lock;
   1226	tx_lock = atomic_dec_return(&priv->tx_lock);
   1227	BUG_ON(tx_lock < 0);
   1228
   1229	if (tx_lock == 0) {
   1230		if (!priv->bh_error)
   1231			cw1200_bh_wakeup(priv);
   1232		pr_debug("[WSM] TX is unlocked.\n");
   1233	}
   1234}
   1235
   1236/* ******************************************************************** */
   1237/* WSM RX								*/
   1238
   1239int wsm_handle_exception(struct cw1200_common *priv, u8 *data, size_t len)
   1240{
   1241	struct wsm_buf buf;
   1242	u32 reason;
   1243	u32 reg[18];
   1244	char fname[48];
   1245	unsigned int i;
   1246
   1247	static const char * const reason_str[] = {
   1248		"undefined instruction",
   1249		"prefetch abort",
   1250		"data abort",
   1251		"unknown error",
   1252	};
   1253
   1254	buf.begin = buf.data = data;
   1255	buf.end = &buf.begin[len];
   1256
   1257	reason = WSM_GET32(&buf);
   1258	for (i = 0; i < ARRAY_SIZE(reg); ++i)
   1259		reg[i] = WSM_GET32(&buf);
   1260	WSM_GET(&buf, fname, sizeof(fname));
   1261
   1262	if (reason < 4)
   1263		wiphy_err(priv->hw->wiphy,
   1264			  "Firmware exception: %s.\n",
   1265			  reason_str[reason]);
   1266	else
   1267		wiphy_err(priv->hw->wiphy,
   1268			  "Firmware assert at %.*s, line %d\n",
   1269			  (int) sizeof(fname), fname, reg[1]);
   1270
   1271	for (i = 0; i < 12; i += 4)
   1272		wiphy_err(priv->hw->wiphy,
   1273			  "R%d: 0x%.8X, R%d: 0x%.8X, R%d: 0x%.8X, R%d: 0x%.8X,\n",
   1274			  i + 0, reg[i + 0], i + 1, reg[i + 1],
   1275			  i + 2, reg[i + 2], i + 3, reg[i + 3]);
   1276	wiphy_err(priv->hw->wiphy,
   1277		  "R12: 0x%.8X, SP: 0x%.8X, LR: 0x%.8X, PC: 0x%.8X,\n",
   1278		  reg[i + 0], reg[i + 1], reg[i + 2], reg[i + 3]);
   1279	i += 4;
   1280	wiphy_err(priv->hw->wiphy,
   1281		  "CPSR: 0x%.8X, SPSR: 0x%.8X\n",
   1282		  reg[i + 0], reg[i + 1]);
   1283
   1284	print_hex_dump_bytes("R1: ", DUMP_PREFIX_NONE,
   1285			     fname, sizeof(fname));
   1286	return 0;
   1287
   1288underflow:
   1289	wiphy_err(priv->hw->wiphy, "Firmware exception.\n");
   1290	print_hex_dump_bytes("Exception: ", DUMP_PREFIX_NONE,
   1291			     data, len);
   1292	return -EINVAL;
   1293}
   1294
   1295int wsm_handle_rx(struct cw1200_common *priv, u16 id,
   1296		  struct wsm_hdr *wsm, struct sk_buff **skb_p)
   1297{
   1298	int ret = 0;
   1299	struct wsm_buf wsm_buf;
   1300	int link_id = (id >> 6) & 0x0F;
   1301
   1302	/* Strip link id. */
   1303	id &= ~WSM_TX_LINK_ID(WSM_TX_LINK_ID_MAX);
   1304
   1305	wsm_buf.begin = (u8 *)&wsm[0];
   1306	wsm_buf.data = (u8 *)&wsm[1];
   1307	wsm_buf.end = &wsm_buf.begin[__le16_to_cpu(wsm->len)];
   1308
   1309	pr_debug("[WSM] <<< 0x%.4X (%td)\n", id,
   1310		 wsm_buf.end - wsm_buf.begin);
   1311
   1312	if (id == WSM_TX_CONFIRM_IND_ID) {
   1313		ret = wsm_tx_confirm(priv, &wsm_buf, link_id);
   1314	} else if (id == WSM_MULTI_TX_CONFIRM_ID) {
   1315		ret = wsm_multi_tx_confirm(priv, &wsm_buf, link_id);
   1316	} else if (id & 0x0400) {
   1317		void *wsm_arg;
   1318		u16 wsm_cmd;
   1319
   1320		/* Do not trust FW too much. Protection against repeated
   1321		 * response and race condition removal (see above).
   1322		 */
   1323		spin_lock(&priv->wsm_cmd.lock);
   1324		wsm_arg = priv->wsm_cmd.arg;
   1325		wsm_cmd = priv->wsm_cmd.cmd &
   1326				~WSM_TX_LINK_ID(WSM_TX_LINK_ID_MAX);
   1327		priv->wsm_cmd.cmd = 0xFFFF;
   1328		spin_unlock(&priv->wsm_cmd.lock);
   1329
   1330		if (WARN_ON((id & ~0x0400) != wsm_cmd)) {
   1331			/* Note that any non-zero is a fatal retcode. */
   1332			ret = -EINVAL;
   1333			goto out;
   1334		}
   1335
   1336		/* Note that wsm_arg can be NULL in case of timeout in
   1337		 * wsm_cmd_send().
   1338		 */
   1339
   1340		switch (id) {
   1341		case WSM_READ_MIB_RESP_ID:
   1342			if (wsm_arg)
   1343				ret = wsm_read_mib_confirm(priv, wsm_arg,
   1344								&wsm_buf);
   1345			break;
   1346		case WSM_WRITE_MIB_RESP_ID:
   1347			if (wsm_arg)
   1348				ret = wsm_write_mib_confirm(priv, wsm_arg,
   1349							    &wsm_buf);
   1350			break;
   1351		case WSM_START_SCAN_RESP_ID:
   1352			if (wsm_arg)
   1353				ret = wsm_scan_started(priv, wsm_arg, &wsm_buf);
   1354			break;
   1355		case WSM_CONFIGURATION_RESP_ID:
   1356			if (wsm_arg)
   1357				ret = wsm_configuration_confirm(priv, wsm_arg,
   1358								&wsm_buf);
   1359			break;
   1360		case WSM_JOIN_RESP_ID:
   1361			if (wsm_arg)
   1362				ret = wsm_join_confirm(priv, wsm_arg, &wsm_buf);
   1363			break;
   1364		case WSM_STOP_SCAN_RESP_ID:
   1365		case WSM_RESET_RESP_ID:
   1366		case WSM_ADD_KEY_RESP_ID:
   1367		case WSM_REMOVE_KEY_RESP_ID:
   1368		case WSM_SET_PM_RESP_ID:
   1369		case WSM_SET_BSS_PARAMS_RESP_ID:
   1370		case 0x0412: /* set_tx_queue_params */
   1371		case WSM_EDCA_PARAMS_RESP_ID:
   1372		case WSM_SWITCH_CHANNEL_RESP_ID:
   1373		case WSM_START_RESP_ID:
   1374		case WSM_BEACON_TRANSMIT_RESP_ID:
   1375		case 0x0419: /* start_find */
   1376		case 0x041A: /* stop_find */
   1377		case 0x041B: /* update_ie */
   1378		case 0x041C: /* map_link */
   1379			WARN_ON(wsm_arg != NULL);
   1380			ret = wsm_generic_confirm(priv, wsm_arg, &wsm_buf);
   1381			if (ret) {
   1382				wiphy_warn(priv->hw->wiphy,
   1383					   "wsm_generic_confirm failed for request 0x%04x.\n",
   1384					   id & ~0x0400);
   1385
   1386				/* often 0x407 and 0x410 occur, this means we're dead.. */
   1387				if (priv->join_status >= CW1200_JOIN_STATUS_JOINING) {
   1388					wsm_lock_tx(priv);
   1389					if (queue_work(priv->workqueue, &priv->unjoin_work) <= 0)
   1390						wsm_unlock_tx(priv);
   1391				}
   1392			}
   1393			break;
   1394		default:
   1395			wiphy_warn(priv->hw->wiphy,
   1396				   "Unrecognized confirmation 0x%04x\n",
   1397				   id & ~0x0400);
   1398		}
   1399
   1400		spin_lock(&priv->wsm_cmd.lock);
   1401		priv->wsm_cmd.ret = ret;
   1402		priv->wsm_cmd.done = 1;
   1403		spin_unlock(&priv->wsm_cmd.lock);
   1404
   1405		ret = 0; /* Error response from device should ne stop BH. */
   1406
   1407		wake_up(&priv->wsm_cmd_wq);
   1408	} else if (id & 0x0800) {
   1409		switch (id) {
   1410		case WSM_STARTUP_IND_ID:
   1411			ret = wsm_startup_indication(priv, &wsm_buf);
   1412			break;
   1413		case WSM_RECEIVE_IND_ID:
   1414			ret = wsm_receive_indication(priv, link_id,
   1415						     &wsm_buf, skb_p);
   1416			break;
   1417		case 0x0805:
   1418			ret = wsm_event_indication(priv, &wsm_buf);
   1419			break;
   1420		case WSM_SCAN_COMPLETE_IND_ID:
   1421			ret = wsm_scan_complete_indication(priv, &wsm_buf);
   1422			break;
   1423		case 0x0808:
   1424			ret = wsm_ba_timeout_indication(priv, &wsm_buf);
   1425			break;
   1426		case 0x0809:
   1427			ret = wsm_set_pm_indication(priv, &wsm_buf);
   1428			break;
   1429		case 0x080A:
   1430			ret = wsm_channel_switch_indication(priv, &wsm_buf);
   1431			break;
   1432		case 0x080B:
   1433			ret = wsm_find_complete_indication(priv, &wsm_buf);
   1434			break;
   1435		case 0x080C:
   1436			ret = wsm_suspend_resume_indication(priv,
   1437					link_id, &wsm_buf);
   1438			break;
   1439		case 0x080F:
   1440			ret = wsm_join_complete_indication(priv, &wsm_buf);
   1441			break;
   1442		default:
   1443			pr_warn("Unrecognised WSM ID %04x\n", id);
   1444		}
   1445	} else {
   1446		WARN_ON(1);
   1447		ret = -EINVAL;
   1448	}
   1449out:
   1450	return ret;
   1451}
   1452
   1453static bool wsm_handle_tx_data(struct cw1200_common *priv,
   1454			       struct wsm_tx *wsm,
   1455			       const struct ieee80211_tx_info *tx_info,
   1456			       const struct cw1200_txpriv *txpriv,
   1457			       struct cw1200_queue *queue)
   1458{
   1459	bool handled = false;
   1460	const struct ieee80211_hdr *frame =
   1461		(struct ieee80211_hdr *)&((u8 *)wsm)[txpriv->offset];
   1462	__le16 fctl = frame->frame_control;
   1463	enum {
   1464		do_probe,
   1465		do_drop,
   1466		do_wep,
   1467		do_tx,
   1468	} action = do_tx;
   1469
   1470	switch (priv->mode) {
   1471	case NL80211_IFTYPE_STATION:
   1472		if (priv->join_status == CW1200_JOIN_STATUS_MONITOR)
   1473			action = do_tx;
   1474		else if (priv->join_status < CW1200_JOIN_STATUS_PRE_STA)
   1475			action = do_drop;
   1476		break;
   1477	case NL80211_IFTYPE_AP:
   1478		if (!priv->join_status) {
   1479			action = do_drop;
   1480		} else if (!(BIT(txpriv->raw_link_id) &
   1481			     (BIT(0) | priv->link_id_map))) {
   1482			wiphy_warn(priv->hw->wiphy,
   1483				   "A frame with expired link id is dropped.\n");
   1484			action = do_drop;
   1485		}
   1486		if (cw1200_queue_get_generation(wsm->packet_id) >
   1487				CW1200_MAX_REQUEUE_ATTEMPTS) {
   1488			/* HACK!!! WSM324 firmware has tendency to requeue
   1489			 * multicast frames in a loop, causing performance
   1490			 * drop and high power consumption of the driver.
   1491			 * In this situation it is better just to drop
   1492			 * the problematic frame.
   1493			 */
   1494			wiphy_warn(priv->hw->wiphy,
   1495				   "Too many attempts to requeue a frame; dropped.\n");
   1496			action = do_drop;
   1497		}
   1498		break;
   1499	case NL80211_IFTYPE_ADHOC:
   1500		if (priv->join_status != CW1200_JOIN_STATUS_IBSS)
   1501			action = do_drop;
   1502		break;
   1503	case NL80211_IFTYPE_MESH_POINT:
   1504		action = do_tx; /* TODO:  Test me! */
   1505		break;
   1506	case NL80211_IFTYPE_MONITOR:
   1507	default:
   1508		action = do_drop;
   1509		break;
   1510	}
   1511
   1512	if (action == do_tx) {
   1513		if (ieee80211_is_nullfunc(fctl)) {
   1514			spin_lock(&priv->bss_loss_lock);
   1515			if (priv->bss_loss_state) {
   1516				priv->bss_loss_confirm_id = wsm->packet_id;
   1517				wsm->queue_id = WSM_QUEUE_VOICE;
   1518			}
   1519			spin_unlock(&priv->bss_loss_lock);
   1520		} else if (ieee80211_is_probe_req(fctl)) {
   1521			action = do_probe;
   1522		} else if (ieee80211_is_deauth(fctl) &&
   1523			   priv->mode != NL80211_IFTYPE_AP) {
   1524			pr_debug("[WSM] Issue unjoin command due to tx deauth.\n");
   1525			wsm_lock_tx_async(priv);
   1526			if (queue_work(priv->workqueue,
   1527				       &priv->unjoin_work) <= 0)
   1528				wsm_unlock_tx(priv);
   1529		} else if (ieee80211_has_protected(fctl) &&
   1530			   tx_info->control.hw_key &&
   1531			   tx_info->control.hw_key->keyidx != priv->wep_default_key_id &&
   1532			   (tx_info->control.hw_key->cipher == WLAN_CIPHER_SUITE_WEP40 ||
   1533			    tx_info->control.hw_key->cipher == WLAN_CIPHER_SUITE_WEP104)) {
   1534			action = do_wep;
   1535		}
   1536	}
   1537
   1538	switch (action) {
   1539	case do_probe:
   1540		/* An interesting FW "feature". Device filters probe responses.
   1541		 * The easiest way to get it back is to convert
   1542		 * probe request into WSM start_scan command.
   1543		 */
   1544		pr_debug("[WSM] Convert probe request to scan.\n");
   1545		wsm_lock_tx_async(priv);
   1546		priv->pending_frame_id = wsm->packet_id;
   1547		if (queue_delayed_work(priv->workqueue,
   1548				       &priv->scan.probe_work, 0) <= 0)
   1549			wsm_unlock_tx(priv);
   1550		handled = true;
   1551		break;
   1552	case do_drop:
   1553		pr_debug("[WSM] Drop frame (0x%.4X).\n", fctl);
   1554		BUG_ON(cw1200_queue_remove(queue, wsm->packet_id));
   1555		handled = true;
   1556		break;
   1557	case do_wep:
   1558		pr_debug("[WSM] Issue set_default_wep_key.\n");
   1559		wsm_lock_tx_async(priv);
   1560		priv->wep_default_key_id = tx_info->control.hw_key->keyidx;
   1561		priv->pending_frame_id = wsm->packet_id;
   1562		if (queue_work(priv->workqueue, &priv->wep_key_work) <= 0)
   1563			wsm_unlock_tx(priv);
   1564		handled = true;
   1565		break;
   1566	case do_tx:
   1567		pr_debug("[WSM] Transmit frame.\n");
   1568		break;
   1569	default:
   1570		/* Do nothing */
   1571		break;
   1572	}
   1573	return handled;
   1574}
   1575
   1576static int cw1200_get_prio_queue(struct cw1200_common *priv,
   1577				 u32 link_id_map, int *total)
   1578{
   1579	static const int urgent = BIT(CW1200_LINK_ID_AFTER_DTIM) |
   1580		BIT(CW1200_LINK_ID_UAPSD);
   1581	struct wsm_edca_queue_params *edca;
   1582	unsigned score, best = -1;
   1583	int winner = -1;
   1584	int queued;
   1585	int i;
   1586
   1587	/* search for a winner using edca params */
   1588	for (i = 0; i < 4; ++i) {
   1589		queued = cw1200_queue_get_num_queued(&priv->tx_queue[i],
   1590				link_id_map);
   1591		if (!queued)
   1592			continue;
   1593		*total += queued;
   1594		edca = &priv->edca.params[i];
   1595		score = ((edca->aifns + edca->cwmin) << 16) +
   1596			((edca->cwmax - edca->cwmin) *
   1597			 (get_random_int() & 0xFFFF));
   1598		if (score < best && (winner < 0 || i != 3)) {
   1599			best = score;
   1600			winner = i;
   1601		}
   1602	}
   1603
   1604	/* override winner if bursting */
   1605	if (winner >= 0 && priv->tx_burst_idx >= 0 &&
   1606	    winner != priv->tx_burst_idx &&
   1607	    !cw1200_queue_get_num_queued(
   1608		    &priv->tx_queue[winner],
   1609		    link_id_map & urgent) &&
   1610	    cw1200_queue_get_num_queued(
   1611		    &priv->tx_queue[priv->tx_burst_idx],
   1612		    link_id_map))
   1613		winner = priv->tx_burst_idx;
   1614
   1615	return winner;
   1616}
   1617
   1618static int wsm_get_tx_queue_and_mask(struct cw1200_common *priv,
   1619				     struct cw1200_queue **queue_p,
   1620				     u32 *tx_allowed_mask_p,
   1621				     bool *more)
   1622{
   1623	int idx;
   1624	u32 tx_allowed_mask;
   1625	int total = 0;
   1626
   1627	/* Search for a queue with multicast frames buffered */
   1628	if (priv->tx_multicast) {
   1629		tx_allowed_mask = BIT(CW1200_LINK_ID_AFTER_DTIM);
   1630		idx = cw1200_get_prio_queue(priv,
   1631				tx_allowed_mask, &total);
   1632		if (idx >= 0) {
   1633			*more = total > 1;
   1634			goto found;
   1635		}
   1636	}
   1637
   1638	/* Search for unicast traffic */
   1639	tx_allowed_mask = ~priv->sta_asleep_mask;
   1640	tx_allowed_mask |= BIT(CW1200_LINK_ID_UAPSD);
   1641	if (priv->sta_asleep_mask) {
   1642		tx_allowed_mask |= priv->pspoll_mask;
   1643		tx_allowed_mask &= ~BIT(CW1200_LINK_ID_AFTER_DTIM);
   1644	} else {
   1645		tx_allowed_mask |= BIT(CW1200_LINK_ID_AFTER_DTIM);
   1646	}
   1647	idx = cw1200_get_prio_queue(priv,
   1648			tx_allowed_mask, &total);
   1649	if (idx < 0)
   1650		return -ENOENT;
   1651
   1652found:
   1653	*queue_p = &priv->tx_queue[idx];
   1654	*tx_allowed_mask_p = tx_allowed_mask;
   1655	return 0;
   1656}
   1657
   1658int wsm_get_tx(struct cw1200_common *priv, u8 **data,
   1659	       size_t *tx_len, int *burst)
   1660{
   1661	struct wsm_tx *wsm = NULL;
   1662	struct ieee80211_tx_info *tx_info;
   1663	struct cw1200_queue *queue = NULL;
   1664	int queue_num;
   1665	u32 tx_allowed_mask = 0;
   1666	const struct cw1200_txpriv *txpriv = NULL;
   1667	int count = 0;
   1668
   1669	/* More is used only for broadcasts. */
   1670	bool more = false;
   1671
   1672	if (priv->wsm_cmd.ptr) { /* CMD request */
   1673		++count;
   1674		spin_lock(&priv->wsm_cmd.lock);
   1675		BUG_ON(!priv->wsm_cmd.ptr);
   1676		*data = priv->wsm_cmd.ptr;
   1677		*tx_len = priv->wsm_cmd.len;
   1678		*burst = 1;
   1679		spin_unlock(&priv->wsm_cmd.lock);
   1680	} else {
   1681		for (;;) {
   1682			int ret;
   1683
   1684			if (atomic_add_return(0, &priv->tx_lock))
   1685				break;
   1686
   1687			spin_lock_bh(&priv->ps_state_lock);
   1688
   1689			ret = wsm_get_tx_queue_and_mask(priv, &queue,
   1690							&tx_allowed_mask, &more);
   1691			queue_num = queue - priv->tx_queue;
   1692
   1693			if (priv->buffered_multicasts &&
   1694			    (ret || !more) &&
   1695			    (priv->tx_multicast || !priv->sta_asleep_mask)) {
   1696				priv->buffered_multicasts = false;
   1697				if (priv->tx_multicast) {
   1698					priv->tx_multicast = false;
   1699					queue_work(priv->workqueue,
   1700						   &priv->multicast_stop_work);
   1701				}
   1702			}
   1703
   1704			spin_unlock_bh(&priv->ps_state_lock);
   1705
   1706			if (ret)
   1707				break;
   1708
   1709			if (cw1200_queue_get(queue,
   1710					     tx_allowed_mask,
   1711					     &wsm, &tx_info, &txpriv))
   1712				continue;
   1713
   1714			if (wsm_handle_tx_data(priv, wsm,
   1715					       tx_info, txpriv, queue))
   1716				continue;  /* Handled by WSM */
   1717
   1718			wsm->hdr.id &= __cpu_to_le16(
   1719				~WSM_TX_LINK_ID(WSM_TX_LINK_ID_MAX));
   1720			wsm->hdr.id |= cpu_to_le16(
   1721				WSM_TX_LINK_ID(txpriv->raw_link_id));
   1722			priv->pspoll_mask &= ~BIT(txpriv->raw_link_id);
   1723
   1724			*data = (u8 *)wsm;
   1725			*tx_len = __le16_to_cpu(wsm->hdr.len);
   1726
   1727			/* allow bursting if txop is set */
   1728			if (priv->edca.params[queue_num].txop_limit)
   1729				*burst = min(*burst,
   1730					     (int)cw1200_queue_get_num_queued(queue, tx_allowed_mask) + 1);
   1731			else
   1732				*burst = 1;
   1733
   1734			/* store index of bursting queue */
   1735			if (*burst > 1)
   1736				priv->tx_burst_idx = queue_num;
   1737			else
   1738				priv->tx_burst_idx = -1;
   1739
   1740			if (more) {
   1741				struct ieee80211_hdr *hdr =
   1742					(struct ieee80211_hdr *)
   1743					&((u8 *)wsm)[txpriv->offset];
   1744				/* more buffered multicast/broadcast frames
   1745				 *  ==> set MoreData flag in IEEE 802.11 header
   1746				 *  to inform PS STAs
   1747				 */
   1748				hdr->frame_control |=
   1749					cpu_to_le16(IEEE80211_FCTL_MOREDATA);
   1750			}
   1751
   1752			pr_debug("[WSM] >>> 0x%.4X (%zu) %p %c\n",
   1753				 0x0004, *tx_len, *data,
   1754				 wsm->more ? 'M' : ' ');
   1755			++count;
   1756			break;
   1757		}
   1758	}
   1759
   1760	return count;
   1761}
   1762
   1763void wsm_txed(struct cw1200_common *priv, u8 *data)
   1764{
   1765	if (data == priv->wsm_cmd.ptr) {
   1766		spin_lock(&priv->wsm_cmd.lock);
   1767		priv->wsm_cmd.ptr = NULL;
   1768		spin_unlock(&priv->wsm_cmd.lock);
   1769	}
   1770}
   1771
   1772/* ******************************************************************** */
   1773/* WSM buffer								*/
   1774
   1775void wsm_buf_init(struct wsm_buf *buf)
   1776{
   1777	BUG_ON(buf->begin);
   1778	buf->begin = kmalloc(FWLOAD_BLOCK_SIZE, GFP_KERNEL | GFP_DMA);
   1779	buf->end = buf->begin ? &buf->begin[FWLOAD_BLOCK_SIZE] : buf->begin;
   1780	wsm_buf_reset(buf);
   1781}
   1782
   1783void wsm_buf_deinit(struct wsm_buf *buf)
   1784{
   1785	kfree(buf->begin);
   1786	buf->begin = buf->data = buf->end = NULL;
   1787}
   1788
   1789static void wsm_buf_reset(struct wsm_buf *buf)
   1790{
   1791	if (buf->begin) {
   1792		buf->data = &buf->begin[4];
   1793		*(u32 *)buf->begin = 0;
   1794	} else {
   1795		buf->data = buf->begin;
   1796	}
   1797}
   1798
   1799static int wsm_buf_reserve(struct wsm_buf *buf, size_t extra_size)
   1800{
   1801	size_t pos = buf->data - buf->begin;
   1802	size_t size = pos + extra_size;
   1803	u8 *tmp;
   1804
   1805	size = round_up(size, FWLOAD_BLOCK_SIZE);
   1806
   1807	tmp = krealloc(buf->begin, size, GFP_KERNEL | GFP_DMA);
   1808	if (!tmp) {
   1809		wsm_buf_deinit(buf);
   1810		return -ENOMEM;
   1811	}
   1812
   1813	buf->begin = tmp;
   1814	buf->data = &buf->begin[pos];
   1815	buf->end = &buf->begin[size];
   1816	return 0;
   1817}